]> git.sesse.net Git - bcachefs-tools-debian/blobdiff - libbcachefs/super-io.c
Update bcachefs sources to fbb669e9de bcachefs: Kill btree_node_iter_large
[bcachefs-tools-debian] / libbcachefs / super-io.c
index bcb6e3fba9cd30abdd699b7d718c34dd33ac827f..daaeaf0446a3958153f2f8883499fc2cc9285c97 100644 (file)
@@ -1,11 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0
 
 #include "bcachefs.h"
+#include "buckets.h"
 #include "checksum.h"
 #include "disk_groups.h"
 #include "ec.h"
 #include "error.h"
 #include "io.h"
 #include "journal.h"
+#include "journal_seq_blacklist.h"
 #include "replicas.h"
 #include "quota.h"
 #include "super-io.h"
@@ -467,9 +470,8 @@ reread:
        bio_reset(sb->bio);
        bio_set_dev(sb->bio, sb->bdev);
        sb->bio->bi_iter.bi_sector = offset;
-       sb->bio->bi_iter.bi_size = PAGE_SIZE << sb->page_order;
        bio_set_op_attrs(sb->bio, REQ_OP_READ, REQ_SYNC|REQ_META);
-       bch2_bio_map(sb->bio, sb->sb);
+       bch2_bio_map(sb->bio, sb->sb, PAGE_SIZE << sb->page_order);
 
        if (submit_bio_wait(sb->bio))
                return "IO error";
@@ -571,13 +573,12 @@ int bch2_read_super(const char *path, struct bch_opts *opts,
        bio_reset(sb->bio);
        bio_set_dev(sb->bio, sb->bdev);
        sb->bio->bi_iter.bi_sector = BCH_SB_LAYOUT_SECTOR;
-       sb->bio->bi_iter.bi_size = sizeof(struct bch_sb_layout);
        bio_set_op_attrs(sb->bio, REQ_OP_READ, REQ_SYNC|REQ_META);
        /*
         * use sb buffer to read layout, since sb buffer is page aligned but
         * layout won't be:
         */
-       bch2_bio_map(sb->bio, sb->sb);
+       bch2_bio_map(sb->bio, sb->sb, sizeof(struct bch_sb_layout));
 
        err = "IO error";
        if (submit_bio_wait(sb->bio))
@@ -647,11 +648,10 @@ static void read_back_super(struct bch_fs *c, struct bch_dev *ca)
        bio_reset(bio);
        bio_set_dev(bio, ca->disk_sb.bdev);
        bio->bi_iter.bi_sector  = le64_to_cpu(sb->layout.sb_offset[0]);
-       bio->bi_iter.bi_size    = 4096;
        bio->bi_end_io          = write_super_endio;
        bio->bi_private         = ca;
        bio_set_op_attrs(bio, REQ_OP_READ, REQ_SYNC|REQ_META);
-       bch2_bio_map(bio, ca->sb_read_scratch);
+       bch2_bio_map(bio, ca->sb_read_scratch, PAGE_SIZE);
 
        this_cpu_add(ca->io_done->sectors[READ][BCH_DATA_SB],
                     bio_sectors(bio));
@@ -674,13 +674,12 @@ static void write_one_super(struct bch_fs *c, struct bch_dev *ca, unsigned idx)
        bio_reset(bio);
        bio_set_dev(bio, ca->disk_sb.bdev);
        bio->bi_iter.bi_sector  = le64_to_cpu(sb->offset);
-       bio->bi_iter.bi_size    =
-               roundup((size_t) vstruct_bytes(sb),
-                       bdev_logical_block_size(ca->disk_sb.bdev));
        bio->bi_end_io          = write_super_endio;
        bio->bi_private         = ca;
        bio_set_op_attrs(bio, REQ_OP_WRITE, REQ_SYNC|REQ_META);
-       bch2_bio_map(bio, sb);
+       bch2_bio_map(bio, sb,
+                    roundup((size_t) vstruct_bytes(sb),
+                            bdev_logical_block_size(ca->disk_sb.bdev)));
 
        this_cpu_add(ca->io_done->sectors[WRITE][BCH_DATA_SB],
                     bio_sectors(bio));
@@ -796,6 +795,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,16 +953,36 @@ 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_INFO);
+       c->disk_sb.sb->compat[0] &= ~(1ULL << BCH_COMPAT_FEAT_ALLOC_METADATA);
        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)
