]> www.infradead.org Git - users/hch/dma-mapping.git/commitdiff
bcachefs: Don't delete open files in online fsck
authorKent Overstreet <kent.overstreet@linux.dev>
Sun, 8 Sep 2024 05:06:57 +0000 (01:06 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Mon, 9 Sep 2024 13:41:47 +0000 (09:41 -0400)
If a file is unlinked but still open, we don't want online fsck to
delete it - or fun inconsistencies will happen.

https://github.com/koverstreet/bcachefs/issues/727

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/fs.c
fs/bcachefs/fs.h
fs/bcachefs/fsck.c

index 94c392abef65cdda64624c9eeec5c56875611e1e..257f07656e5f5a3662df7297faa63994e2e434f1 100644 (file)
@@ -177,6 +177,14 @@ static unsigned bch2_inode_hash(subvol_inum inum)
        return jhash_3words(inum.subvol, inum.inum >> 32, inum.inum, JHASH_INITVAL);
 }
 
+struct bch_inode_info *__bch2_inode_hash_find(struct bch_fs *c, subvol_inum inum)
+{
+       return to_bch_ei(ilookup5_nowait(c->vfs_sb,
+                                        bch2_inode_hash(inum),
+                                        bch2_iget5_test,
+                                        &inum));
+}
+
 static struct bch_inode_info *bch2_inode_insert(struct bch_fs *c, struct bch_inode_info *inode)
 {
        subvol_inum inum = inode_inum(inode);
index c3af7225ff693ec9c5af06502e22f3fbc8354fd5..990ec43e0365d3066825b140c272700316160dd5 100644 (file)
@@ -56,6 +56,8 @@ static inline subvol_inum inode_inum(struct bch_inode_info *inode)
        };
 }
 
+struct bch_inode_info *__bch2_inode_hash_find(struct bch_fs *, subvol_inum);
+
 /*
  * Set if we've gotten a btree error for this inode, and thus the vfs inode and
  * btree inode may be inconsistent:
@@ -194,6 +196,11 @@ int bch2_vfs_init(void);
 
 #define bch2_inode_update_after_write(_trans, _inode, _inode_u, _fields)       ({ do {} while (0); })
 
+static inline struct bch_inode_info *__bch2_inode_hash_find(struct bch_fs *c, subvol_inum inum)
+{
+       return NULL;
+}
+
 static inline void bch2_evict_subvolume_inodes(struct bch_fs *c,
                                               snapshot_id_list *s) {}
 static inline void bch2_vfs_exit(void) {}
index 83bd31b44aad0bf8107b46ccaef46b2d0c468b04..9b3470a975461f777221443d4953cbd391a3fe66 100644 (file)
@@ -8,6 +8,7 @@
 #include "darray.h"
 #include "dirent.h"
 #include "error.h"
+#include "fs.h"
 #include "fs-common.h"
 #include "fsck.h"
 #include "inode.h"
@@ -962,6 +963,22 @@ fsck_err:
        return ret;
 }
 
+static bool bch2_inode_open(struct bch_fs *c, struct bpos p)
+{
+       subvol_inum inum = {
+               .subvol = snapshot_t(c, p.snapshot)->subvol,
+               .inum   = p.offset,
+       };
+
+       /* snapshot tree corruption, can't safely delete */
+       if (!inum.subvol) {
+               bch_err_ratelimited(c, "%s(): snapshot %u has no subvol", __func__, p.snapshot);
+               return true;
+       }
+
+       return __bch2_inode_hash_find(c, inum) != NULL;
+}
+
 static int check_inode(struct btree_trans *trans,
                       struct btree_iter *iter,
                       struct bkey_s_c k,
@@ -1040,6 +1057,7 @@ static int check_inode(struct btree_trans *trans,
        }
 
        if (u.bi_flags & BCH_INODE_unlinked &&
+           !bch2_inode_open(c, k.k->p) &&
            (!c->sb.clean ||
             fsck_err(trans, inode_unlinked_but_clean,
                      "filesystem marked clean, but inode %llu unlinked",