diff --git a/fs/inode.c b/fs/inode.c index bd71059cae4debe182de364ac01f8da5f1bde60b..b3c3f1cad756680429e5610eaadcc43c993eeb7c 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -645,22 +645,18 @@ void dump_mapping(const struct address_space *mapping) void clear_inode(struct inode *inode) { - /* - * We have to cycle the i_pages lock here because reclaim can be in the - * process of removing the last page (in __filemap_remove_folio()) - * and we must not free the mapping under it. - */ - xa_lock_irq(&inode->i_data.i_pages); - BUG_ON(inode->i_data.nrpages); /* * Almost always, mapping_empty(&inode->i_data) here; but there are * two known and long-standing ways in which nodes may get left behind * (when deep radix-tree node allocation failed partway; or when THP - * collapse_file() failed). Until those two known cases are cleaned up, - * or a cleanup function is called here, do not BUG_ON(!mapping_empty), - * nor even WARN_ON(!mapping_empty). + * collapse_file() failed). + * + * xa_destroy() also cycles the lock for us, which is needed because + * reclaim can be in the process of removing the last folio (in + * __filemap_remove_folio()) and we must not free the mapping under it. */ - xa_unlock_irq(&inode->i_data.i_pages); + xa_destroy(&inode->i_data.i_pages); + BUG_ON(inode->i_data.nrpages); BUG_ON(!list_empty(&inode->i_data.private_list)); BUG_ON(!(inode->i_state & I_FREEING)); BUG_ON(inode->i_state & I_CLEAR);