bcachefs: Track whether filesystem has errors in superblock
authorKent Overstreet <kent.overstreet@gmail.com>
Thu, 28 Mar 2019 13:34:55 +0000 (09:34 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:08:19 +0000 (17:08 -0400)
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/bcachefs.h
fs/bcachefs/bcachefs_format.h
fs/bcachefs/error.c
fs/bcachefs/recovery.c
fs/bcachefs/super-io.c
fs/bcachefs/super.c

index a2d8e37e7eb6a9612ea22e20a646f4076a0c3233..d8a9d4962d709c78e38c8caa86283015fbde8355 100644 (file)
@@ -473,14 +473,6 @@ struct bch_dev {
        struct io_count __percpu *io_done;
 };
 
-/*
- * Flag bits for what phase of startup/shutdown the cache set is at, how we're
- * shutting down, etc.:
- *
- * BCH_FS_UNREGISTERING means we're not just shutting down, we're detaching
- * all the backing devices first (their cached data gets invalidated, and they
- * won't automatically reattach).
- */
 enum {
        /* startup: */
        BCH_FS_ALLOC_READ_DONE,
@@ -497,11 +489,10 @@ enum {
 
        /* errors: */
        BCH_FS_ERROR,
+       BCH_FS_ERRORS_FIXED,
 
        /* misc: */
        BCH_FS_BDEV_MOUNTED,
-       BCH_FS_FSCK_FIXED_ERRORS,
-       BCH_FS_FSCK_UNFIXED_ERRORS,
        BCH_FS_FIXED_GENS,
        BCH_FS_REBUILD_REPLICAS,
        BCH_FS_HOLD_BTREE_WRITES,
index 9a3ca6fa30b74821e706b1042f14e7f360ce8644..646910a6a4bb248fa4bbe65291fb179646aa53d9 100644 (file)
@@ -1241,7 +1241,9 @@ LE64_BITMASK(BCH_SB_USRQUOTA,             struct bch_sb, flags[0], 57, 58);
 LE64_BITMASK(BCH_SB_GRPQUOTA,          struct bch_sb, flags[0], 58, 59);
 LE64_BITMASK(BCH_SB_PRJQUOTA,          struct bch_sb, flags[0], 59, 60);
 
-/* 60-64 unused */
+LE64_BITMASK(BCH_SB_HAS_ERRORS,                struct bch_sb, flags[0], 60, 61);
+
+/* 61-64 unused */
 
 LE64_BITMASK(BCH_SB_STR_HASH_TYPE,     struct bch_sb, flags[1],  0,  4);
 LE64_BITMASK(BCH_SB_COMPRESSION_TYPE,  struct bch_sb, flags[1],  4,  8);
index f0a44101b7e7aa45587a0ce8cd94eb2e31a125b0..1aaff44e18cf0047f8a677852990c165b003a7d4 100644 (file)
@@ -72,12 +72,9 @@ enum fsck_err_ret bch2_fsck_err(struct bch_fs *c, unsigned flags,
                vprintk(fmt, args);
                va_end(args);
 
-               if (c->opts.errors == BCH_ON_ERROR_CONTINUE &&
-                   flags & FSCK_CAN_FIX)
-                       return FSCK_ERR_FIX;
-
-               bch2_inconsistent_error(c);
-               return FSCK_ERR_EXIT;
+               return bch2_inconsistent_error(c)
+                       ? FSCK_ERR_EXIT
+                       : FSCK_ERR_FIX;
        }
 
        mutex_lock(&c->fsck_error_lock);
@@ -110,11 +107,7 @@ print:
 
        if (c->opts.fix_errors == FSCK_OPT_EXIT) {
                bch_err(c, "%s, exiting", buf);
-               mutex_unlock(&c->fsck_error_lock);
-               return FSCK_ERR_EXIT;
-       }
-
-       if (flags & FSCK_CAN_FIX) {
+       } else if (flags & FSCK_CAN_FIX) {
                if (c->opts.fix_errors == FSCK_OPT_ASK) {
                        printk(KERN_ERR "%s: fix?", buf);
                        fix = ask_yn();
@@ -142,13 +135,16 @@ print:
 
        mutex_unlock(&c->fsck_error_lock);
 
-       set_bit(fix
-               ? BCH_FS_FSCK_FIXED_ERRORS
-               : BCH_FS_FSCK_UNFIXED_ERRORS, &c->flags);
-
-       return fix                              ? FSCK_ERR_FIX
-               : flags & FSCK_CAN_IGNORE       ? FSCK_ERR_IGNORE
-                                               : FSCK_ERR_EXIT;
+       if (fix) {
+               set_bit(BCH_FS_ERRORS_FIXED, &c->flags);
+               return FSCK_ERR_FIX;
+       } else {
+               set_bit(BCH_FS_ERROR, &c->flags);
+               return c->opts.fix_errors == FSCK_OPT_EXIT ||
+                       !(flags & FSCK_CAN_IGNORE)
+                       ? FSCK_ERR_EXIT
+                       : FSCK_ERR_IGNORE;
+       }
 }
 
 void bch2_flush_fsck_errs(struct bch_fs *c)
index 93c4d5887e8bfa5e44bb5eabbac0cebf609c87fa..68415df8565b5c0a2b55b50577641872d89807e0 100644 (file)
@@ -365,8 +365,11 @@ int bch2_fs_recovery(struct bch_fs *c)
                c->disk_sb.sb->version = le16_to_cpu(bcachefs_metadata_version_current);
        }
 
-       if (!test_bit(BCH_FS_FSCK_UNFIXED_ERRORS, &c->flags))
+       if (c->opts.fsck &&
+           !test_bit(BCH_FS_ERROR, &c->flags)) {
                c->disk_sb.sb->features[0] |= 1ULL << BCH_FEATURE_ATOMIC_NLINK;
+               SET_BCH_SB_HAS_ERRORS(c->disk_sb.sb, 0);
+       }
        mutex_unlock(&c->sb_lock);
 
        if (enabled_qtypes(c)) {
index f504743fff4deb04ad5d06691321d6cc90ea1b31..9fd77e57cafe0ed6b681ec286ccb54e03942c267 100644 (file)
@@ -707,6 +707,9 @@ int bch2_write_super(struct bch_fs *c)
 
        le64_add_cpu(&c->disk_sb.sb->seq, 1);
 
+       if (test_bit(BCH_FS_ERROR, &c->flags))
+               SET_BCH_SB_HAS_ERRORS(c->disk_sb.sb, 1);
+
        for_each_online_member(ca, c, i)
                bch2_sb_from_fs(c, ca);
 
@@ -719,8 +722,7 @@ int bch2_write_super(struct bch_fs *c)
                }
        }
 
-       if (c->opts.nochanges ||
-           test_bit(BCH_FS_ERROR, &c->flags))
+       if (c->opts.nochanges)
                goto out;
 
        for_each_online_member(ca, c, i) {
index 369c533e677b489d900ffa5fbb2ea91dd21604a6..f8e921b3fb8d71b8c70ff1365e59917fb8a42262 100644 (file)
@@ -843,7 +843,6 @@ err:
        }
 
        BUG_ON(!err);
-       set_bit(BCH_FS_ERROR, &c->flags);
        goto out;
 }