]> git.sesse.net Git - bcachefs-tools-debian/commitdiff
Update bcachefs sources to 9d28e4a535 bcachefs: bch2_journal_entry_to_text()
authorKent Overstreet <kent.overstreet@gmail.com>
Fri, 31 Dec 2021 22:23:40 +0000 (17:23 -0500)
committerKent Overstreet <kent.overstreet@gmail.com>
Sun, 2 Jan 2022 02:14:28 +0000 (21:14 -0500)
12 files changed:
.bcachefs_revision
libbcachefs/bcachefs_format.h
libbcachefs/bset.c
libbcachefs/btree_types.h
libbcachefs/btree_update_leaf.c
libbcachefs/buckets.c
libbcachefs/journal_io.c
libbcachefs/journal_io.h
libbcachefs/opts.c
libbcachefs/opts.h
libbcachefs/recovery.c
libbcachefs/super-io.c

index 722644155bd47cc79d1dcea39fc63e09809347c9..a0684850ca39f391512544276d56681be9279e75 100644 (file)
@@ -1 +1 @@
-916d92b6b46b13873118a608ff16212f966375ba
+9d28e4a535cac3b88104a4525dd39fc16175f38c
index a053fca7886dc8131dd7ada2d0192ad2cacff6ba..8ec718cd656b2ea2b1f45a3af4d79222f5c6ea22 100644 (file)
@@ -76,6 +76,7 @@
 #include <asm/byteorder.h>
 #include <linux/kernel.h>
 #include <linux/uuid.h>
+#include "vstructs.h"
 
 #define LE_BITMASK(_bits, name, type, field, offset, end)              \
 static const unsigned  name##_OFFSET = offset;                         \
@@ -1660,7 +1661,8 @@ static inline __u64 __bset_magic(struct bch_sb *sb)
        x(usage,                5)              \
        x(data_usage,           6)              \
        x(clock,                7)              \
