bcachefs: When fsck finds redundant snapshot keys, trigger snapshots cleanup
authorKent Overstreet <kent.overstreet@gmail.com>
Sun, 17 Jul 2022 03:21:15 +0000 (23:21 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:09:35 +0000 (17:09 -0400)
Fsck now checks for keys in different snapshot IDs that are now
redundant due to other snapshots being deleted - it needs to for its own
algorithms to not get confused.

When it detects this it should re-run the post snapshot deletion cleanup
- this patch does that.

Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
fs/bcachefs/errcode.h
fs/bcachefs/fsck.c

index f7d12915c1ccda5f7674dcb9fca7098a030f2bba..0581f3c7a0d82c421ef2250486112dc107abe391 100644 (file)
@@ -7,6 +7,7 @@ enum {
        OPEN_BUCKETS_EMPTY =    2048,
        FREELIST_EMPTY,         /* Allocator thread not keeping up */
        INSUFFICIENT_DEVICES,
+       NEED_SNAPSHOT_CLEANUP,
 };
 
 #endif /* _BCACHFES_ERRCODE_H */
index 43575d7e050edec4f95198d0140c46a146be7b40..b401c0913bdc4cc0fc2b0a67c426c32103c85bfe 100644 (file)
@@ -512,7 +512,7 @@ static int snapshots_seen_update(struct bch_fs *c, struct snapshots_seen *s,
                                        bch2_btree_ids[btree_id],
                                        pos.inode, pos.offset,
                                        i->id, n.id, n.equiv);
-                               return -EINVAL;
+                               return -NEED_SNAPSHOT_CLEANUP;
                        }
 
                        return 0;
@@ -2388,7 +2388,9 @@ static int fix_reflink_p(struct bch_fs *c)
  */
 int bch2_fsck_full(struct bch_fs *c)
 {
-       return  bch2_fs_check_snapshots(c) ?:
+       int ret;
+again:
+       ret =   bch2_fs_check_snapshots(c) ?:
                bch2_fs_check_subvols(c) ?:
                bch2_delete_dead_snapshots(c) ?:
                check_inodes(c, true) ?:
@@ -2399,6 +2401,13 @@ int bch2_fsck_full(struct bch_fs *c)
                check_directory_structure(c) ?:
                check_nlinks(c) ?:
                fix_reflink_p(c);
+
+       if (ret == -NEED_SNAPSHOT_CLEANUP) {
+               set_bit(BCH_FS_HAVE_DELETED_SNAPSHOTS, &c->flags);
+               goto again;
+       }
+
+       return ret;
 }
 
 int bch2_fsck_walk_inodes_only(struct bch_fs *c)