summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2019-03-28 09:34:55 -0400
committerKent Overstreet <kent.overstreet@gmail.com>2019-04-03 12:44:14 -0400
commitd0d605749335fb16c76235abfed08af4ca9ea739 (patch)
tree415a937dd25bbb4d0ed4856067f06e089d81c078
parent183f66ecf1bebb19f0db971e0eb5082ade0b67e1 (diff)
bcachefs: Track whether filesystem has errors in superblock
-rw-r--r--fs/bcachefs/bcachefs.h11
-rw-r--r--fs/bcachefs/bcachefs_format.h4
-rw-r--r--fs/bcachefs/error.c32
-rw-r--r--fs/bcachefs/recovery.c5
-rw-r--r--fs/bcachefs/super-io.c6
-rw-r--r--fs/bcachefs/super.c1
6 files changed, 26 insertions, 33 deletions
diff --git a/fs/bcachefs/bcachefs.h b/fs/bcachefs/bcachefs.h
index 44f60740c3e6..effebcb729f5 100644
--- a/fs/bcachefs/bcachefs.h
+++ b/fs/bcachefs/bcachefs.h
@@ -470,14 +470,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,
@@ -494,11 +486,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,
diff --git a/fs/bcachefs/bcachefs_format.h b/fs/bcachefs/bcachefs_format.h
index 56bf69eb66d4..e899d03f9dbf 100644
--- a/fs/bcachefs/bcachefs_format.h
+++ b/fs/bcachefs/bcachefs_format.h
@@ -1236,7 +1236,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);
diff --git a/fs/bcachefs/error.c b/fs/bcachefs/error.c
index e3747781c4b9..afffbfb36954 100644
--- a/fs/bcachefs/error.c
+++ b/fs/bcachefs/error.c
@@ -71,12 +71,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);
@@ -109,11 +106,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();
@@ -141,13 +134,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)
diff --git a/fs/bcachefs/recovery.c b/fs/bcachefs/recovery.c
index 4cde23b9e43d..00161e05e786 100644
--- a/fs/bcachefs/recovery.c
+++ b/fs/bcachefs/recovery.c
@@ -364,8 +364,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)) {
diff --git a/fs/bcachefs/super-io.c b/fs/bcachefs/super-io.c
index 9568cb46755c..bcb6e3fba9cd 100644
--- a/fs/bcachefs/super-io.c
+++ b/fs/bcachefs/super-io.c
@@ -706,6 +706,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);
@@ -718,8 +721,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) {
diff --git a/fs/bcachefs/super.c b/fs/bcachefs/super.c
index 7b1683611c1e..1509c0fff96a 100644
--- a/fs/bcachefs/super.c
+++ b/fs/bcachefs/super.c
@@ -875,7 +875,6 @@ err:
}
BUG_ON(!err);
- set_bit(BCH_FS_ERROR, &c->flags);
goto out;
}