]> git.sesse.net Git - bcachefs-tools-debian/blobdiff - libbcachefs/super-io.c
Update bcachefs sources to 3592e42edf bcachefs: Shut down quicker
[bcachefs-tools-debian] / libbcachefs / super-io.c
index 3043def884ab43ea01f555ee35aded06f3f9d986..e3cb08d8c976c04dc9bca712c051d8bfa7d8d8d7 100644 (file)
@@ -51,7 +51,9 @@ static struct bch_sb_field *__bch2_sb_field_resize(struct bch_sb_handle *sb,
        BUG_ON(get_order(__vstruct_bytes(struct bch_sb, sb_u64s)) >
               sb->page_order);
 
-       if (!f) {
+       if (!f && !u64s) {
+               /* nothing to do: */
+       } else if (!f) {
                f = vstruct_last(sb->sb);
                memset(f, 0, sizeof(u64) * u64s);
                f->u64s = cpu_to_le32(u64s);
@@ -795,6 +797,17 @@ out:
        return ret;
 }
 
+void __bch2_check_set_feature(struct bch_fs *c, unsigned feat)
+{
+       mutex_lock(&c->sb_lock);
+       if (!(c->sb.features & (1ULL << feat))) {
+               c->disk_sb.sb->features[0] |= cpu_to_le64(1ULL << feat);
+
+               bch2_write_super(c);
+       }
+       mutex_unlock(&c->sb_lock);
+}
+
 /* BCH_SB_FIELD_journal: */
 
 static int u64_cmp(const void *_l, const void *_r)
@@ -943,12 +956,33 @@ int bch2_fs_mark_dirty(struct bch_fs *c)
        mutex_lock(&c->sb_lock);
        SET_BCH_SB_CLEAN(c->disk_sb.sb, false);
        c->disk_sb.sb->compat[0] &= ~(1ULL << BCH_COMPAT_FEAT_ALLOC_METADATA);
+       c->disk_sb.sb->features[0] |= 1ULL << BCH_FEATURE_new_extent_overwrite;
+       c->disk_sb.sb->features[0] |= 1ULL << BCH_FEATURE_extents_above_btree_updates;
        ret = bch2_write_super(c);
        mutex_unlock(&c->sb_lock);
 
        return ret;
 }
 
+static void
+entry_init_u64s(struct jset_entry *entry, unsigned u64s)
+{
+       memset(entry, 0, u64s * sizeof(u64));
+
+       /*
+        * The u64s field counts from the start of data, ignoring the shared
+        * fields.
+        */
+       entry->u64s = u64s - 1;
+}
+
+static void
+entry_init_size(struct jset_entry *entry, size_t size)
+{
+       unsigned u64s = DIV_ROUND_UP(size, sizeof(u64));
+       entry_init_u64s(entry, u64s);
+}
+
 struct jset_entry *
 bch2_journal_super_entries_add_common(struct bch_fs *c,
                                      struct jset_entry *entry,
@@ -963,7 +997,7 @@ bch2_journal_super_entries_add_common(struct bch_fs *c,
             r < c->btree_roots + BTREE_ID_NR;
             r++)
                if (r->alive) {
-                       entry->u64s     = r->key.u64s;
+                       entry_init_u64s(entry, r->key.u64s + 1);
                        entry->btree_id = r - c->btree_roots;
                        entry->level    = r->level;
                        entry->type     = BCH_JSET_ENTRY_btree_root;
@@ -988,8 +1022,7 @@ bch2_journal_super_entries_add_common(struct bch_fs *c,
                struct jset_entry_usage *u =
                        container_of(entry, struct jset_entry_usage, entry);
 
-               memset(u, 0, sizeof(*u));
-               u->entry.u64s   = DIV_ROUND_UP(sizeof(*u), sizeof(u64)) - 1;
+               entry_init_size(entry, sizeof(*u));
                u->entry.type   = BCH_JSET_ENTRY_usage;
                u->entry.btree_id = FS_USAGE_INODES;
                u->v            = cpu_to_le64(c->usage_base->nr_inodes);
@@ -1001,8 +1034,7 @@ bch2_journal_super_entries_add_common(struct bch_fs *c,
                struct jset_entry_usage *u =
                        container_of(entry, struct jset_entry_usage, entry);
 
-               memset(u, 0, sizeof(*u));
-               u->entry.u64s   = DIV_ROUND_UP(sizeof(*u), sizeof(u64)) - 1;
+               entry_init_size(entry, sizeof(*u));
                u->entry.type   = BCH_JSET_ENTRY_usage;
                u->entry.btree_id = FS_USAGE_KEY_VERSION;
                u->v            = cpu_to_le64(atomic64_read(&c->key_version));
@@ -1014,8 +1046,7 @@ bch2_journal_super_entries_add_common(struct bch_fs *c,
                struct jset_entry_usage *u =
                        container_of(entry, struct jset_entry_usage, entry);
 
-               memset(u, 0, sizeof(*u));
-               u->entry.u64s   = DIV_ROUND_UP(sizeof(*u), sizeof(u64)) - 1;
+               entry_init_size(entry, sizeof(*u));
                u->entry.type   = BCH_JSET_ENTRY_usage;
                u->entry.btree_id = FS_USAGE_RESERVED;
                u->entry.level  = i;
@@ -1030,9 +1061,7 @@ bch2_journal_super_entries_add_common(struct bch_fs *c,
                struct jset_entry_data_usage *u =
                        container_of(entry, struct jset_entry_data_usage, entry);
 
-               memset(u, 0, sizeof(*u));
-               u->entry.u64s   = DIV_ROUND_UP(sizeof(*u) + e->nr_devs,
-                                              sizeof(u64)) - 1;
+               entry_init_size(entry, sizeof(*u) + e->nr_devs);
                u->entry.type   = BCH_JSET_ENTRY_data_usage;
                u->v            = cpu_to_le64(c->usage_base->replicas[i]);
                memcpy(&u->r, e, replicas_entry_bytes(e));
@@ -1059,6 +1088,7 @@ void bch2_fs_mark_clean(struct bch_fs *c)
 
        c->disk_sb.sb->compat[0] |= 1ULL << BCH_COMPAT_FEAT_ALLOC_INFO;
        c->disk_sb.sb->compat[0] |= 1ULL << BCH_COMPAT_FEAT_ALLOC_METADATA;
+       c->disk_sb.sb->features[0] &= ~(1ULL << BCH_FEATURE_extents_above_btree_updates);
 
        u64s = sizeof(*sb_clean) / sizeof(u64) + c->journal.entry_u64s_reserved;