diff --git a/fs/bcachefs/disk_groups.c b/fs/bcachefs/disk_groups.c index e9ee37f1e07d..97eb21827cb3 100644 --- a/fs/bcachefs/disk_groups.c +++ b/fs/bcachefs/disk_groups.c @@ -445,7 +445,10 @@ int bch2_opt_target_parse(struct bch_fs *c, const char *buf, u64 *v) return -EINVAL; } -void bch2_sb_target_to_text(struct printbuf *out, struct bch_sb *sb, u64 v) +void bch2_opt_target_to_text(struct printbuf *out, + struct bch_fs *c, + struct bch_sb *sb, + u64 v) { struct target t = target_decode(v); @@ -453,60 +456,46 @@ void bch2_sb_target_to_text(struct printbuf *out, struct bch_sb *sb, u64 v) case TARGET_NULL: pr_buf(out, "none"); break; - case TARGET_DEV: { - struct bch_sb_field_members *mi = bch2_sb_get_members(sb); - struct bch_member *m = mi->members + t.dev; + case TARGET_DEV: + if (c) { + struct bch_dev *ca; - if (bch2_dev_exists(sb, mi, t.dev)) { - pr_buf(out, "Device "); - pr_uuid(out, m->uuid.b); - pr_buf(out, " (%u)", t.dev); + rcu_read_lock(); + ca = t.dev < c->sb.nr_devices + ? rcu_dereference(c->devs[t.dev]) + : NULL; + + if (ca && percpu_ref_tryget(&ca->io_ref)) { + pr_buf(out, "/dev/%pg", ca->disk_sb.bdev); + percpu_ref_put(&ca->io_ref); + } else if (ca) { + pr_buf(out, "offline device %u", t.dev); + } else { + pr_buf(out, "invalid device %u", t.dev); + } + + rcu_read_unlock(); } else { - pr_buf(out, "Bad device %u", t.dev); - } + struct bch_sb_field_members *mi = bch2_sb_get_members(sb); + struct bch_member *m = mi->members + t.dev; + if (bch2_dev_exists(sb, mi, t.dev)) { + pr_buf(out, "Device "); + pr_uuid(out, m->uuid.b); + pr_buf(out, " (%u)", t.dev); + } else { + pr_buf(out, "Bad device %u", t.dev); + } + } break; - } case TARGET_GROUP: - bch2_disk_path_to_text(out, sb, t.group); - break; - default: - BUG(); - } -} - -void bch2_opt_target_to_text(struct printbuf *out, struct bch_fs *c, u64 v) -{ - struct target t = target_decode(v); - - switch (t.type) { - case TARGET_NULL: - pr_buf(out, "none"); - break; - case TARGET_DEV: { - struct bch_dev *ca; - - rcu_read_lock(); - ca = t.dev < c->sb.nr_devices - ? rcu_dereference(c->devs[t.dev]) - : NULL; - - if (ca && percpu_ref_tryget(&ca->io_ref)) { - pr_buf(out, "/dev/%pg", ca->disk_sb.bdev); - percpu_ref_put(&ca->io_ref); - } else if (ca) { - pr_buf(out, "offline device %u", t.dev); - } else { - pr_buf(out, "invalid device %u", t.dev); - } - - rcu_read_unlock(); - break; - } - case TARGET_GROUP: - mutex_lock(&c->sb_lock); - bch2_disk_path_to_text(out, c->disk_sb.sb, t.group); - mutex_unlock(&c->sb_lock); + if (c) { + mutex_lock(&c->sb_lock); + bch2_disk_path_to_text(out, c->disk_sb.sb, t.group); + mutex_unlock(&c->sb_lock); + } else { + bch2_disk_path_to_text(out, sb, t.group); + } break; default: BUG(); diff --git a/fs/bcachefs/disk_groups.h b/fs/bcachefs/disk_groups.h index a274aacbdf92..de915480514b 100644 --- a/fs/bcachefs/disk_groups.h +++ b/fs/bcachefs/disk_groups.h @@ -77,10 +77,8 @@ int bch2_disk_path_find_or_create(struct bch_sb_handle *, const char *); void bch2_disk_path_to_text(struct printbuf *, struct bch_sb *, unsigned); -void bch2_sb_target_to_text(struct printbuf *, struct bch_sb *, u64); - int bch2_opt_target_parse(struct bch_fs *, const char *, u64 *); -void bch2_opt_target_to_text(struct printbuf *, struct bch_fs *, u64); +void bch2_opt_target_to_text(struct printbuf *, struct bch_fs *, struct bch_sb *, u64); int bch2_sb_disk_groups_to_cpu(struct bch_fs *); diff --git a/fs/bcachefs/fs.c b/fs/bcachefs/fs.c index 310e317738b9..4c68cee013e3 100644 --- a/fs/bcachefs/fs.c +++ b/fs/bcachefs/fs.c @@ -1691,7 +1691,7 @@ static int bch2_show_options(struct seq_file *seq, struct dentry *root) continue; printbuf_reset(&buf); - bch2_opt_to_text(&buf, c, opt, v, + bch2_opt_to_text(&buf, c, c->disk_sb.sb, opt, v, OPT_SHOW_MOUNT_STYLE); seq_putc(seq, ','); seq_puts(seq, buf.buf); diff --git a/fs/bcachefs/opts.c b/fs/bcachefs/opts.c index 71bf26eb13d5..e78d3b75f6fb 100644 --- a/fs/bcachefs/opts.c +++ b/fs/bcachefs/opts.c @@ -96,6 +96,16 @@ const char * const bch2_d_types[BCH_DT_MAX] = { [DT_SUBVOL] = "subvol", }; +u64 BCH2_NO_SB_OPT(const struct bch_sb *sb) +{ + BUG(); +} + +void SET_BCH2_NO_SB_OPT(struct bch_sb *sb, u64 v) +{ + BUG(); +} + void bch2_opts_apply(struct bch_opts *dst, struct bch_opts src) { #define x(_name, ...) \ @@ -280,7 +290,8 @@ int bch2_opt_parse(struct bch_fs *c, const char *msg, return bch2_opt_validate(opt, msg, *res); } -void bch2_opt_to_text(struct printbuf *out, struct bch_fs *c, +void bch2_opt_to_text(struct printbuf *out, + struct bch_fs *c, struct bch_sb *sb, const struct bch_option *opt, u64 v, unsigned flags) { @@ -310,7 +321,7 @@ void bch2_opt_to_text(struct printbuf *out, struct bch_fs *c, pr_buf(out, opt->choices[v]); break; case BCH_OPT_FN: - opt->to_text(out, c, v); + opt->to_text(out, c, sb, v); break; default: BUG(); @@ -431,6 +442,22 @@ int bch2_parse_mount_opts(struct bch_fs *c, struct bch_opts *opts, return ret; } +u64 bch2_opt_from_sb(struct bch_sb *sb, enum bch_opt_id id) +{ + const struct bch_option *opt = bch2_opt_table + id; + u64 v; + + v = opt->get_sb(sb); + + if (opt->flags & OPT_SB_FIELD_ILOG2) + v = 1ULL << v; + + if (opt->flags & OPT_SB_FIELD_SECTORS) + v <<= 9; + + return v; +} + /* * Initial options from superblock - here we don't want any options undefined, * any options the superblock doesn't specify are set to 0: @@ -444,16 +471,10 @@ int bch2_opts_from_sb(struct bch_opts *opts, struct bch_sb *sb) const struct bch_option *opt = bch2_opt_table + id; u64 v; - if (opt->get_sb == NO_SB_OPT) + if (opt->get_sb == BCH2_NO_SB_OPT) continue; - v = opt->get_sb(sb); - - if (opt->flags & OPT_SB_FIELD_ILOG2) - v = 1ULL << v; - - if (opt->flags & OPT_SB_FIELD_SECTORS) - v <<= 9; + v = bch2_opt_from_sb(sb, id); ret = bch2_opt_validate(opt, "superblock option ", v); if (ret) @@ -467,7 +488,7 @@ int bch2_opts_from_sb(struct bch_opts *opts, struct bch_sb *sb) void __bch2_opt_set_sb(struct bch_sb *sb, const struct bch_option *opt, u64 v) { - if (opt->set_sb == SET_NO_SB_OPT) + if (opt->set_sb == SET_BCH2_NO_SB_OPT) return; if (opt->flags & OPT_SB_FIELD_SECTORS) @@ -481,7 +502,7 @@ void __bch2_opt_set_sb(struct bch_sb *sb, const struct bch_option *opt, u64 v) void bch2_opt_set_sb(struct bch_fs *c, const struct bch_option *opt, u64 v) { - if (opt->set_sb == SET_NO_SB_OPT) + if (opt->set_sb == SET_BCH2_NO_SB_OPT) return; mutex_lock(&c->sb_lock); diff --git a/fs/bcachefs/opts.h b/fs/bcachefs/opts.h index b03cac016f0b..fffe3e066864 100644 --- a/fs/bcachefs/opts.h +++ b/fs/bcachefs/opts.h @@ -42,7 +42,8 @@ static inline const char *bch2_d_type_str(unsigned d_type) */ /* dummy option, for options that aren't stored in the superblock */ -LE64_BITMASK(NO_SB_OPT, struct bch_sb, flags[0], 0, 0); +u64 BCH2_NO_SB_OPT(const struct bch_sb *); +void SET_BCH2_NO_SB_OPT(struct bch_sb *, u64); /* When can be set: */ enum opt_flags { @@ -202,7 +203,7 @@ enum opt_type { x(btree_node_mem_ptr_optimization, u8, \ OPT_FS|OPT_MOUNT|OPT_RUNTIME, \ OPT_BOOL(), \ - NO_SB_OPT, true, \ + BCH2_NO_SB_OPT, true, \ NULL, "Stash pointer to in memory btree node in btree ptr")\ x(gc_reserve_percent, u8, \ OPT_FS|OPT_FORMAT|OPT_MOUNT|OPT_RUNTIME, \ @@ -229,7 +230,7 @@ enum opt_type { x(inline_data, u8, \ OPT_FS|OPT_MOUNT|OPT_RUNTIME, \ OPT_BOOL(), \ - NO_SB_OPT, true, \ + BCH2_NO_SB_OPT, true, \ NULL, "Enable inline data extents") \ x(acl, u8, \ OPT_FS|OPT_FORMAT|OPT_MOUNT, \ @@ -254,22 +255,22 @@ enum opt_type { x(degraded, u8, \ OPT_FS|OPT_MOUNT, \ OPT_BOOL(), \ - NO_SB_OPT, false, \ + BCH2_NO_SB_OPT, false, \ NULL, "Allow mounting in degraded mode") \ x(very_degraded, u8, \ OPT_FS|OPT_MOUNT, \ OPT_BOOL(), \ - NO_SB_OPT, false, \ + BCH2_NO_SB_OPT, false, \ NULL, "Allow mounting in when data will be missing") \ x(discard, u8, \ OPT_FS|OPT_MOUNT|OPT_DEVICE, \ OPT_BOOL(), \ - NO_SB_OPT, false, \ + BCH2_NO_SB_OPT, false, \ NULL, "Enable discard/TRIM support") \ x(verbose, u8, \ OPT_FS|OPT_MOUNT, \ OPT_BOOL(), \ - NO_SB_OPT, false, \ + BCH2_NO_SB_OPT, false, \ NULL, "Extra debugging information during mount/recovery")\ x(journal_flush_delay, u32, \ OPT_FS|OPT_MOUNT|OPT_RUNTIME, \ @@ -291,48 +292,48 @@ enum opt_type { x(fsck, u8, \ OPT_FS|OPT_MOUNT, \ OPT_BOOL(), \ - NO_SB_OPT, false, \ + BCH2_NO_SB_OPT, false, \ NULL, "Run fsck on mount") \ x(fix_errors, u8, \ OPT_FS|OPT_MOUNT, \ OPT_BOOL(), \ - NO_SB_OPT, false, \ + BCH2_NO_SB_OPT, false, \ NULL, "Fix errors during fsck without asking") \ x(ratelimit_errors, u8, \ OPT_FS|OPT_MOUNT, \ OPT_BOOL(), \ - NO_SB_OPT, RATELIMIT_ERRORS_DEFAULT, \ + BCH2_NO_SB_OPT, RATELIMIT_ERRORS_DEFAULT, \ NULL, "Ratelimit error messages during fsck") \ x(nochanges, u8, \ OPT_FS|OPT_MOUNT, \ OPT_BOOL(), \ - NO_SB_OPT, false, \ + BCH2_NO_SB_OPT, false, \ NULL, "Super read only mode - no writes at all will be issued,\n"\ "even if we have to replay the journal") \ x(norecovery, u8, \ OPT_FS|OPT_MOUNT, \ OPT_BOOL(), \ - NO_SB_OPT, false, \ + BCH2_NO_SB_OPT, false, \ NULL, "Don't replay the journal") \ x(rebuild_replicas, u8, \ OPT_FS|OPT_MOUNT, \ OPT_BOOL(), \ - NO_SB_OPT, false, \ + BCH2_NO_SB_OPT, false, \ NULL, "Rebuild the superblock replicas section") \ x(keep_journal, u8, \ 0, \ OPT_BOOL(), \ - NO_SB_OPT, false, \ + BCH2_NO_SB_OPT, false, \ NULL, "Don't free journal entries/keys after startup")\ x(read_entire_journal, u8, \ 0, \ OPT_BOOL(), \ - NO_SB_OPT, false, \ + BCH2_NO_SB_OPT, false, \ NULL, "Read all journal entries, not just dirty ones")\ x(read_journal_only, u8, \ 0, \ OPT_BOOL(), \ - NO_SB_OPT, false, \ + BCH2_NO_SB_OPT, false, \ NULL, "Only read the journal, skip the rest of recovery")\ x(journal_transaction_names, u8, \ OPT_FS|OPT_FORMAT|OPT_MOUNT|OPT_RUNTIME, \ @@ -342,64 +343,64 @@ enum opt_type { x(noexcl, u8, \ OPT_FS|OPT_MOUNT, \ OPT_BOOL(), \ - NO_SB_OPT, false, \ + BCH2_NO_SB_OPT, false, \ NULL, "Don't open device in exclusive mode") \ x(sb, u64, \ OPT_MOUNT, \ OPT_UINT(0, S64_MAX), \ - NO_SB_OPT, BCH_SB_SECTOR, \ + BCH2_NO_SB_OPT, BCH_SB_SECTOR, \ "offset", "Sector offset of superblock") \ x(read_only, u8, \ OPT_FS, \ OPT_BOOL(), \ - NO_SB_OPT, false, \ + BCH2_NO_SB_OPT, false, \ NULL, NULL) \ x(nostart, u8, \ 0, \ OPT_BOOL(), \ - NO_SB_OPT, false, \ + BCH2_NO_SB_OPT, false, \ NULL, "Don\'t start filesystem, only open devices") \ x(reconstruct_alloc, u8, \ OPT_FS|OPT_MOUNT, \ OPT_BOOL(), \ - NO_SB_OPT, false, \ + BCH2_NO_SB_OPT, false, \ NULL, "Reconstruct alloc btree") \ x(version_upgrade, u8, \ OPT_FS|OPT_MOUNT, \ OPT_BOOL(), \ - NO_SB_OPT, false, \ + BCH2_NO_SB_OPT, false, \ NULL, "Set superblock to latest version,\n" \ "allowing any new features to be used") \ x(buckets_nouse, u8, \ 0, \ OPT_BOOL(), \ - NO_SB_OPT, false, \ + BCH2_NO_SB_OPT, false, \ NULL, "Allocate the buckets_nouse bitmap") \ x(project, u8, \ OPT_INODE, \ OPT_BOOL(), \ - NO_SB_OPT, false, \ + BCH2_NO_SB_OPT, false, \ NULL, NULL) \ x(no_data_io, u8, \ OPT_MOUNT, \ OPT_BOOL(), \ - NO_SB_OPT, false, \ + BCH2_NO_SB_OPT, false, \ NULL, "Skip submit_bio() for data reads and writes, " \ "for performance testing purposes") \ x(fs_size, u64, \ OPT_DEVICE, \ OPT_UINT(0, S64_MAX), \ - NO_SB_OPT, 0, \ + BCH2_NO_SB_OPT, 0, \ "size", "Size of filesystem on device") \ x(bucket, u32, \ OPT_DEVICE, \ OPT_UINT(0, S64_MAX), \ - NO_SB_OPT, 0, \ + BCH2_NO_SB_OPT, 0, \ "size", "Size of filesystem on device") \ x(durability, u8, \ OPT_DEVICE, \ OPT_UINT(0, BCH_REPLICAS_MAX), \ - NO_SB_OPT, 1, \ + BCH2_NO_SB_OPT, 1, \ "n", "Data written to this device will be considered\n"\ "to have already been replicated n times") @@ -466,7 +467,7 @@ struct bch_option { }; struct { int (*parse)(struct bch_fs *, const char *, u64 *); - void (*to_text)(struct printbuf *, struct bch_fs *, u64); + void (*to_text)(struct printbuf *, struct bch_fs *, struct bch_sb *, u64); }; }; @@ -481,6 +482,7 @@ bool bch2_opt_defined_by_id(const struct bch_opts *, enum bch_opt_id); u64 bch2_opt_get_by_id(const struct bch_opts *, enum bch_opt_id); void bch2_opt_set_by_id(struct bch_opts *, enum bch_opt_id, u64); +u64 bch2_opt_from_sb(struct bch_sb *, enum bch_opt_id); int bch2_opts_from_sb(struct bch_opts *, struct bch_sb *); void __bch2_opt_set_sb(struct bch_sb *, const struct bch_option *, u64); void bch2_opt_set_sb(struct bch_fs *, const struct bch_option *, u64); @@ -492,7 +494,7 @@ int bch2_opt_parse(struct bch_fs *, const char *, const struct bch_option *, #define OPT_SHOW_FULL_LIST (1 << 0) #define OPT_SHOW_MOUNT_STYLE (1 << 1) -void bch2_opt_to_text(struct printbuf *, struct bch_fs *, +void bch2_opt_to_text(struct printbuf *, struct bch_fs *, struct bch_sb *, const struct bch_option *, u64, unsigned); int bch2_opt_check_may_set(struct bch_fs *, int, u64); diff --git a/fs/bcachefs/super-io.c b/fs/bcachefs/super-io.c index 03a8ae496668..bb61a288b7fd 100644 --- a/fs/bcachefs/super-io.c +++ b/fs/bcachefs/super-io.c @@ -1047,45 +1047,56 @@ static void bch2_sb_members_to_text(struct printbuf *out, struct bch_sb *sb, if (!bch2_member_exists(m)) continue; - pr_buf(out, "Device: %u", i); + pr_buf(out, "Device:"); + pr_tab(out); + pr_buf(out, "%u", i); pr_newline(out); pr_indent_push(out, 2); - pr_buf(out, "UUID: "); + pr_buf(out, "UUID:"); + pr_tab(out); pr_uuid(out, m->uuid.b); pr_newline(out); - pr_buf(out, "Size: "); + pr_buf(out, "Size:"); + pr_tab(out); pr_units(out, device_size, device_size << 9); pr_newline(out); - pr_buf(out, "Bucket size: "); + pr_buf(out, "Bucket size:"); + pr_tab(out); pr_units(out, bucket_size, bucket_size << 9); pr_newline(out); - pr_buf(out, "First bucket: %u", - le16_to_cpu(m->first_bucket)); + pr_buf(out, "First bucket:"); + pr_tab(out); + pr_buf(out, "%u", le16_to_cpu(m->first_bucket)); pr_newline(out); - pr_buf(out, "Buckets: %llu", - le64_to_cpu(m->nbuckets)); + pr_buf(out, "Buckets:"); + pr_tab(out); + pr_buf(out, "%llu", le64_to_cpu(m->nbuckets)); pr_newline(out); - pr_buf(out, "Last mount: "); + pr_buf(out, "Last mount:"); + pr_tab(out); if (m->last_mount) pr_time(out, le64_to_cpu(m->last_mount)); else pr_buf(out, "(never)"); pr_newline(out); - pr_buf(out, "State: %s", + pr_buf(out, "State:"); + pr_tab(out); + pr_buf(out, "%s", BCH_MEMBER_STATE(m) < BCH_MEMBER_STATE_NR ? bch2_member_states[BCH_MEMBER_STATE(m)] : "unknown"); pr_newline(out); - pr_buf(out, "Group: "); + pr_buf(out, "Group:"); + pr_tab(out); if (BCH_MEMBER_GROUP(m)) { unsigned idx = BCH_MEMBER_GROUP(m) - 1; @@ -1099,7 +1110,8 @@ static void bch2_sb_members_to_text(struct printbuf *out, struct bch_sb *sb, } pr_newline(out); - pr_buf(out, "Data allowed: "); + pr_buf(out, "Data allowed:"); + pr_tab(out); if (BCH_MEMBER_DATA_ALLOWED(m)) bch2_flags_to_text(out, bch2_data_types, BCH_MEMBER_DATA_ALLOWED(m)); @@ -1107,15 +1119,17 @@ static void bch2_sb_members_to_text(struct printbuf *out, struct bch_sb *sb, pr_buf(out, "(none)"); pr_newline(out); - pr_buf(out, "Has data: "); + pr_buf(out, "Has data:"); + pr_tab(out); if (data_have) bch2_flags_to_text(out, bch2_data_types, data_have); else pr_buf(out, "(none)"); pr_newline(out); - pr_buf(out, "Discard: %llu", - BCH_MEMBER_DISCARD(m)); + pr_buf(out, "Discard:"); + pr_tab(out); + pr_buf(out, "%llu", BCH_MEMBER_DISCARD(m)); pr_newline(out); pr_indent_pop(out, 2); @@ -1452,6 +1466,9 @@ void bch2_sb_field_to_text(struct printbuf *out, struct bch_sb *sb, const struct bch_sb_field_ops *ops = type < BCH_SB_FIELD_NR ? bch2_sb_field_ops[type] : NULL; + if (!out->tabstops[0]) + out->tabstops[0] = 32; + if (ops) pr_buf(out, "%s", bch2_sb_fields[type]); else @@ -1500,6 +1517,9 @@ void bch2_sb_to_text(struct printbuf *out, struct bch_sb *sb, u64 fields_have = 0; unsigned nr_devices = 0; + if (!out->tabstops[0]) + out->tabstops[0] = 32; + mi = bch2_sb_get_members(sb); if (mi) { struct bch_member *m; @@ -1510,137 +1530,106 @@ void bch2_sb_to_text(struct printbuf *out, struct bch_sb *sb, nr_devices += bch2_member_exists(m); } - pr_buf(out, "External UUID: "); + pr_buf(out, "External UUID:"); + pr_tab(out); pr_uuid(out, sb->user_uuid.b); pr_newline(out); - pr_buf(out, "Internal UUID: "); + pr_buf(out, "Internal UUID:"); + pr_tab(out); pr_uuid(out, sb->uuid.b); pr_newline(out); - pr_buf(out, "Device index: %u", sb->dev_idx); + pr_buf(out, "Device index:"); + pr_tab(out); + pr_buf(out, "%u", sb->dev_idx); pr_newline(out); - pr_buf(out, "Label: "); + pr_buf(out, "Label:"); + pr_tab(out); pr_buf(out, "%.*s", (int) sizeof(sb->label), sb->label); pr_newline(out); - pr_buf(out, "Version: %u", le16_to_cpu(sb->version)); + pr_buf(out, "Version:"); + pr_tab(out); + pr_buf(out, "%u", le16_to_cpu(sb->version)); pr_newline(out); - pr_buf(out, "Oldest version on disk: %u", le16_to_cpu(sb->version_min)); + pr_buf(out, "Oldest version on disk:"); + pr_tab(out); + pr_buf(out, "%u", le16_to_cpu(sb->version_min)); pr_newline(out); - pr_buf(out, "Created: "); + pr_buf(out, "Created:"); + pr_tab(out); if (sb->time_base_lo) pr_time(out, div_u64(le64_to_cpu(sb->time_base_lo), NSEC_PER_SEC)); else pr_buf(out, "(not set)"); pr_newline(out); - pr_buf(out, "Squence number: %llu", le64_to_cpu(sb->seq)); + pr_buf(out, "Sequence number:"); + pr_tab(out); + pr_buf(out, "%llu", le64_to_cpu(sb->seq)); pr_newline(out); - pr_buf(out, "Block_size: "); - pr_units(out, le16_to_cpu(sb->block_size), - (u32) le16_to_cpu(sb->block_size) << 9); + pr_buf(out, "Superblock size:"); + pr_tab(out); + pr_buf(out, "%zu", vstruct_bytes(sb)); pr_newline(out); - pr_buf(out, "Btree node size: "); - pr_units(out, BCH_SB_BTREE_NODE_SIZE(sb), - BCH_SB_BTREE_NODE_SIZE(sb) << 9); + pr_buf(out, "Clean:"); + pr_tab(out); + pr_buf(out, "%llu", BCH_SB_CLEAN(sb)); pr_newline(out); - pr_buf(out, "Error action: %s", - BCH_SB_ERROR_ACTION(sb) < BCH_ON_ERROR_NR - ? bch2_error_actions[BCH_SB_ERROR_ACTION(sb)] - : "unknown"); + pr_buf(out, "Devices:"); + pr_tab(out); + pr_buf(out, "%u", nr_devices); pr_newline(out); - pr_buf(out, "Clean: %llu", BCH_SB_CLEAN(sb)); + pr_buf(out, "Sections:"); + vstruct_for_each(sb, f) + fields_have |= 1 << le32_to_cpu(f->type); + pr_tab(out); + bch2_flags_to_text(out, bch2_sb_fields, fields_have); pr_newline(out); - pr_buf(out, "Features: "); + pr_buf(out, "Features:"); + pr_tab(out); bch2_flags_to_text(out, bch2_sb_features, le64_to_cpu(sb->features[0])); pr_newline(out); - pr_buf(out, "Compat features: "); + pr_buf(out, "Compat features:"); + pr_tab(out); bch2_flags_to_text(out, bch2_sb_compat, le64_to_cpu(sb->compat[0])); pr_newline(out); - pr_buf(out, "Metadata replicas: %llu", BCH_SB_META_REPLICAS_WANT(sb)); pr_newline(out); + pr_buf(out, "Options:"); + pr_newline(out); + pr_indent_push(out, 2); + { + enum bch_opt_id id; - pr_buf(out, "Data replicas: %llu", BCH_SB_DATA_REPLICAS_WANT(sb)); - pr_newline(out); + for (id = 0; id < bch2_opts_nr; id++) { + const struct bch_option *opt = bch2_opt_table + id; - pr_buf(out, "Metadata checksum type: %s (%llu)", - BCH_SB_META_CSUM_TYPE(sb) < BCH_CSUM_OPT_NR - ? bch2_csum_opts[BCH_SB_META_CSUM_TYPE(sb)] - : "unknown", - BCH_SB_META_CSUM_TYPE(sb)); - pr_newline(out); + if (opt->get_sb != BCH2_NO_SB_OPT) { + u64 v = bch2_opt_from_sb(sb, id); - pr_buf(out, "Data checksum type: %s (%llu)", - BCH_SB_DATA_CSUM_TYPE(sb) < BCH_CSUM_OPT_NR - ? bch2_csum_opts[BCH_SB_DATA_CSUM_TYPE(sb)] - : "unknown", - BCH_SB_DATA_CSUM_TYPE(sb)); - pr_newline(out); + pr_buf(out, "%s:", opt->attr.name); + pr_tab(out); + bch2_opt_to_text(out, NULL, sb, opt, v, + OPT_HUMAN_READABLE|OPT_SHOW_FULL_LIST); + pr_newline(out); + } + } + } - pr_buf(out, "Compression type: %s (%llu)", - BCH_SB_COMPRESSION_TYPE(sb) < BCH_COMPRESSION_OPT_NR - ? bch2_compression_opts[BCH_SB_COMPRESSION_TYPE(sb)] - : "unknown", - BCH_SB_COMPRESSION_TYPE(sb)); - pr_newline(out); - - pr_buf(out, "Foreground write target: "); - bch2_sb_target_to_text(out, sb, BCH_SB_FOREGROUND_TARGET(sb)); - pr_newline(out); - - pr_buf(out, "Background write target: "); - bch2_sb_target_to_text(out, sb, BCH_SB_BACKGROUND_TARGET(sb)); - pr_newline(out); - - pr_buf(out, "Promote target: "); - bch2_sb_target_to_text(out, sb, BCH_SB_PROMOTE_TARGET(sb)); - pr_newline(out); - - pr_buf(out, "Metadata target: "); - bch2_sb_target_to_text(out, sb, BCH_SB_METADATA_TARGET(sb)); - pr_newline(out); - - pr_buf(out, "String hash type: %s (%llu)", - BCH_SB_STR_HASH_TYPE(sb) < BCH_STR_HASH_NR - ? bch2_str_hash_types[BCH_SB_STR_HASH_TYPE(sb)] - : "unknown", - BCH_SB_STR_HASH_TYPE(sb)); - pr_newline(out); - - pr_buf(out, "32 bit inodes: %llu", BCH_SB_INODE_32BIT(sb)); - pr_newline(out); - - pr_buf(out, "GC reserve percentage: %llu%%", BCH_SB_GC_RESERVE(sb)); - pr_newline(out); - - pr_buf(out, "Root reserve percentage: %llu%%", BCH_SB_ROOT_RESERVE(sb)); - pr_newline(out); - - pr_buf(out, "Devices: %u live, %u total", - nr_devices, sb->nr_devices); - pr_newline(out); - - pr_buf(out, "Sections: "); - vstruct_for_each(sb, f) - fields_have |= 1 << le32_to_cpu(f->type); - bch2_flags_to_text(out, bch2_sb_fields, fields_have); - pr_newline(out); - - pr_buf(out, "Superblock size: %zu", vstruct_bytes(sb)); - pr_newline(out); + pr_indent_pop(out, 2); if (print_layout) { pr_newline(out); diff --git a/fs/bcachefs/super.c b/fs/bcachefs/super.c index 0bc78c50150a..56b01624d5fb 100644 --- a/fs/bcachefs/super.c +++ b/fs/bcachefs/super.c @@ -891,7 +891,7 @@ static void print_mount_opts(struct bch_fs *c) if (!first) pr_buf(&p, ","); first = false; - bch2_opt_to_text(&p, c, opt, v, OPT_SHOW_MOUNT_STYLE); + bch2_opt_to_text(&p, c, c->disk_sb.sb, opt, v, OPT_SHOW_MOUNT_STYLE); } if (!p.pos) diff --git a/fs/bcachefs/sysfs.c b/fs/bcachefs/sysfs.c index 3018250d421b..49e38859bff8 100644 --- a/fs/bcachefs/sysfs.c +++ b/fs/bcachefs/sysfs.c @@ -597,7 +597,7 @@ SHOW(bch2_fs_opts_dir) int id = opt - bch2_opt_table; u64 v = bch2_opt_get_by_id(&c->opts, id); - bch2_opt_to_text(out, c, opt, v, OPT_SHOW_FULL_LIST); + bch2_opt_to_text(out, c, c->disk_sb.sb, opt, v, OPT_SHOW_FULL_LIST); pr_char(out, '\n'); return 0; diff --git a/fs/bcachefs/xattr.c b/fs/bcachefs/xattr.c index f4e20e796ba0..08b33ab8489f 100644 --- a/fs/bcachefs/xattr.c +++ b/fs/bcachefs/xattr.c @@ -448,7 +448,7 @@ static int __bch2_xattr_bcachefs_get(const struct xattr_handler *handler, return -ENODATA; v = bch2_opt_get_by_id(&opts, id); - bch2_opt_to_text(&out, c, opt, v, 0); + bch2_opt_to_text(&out, c, c->disk_sb.sb, opt, v, 0); ret = out.pos;