X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libbcachefs%2Fsuper-io.c;h=d2d3eba4d229170f0d29080952f5948b30e99117;hb=ded0160563b045b61e79949f07bed903e98b6528;hp=1ac36060ed2d839215b751f8fd1f02d4d2ab0d61;hpb=73bf371f4c2b7b5323cef9b6813fc813ac9d385b;p=bcachefs-tools-debian diff --git a/libbcachefs/super-io.c b/libbcachefs/super-io.c index 1ac3606..d2d3eba 100644 --- a/libbcachefs/super-io.c +++ b/libbcachefs/super-io.c @@ -4,6 +4,7 @@ #include "btree_update_interior.h" #include "buckets.h" #include "checksum.h" +#include "counters.h" #include "disk_groups.h" #include "ec.h" #include "error.h" @@ -12,24 +13,29 @@ #include "journal_io.h" #include "journal_sb.h" #include "journal_seq_blacklist.h" +#include "recovery.h" #include "replicas.h" #include "quota.h" #include "super-io.h" #include "super.h" #include "trace.h" #include "vstructs.h" -#include "counters.h" #include #include -struct bch2_metadata_version_str { +struct bch2_metadata_version { u16 version; const char *name; + u64 recovery_passes; }; -static const struct bch2_metadata_version_str bch2_metadata_versions[] = { -#define x(n, v) { .version = v, .name = #n }, +static const struct bch2_metadata_version bch2_metadata_versions[] = { +#define x(n, v, _recovery_passes) { \ + .version = v, \ + .name = #n, \ + .recovery_passes = _recovery_passes, \ +}, BCH_METADATA_VERSIONS() #undef x }; @@ -61,6 +67,24 @@ unsigned bch2_latest_compatible_version(unsigned v) return v; } +u64 bch2_upgrade_recovery_passes(struct bch_fs *c, + unsigned old_version, + unsigned new_version) +{ + u64 ret = 0; + + for (const struct bch2_metadata_version *i = bch2_metadata_versions; + i < bch2_metadata_versions + ARRAY_SIZE(bch2_metadata_versions); + i++) + if (i->version > old_version && i->version <= new_version) { + if (i->recovery_passes & RECOVERY_PASS_ALL_FSCK) + ret |= bch2_fsck_recovery_passes(); + ret |= i->recovery_passes; + } + + return ret &= ~RECOVERY_PASS_ALL_FSCK; +} + const char * const bch2_sb_fields[] = { #define x(name, nr) #name, BCH_SB_FIELDS() @@ -394,6 +418,9 @@ static int bch2_sb_validate(struct bch_sb_handle *disk_sb, struct printbuf *out, SET_BCH_SB_JOURNAL_FLUSH_DELAY(sb, 1000); if (!BCH_SB_JOURNAL_RECLAIM_DELAY(sb)) SET_BCH_SB_JOURNAL_RECLAIM_DELAY(sb, 1000); + + if (!BCH_SB_VERSION_UPGRADE_COMPLETE(sb)) + SET_BCH_SB_VERSION_UPGRADE_COMPLETE(sb, le16_to_cpu(sb->version)); } for (opt_id = 0; opt_id < bch2_opts_nr; opt_id++) { @@ -468,7 +495,7 @@ static void bch2_sb_update(struct bch_fs *c) c->sb.user_uuid = src->user_uuid; c->sb.version = le16_to_cpu(src->version); c->sb.version_min = le16_to_cpu(src->version_min); - c->sb.version_upgrade_complete = BCH_SB_VERSION_UPGRADE_COMPLETE(src) ?: c->sb.version; + c->sb.version_upgrade_complete = BCH_SB_VERSION_UPGRADE_COMPLETE(src); c->sb.nr_devices = src->nr_devices; c->sb.clean = BCH_SB_CLEAN(src); c->sb.encryption_type = BCH_SB_ENCRYPTION_TYPE(src); @@ -634,11 +661,18 @@ int bch2_read_super(const char *path, struct bch_opts *opts, struct printbuf err = PRINTBUF; __le64 *i; int ret; - +#ifndef __KERNEL__ +retry: +#endif memset(sb, 0, sizeof(*sb)); sb->mode = FMODE_READ; sb->have_bio = true; +#ifndef __KERNEL__ + if (opt_get(*opts, direct_io) == false) + sb->mode |= FMODE_BUFFERED; +#endif + if (!opt_get(*opts, noexcl)) sb->mode |= FMODE_EXCL; @@ -723,7 +757,13 @@ int bch2_read_super(const char *path, struct bch_opts *opts, got_super: if (le16_to_cpu(sb->sb->block_size) << 9 < - bdev_logical_block_size(sb->bdev)) { + bdev_logical_block_size(sb->bdev) && + opt_get(*opts, direct_io)) { +#ifndef __KERNEL__ + opt_set(*opts, direct_io, false); + bch2_free_super(sb); + goto retry; +#endif prt_printf(&err, "block size (%u) smaller than device block size (%u)", le16_to_cpu(sb->sb->block_size) << 9, bdev_logical_block_size(sb->bdev)); @@ -1456,9 +1496,7 @@ static const struct bch_sb_field_ops *bch2_sb_field_ops[] = { #undef x }; -static const struct bch_sb_field_ops bch2_sb_field_null_ops = { - NULL -}; +static const struct bch_sb_field_ops bch2_sb_field_null_ops; static const struct bch_sb_field_ops *bch2_sb_field_type_ops(unsigned type) {