From: Filipe Manana Date: Tue, 31 May 2022 15:06:36 +0000 (+0100) Subject: btrfs: deal with deletion errors when deleting delayed items X-Git-Tag: v6.1-rc5~427^2~162 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=2b1d260de14064606601f2e125cb8627ffeecd7e;p=platform%2Fkernel%2Flinux-starfive.git btrfs: deal with deletion errors when deleting delayed items Currently, btrfs_delete_delayed_items() ignores any errors returned from btrfs_batch_delete_items(). This looks fishy but it's not a problem at the moment because: 1) Two of the errors returned from btrfs_batch_delete_items() are for impossible cases, cases where a delayed item does not match any item in the leaf the path points to - btrfs_delete_delayed_items() always calls btrfs_batch_delete_items() with a path that points to a leaf that contains an item matching a delayed item; 2) btrfs_batch_delete_items() may return an error from btrfs_del_items(), in which case it does not release the delayed items of the batch. At the moment this is harmless because btrfs_del_items() actually is always able to delete items, even if it returns an error - when it returns an error it's because it ended up with a leaf mostly empty (less than 1/3 full) and failed to migrate items from that leaf into its neighbour leaves - this is not critical, as all the items were deleted, we just left the tree a bit unbalanced, but it's still a valid tree and causes no harm, and future operations on the tree will eventually balance it. So even if we get an error from btrfs_del_items(), the delayed items will not be released but the next time we run delayed items we will find out, at btrfs_delete_delayed_items(), that they are not present in the tree anymore and then release them. This is all a bit subtle, and it's certainly prone to be a disaster in case btrfs_del_items() changes one day and may return errors before being able to delete all the requested items, in which case we could leave the filesystem in an inconsistent state as we would commit a transaction despite a failure from deleting items from the tree. So make btrfs_delete_delayed_items() check for any errors from the call to btrfs_batch_delete_items(). Reviewed-by: Anand Jain Reviewed-by: Nikolay Borisov Signed-off-by: Filipe Manana Reviewed-by: David Sterba Signed-off-by: David Sterba --- diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c index 1dc4ebb..c8deab7 100644 --- a/fs/btrfs/delayed-inode.c +++ b/fs/btrfs/delayed-inode.c @@ -896,7 +896,9 @@ do_again: goto delete_fail; } - btrfs_batch_delete_items(trans, root, path, curr); + ret = btrfs_batch_delete_items(trans, root, path, curr); + if (ret) + goto delete_fail; btrfs_release_path(path); mutex_unlock(&node->mutex); goto do_again;