]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
btrfs: abort transaction on failure to add link to inode
authorFilipe Manana <fdmanana@suse.com>
Fri, 25 Jul 2025 15:51:49 +0000 (16:51 +0100)
committerDavid Sterba <dsterba@suse.com>
Thu, 21 Aug 2025 22:58:25 +0000 (00:58 +0200)
If we fail to update the inode or delete the orphan item, we must abort
the transaction to prevent persisting an inconsistent state. For example
if we fail to update the inode item, we have the inconsistency of having
a persisted inode item with a link count of N but we have N + 1 inode ref
items and N + 1 directory entries pointing to our inode in case the
transaction gets committed.

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/inode.c

index 9e4aec7330cb612711c5840cc35e502a7f993bcc..af2f9b2c8c851c1b6cf695c876fa1271052cc7cf 100644 (file)
@@ -6852,16 +6852,20 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir,
                struct dentry *parent = dentry->d_parent;
 
                ret = btrfs_update_inode(trans, BTRFS_I(inode));
-               if (ret)
+               if (ret) {
+                       btrfs_abort_transaction(trans, ret);
                        goto fail;
+               }
                if (inode->i_nlink == 1) {
                        /*
                         * If new hard link count is 1, it's a file created
                         * with open(2) O_TMPFILE flag.
                         */
                        ret = btrfs_orphan_del(trans, BTRFS_I(inode));
-                       if (ret)
+                       if (ret) {
+                               btrfs_abort_transaction(trans, ret);
                                goto fail;
+                       }
                }
                d_instantiate(dentry, inode);
                btrfs_log_new_name(trans, old_dentry, NULL, 0, parent);