+                                     struct jset_entry *entry,
+                                     u64 journal_seq)
 {
        struct btree_root *r;
        unsigned i;
@@ -963,7 +993,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;
@@ -975,18 +1005,23 @@ bch2_journal_super_entries_add_common(struct bch_fs *c,
 
        mutex_unlock(&c->btree_root_lock);
 
-       percpu_down_read_preempt_disable(&c->mark_lock);
+       percpu_down_write(&c->mark_lock);
+
+       if (!journal_seq) {
+               bch2_fs_usage_acc_to_base(c, 0);
+               bch2_fs_usage_acc_to_base(c, 1);
+       } else {
+               bch2_fs_usage_acc_to_base(c, journal_seq & 1);
+       }
 
        {
-               u64 nr_inodes = percpu_u64_get(&c->usage[0]->nr_inodes);
                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(nr_inodes);
+               u->v            = cpu_to_le64(c->usage_base->nr_inodes);
 
                entry = vstruct_next(entry);
        }
@@ -995,8 +1030,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));
@@ -1007,17 +1041,12 @@ bch2_journal_super_entries_add_common(struct bch_fs *c,
        for (i = 0; i < BCH_REPLICAS_MAX; i++) {
                struct jset_entry_usage *u =
                        container_of(entry, struct jset_entry_usage, entry);
-               u64 sectors = percpu_u64_get(&c->usage[0]->persistent_reserved[i]);
-
-               if (!sectors)
-                       continue;
 
-               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;
-               u->v            = sectors;
+               u->v            = cpu_to_le64(c->usage_base->persistent_reserved[i]);
 
                entry = vstruct_next(entry);
        }
@@ -1025,21 +1054,18 @@ bch2_journal_super_entries_add_common(struct bch_fs *c,
        for (i = 0; i < c->replicas.nr; i++) {
                struct bch_replicas_entry *e =
                        cpu_replicas_entry(&c->replicas, i);
-               u64 sectors = percpu_u64_get(&c->usage[0]->replicas[i]);
                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(sectors);
+               u->v            = cpu_to_le64(c->usage_base->replicas[i]);
                memcpy(&u->r, e, replicas_entry_bytes(e));
 
                entry = vstruct_next(entry);
        }
 
-       percpu_up_read_preempt_enable(&c->mark_lock);
+       percpu_up_write(&c->mark_lock);
 
        return entry;
 }
@@ -1057,6 +1083,7 @@ void bch2_fs_mark_clean(struct bch_fs *c)
        SET_BCH_SB_CLEAN(c->disk_sb.sb, true);
 
        c->disk_sb.sb->compat[0] |= 1ULL << BCH_COMPAT_FEAT_ALLOC_INFO;
+       c->disk_sb.sb->compat[0] |= 1ULL << BCH_COMPAT_FEAT_ALLOC_METADATA;
 
        u64s = sizeof(*sb_clean) / sizeof(u64) + c->journal.entry_u64s_reserved;
 
@@ -1075,7 +1102,7 @@ void bch2_fs_mark_clean(struct bch_fs *c)
        BUG_ON(le64_to_cpu(sb_clean->journal_seq) > S64_MAX);
 
        entry = sb_clean->start;
-       entry = bch2_journal_super_entries_add_common(c, entry);
+       entry = bch2_journal_super_entries_add_common(c, entry, 0);
        BUG_ON((void *) entry > vstruct_end(&sb_clean->field));
 
        memset(entry, 0,