summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.bcachefs_revision2
-rw-r--r--cmd_fsck.c4
-rw-r--r--libbcachefs/bcachefs.h11
-rw-r--r--libbcachefs/bcachefs_format.h4
-rw-r--r--libbcachefs/error.c32
-rw-r--r--libbcachefs/fsck.c21
-rw-r--r--libbcachefs/recovery.c5
-rw-r--r--libbcachefs/super-io.c6
-rw-r--r--libbcachefs/super.c18
9 files changed, 52 insertions, 51 deletions
diff --git a/.bcachefs_revision b/.bcachefs_revision
index e42a96d6..e025c5ab 100644
--- a/.bcachefs_revision
+++ b/.bcachefs_revision
@@ -1 +1 @@
-d868a87c678935c89df9bca63d708d616529b0d2
+1712318522fdaa533f8622f4c7da05e44a4828b0
diff --git a/cmd_fsck.c b/cmd_fsck.c
index e0961b99..824c4a1c 100644
--- a/cmd_fsck.c
+++ b/cmd_fsck.c
@@ -65,9 +65,9 @@ int cmd_fsck(int argc, char *argv[])
if (IS_ERR(c))
die("error opening %s: %s", argv[0], strerror(-PTR_ERR(c)));
- if (test_bit(BCH_FS_FSCK_FIXED_ERRORS, &c->flags))
+ if (test_bit(BCH_FS_ERRORS_FIXED, &c->flags))
ret = 2;
- if (test_bit(BCH_FS_FSCK_UNFIXED_ERRORS, &c->flags))
+ if (test_bit(BCH_FS_ERROR, &c->flags))
ret = 4;
bch2_fs_stop(c);
diff --git a/libbcachefs/bcachefs.h b/libbcachefs/bcachefs.h
index 9ee06e58..9a90a68c 100644
--- a/libbcachefs/bcachefs.h
+++ b/libbcachefs/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/libbcachefs/bcachefs_format.h b/libbcachefs/bcachefs_format.h
index 56bf69eb..e899d03f 100644
--- a/libbcachefs/bcachefs_format.h
+++ b/libbcachefs/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/libbcachefs/error.c b/libbcachefs/error.c
index e3747781..afffbfb3 100644
--- a/libbcachefs/error.c
+++ b/libbcachefs/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/libbcachefs/fsck.c b/libbcachefs/fsck.c
index 5c2329d9..bc501d40 100644
--- a/libbcachefs/fsck.c
+++ b/libbcachefs/fsck.c
@@ -90,7 +90,9 @@ static int reattach_inode(struct bch_fs *c,
bch2_inode_pack(&packed, lostfound_inode);
ret = bch2_btree_insert(c, BTREE_ID_INODES, &packed.inode.k_i,
- NULL, NULL, BTREE_INSERT_NOFAIL);
+ NULL, NULL,
+ BTREE_INSERT_NOFAIL|
+ BTREE_INSERT_LAZY_RW);
if (ret) {
bch_err(c, "error %i reattaching inode %llu while updating lost+found",
ret, inum);
@@ -100,7 +102,8 @@ static int reattach_inode(struct bch_fs *c,
ret = bch2_dirent_create(c, lostfound_inode->bi_inum,
&lostfound_hash_info,
DT_DIR, &name, inum, NULL,
- BTREE_INSERT_NOFAIL);
+ BTREE_INSERT_NOFAIL|
+ BTREE_INSERT_LAZY_RW);
if (ret) {
bch_err(c, "error %i reattaching inode %llu while creating new dirent",
ret, inum);
@@ -482,7 +485,8 @@ static int check_extents(struct bch_fs *c)
ret = bch2_btree_insert(c, BTREE_ID_INODES,
&p.inode.k_i, NULL, NULL,
- BTREE_INSERT_NOFAIL);
+ BTREE_INSERT_NOFAIL|
+ BTREE_INSERT_LAZY_RW);
if (ret) {
bch_err(c, "error in fs gc: error %i "
"updating inode", ret);
@@ -750,7 +754,9 @@ create_root:
bch2_inode_pack(&packed, root_inode);
return bch2_btree_insert(c, BTREE_ID_INODES, &packed.inode.k_i,
- NULL, NULL, BTREE_INSERT_NOFAIL);
+ NULL, NULL,
+ BTREE_INSERT_NOFAIL|
+ BTREE_INSERT_LAZY_RW);
}
/* Get lost+found, create if it doesn't exist: */
@@ -794,7 +800,9 @@ create_lostfound:
bch2_inode_pack(&packed, root_inode);
ret = bch2_btree_insert(c, BTREE_ID_INODES, &packed.inode.k_i,
- NULL, NULL, BTREE_INSERT_NOFAIL);
+ NULL, NULL,
+ BTREE_INSERT_NOFAIL|
+ BTREE_INSERT_LAZY_RW);
if (ret)
return ret;
@@ -808,7 +816,8 @@ create_lostfound:
ret = bch2_dirent_create(c, BCACHEFS_ROOT_INO, &root_hash_info, DT_DIR,
&lostfound, lostfound_inode->bi_inum, NULL,
- BTREE_INSERT_NOFAIL);
+ BTREE_INSERT_NOFAIL|
+ BTREE_INSERT_LAZY_RW);
if (ret)
return ret;
diff --git a/libbcachefs/recovery.c b/libbcachefs/recovery.c
index 4cde23b9..00161e05 100644
--- a/libbcachefs/recovery.c
+++ b/libbcachefs/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/libbcachefs/super-io.c b/libbcachefs/super-io.c
index 9568cb46..bcb6e3fb 100644
--- a/libbcachefs/super-io.c
+++ b/libbcachefs/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/libbcachefs/super.c b/libbcachefs/super.c
index 3bcc3240..7748dafb 100644
--- a/libbcachefs/super.c
+++ b/libbcachefs/super.c
@@ -206,7 +206,7 @@ static void __bch2_fs_read_only(struct bch_fs *c)
{
struct bch_dev *ca;
bool wrote;
- unsigned i;
+ unsigned i, clean_passes = 0;
int ret;
bch2_rebalance_stop(c);
@@ -226,15 +226,15 @@ static void __bch2_fs_read_only(struct bch_fs *c)
goto allocator_not_running;
do {
- ret = bch2_alloc_write(c, false, &wrote);
+ ret = bch2_stripes_write(c, &wrote);
if (ret) {
- bch2_fs_inconsistent(c, "error writing out alloc info %i", ret);
+ bch2_fs_inconsistent(c, "error writing out stripes");
break;
}
- ret = bch2_stripes_write(c, &wrote);
+ ret = bch2_alloc_write(c, false, &wrote);
if (ret) {
- bch2_fs_inconsistent(c, "error writing out stripes");
+ bch2_fs_inconsistent(c, "error writing out alloc info %i", ret);
break;
}
@@ -252,7 +252,9 @@ static void __bch2_fs_read_only(struct bch_fs *c)
*/
closure_wait_event(&c->btree_interior_update_wait,
!bch2_btree_interior_updates_nr_pending(c));
- } while (wrote);
+
+ clean_passes = wrote ? 0 : clean_passes + 1;
+ } while (clean_passes < 2);
allocator_not_running:
for_each_member_device(ca, c, i)
bch2_dev_allocator_stop(ca);
@@ -461,9 +463,6 @@ int bch2_fs_read_write_early(struct bch_fs *c)
{
lockdep_assert_held(&c->state_lock);
- if (c->opts.read_only)
- return -EROFS;
-
return __bch2_fs_read_write(c, true);
}
@@ -873,7 +872,6 @@ err:
}
BUG_ON(!err);
- set_bit(BCH_FS_ERROR, &c->flags);
goto out;
}