Commit 619f5bee authored by Kent Overstreet's avatar Kent Overstreet Committed by Kent Overstreet

bcachefs: some improvements to startup messages and options

Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent 460651ee
...@@ -158,7 +158,7 @@ static long bch2_ioctl_start(struct bch_fs *c, struct bch_ioctl_start arg) ...@@ -158,7 +158,7 @@ static long bch2_ioctl_start(struct bch_fs *c, struct bch_ioctl_start arg)
if (arg.flags || arg.pad) if (arg.flags || arg.pad)
return -EINVAL; return -EINVAL;
return bch2_fs_start(c) ? -EIO : 0; return bch2_fs_start(c);
} }
static long bch2_ioctl_stop(struct bch_fs *c) static long bch2_ioctl_stop(struct bch_fs *c)
......
...@@ -267,7 +267,8 @@ long bch2_fs_file_ioctl(struct file *file, unsigned cmd, unsigned long arg) ...@@ -267,7 +267,8 @@ long bch2_fs_file_ioctl(struct file *file, unsigned cmd, unsigned long arg)
down_write(&sb->s_umount); down_write(&sb->s_umount);
sb->s_flags |= SB_RDONLY; sb->s_flags |= SB_RDONLY;
bch2_fs_emergency_read_only(c); if (bch2_fs_emergency_read_only(c))
bch_err(c, "emergency read only due to ioctl");
up_write(&sb->s_umount); up_write(&sb->s_umount);
return 0; return 0;
......
...@@ -1834,12 +1834,15 @@ static struct dentry *bch2_mount(struct file_system_type *fs_type, ...@@ -1834,12 +1834,15 @@ static struct dentry *bch2_mount(struct file_system_type *fs_type,
vinode = bch2_vfs_inode_get(c, BCACHEFS_ROOT_INO); vinode = bch2_vfs_inode_get(c, BCACHEFS_ROOT_INO);
if (IS_ERR(vinode)) { if (IS_ERR(vinode)) {
bch_err(c, "error mounting: error getting root inode %i",
(int) PTR_ERR(vinode));
ret = PTR_ERR(vinode); ret = PTR_ERR(vinode);
goto err_put_super; goto err_put_super;
} }
sb->s_root = d_make_root(vinode); sb->s_root = d_make_root(vinode);
if (!sb->s_root) { if (!sb->s_root) {
bch_err(c, "error mounting: error allocating root dentry");
ret = -ENOMEM; ret = -ENOMEM;
goto err_put_super; goto err_put_super;
} }
......
...@@ -499,8 +499,7 @@ static int check_extents(struct bch_fs *c) ...@@ -499,8 +499,7 @@ static int check_extents(struct bch_fs *c)
BTREE_INSERT_NOFAIL| BTREE_INSERT_NOFAIL|
BTREE_INSERT_LAZY_RW); BTREE_INSERT_LAZY_RW);
if (ret) { if (ret) {
bch_err(c, "error in fs gc: error %i " bch_err(c, "error in fsck: error %i updating inode", ret);
"updating inode", ret);
goto err; goto err;
} }
...@@ -1064,7 +1063,7 @@ static void inc_link(struct bch_fs *c, nlink_table *links, ...@@ -1064,7 +1063,7 @@ static void inc_link(struct bch_fs *c, nlink_table *links,
link = genradix_ptr_alloc(links, inum - range_start, GFP_KERNEL); link = genradix_ptr_alloc(links, inum - range_start, GFP_KERNEL);
if (!link) { if (!link) {
bch_verbose(c, "allocation failed during fs gc - will need another pass"); bch_verbose(c, "allocation failed during fsck - will need another pass");
*range_end = inum; *range_end = inum;
return; return;
} }
...@@ -1111,7 +1110,7 @@ static int bch2_gc_walk_dirents(struct bch_fs *c, nlink_table *links, ...@@ -1111,7 +1110,7 @@ static int bch2_gc_walk_dirents(struct bch_fs *c, nlink_table *links,
} }
ret = bch2_trans_exit(&trans) ?: ret; ret = bch2_trans_exit(&trans) ?: ret;
if (ret) if (ret)
bch_err(c, "error in fs gc: btree error %i while walking dirents", ret); bch_err(c, "error in fsck: btree error %i while walking dirents", ret);
return ret; return ret;
} }
...@@ -1252,8 +1251,7 @@ static int check_inode(struct btree_trans *trans, ...@@ -1252,8 +1251,7 @@ static int check_inode(struct btree_trans *trans,
ret = bch2_inode_rm(c, u.bi_inum); ret = bch2_inode_rm(c, u.bi_inum);
if (ret) if (ret)
bch_err(c, "error in fs gc: error %i " bch_err(c, "error in fsck: error %i while deleting inode", ret);
"while deleting inode", ret);
return ret; return ret;
} }
...@@ -1270,8 +1268,7 @@ static int check_inode(struct btree_trans *trans, ...@@ -1270,8 +1268,7 @@ static int check_inode(struct btree_trans *trans,
ret = bch2_inode_truncate(c, u.bi_inum, u.bi_size); ret = bch2_inode_truncate(c, u.bi_inum, u.bi_size);
if (ret) { if (ret) {
bch_err(c, "error in fs gc: error %i " bch_err(c, "error in fsck: error %i truncating inode", ret);
"truncating inode", ret);
return ret; return ret;
} }
...@@ -1296,8 +1293,7 @@ static int check_inode(struct btree_trans *trans, ...@@ -1296,8 +1293,7 @@ static int check_inode(struct btree_trans *trans,
sectors = bch2_count_inode_sectors(trans, u.bi_inum); sectors = bch2_count_inode_sectors(trans, u.bi_inum);
if (sectors < 0) { if (sectors < 0) {
bch_err(c, "error in fs gc: error %i " bch_err(c, "error in fsck: error %i recounting inode sectors",
"recounting inode sectors",
(int) sectors); (int) sectors);
return sectors; return sectors;
} }
...@@ -1317,7 +1313,7 @@ static int check_inode(struct btree_trans *trans, ...@@ -1317,7 +1313,7 @@ static int check_inode(struct btree_trans *trans,
BTREE_INSERT_NOFAIL| BTREE_INSERT_NOFAIL|
BTREE_INSERT_LAZY_RW); BTREE_INSERT_LAZY_RW);
if (ret && ret != -EINTR) if (ret && ret != -EINTR)
bch_err(c, "error in fs gc: error %i " bch_err(c, "error in fsck: error %i "
"updating inode", ret); "updating inode", ret);
} }
fsck_err: fsck_err:
...@@ -1388,7 +1384,7 @@ peek_nlinks: link = genradix_iter_peek(&nlinks_iter, links); ...@@ -1388,7 +1384,7 @@ peek_nlinks: link = genradix_iter_peek(&nlinks_iter, links);
bch2_trans_exit(&trans); bch2_trans_exit(&trans);
if (ret2) if (ret2)
bch_err(c, "error in fs gc: btree error %i while walking inodes", ret2); bch_err(c, "error in fsck: btree error %i while walking inodes", ret2);
return ret ?: ret2; return ret ?: ret2;
} }
...@@ -1429,101 +1425,60 @@ static int check_inode_nlinks(struct bch_fs *c, ...@@ -1429,101 +1425,60 @@ static int check_inode_nlinks(struct bch_fs *c,
return ret; return ret;
} }
noinline_for_stack
static int check_inodes_fast(struct bch_fs *c)
{
struct btree_trans trans;
struct btree_iter *iter;
struct bkey_s_c k;
struct bkey_s_c_inode inode;
int ret;
bch2_trans_init(&trans, c);
bch2_trans_preload_iters(&trans);
for_each_btree_key(&trans, iter, BTREE_ID_INODES, POS_MIN, 0, k, ret) {
if (k.k->type != KEY_TYPE_inode)
continue;
inode = bkey_s_c_to_inode(k);
if (inode.v->bi_flags &
(BCH_INODE_I_SIZE_DIRTY|
BCH_INODE_I_SECTORS_DIRTY|
BCH_INODE_UNLINKED)) {
ret = check_inode(&trans, NULL, iter, inode, NULL);
BUG_ON(ret == -EINTR);
if (ret)
break;
}
}
BUG_ON(ret == -EINTR);
return bch2_trans_exit(&trans) ?: ret;
}
/* /*
* Checks for inconsistencies that shouldn't happen, unless we have a bug. * Checks for inconsistencies that shouldn't happen, unless we have a bug.
* Doesn't fix them yet, mainly because they haven't yet been observed: * Doesn't fix them yet, mainly because they haven't yet been observed:
*/ */
static int bch2_fsck_full(struct bch_fs *c) int bch2_fsck_full(struct bch_fs *c)
{ {
struct bch_inode_unpacked root_inode, lostfound_inode; struct bch_inode_unpacked root_inode, lostfound_inode;
int ret;
bch_verbose(c, "starting fsck:"); return check_extents(c) ?:
ret = check_extents(c) ?:
check_dirents(c) ?: check_dirents(c) ?:
check_xattrs(c) ?: check_xattrs(c) ?:
check_root(c, &root_inode) ?: check_root(c, &root_inode) ?:
check_lostfound(c, &root_inode, &lostfound_inode) ?: check_lostfound(c, &root_inode, &lostfound_inode) ?:
check_directory_structure(c, &lostfound_inode) ?: check_directory_structure(c, &lostfound_inode) ?:
check_inode_nlinks(c, &lostfound_inode); check_inode_nlinks(c, &lostfound_inode);
bch2_flush_fsck_errs(c);
bch_verbose(c, "fsck done");
return ret;
} }
static int bch2_fsck_inode_nlink(struct bch_fs *c) int bch2_fsck_inode_nlink(struct bch_fs *c)
{ {
struct bch_inode_unpacked root_inode, lostfound_inode; struct bch_inode_unpacked root_inode, lostfound_inode;
int ret;
bch_verbose(c, "checking inode link counts:"); return check_root(c, &root_inode) ?:
ret = check_root(c, &root_inode) ?:
check_lostfound(c, &root_inode, &lostfound_inode) ?: check_lostfound(c, &root_inode, &lostfound_inode) ?:
check_inode_nlinks(c, &lostfound_inode); check_inode_nlinks(c, &lostfound_inode);
bch2_flush_fsck_errs(c);
bch_verbose(c, "done");
return ret;
} }
static int bch2_fsck_walk_inodes_only(struct bch_fs *c) int bch2_fsck_walk_inodes_only(struct bch_fs *c)
{ {
struct btree_trans trans;
struct btree_iter *iter;
struct bkey_s_c k;
struct bkey_s_c_inode inode;
int ret; int ret;
bch_verbose(c, "walking inodes:"); bch2_trans_init(&trans, c);
ret = check_inodes_fast(c); bch2_trans_preload_iters(&trans);
bch2_flush_fsck_errs(c);
bch_verbose(c, "done");
return ret; for_each_btree_key(&trans, iter, BTREE_ID_INODES, POS_MIN, 0, k, ret) {
} if (k.k->type != KEY_TYPE_inode)
continue;
int bch2_fsck(struct bch_fs *c) inode = bkey_s_c_to_inode(k);
{
if (c->opts.fsck)
return bch2_fsck_full(c);
if (c->sb.clean) if (inode.v->bi_flags &
return 0; (BCH_INODE_I_SIZE_DIRTY|
BCH_INODE_I_SECTORS_DIRTY|
BCH_INODE_UNLINKED)) {
ret = check_inode(&trans, NULL, iter, inode, NULL);
BUG_ON(ret == -EINTR);
if (ret)
break;
}
}
BUG_ON(ret == -EINTR);
return c->sb.features & (1 << BCH_FEATURE_ATOMIC_NLINK) return bch2_trans_exit(&trans) ?: ret;
? bch2_fsck_walk_inodes_only(c)
: bch2_fsck_inode_nlink(c);
} }
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
#ifndef _BCACHEFS_FSCK_H #ifndef _BCACHEFS_FSCK_H
#define _BCACHEFS_FSCK_H #define _BCACHEFS_FSCK_H
int bch2_fsck(struct bch_fs *); int bch2_fsck_full(struct bch_fs *);
int bch2_fsck_inode_nlink(struct bch_fs *);
int bch2_fsck_walk_inodes_only(struct bch_fs *);
#endif /* _BCACHEFS_FSCK_H */ #endif /* _BCACHEFS_FSCK_H */
...@@ -233,16 +233,11 @@ enum opt_type { ...@@ -233,16 +233,11 @@ enum opt_type {
NO_SB_OPT, false, \ NO_SB_OPT, false, \
NULL, "Super read only mode - no writes at all will be issued,\n"\ NULL, "Super read only mode - no writes at all will be issued,\n"\
"even if we have to replay the journal") \ "even if we have to replay the journal") \
x(noreplay, u8, \
OPT_MOUNT, \
OPT_BOOL(), \
NO_SB_OPT, false, \
NULL, "Don't replay the journal (only for internal tools)")\
x(norecovery, u8, \ x(norecovery, u8, \
OPT_MOUNT, \ OPT_MOUNT, \
OPT_BOOL(), \ OPT_BOOL(), \
NO_SB_OPT, false, \ NO_SB_OPT, false, \
NULL, NULL) \ NULL, "Don't replay the journal") \
x(noexcl, u8, \ x(noexcl, u8, \
OPT_MOUNT, \ OPT_MOUNT, \
OPT_BOOL(), \ OPT_BOOL(), \
......
...@@ -714,8 +714,8 @@ int bch2_fs_recovery(struct bch_fs *c) ...@@ -714,8 +714,8 @@ int bch2_fs_recovery(struct bch_fs *c)
if (!c->sb.clean) { if (!c->sb.clean) {
ret = bch2_journal_seq_blacklist_add(c, ret = bch2_journal_seq_blacklist_add(c,
journal_seq, journal_seq,
journal_seq + 4); journal_seq + 4);
if (ret) { if (ret) {
bch_err(c, "error creating new journal seq blacklist entry"); bch_err(c, "error creating new journal seq blacklist entry");
goto err; goto err;
...@@ -763,7 +763,7 @@ int bch2_fs_recovery(struct bch_fs *c) ...@@ -763,7 +763,7 @@ int bch2_fs_recovery(struct bch_fs *c)
* journal; after an unclean shutdown we have to walk all * journal; after an unclean shutdown we have to walk all
* pointers to metadata: * pointers to metadata:
*/ */
bch_verbose(c, "starting metadata mark and sweep:"); bch_info(c, "starting metadata mark and sweep");
err = "error in mark and sweep"; err = "error in mark and sweep";
ret = bch2_gc(c, NULL, true, true); ret = bch2_gc(c, NULL, true, true);
if (ret) if (ret)
...@@ -774,7 +774,7 @@ int bch2_fs_recovery(struct bch_fs *c) ...@@ -774,7 +774,7 @@ int bch2_fs_recovery(struct bch_fs *c)
if (c->opts.fsck || if (c->opts.fsck ||
!(c->sb.compat & (1ULL << BCH_COMPAT_FEAT_ALLOC_INFO)) || !(c->sb.compat & (1ULL << BCH_COMPAT_FEAT_ALLOC_INFO)) ||
test_bit(BCH_FS_REBUILD_REPLICAS, &c->flags)) { test_bit(BCH_FS_REBUILD_REPLICAS, &c->flags)) {
bch_verbose(c, "starting mark and sweep:"); bch_info(c, "starting mark and sweep");
err = "error in mark and sweep"; err = "error in mark and sweep";
ret = bch2_gc(c, &journal_keys, true, false); ret = bch2_gc(c, &journal_keys, true, false);
if (ret) if (ret)
...@@ -792,36 +792,63 @@ int bch2_fs_recovery(struct bch_fs *c) ...@@ -792,36 +792,63 @@ int bch2_fs_recovery(struct bch_fs *c)
if (c->sb.encryption_type && !c->sb.clean) if (c->sb.encryption_type && !c->sb.clean)
atomic64_add(1 << 16, &c->key_version); atomic64_add(1 << 16, &c->key_version);
if (c->opts.noreplay) if (c->opts.norecovery)
goto out; goto out;
bch_verbose(c, "starting journal replay:"); bch_verbose(c, "starting journal replay");
err = "journal replay failed"; err = "journal replay failed";
ret = bch2_journal_replay(c, journal_keys); ret = bch2_journal_replay(c, journal_keys);
if (ret) if (ret)
goto err; goto err;
bch_verbose(c, "journal replay done"); bch_verbose(c, "journal replay done");
bch_verbose(c, "writing allocation info:"); if (!c->opts.nochanges) {
err = "error writing out alloc info"; /*
ret = bch2_stripes_write(c, BTREE_INSERT_LAZY_RW, &wrote) ?: * note that even when filesystem was clean there might be work
bch2_alloc_write(c, BTREE_INSERT_LAZY_RW, &wrote); * to do here, if we ran gc (because of fsck) which recalculated
if (ret) { * oldest_gen:
bch_err(c, "error writing alloc info"); */
goto err; bch_verbose(c, "writing allocation info");
err = "error writing out alloc info";
ret = bch2_stripes_write(c, BTREE_INSERT_LAZY_RW, &wrote) ?:
bch2_alloc_write(c, BTREE_INSERT_LAZY_RW, &wrote);
if (ret) {
bch_err(c, "error writing alloc info");
goto err;
}
bch_verbose(c, "alloc write done");
} }
bch_verbose(c, "alloc write done");
if (c->opts.norecovery) if (!c->sb.clean) {
goto out; if (!(c->sb.features & (1 << BCH_FEATURE_ATOMIC_NLINK))) {
bch_info(c, "checking inode link counts");
err = "error in recovery";
ret = bch2_fsck_inode_nlink(c);
if (ret)
goto err;
bch_verbose(c, "check inodes done");
err = "error in fsck"; } else {
ret = bch2_fsck(c); bch_verbose(c, "checking for deleted inodes");
if (ret) err = "error in recovery";
goto err; ret = bch2_fsck_walk_inodes_only(c);
if (ret)
goto err;
bch_verbose(c, "check inodes done");
}
}
if (c->opts.fsck) {
bch_info(c, "starting fsck");
err = "error in fsck";
ret = bch2_fsck_full(c);
if (ret)
goto err;
bch_verbose(c, "fsck done");
}
if (enabled_qtypes(c)) { if (enabled_qtypes(c)) {
bch_verbose(c, "reading quotas:"); bch_verbose(c, "reading quotas");
ret = bch2_fs_quota_read(c); ret = bch2_fs_quota_read(c);
if (ret) if (ret)
goto err; goto err;
...@@ -857,14 +884,18 @@ int bch2_fs_recovery(struct bch_fs *c) ...@@ -857,14 +884,18 @@ int bch2_fs_recovery(struct bch_fs *c)
c->journal_seq_blacklist_table->nr > 128) c->journal_seq_blacklist_table->nr > 128)
queue_work(system_long_wq, &c->journal_seq_blacklist_gc_work); queue_work(system_long_wq, &c->journal_seq_blacklist_gc_work);
out: out:
ret = 0;
err:
fsck_err:
bch2_flush_fsck_errs(c);
journal_keys_free(&journal_keys); journal_keys_free(&journal_keys);
journal_entries_free(&journal_entries); journal_entries_free(&journal_entries);
kfree(clean); kfree(clean);
if (ret)
bch_err(c, "Error in recovery: %s (%i)", err, ret);
else
bch_verbose(c, "ret %i", ret);
return ret; return ret;
err:
fsck_err:
bch_err(c, "Error in recovery: %s (%i)", err, ret);
goto out;
} }
int bch2_fs_initialize(struct bch_fs *c) int bch2_fs_initialize(struct bch_fs *c)
......
...@@ -305,7 +305,6 @@ void bch2_fs_read_only(struct bch_fs *c) ...@@ -305,7 +305,6 @@ void bch2_fs_read_only(struct bch_fs *c)
!test_bit(BCH_FS_ERROR, &c->flags) && !test_bit(BCH_FS_ERROR, &c->flags) &&
!test_bit(BCH_FS_EMERGENCY_RO, &c->flags) && !test_bit(BCH_FS_EMERGENCY_RO, &c->flags) &&
test_bit(BCH_FS_STARTED, &c->flags) && test_bit(BCH_FS_STARTED, &c->flags) &&
!c->opts.noreplay &&
!c->opts.norecovery) !c->opts.norecovery)
bch2_fs_mark_clean(c); bch2_fs_mark_clean(c);
...@@ -379,9 +378,14 @@ int __bch2_fs_read_write(struct bch_fs *c, bool early) ...@@ -379,9 +378,14 @@ int __bch2_fs_read_write(struct bch_fs *c, bool early)
if (test_bit(BCH_FS_RW, &c->flags)) if (test_bit(BCH_FS_RW, &c->flags))
return 0; return 0;
if (c->opts.nochanges || /*
c->opts.noreplay) * nochanges is used for fsck -n mode - we have to allow going rw
return -EINVAL; * during recovery for that to work:
*/
if (c->opts.norecovery ||
(c->opts.nochanges &&
(!early || c->opts.read_only)))
return -EROFS;
ret = bch2_fs_mark_dirty(c); ret = bch2_fs_mark_dirty(c);
if (ret) if (ret)
...@@ -694,10 +698,6 @@ static struct bch_fs *bch2_fs_alloc(struct bch_sb *sb, struct bch_opts opts) ...@@ -694,10 +698,6 @@ static struct bch_fs *bch2_fs_alloc(struct bch_sb *sb, struct bch_opts opts)
c->block_bits = ilog2(c->opts.block_size); c->block_bits = ilog2(c->opts.block_size);
c->btree_foreground_merge_threshold = BTREE_FOREGROUND_MERGE_THRESHOLD(c); c->btree_foreground_merge_threshold = BTREE_FOREGROUND_MERGE_THRESHOLD(c);
c->opts.nochanges |= c->opts.noreplay;
c->opts.read_only |= c->opts.nochanges;
c->opts.read_only |= c->opts.noreplay;
if (bch2_fs_init_fault("fs_alloc")) if (bch2_fs_init_fault("fs_alloc"))
goto err; goto err;
...@@ -776,7 +776,41 @@ static struct bch_fs *bch2_fs_alloc(struct bch_sb *sb, struct bch_opts opts) ...@@ -776,7 +776,41 @@ static struct bch_fs *bch2_fs_alloc(struct bch_sb *sb, struct bch_opts opts)
goto out; goto out;
} }
const char *bch2_fs_start(struct bch_fs *c) noinline_for_stack
static void print_mount_opts(struct bch_fs *c)
{
enum bch_opt_id i;
char buf[512];
struct printbuf p = PBUF(buf);
bool first = true;
strcpy(buf, "(null)");
if (c->opts.read_only) {
pr_buf(&p, "ro");
first = false;
}
for (i = 0; i < bch2_opts_nr; i++) {
const struct bch_option *opt = &bch2_opt_table[i];
u64 v = bch2_opt_get_by_id(&c->opts, i);
if (!(opt->mode & OPT_MOUNT))
continue;
if (v == bch2_opt_get_by_id(&bch2_opts_default, i))
continue;
if (!first)
pr_buf(&p, ",");
first = false;
bch2_opt_to_text(&p, c, opt, v, OPT_SHOW_MOUNT_STYLE);
}
bch_info(c, "mounted with opts: %s", buf);
}
int bch2_fs_start(struct bch_fs *c)
{ {
const char *err = "cannot allocate memory"; const char *err = "cannot allocate memory";
struct bch_sb_field_members *mi; struct bch_sb_field_members *mi;
...@@ -815,26 +849,27 @@ const char *bch2_fs_start(struct bch_fs *c) ...@@ -815,26 +849,27 @@ const char *bch2_fs_start(struct bch_fs *c)
goto err; goto err;
err = "dynamic fault"; err = "dynamic fault";
ret = -EINVAL;
if (bch2_fs_init_fault("fs_start")) if (bch2_fs_init_fault("fs_start"))
goto err; goto err;
if (c->opts.read_only) { if (c->opts.read_only || c->opts.nochanges) {
bch2_fs_read_only(c); bch2_fs_read_only(c);
} else { } else {
if (!test_bit(BCH_FS_RW, &c->flags) err = "error going read write";
? bch2_fs_read_write(c) ret = !test_bit(BCH_FS_RW, &c->flags)
: bch2_fs_read_write_late(c)) { ? bch2_fs_read_write(c)
err = "error going read write"; : bch2_fs_read_write_late(c);
if (ret)
goto err; goto err;
}
} }
set_bit(BCH_FS_STARTED, &c->flags); set_bit(BCH_FS_STARTED, &c->flags);
print_mount_opts(c);
err = NULL; ret = 0;
out: out:
mutex_unlock(&c->state_lock); mutex_unlock(&c->state_lock);
return err; return ret;
err: err:
switch (ret) { switch (ret) {
case BCH_FSCK_ERRORS_NOT_FIXED: case BCH_FSCK_ERRORS_NOT_FIXED:
...@@ -862,7 +897,7 @@ const char *bch2_fs_start(struct bch_fs *c) ...@@ -862,7 +897,7 @@ const char *bch2_fs_start(struct bch_fs *c)
break; break;
} }
BUG_ON(!err); BUG_ON(!ret);
goto out; goto out;
} }
...@@ -1789,9 +1824,9 @@ struct bch_fs *bch2_fs_open(char * const *devices, unsigned nr_devices, ...@@ -1789,9 +1824,9 @@ struct bch_fs *bch2_fs_open(char * const *devices, unsigned nr_devices,
goto err_print; goto err_print;
if (!c->opts.nostart) { if (!c->opts.nostart) {
err = bch2_fs_start(c); ret = bch2_fs_start(c);
if (err) if (ret)
goto err_print; goto err;
} }
out: out:
kfree(sb); kfree(sb);
...@@ -1818,6 +1853,7 @@ static const char *__bch2_fs_open_incremental(struct bch_sb_handle *sb, ...@@ -1818,6 +1853,7 @@ static const char *__bch2_fs_open_incremental(struct bch_sb_handle *sb,
const char *err; const char *err;
struct bch_fs *c; struct bch_fs *c;
bool allocated_fs = false; bool allocated_fs = false;
int ret;
err = bch2_sb_validate(sb); err = bch2_sb_validate(sb);
if (err) if (err)
...@@ -1850,8 +1886,9 @@ static const char *__bch2_fs_open_incremental(struct bch_sb_handle *sb, ...@@ -1850,8 +1886,9 @@ static const char *__bch2_fs_open_incremental(struct bch_sb_handle *sb,
mutex_unlock(&c->sb_lock); mutex_unlock(&c->sb_lock);
if (!c->opts.nostart && bch2_fs_may_start(c)) { if (!c->opts.nostart && bch2_fs_may_start(c)) {
err = bch2_fs_start(c); err = "error starting filesystem";
if (err) ret = bch2_fs_start(c);
if (ret)
goto err; goto err;
} }
......
...@@ -224,7 +224,7 @@ int bch2_fs_read_write_early(struct bch_fs *); ...@@ -224,7 +224,7 @@ int bch2_fs_read_write_early(struct bch_fs *);
void bch2_fs_stop(struct bch_fs *); void bch2_fs_stop(struct bch_fs *);
const char *bch2_fs_start(struct bch_fs *); int bch2_fs_start(struct bch_fs *);
struct bch_fs *bch2_fs_open(char * const *, unsigned, struct bch_opts); struct bch_fs *bch2_fs_open(char * const *, unsigned, struct bch_opts);
const char *bch2_fs_open_incremental(const char *path); const char *bch2_fs_open_incremental(const char *path);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment