@@ -846,6 +846,36 @@ int dax_delete_mapping_entry(struct address_space *mapping, pgoff_t index)
846
846
return ret ;
847
847
}
848
848
849
+ void dax_delete_mapping_range (struct address_space * mapping ,
850
+ loff_t start , loff_t end )
851
+ {
852
+ void * entry ;
853
+ pgoff_t start_idx = start >> PAGE_SHIFT ;
854
+ pgoff_t end_idx ;
855
+ XA_STATE (xas , & mapping -> i_pages , start_idx );
856
+
857
+ /* If end == LLONG_MAX, all pages from start to till end of file */
858
+ if (end == LLONG_MAX )
859
+ end_idx = ULONG_MAX ;
860
+ else
861
+ end_idx = end >> PAGE_SHIFT ;
862
+
863
+ xas_lock_irq (& xas );
864
+ xas_for_each (& xas , entry , end_idx ) {
865
+ if (!xa_is_value (entry ))
866
+ continue ;
867
+ entry = wait_entry_unlocked_exclusive (& xas , entry );
868
+ if (!entry )
869
+ continue ;
870
+ dax_disassociate_entry (entry , mapping , true);
871
+ xas_store (& xas , NULL );
872
+ mapping -> nrpages -= 1UL << dax_entry_order (entry );
873
+ put_unlocked_entry (& xas , entry , WAKE_ALL );
874
+ }
875
+ xas_unlock_irq (& xas );
876
+ }
877
+ EXPORT_SYMBOL_GPL (dax_delete_mapping_range );
878
+
849
879
static int wait_page_idle (struct page * page ,
850
880
void (cb )(struct inode * ),
851
881
struct inode * inode )
@@ -857,6 +887,9 @@ static int wait_page_idle(struct page *page,
857
887
/*
858
888
* Unmaps the inode and waits for any DMA to complete prior to deleting the
859
889
* DAX mapping entries for the range.
890
+ *
891
+ * For NOWAIT behavior, pass @cb as NULL to early-exit on first found
892
+ * busy page
860
893
*/
861
894
int dax_break_layout (struct inode * inode , loff_t start , loff_t end ,
862
895
void (cb )(struct inode * ))
@@ -871,10 +904,17 @@ int dax_break_layout(struct inode *inode, loff_t start, loff_t end,
871
904
page = dax_layout_busy_page_range (inode -> i_mapping , start , end );
872
905
if (!page )
873
906
break ;
907
+ if (!cb ) {
908
+ error = - ERESTARTSYS ;
909
+ break ;
910
+ }
874
911
875
912
error = wait_page_idle (page , cb , inode );
876
913
} while (error == 0 );
877
914
915
+ if (!page )
916
+ dax_delete_mapping_range (inode -> i_mapping , start , end );
917
+
878
918
return error ;
879
919
}
880
920
EXPORT_SYMBOL_GPL (dax_break_layout );
0 commit comments