-       x(dev_usage,            8)
+       x(dev_usage,            8)              \
+       x(log,                  9)
 
 enum {
 #define x(f, nr)       BCH_JSET_ENTRY_##f      = nr,
@@ -1690,11 +1692,16 @@ struct jset_entry_blacklist_v2 {
        __le64                  end;
 };
 
+#define BCH_FS_USAGE_TYPES()                   \
+       x(reserved,             0)              \
+       x(inodes,               1)              \
+       x(key_version,          2)
+
 enum {
-       FS_USAGE_RESERVED               = 0,
-       FS_USAGE_INODES                 = 1,
-       FS_USAGE_KEY_VERSION            = 2,
-       FS_USAGE_NR                     = 3
+#define x(f, nr)       BCH_FS_USAGE_##f        = nr,
+       BCH_FS_USAGE_TYPES()
+#undef x
+       BCH_FS_USAGE_NR
 };
 
 struct jset_entry_usage {
@@ -1732,6 +1739,17 @@ struct jset_entry_dev_usage {
        struct jset_entry_dev_usage_type d[];
 } __attribute__((packed));
 
+static inline unsigned jset_entry_dev_usage_nr_types(struct jset_entry_dev_usage *u)
+{
+       return (vstruct_bytes(&u->entry) - sizeof(struct jset_entry_dev_usage)) /
+               sizeof(struct jset_entry_dev_usage_type);
+}
+
+struct jset_entry_log {
+       struct jset_entry       entry;
+       u8                      d[];
+} __attribute__((packed));
+
 /*
  * On disk format for a journal entry:
  * seq is monotonically increasing; every journal entry has its own unique
index 59e4c1d1a2a5d0b9575f53a947b6b46b02a1de90..a4e0d149e1dc0dfcf0b88e7dcd395fcfeca7e822 100644 (file)
@@ -1547,10 +1547,6 @@ static inline void __bch2_btree_node_iter_advance(struct btree_node_iter *iter,
 
        EBUG_ON(iter->data->k > iter->data->end);
 
-       while (!__btree_node_iter_set_end(iter, 0) &&
-              !__bch2_btree_node_iter_peek_all(iter, b)->u64s)
-               iter->data->k++;
-
        if (unlikely(__btree_node_iter_set_end(iter, 0))) {
                bch2_btree_node_iter_set_drop(iter, iter->data);
                return;
index c84bba7bcda5bf227d5d0a01251f2f77386d2362..08c49ae3b338d22a46911a25f9fe90ad654807d8 100644 (file)
@@ -382,6 +382,7 @@ struct btree_trans {
        bool                    used_mempool:1;
        bool                    in_traverse_all:1;
        bool                    restarted:1;
+       bool                    journal_transaction_names:1;
        /*
         * For when bch2_trans_update notices we'll be splitting a compressed
         * extent:
index f561e09cd3ef49fe907432307bc0d353d20aeb59..05e119832d6f6301b589b7f892108286d5c8f145 100644 (file)
@@ -290,6 +290,31 @@ static inline int bch2_trans_journal_res_get(struct btree_trans *trans,
        return ret == -EAGAIN ? BTREE_INSERT_NEED_JOURNAL_RES : ret;
 }
 
+#define JSET_ENTRY_LOG_U64s            4
+
+static noinline void journal_transaction_name(struct btree_trans *trans)
+{
+       struct bch_fs *c = trans->c;
+       struct jset_entry *entry = journal_res_entry(&c->journal, &trans->journal_res);
+       struct jset_entry_log *l = container_of(entry, struct jset_entry_log, entry);
+       unsigned u64s = JSET_ENTRY_LOG_U64s - 1;
+       unsigned b, buflen = u64s * sizeof(u64);
+
+       l->entry.u64s           = cpu_to_le16(u64s);
+       l->entry.btree_id       = 0;
+       l->entry.level          = 0;
+       l->entry.type           = BCH_JSET_ENTRY_log;
+       l->entry.pad[0]         = 0;
+       l->entry.pad[1]         = 0;
+       l->entry.pad[2]         = 0;
+       b = snprintf(l->d, buflen, "%ps", (void *) trans->ip);
+       while (b < buflen)
+               l->d[b++] = '\0';
+
+       trans->journal_res.offset       += JSET_ENTRY_LOG_U64s;
+       trans->journal_res.u64s         -= JSET_ENTRY_LOG_U64s;
+}
+
 static inline enum btree_insert_ret
 btree_key_can_insert(struct btree_trans *trans,
                     struct btree *b,
@@ -454,6 +479,9 @@ bch2_trans_commit_write_locked(struct btree_trans *trans,
                trans->journal_res.seq = c->journal.replay_journal_seq;
        }
 
+       if (unlikely(trans->journal_transaction_names))
+               journal_transaction_name(trans);
+
        if (unlikely(trans->extra_journal_entry_u64s)) {
                memcpy_u64s_small(journal_res_entry(&c->journal, &trans->journal_res),
                                  trans->extra_journal_entries,
@@ -910,6 +938,7 @@ static int bch2_trans_commit_run_triggers(struct btree_trans *trans)
 
 int __bch2_trans_commit(struct btree_trans *trans)
 {
+       struct bch_fs *c = trans->c;
        struct btree_insert_entry *i = NULL;
        unsigned u64s;
        int ret = 0;
@@ -919,15 +948,20 @@ int __bch2_trans_commit(struct btree_trans *trans)
                goto out_reset;
 
        if (trans->flags & BTREE_INSERT_GC_LOCK_HELD)
-               lockdep_assert_held(&trans->c->gc_lock);
+               lockdep_assert_held(&c->gc_lock);
 
        memset(&trans->journal_preres, 0, sizeof(trans->journal_preres));
 
        trans->journal_u64s             = trans->extra_journal_entry_u64s;
        trans->journal_preres_u64s      = 0;
 
+       trans->journal_transaction_names = READ_ONCE(c->opts.journal_transaction_names);
+
+       if (trans->journal_transaction_names)
+               trans->journal_u64s += JSET_ENTRY_LOG_U64s;
+
        if (!(trans->flags & BTREE_INSERT_NOCHECK_RW) &&
-           unlikely(!percpu_ref_tryget(&trans->c->writes))) {
+           unlikely(!percpu_ref_tryget(&c->writes))) {
                ret = bch2_trans_commit_get_rw_cold(trans);
                if (ret)
                        goto out_reset;
@@ -969,7 +1003,7 @@ int __bch2_trans_commit(struct btree_trans *trans)
        }
 
        if (trans->extra_journal_res) {
-               ret = bch2_disk_reservation_add(trans->c, trans->disk_res,
+               ret = bch2_disk_reservation_add(c, trans->disk_res,
                                trans->extra_journal_res,
                                (trans->flags & BTREE_INSERT_NOFAIL)
                                ? BCH_DISK_RESERVATION_NOFAIL : 0);
@@ -988,10 +1022,10 @@ retry:
        if (ret)
                goto err;
 out:
-       bch2_journal_preres_put(&trans->c->journal, &trans->journal_preres);
+       bch2_journal_preres_put(&c->journal, &trans->journal_preres);
 
        if (likely(!(trans->flags & BTREE_INSERT_NOCHECK_RW)))
-               percpu_ref_put(&trans->c->writes);
+               percpu_ref_put(&c->writes);
 out_reset:
        trans_for_each_update(trans, i)
                bch2_path_put(trans, i->path, true);
index 709df569ad90a9c831cce564054b15b5a6d7ae00..94aa81e71492344ef417f99ee6d251f46ff79feb 100644 (file)
@@ -358,13 +358,6 @@ static void bch2_dev_usage_update(struct bch_fs *c, struct bch_dev *ca,
        struct bch_fs_usage *fs_usage;
        struct bch_dev_usage *u;
 
-       /*
-        * Hack for bch2_fs_initialize path, where we're first marking sb and
-        * journal non-transactionally:
-        */
-       if (!journal_seq && !test_bit(BCH_FS_INITIALIZED, &c->flags))
-               journal_seq = 1;
-
        preempt_disable();
        fs_usage = fs_usage_ptr(c, journal_seq, gc);
        u = dev_usage_ptr(ca, journal_seq, gc);
index 77201a0ee21d23745c1a9f469a33d94e0eb3d242..0d5bdbaa315dd179b1b3f12745b3b06a6d577486 100644 (file)
@@ -274,7 +274,7 @@ fsck_err:
        return ret;
 }
 
-static int journal_entry_validate_btree_keys(struct bch_fs *c,
+static int journal_entry_btree_keys_validate(struct bch_fs *c,
                                             const char *where,
                                             struct jset_entry *entry,
                                             unsigned version, int big_endian, int write)
@@ -295,7 +295,18 @@ static int journal_entry_validate_btree_keys(struct bch_fs *c,
        return 0;
 }
 
-static int journal_entry_validate_btree_root(struct bch_fs *c,
+static void journal_entry_btree_keys_to_text(struct printbuf *out, struct bch_fs *c,
+                                            struct jset_entry *entry)
+{
+       struct bkey_i *k;
+
+       pr_buf(out, "btree=%s l=%u ", bch2_btree_ids[entry->btree_id], entry->level);
+
+       vstruct_for_each(entry, k)
+               bch2_bkey_val_to_text(out, c, bkey_i_to_s_c(k));
+}
+
+static int journal_entry_btree_root_validate(struct bch_fs *c,
                                             const char *where,
                                             struct jset_entry *entry,
                                             unsigned version, int big_endian, int write)
@@ -323,7 +334,13 @@ fsck_err:
        return ret;
 }
 
-static int journal_entry_validate_prio_ptrs(struct bch_fs *c,
+static void journal_entry_btree_root_to_text(struct printbuf *out, struct bch_fs *c,
+                                            struct jset_entry *entry)
+{
+       journal_entry_btree_keys_to_text(out, c, entry);
+}
+
+static int journal_entry_prio_ptrs_validate(struct bch_fs *c,
                                            const char *where,
                                            struct jset_entry *entry,
                                            unsigned version, int big_endian, int write)
@@ -332,7 +349,12 @@ static int journal_entry_validate_prio_ptrs(struct bch_fs *c,
        return 0;
 }
 
-static int journal_entry_validate_blacklist(struct bch_fs *c,
+static void journal_entry_prio_ptrs_to_text(struct printbuf *out, struct bch_fs *c,
+                                           struct jset_entry *entry)
+{
+}
+
+static int journal_entry_blacklist_validate(struct bch_fs *c,
                                            const char *where,
                                            struct jset_entry *entry,
                                            unsigned version, int big_endian, int write)
@@ -347,7 +369,16 @@ fsck_err:
        return ret;
 }
 
-static int journal_entry_validate_blacklist_v2(struct bch_fs *c,
+static void journal_entry_blacklist_to_text(struct printbuf *out, struct bch_fs *c,
+                                           struct jset_entry *entry)
+{
+       struct jset_entry_blacklist *bl =
+               container_of(entry, struct jset_entry_blacklist, entry);
+
+       pr_buf(out, "seq=%llu", le64_to_cpu(bl->seq));
+}
+
+static int journal_entry_blacklist_v2_validate(struct bch_fs *c,
                                               const char *where,
                                               struct jset_entry *entry,
                                               unsigned version, int big_endian, int write)
@@ -373,7 +404,18 @@ fsck_err:
        return ret;
 }
 
-static int journal_entry_validate_usage(struct bch_fs *c,
+static void journal_entry_blacklist_v2_to_text(struct printbuf *out, struct bch_fs *c,
+                                              struct jset_entry *entry)
+{
+       struct jset_entry_blacklist_v2 *bl =
+               container_of(entry, struct jset_entry_blacklist_v2, entry);
+
+       pr_buf(out, "start=%llu end=%llu",
+              le64_to_cpu(bl->start),
+              le64_to_cpu(bl->end));
+}
+
+static int journal_entry_usage_validate(struct bch_fs *c,
                                        const char *where,
                                        struct jset_entry *entry,
                                        unsigned version, int big_endian, int write)
@@ -394,7 +436,18 @@ fsck_err:
        return ret;
 }
 
-static int journal_entry_validate_data_usage(struct bch_fs *c,
+static void journal_entry_usage_to_text(struct printbuf *out, struct bch_fs *c,
+                                       struct jset_entry *entry)
+{
+       struct jset_entry_usage *u =
+               container_of(entry, struct jset_entry_usage, entry);
+
+       pr_buf(out, "type=%s v=%llu",
+              bch2_fs_usage_types[u->entry.btree_id],
+              le64_to_cpu(u->v));
+}
+
+static int journal_entry_data_usage_validate(struct bch_fs *c,
                                        const char *where,
                                        struct jset_entry *entry,
                                        unsigned version, int big_endian, int write)
@@ -416,7 +469,17 @@ fsck_err:
        return ret;
 }
 
-static int journal_entry_validate_clock(struct bch_fs *c,
+static void journal_entry_data_usage_to_text(struct printbuf *out, struct bch_fs *c,
+                                            struct jset_entry *entry)
+{
+       struct jset_entry_data_usage *u =
+               container_of(entry, struct jset_entry_data_usage, entry);
+
+       bch2_replicas_entry_to_text(out, &u->r);
+       pr_buf(out, "=%llu", le64_to_cpu(u->v));
+}
+
+static int journal_entry_clock_validate(struct bch_fs *c,
                                        const char *where,
                                        struct jset_entry *entry,
                                        unsigned version, int big_endian, int write)
@@ -442,7 +505,16 @@ fsck_err:
        return ret;
 }
 
-static int journal_entry_validate_dev_usage(struct bch_fs *c,
+static void journal_entry_clock_to_text(struct printbuf *out, struct bch_fs *c,
+                                       struct jset_entry *entry)
+{
+       struct jset_entry_clock *clock =
+               container_of(entry, struct jset_entry_clock, entry);
+
+       pr_buf(out, "%s=%llu", clock->rw ? "write" : "read", le64_to_cpu(clock->time));
+}
+
+static int journal_entry_dev_usage_validate(struct bch_fs *c,
                                            const char *where,
                                            struct jset_entry *entry,
                                            unsigned version, int big_endian, int write)
@@ -479,15 +551,59 @@ fsck_err:
        return ret;
 }
 
+static void journal_entry_dev_usage_to_text(struct printbuf *out, struct bch_fs *c,
+                                           struct jset_entry *entry)
+{
+       struct jset_entry_dev_usage *u =
+               container_of(entry, struct jset_entry_dev_usage, entry);
+       unsigned i, nr_types = jset_entry_dev_usage_nr_types(u);
+
+       pr_buf(out, "dev=%u ", le32_to_cpu(u->dev));
+
+       for (i = 0; i < nr_types; i++) {
+               if (i < BCH_DATA_NR)
+                       pr_buf(out, "%s", bch2_data_types[i]);
+               else
+                       pr_buf(out, "(unknown data type %u)", i);
+               pr_buf(out, ": buckets=%llu sectors=%llu fragmented=%llu",
+                      le64_to_cpu(u->d[i].buckets),
+                      le64_to_cpu(u->d[i].sectors),
+                      le64_to_cpu(u->d[i].fragmented));
+       }
+
+       pr_buf(out, "buckets_ec: %llu buckets_unavailable: %llu",
+              le64_to_cpu(u->buckets_ec),
+              le64_to_cpu(u->buckets_unavailable));
+}
+
+static int journal_entry_log_validate(struct bch_fs *c,
+                                     const char *where,
+                                     struct jset_entry *entry,
+                                     unsigned version, int big_endian, int write)
+{
+       return 0;
+}
+
+static void journal_entry_log_to_text(struct printbuf *out, struct bch_fs *c,
+                                     struct jset_entry *entry)
+{
+       struct jset_entry_log *l = container_of(entry, struct jset_entry_log, entry);
+       unsigned bytes = vstruct_bytes(entry) - offsetof(struct jset_entry_log, d);
+
+       bch_scnmemcpy(out, l->d, strnlen(l->d, bytes));
+}
+
 struct jset_entry_ops {
        int (*validate)(struct bch_fs *, const char *,
                        struct jset_entry *, unsigned, int, int);
+       void (*to_text)(struct printbuf *, struct bch_fs *, struct jset_entry *);
 };
 
 static const struct jset_entry_ops bch2_jset_entry_ops[] = {
 #define x(f, nr)                                               \
        [BCH_JSET_ENTRY_##f]    = (struct jset_entry_ops) {     \
-               .validate       = journal_entry_validate_##f,   \
+               .validate       = journal_entry_##f##_validate, \
+               .to_text        = journal_entry_##f##_to_text,  \
        },
        BCH_JSET_ENTRY_TYPES()
 #undef x
@@ -503,6 +619,17 @@ int bch2_journal_entry_validate(struct bch_fs *c, const char *where,
                : 0;
 }
 
+void bch2_journal_entry_to_text(struct printbuf *out, struct bch_fs *c,
+                               struct jset_entry *entry)
+{
+       if (entry->type < BCH_JSET_ENTRY_NR) {
+               pr_buf(out, "%s: ", bch2_jset_entry_types[entry->type]);
+               bch2_jset_entry_ops[entry->type].to_text(out, c, entry);
+       } else {
+               pr_buf(out, "(unknown type %u)", entry->type);
+       }
+}
+
 static int jset_validate_entries(struct bch_fs *c, struct jset *jset,
                                 int write)
 {
index f34281a28f12bc64f06dc62383c16af1f3389129..d8425fe0d67b6826c2de50196d3af23d95f16d55 100644 (file)
@@ -40,8 +40,10 @@ static inline struct jset_entry *__jset_entry_type_next(struct jset *jset,
        for_each_jset_entry_type(entry, jset, BCH_JSET_ENTRY_btree_keys)        \
                vstruct_for_each_safe(entry, k, _n)
 
-int bch2_journal_entry_validate(struct bch_fs *, const char *, struct jset_entry *,
-                               unsigned, int, int);
+int bch2_journal_entry_validate(struct bch_fs *, const char *,
+                               struct jset_entry *, unsigned, int, int);
+void bch2_journal_entry_to_text(struct printbuf *, struct bch_fs *,
+                               struct jset_entry *);
 
 int bch2_journal_read(struct bch_fs *, struct list_head *, u64 *, u64 *);
 
index d9ca69f2ecde91bddedccd3cccede70dc29ce7f4..71bf26eb13d5dbcc767cced43f14f55a4cfa9b5c 100644 (file)
@@ -71,6 +71,16 @@ const char * const bch2_member_states[] = {
        NULL
 };
 
+const char * const bch2_jset_entry_types[] = {
+       BCH_JSET_ENTRY_TYPES()
+       NULL
+};
+
+const char * const bch2_fs_usage_types[] = {
+       BCH_FS_USAGE_TYPES()
+       NULL
+};
+
 #undef x
 
 const char * const bch2_d_types[BCH_DT_MAX] = {
index 661eb5764f685700e785da0b6e75d1e0465ca722..52c0b56aab65f99d3f25abea55bd5b946ad26fe1 100644 (file)
@@ -20,6 +20,8 @@ extern const char * const bch2_str_hash_types[];
 extern const char * const bch2_str_hash_opts[];
 extern const char * const bch2_data_types[];
 extern const char * const bch2_member_states[];
+extern const char * const bch2_jset_entry_types[];
+extern const char * const bch2_fs_usage_types[];
 extern const char * const bch2_d_types[];
 
 static inline const char *bch2_d_type_str(unsigned d_type)
@@ -327,6 +329,11 @@ enum opt_type {
          OPT_BOOL(),                                                   \
          NO_SB_OPT,                    false,                          \
          NULL,         "Read all journal entries, not just dirty ones")\
+       x(journal_transaction_names,    u8,                             \
+         OPT_FS|OPT_MOUNT|OPT_RUNTIME,                                 \
+         OPT_BOOL(),                                                   \
+         NO_SB_OPT,                    false,                          \
+         NULL,         "Log transaction function names in journal")    \
        x(noexcl,                       u8,                             \
          OPT_FS|OPT_MOUNT,                                             \
          OPT_BOOL(),                                                   \
index 0b923037d236fb847490979ba4658be77171b6c1..d332fd16517b983766950e67a7ba4070d85204bd 100644 (file)
@@ -714,15 +714,15 @@ static int journal_replay_entry_early(struct bch_fs *c,
                        container_of(entry, struct jset_entry_usage, entry);
 
                switch (entry->btree_id) {
-               case FS_USAGE_RESERVED:
+               case BCH_FS_USAGE_reserved:
                        if (entry->level < BCH_REPLICAS_MAX)
                                c->usage_base->persistent_reserved[entry->level] =
                                        le64_to_cpu(u->v);
                        break;
-               case FS_USAGE_INODES:
+               case BCH_FS_USAGE_inodes:
                        c->usage_base->nr_inodes = le64_to_cpu(u->v);
                        break;
-               case FS_USAGE_KEY_VERSION:
+               case BCH_FS_USAGE_key_version:
                        atomic64_set(&c->key_version,
                                     le64_to_cpu(u->v));
                        break;
@@ -742,10 +742,7 @@ static int journal_replay_entry_early(struct bch_fs *c,
                struct jset_entry_dev_usage *u =
                        container_of(entry, struct jset_entry_dev_usage, entry);
                struct bch_dev *ca = bch_dev_bkey_exists(c, le32_to_cpu(u->dev));
-               unsigned bytes = jset_u64s(le16_to_cpu(entry->u64s)) * sizeof(u64);
-               unsigned nr_types = (bytes - sizeof(struct jset_entry_dev_usage)) /
-                       sizeof(struct jset_entry_dev_usage_type);
-               unsigned i;
+               unsigned i, nr_types = jset_entry_dev_usage_nr_types(u);
 
                ca->usage_base->buckets_ec              = le64_to_cpu(u->buckets_ec);
                ca->usage_base->buckets_unavailable     = le64_to_cpu(u->buckets_unavailable);
index b8d2cf66a63020d9c4954b844c991b20cfaa2c3a..bbed24b702fdadafc4a6c7d8810d3650980e88ed 100644 (file)
@@ -1027,7 +1027,7 @@ void bch2_journal_super_entries_add_common(struct bch_fs *c,
                                     struct jset_entry_usage, entry);
 
                u->entry.type   = BCH_JSET_ENTRY_usage;
-               u->entry.btree_id = FS_USAGE_INODES;
+               u->entry.btree_id = BCH_FS_USAGE_inodes;
                u->v            = cpu_to_le64(c->usage_base->nr_inodes);
        }
 
@@ -1037,7 +1037,7 @@ void bch2_journal_super_entries_add_common(struct bch_fs *c,
                                     struct jset_entry_usage, entry);
 
                u->entry.type   = BCH_JSET_ENTRY_usage;
-               u->entry.btree_id = FS_USAGE_KEY_VERSION;
+               u->entry.btree_id = BCH_FS_USAGE_key_version;
                u->v            = cpu_to_le64(atomic64_read(&c->key_version));
        }
 
@@ -1047,7 +1047,7 @@ void bch2_journal_super_entries_add_common(struct bch_fs *c,
                                     struct jset_entry_usage, entry);
 
                u->entry.type   = BCH_JSET_ENTRY_usage;
-               u->entry.btree_id = FS_USAGE_RESERVED;
+               u->entry.btree_id = BCH_FS_USAGE_reserved;
                u->entry.level  = i;
                u->v            = cpu_to_le64(c->usage_base->persistent_reserved[i]);
        }