@@ -846,6 +846,36 @@ int dax_delete_mapping_entry(struct address_space *mapping, pgoff_t index)
846846 return ret ;
847847}
848848
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+
849879static int wait_page_idle (struct page * page ,
850880 void (cb )(struct inode * ),
851881 struct inode * inode )
@@ -857,6 +887,9 @@ static int wait_page_idle(struct page *page,
857887/*
858888 * Unmaps the inode and waits for any DMA to complete prior to deleting the
859889 * DAX mapping entries for the range.
890+ *
891+ * For NOWAIT behavior, pass @cb as NULL to early-exit on first found
892+ * busy page
860893 */
861894int dax_break_layout (struct inode * inode , loff_t start , loff_t end ,
862895 void (cb )(struct inode * ))
@@ -871,10 +904,17 @@ int dax_break_layout(struct inode *inode, loff_t start, loff_t end,
871904 page = dax_layout_busy_page_range (inode -> i_mapping , start , end );
872905 if (!page )
873906 break ;
907+ if (!cb ) {
908+ error = - ERESTARTSYS ;
909+ break ;
910+ }
874911
875912 error = wait_page_idle (page , cb , inode );
876913 } while (error == 0 );
877914
915+ if (!page )
916+ dax_delete_mapping_range (inode -> i_mapping , start , end );
917+
878918 return error ;
879919}
880920EXPORT_SYMBOL_GPL (dax_break_layout );
0 commit comments