bcachefs: Fix inode backpointers in RENAME_OVERWRITE
authorKent Overstreet <kent.overstreet@gmail.com>
Thu, 20 May 2021 04:09:47 +0000 (00:09 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:09:04 +0000 (17:09 -0400)
When we delete the dirent an inode points to, we need to zero out the
backpointer fields - this was missed in the RENAME_OVERWRITE case.

Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
fs/bcachefs/dirent.c
fs/bcachefs/fs-common.c

index ec4666143f23693419ffb90b6b153fcf064c7470..3bf6379cefe664b77f3d6ce16de28243ec44f974 100644 (file)
@@ -210,6 +210,8 @@ int bch2_dirent_rename(struct btree_trans *trans,
 
        if (mode != BCH_RENAME)
                *dst_inum = le64_to_cpu(bkey_s_c_to_dirent(old_dst).v->d_inum);
+       if (mode != BCH_RENAME_EXCHANGE)
+               *src_offset = dst_iter->pos.offset;
 
        /* Lookup src: */
        src_iter = bch2_hash_lookup(trans, bch2_dirent_hash_desc,
@@ -290,7 +292,8 @@ int bch2_dirent_rename(struct btree_trans *trans,
        bch2_trans_update(trans, src_iter, &new_src->k_i, 0);
        bch2_trans_update(trans, dst_iter, &new_dst->k_i, 0);
 out_set_offset:
-       *src_offset = new_src->k.p.offset;
+       if (mode == BCH_RENAME_EXCHANGE)
+               *src_offset = new_src->k.p.offset;
        *dst_offset = new_dst->k.p.offset;
 out:
        bch2_trans_iter_put(trans, src_iter);
index 34d69c3f6680bfe602506df57d988c0893498638..08c6af886df7b651c8346e855ba923655838b714 100644 (file)
@@ -289,6 +289,13 @@ int bch2_rename_trans(struct btree_trans *trans,
                        dst_inode_u->bi_dir             = src_dir_u->bi_inum;
                        dst_inode_u->bi_dir_offset      = src_offset;
                }
+
+               if (mode == BCH_RENAME_OVERWRITE &&
+                   dst_inode_u->bi_dir         == dst_dir_u->bi_inum &&
+                   dst_inode_u->bi_dir_offset  == src_offset) {
+                       dst_inode_u->bi_dir             = 0;
+                       dst_inode_u->bi_dir_offset      = 0;
+               }
        }
 
        if (mode == BCH_RENAME_OVERWRITE) {