]> git.sesse.net Git - bcachefs-tools-debian/blobdiff - libbcachefs/buckets.c
Update bcachefs sources to c3e4d892b77b mean and variance: Promote to lib/math
[bcachefs-tools-debian] / libbcachefs / buckets.c
index a8af803e7289fec94dfcc03929b1fcc1c94d5b98..312bd0c86623402d6be837df1fe8298a71dfd5c6 100644 (file)
@@ -61,7 +61,7 @@ void bch2_fs_usage_initialize(struct bch_fs *c)
                usage->reserved += usage->persistent_reserved[i];
 
        for (i = 0; i < c->replicas.nr; i++) {
-               struct bch_replicas_entry *e =
+               struct bch_replicas_entry_v1 *e =
                        cpu_replicas_entry(&c->replicas, i);
 
                fs_usage_data_type_to_base(usage, e->data_type, usage->replicas[i]);
@@ -214,7 +214,7 @@ void bch2_fs_usage_to_text(struct printbuf *out,
        }
 
        for (i = 0; i < c->replicas.nr; i++) {
-               struct bch_replicas_entry *e =
+               struct bch_replicas_entry_v1 *e =
                        cpu_replicas_entry(&c->replicas, i);
 
                prt_printf(out, "\t");
@@ -277,12 +277,28 @@ void bch2_dev_usage_init(struct bch_dev *ca)
        ca->usage_base->d[BCH_DATA_free].buckets = ca->mi.nbuckets - ca->mi.first_bucket;
 }
 
-static inline int bucket_sectors_fragmented(struct bch_dev *ca,
-                                           struct bch_alloc_v4 a)
+void bch2_dev_usage_to_text(struct printbuf *out, struct bch_dev_usage *usage)
 {
-       return a.dirty_sectors
-               ? max(0, (int) ca->mi.bucket_size - (int) a.dirty_sectors)
-               : 0;
+       prt_tab(out);
+       prt_str(out, "buckets");
+       prt_tab_rjust(out);
+       prt_str(out, "sectors");
+       prt_tab_rjust(out);
+       prt_str(out, "fragmented");
+       prt_tab_rjust(out);
+       prt_newline(out);
+
+       for (unsigned i = 0; i < BCH_DATA_NR; i++) {
+               prt_str(out, bch2_data_types[i]);
+               prt_tab(out);
+               prt_u64(out, usage->d[i].buckets);
+               prt_tab_rjust(out);
+               prt_u64(out, usage->d[i].sectors);
+               prt_tab_rjust(out);
+               prt_u64(out, usage->d[i].fragmented);
+               prt_tab_rjust(out);
+               prt_newline(out);
+       }
 }
 
 static void bch2_dev_usage_update(struct bch_fs *c, struct bch_dev *ca,
@@ -306,46 +322,41 @@ static void bch2_dev_usage_update(struct bch_fs *c, struct bch_dev *ca,
        u->d[old.data_type].buckets--;
        u->d[new.data_type].buckets++;
 
-       u->buckets_ec -= (int) !!old.stripe;
-       u->buckets_ec += (int) !!new.stripe;
-
-       u->d[old.data_type].sectors -= old.dirty_sectors;
-       u->d[new.data_type].sectors += new.dirty_sectors;
+       u->d[old.data_type].sectors -= bch2_bucket_sectors_dirty(old);
+       u->d[new.data_type].sectors += bch2_bucket_sectors_dirty(new);
 
        u->d[BCH_DATA_cached].sectors += new.cached_sectors;
        u->d[BCH_DATA_cached].sectors -= old.cached_sectors;
 
-       u->d[old.data_type].fragmented -= bucket_sectors_fragmented(ca, old);
-       u->d[new.data_type].fragmented += bucket_sectors_fragmented(ca, new);
+       u->d[old.data_type].fragmented -= bch2_bucket_sectors_fragmented(ca, old);
+       u->d[new.data_type].fragmented += bch2_bucket_sectors_fragmented(ca, new);
 
        preempt_enable();
 }
 
-static void bch2_dev_usage_update_m(struct bch_fs *c, struct bch_dev *ca,
-                                   struct bucket old, struct bucket new,
-                                   u64 journal_seq, bool gc)
+static inline struct bch_alloc_v4 bucket_m_to_alloc(struct bucket b)
 {
-       struct bch_alloc_v4 old_a = {
-               .gen            = old.gen,
-               .data_type      = old.data_type,
-               .dirty_sectors  = old.dirty_sectors,
-               .cached_sectors = old.cached_sectors,
-               .stripe         = old.stripe,
-       };
-       struct bch_alloc_v4 new_a = {
-               .gen            = new.gen,
-               .data_type      = new.data_type,
-               .dirty_sectors  = new.dirty_sectors,
-               .cached_sectors = new.cached_sectors,
-               .stripe         = new.stripe,
+       return (struct bch_alloc_v4) {
+               .gen            = b.gen,
+               .data_type      = b.data_type,
+               .dirty_sectors  = b.dirty_sectors,
+               .cached_sectors = b.cached_sectors,
+               .stripe         = b.stripe,
        };
+}
 
-       bch2_dev_usage_update(c, ca, old_a, new_a, journal_seq, gc);
+static void bch2_dev_usage_update_m(struct bch_fs *c, struct bch_dev *ca,
+                                   struct bucket old, struct bucket new)
+{
+       bch2_dev_usage_update(c, ca,
+                             bucket_m_to_alloc(old),
+                             bucket_m_to_alloc(new),
+                             0, true);
 }
 
 static inline int __update_replicas(struct bch_fs *c,
                                    struct bch_fs_usage *fs_usage,
-                                   struct bch_replicas_entry *r,
+                                   struct bch_replicas_entry_v1 *r,
                                    s64 sectors)
 {
        int idx = bch2_replicas_entry_idx(c, r);
@@ -359,7 +370,7 @@ static inline int __update_replicas(struct bch_fs *c,
 }
 
 static inline int update_replicas(struct bch_fs *c, struct bkey_s_c k,
-                       struct bch_replicas_entry *r, s64 sectors,
+                       struct bch_replicas_entry_v1 *r, s64 sectors,
                        unsigned journal_seq, bool gc)
 {
        struct bch_fs_usage *fs_usage;
@@ -370,8 +381,8 @@ static inline int update_replicas(struct bch_fs *c, struct bkey_s_c k,
 
        idx = bch2_replicas_entry_idx(c, r);
        if (idx < 0 &&
-           fsck_err(c, "no replicas entry\n"
-                    "  while marking %s",
+           fsck_err(c, ptr_to_missing_replicas_entry,
+                    "no replicas entry\n  while marking %s",
                     (bch2_bkey_val_to_text(&buf, c, k), buf.buf))) {
                percpu_up_read(&c->mark_lock);
                ret = bch2_mark_replicas(c, r);
@@ -453,9 +464,9 @@ int bch2_replicas_deltas_realloc(struct btree_trans *trans, unsigned more)
                                __replicas_deltas_realloc(trans, more, _gfp));
 }
 
-static inline int update_replicas_list(struct btree_trans *trans,
-                                       struct bch_replicas_entry *r,
-                                       s64 sectors)
+int bch2_update_replicas_list(struct btree_trans *trans,
+                        struct bch_replicas_entry_v1 *r,
+                        s64 sectors)
 {
        struct replicas_delta_list *d;
        struct replicas_delta *n;
@@ -481,14 +492,13 @@ static inline int update_replicas_list(struct btree_trans *trans,
        return 0;
 }
 
-static inline int update_cached_sectors_list(struct btree_trans *trans,
-                                             unsigned dev, s64 sectors)
+int bch2_update_cached_sectors_list(struct btree_trans *trans, unsigned dev, s64 sectors)
 {
        struct bch_replicas_padded r;
 
        bch2_replicas_entry_cached(&r.e, dev);
 
-       return update_replicas_list(trans, &r.e, sectors);
+       return bch2_update_replicas_list(trans, &r.e, sectors);
 }
 
 int bch2_mark_alloc(struct btree_trans *trans,
@@ -580,23 +590,6 @@ int bch2_mark_alloc(struct btree_trans *trans,
        }
        percpu_up_read(&c->mark_lock);
 
-       /*
-        * need to know if we're getting called from the invalidate path or
-        * not:
-        */
-
-       if ((flags & BTREE_TRIGGER_BUCKET_INVALIDATE) &&
-           old_a->cached_sectors) {
-               ret = update_cached_sectors(c, new, ca->dev_idx,
-                                           -((s64) old_a->cached_sectors),
-                                           journal_seq, gc);
-               if (ret) {
-                       bch2_fs_fatal_error(c, "%s(): no replicas entry while updating cached sectors",
-                                           __func__);
-                       return ret;
-               }
-       }
-
        if (new_a->data_type == BCH_DATA_free &&
            (!new_a->journal_seq || new_a->journal_seq < c->journal.flushed_seq_ondisk))
                closure_wake_up(&c->freelist_wait);
@@ -658,14 +651,13 @@ int bch2_mark_metadata_bucket(struct bch_fs *c, struct bch_dev *ca,
                goto err;
        }
 
-
        g->data_type = data_type;
        g->dirty_sectors += sectors;
        new = *g;
 err:
        bucket_unlock(g);
        if (!ret)
-               bch2_dev_usage_update_m(c, ca, old, new, 0, true);
+               bch2_dev_usage_update_m(c, ca, old, new);
        percpu_up_read(&c->mark_lock);
        return ret;
 }
@@ -675,14 +667,11 @@ static int check_bucket_ref(struct btree_trans *trans,
                            const struct bch_extent_ptr *ptr,
                            s64 sectors, enum bch_data_type ptr_data_type,
                            u8 b_gen, u8 bucket_data_type,
-                           u32 dirty_sectors, u32 cached_sectors)
+                           u32 bucket_sectors)
 {
        struct bch_fs *c = trans->c;
        struct bch_dev *ca = bch_dev_bkey_exists(c, ptr->dev);
        size_t bucket_nr = PTR_BUCKET_NR(ca, ptr);
-       u32 bucket_sectors = !ptr->cached
-               ? dirty_sectors
-               : cached_sectors;
        struct printbuf buf = PRINTBUF;
        int ret = 0;
 
@@ -695,6 +684,7 @@ static int check_bucket_ref(struct btree_trans *trans,
 
        if (gen_after(ptr->gen, b_gen)) {
                bch2_fsck_err(c, FSCK_CAN_IGNORE|FSCK_NEED_FSCK,
+                             BCH_FSCK_ERR_ptr_gen_newer_than_bucket_gen,
                        "bucket %u:%zu gen %u data type %s: ptr gen %u newer than bucket gen\n"
                        "while marking %s",
                        ptr->dev, bucket_nr, b_gen,
@@ -707,6 +697,7 @@ static int check_bucket_ref(struct btree_trans *trans,
 
        if (gen_cmp(b_gen, ptr->gen) > BUCKET_GC_GEN_MAX) {
                bch2_fsck_err(c, FSCK_CAN_IGNORE|FSCK_NEED_FSCK,
+                             BCH_FSCK_ERR_ptr_too_stale,
                        "bucket %u:%zu gen %u data type %s: ptr gen %u too stale\n"
                        "while marking %s",
                        ptr->dev, bucket_nr, b_gen,
@@ -720,6 +711,7 @@ static int check_bucket_ref(struct btree_trans *trans,
 
        if (b_gen != ptr->gen && !ptr->cached) {
                bch2_fsck_err(c, FSCK_CAN_IGNORE|FSCK_NEED_FSCK,
+                             BCH_FSCK_ERR_stale_dirty_ptr,
                        "bucket %u:%zu gen %u (mem gen %u) data type %s: stale dirty ptr (gen %u)\n"
                        "while marking %s",
                        ptr->dev, bucket_nr, b_gen,
@@ -741,6 +733,7 @@ static int check_bucket_ref(struct btree_trans *trans,
            ptr_data_type &&
            bucket_data_type != ptr_data_type) {
                bch2_fsck_err(c, FSCK_CAN_IGNORE|FSCK_NEED_FSCK,
+                             BCH_FSCK_ERR_ptr_bucket_data_type_mismatch,
                        "bucket %u:%zu gen %u different types of data in same bucket: %s, %s\n"
                        "while marking %s",
                        ptr->dev, bucket_nr, b_gen,
@@ -754,6 +747,7 @@ static int check_bucket_ref(struct btree_trans *trans,
 
        if ((u64) bucket_sectors + sectors > U32_MAX) {
                bch2_fsck_err(c, FSCK_CAN_IGNORE|FSCK_NEED_FSCK,
+                             BCH_FSCK_ERR_bucket_sector_count_overflow,
                        "bucket %u:%zu gen %u data type %s sector count overflow: %u + %lli > U32_MAX\n"
                        "while marking %s",
                        ptr->dev, bucket_nr, b_gen,
@@ -778,7 +772,6 @@ static int mark_stripe_bucket(struct btree_trans *trans,
                              unsigned flags)
 {
        struct bch_fs *c = trans->c;
-       u64 journal_seq = trans->journal_res.seq;
        const struct bch_stripe *s = bkey_s_c_to_stripe(k).v;
        unsigned nr_data = s->nr_blocks - s->nr_redundant;
        bool parity = ptr_idx >= nr_data;
@@ -812,7 +805,7 @@ static int mark_stripe_bucket(struct btree_trans *trans,
 
        ret = check_bucket_ref(trans, k, ptr, sectors, data_type,
                               g->gen, g->data_type,
-                              g->dirty_sectors, g->cached_sectors);
+                              g->dirty_sectors);
        if (ret)
                goto err;
 
@@ -825,7 +818,7 @@ static int mark_stripe_bucket(struct btree_trans *trans,
 err:
        bucket_unlock(g);
        if (!ret)
-               bch2_dev_usage_update_m(c, ca, old, new, journal_seq, true);
+               bch2_dev_usage_update_m(c, ca, old, new);
        percpu_up_read(&c->mark_lock);
        printbuf_exit(&buf);
        return ret;
@@ -842,15 +835,18 @@ static int __mark_pointer(struct btree_trans *trans,
                ? dirty_sectors
                : cached_sectors;
        int ret = check_bucket_ref(trans, k, ptr, sectors, ptr_data_type,
-                                  bucket_gen, *bucket_data_type,
-                                  *dirty_sectors, *cached_sectors);
+                                  bucket_gen, *bucket_data_type, *dst_sectors);
 
        if (ret)
                return ret;
 
        *dst_sectors += sectors;
-       *bucket_data_type = *dirty_sectors || *cached_sectors
-               ? ptr_data_type : 0;
+
+       if (!*dirty_sectors && !*cached_sectors)
+               *bucket_data_type = 0;
+       else if (*bucket_data_type != BCH_DATA_stripe)
+               *bucket_data_type = ptr_data_type;
+
        return 0;
 }
 
@@ -861,7 +857,6 @@ static int bch2_mark_pointer(struct btree_trans *trans,
                             s64 sectors,
                             unsigned flags)
 {
-       u64 journal_seq = trans->journal_res.seq;
        struct bch_fs *c = trans->c;
        struct bch_dev *ca = bch_dev_bkey_exists(c, p.ptr.dev);
        struct bucket old, new, *g;
@@ -888,7 +883,7 @@ static int bch2_mark_pointer(struct btree_trans *trans,
        new = *g;
        bucket_unlock(g);
        if (!ret)
-               bch2_dev_usage_update_m(c, ca, old, new, journal_seq, true);
+               bch2_dev_usage_update_m(c, ca, old, new);
        percpu_up_read(&c->mark_lock);
 
        return ret;
@@ -1195,7 +1190,8 @@ static s64 __bch2_mark_reflink_p(struct btree_trans *trans,
        *idx = r->offset;
        return 0;
 not_found:
-       if (fsck_err(c, "pointer to missing indirect extent\n"
+       if (fsck_err(c, reflink_p_to_missing_reflink_v,
+                    "pointer to missing indirect extent\n"
                     "  %s\n"
                     "  missing range %llu-%llu",
                     (bch2_bkey_val_to_text(&buf, c, p.s_c), buf.buf),
@@ -1316,7 +1312,7 @@ int bch2_trans_fs_usage_apply(struct btree_trans *trans,
        struct bch_fs *c = trans->c;
        static int warned_disk_usage = 0;
        bool warn = false;
-       unsigned disk_res_sectors = trans->disk_res ? trans->disk_res->sectors : 0;
+       u64 disk_res_sectors = trans->disk_res ? trans->disk_res->sectors : 0;
        struct replicas_delta *d, *d2;
        struct replicas_delta *top = (void *) deltas->d + deltas->used;
        struct bch_fs_usage *dst;
@@ -1375,7 +1371,7 @@ int bch2_trans_fs_usage_apply(struct btree_trans *trans,
 
        if (unlikely(warn) && !xchg(&warned_disk_usage, 1))
                bch2_trans_inconsistent(trans,
-                                       "disk usage increased %lli more than %u sectors reserved)",
+                                       "disk usage increased %lli more than %llu sectors reserved)",
                                        should_not_have_added, disk_res_sectors);
        return 0;
 need_mark:
@@ -1464,7 +1460,7 @@ static int bch2_trans_mark_stripe_ptr(struct btree_trans *trans,
 
        bch2_bkey_to_replicas(&r.e, bkey_i_to_s_c(&s->k_i));
        r.e.data_type = data_type;
-       ret = update_replicas_list(trans, &r.e, sectors);
+       ret = bch2_update_replicas_list(trans, &r.e, sectors);
 err:
        bch2_trans_iter_exit(trans, &iter);
        return ret;
@@ -1507,8 +1503,8 @@ static int __trans_mark_extent(struct btree_trans *trans,
 
                if (p.ptr.cached) {
                        if (!stale) {
-                               ret = update_cached_sectors_list(trans, p.ptr.dev,
-                                                                disk_sectors);
+                               ret = bch2_update_cached_sectors_list(trans, p.ptr.dev,
+                                                                     disk_sectors);
                                if (ret)
                                        return ret;
                        }
@@ -1526,7 +1522,7 @@ static int __trans_mark_extent(struct btree_trans *trans,
        }
 
        if (r.e.nr_devs)
-               ret = update_replicas_list(trans, &r.e, dirty_sectors);
+               ret = bch2_update_replicas_list(trans, &r.e, dirty_sectors);
 
        return ret;
 }
@@ -1571,7 +1567,7 @@ static int bch2_trans_mark_stripe_bucket(struct btree_trans *trans,
 
        ret = check_bucket_ref(trans, s.s_c, ptr, sectors, data_type,
                               a->v.gen, a->v.data_type,
-                              a->v.dirty_sectors, a->v.cached_sectors);
+                              a->v.dirty_sectors);
        if (ret)
                goto err;
 
@@ -1663,7 +1659,7 @@ int bch2_trans_mark_stripe(struct btree_trans *trans,
                s64 sectors = le16_to_cpu(new_s->sectors);
 
                bch2_bkey_to_replicas(&r.e, bkey_i_to_s_c(new));
-               ret = update_replicas_list(trans, &r.e, sectors * new_s->nr_redundant);
+               ret = bch2_update_replicas_list(trans, &r.e, sectors * new_s->nr_redundant);
                if (ret)
                        return ret;
        }
@@ -1672,7 +1668,7 @@ int bch2_trans_mark_stripe(struct btree_trans *trans,
                s64 sectors = -((s64) le16_to_cpu(old_s->sectors));
 
                bch2_bkey_to_replicas(&r.e, old);
-               ret = update_replicas_list(trans, &r.e, sectors * old_s->nr_redundant);
+               ret = bch2_update_replicas_list(trans, &r.e, sectors * old_s->nr_redundant);
                if (ret)
                        return ret;
        }
@@ -1857,6 +1853,7 @@ static int __bch2_trans_mark_metadata_bucket(struct btree_trans *trans,
 
        if (a->v.data_type && type && a->v.data_type != type) {
                bch2_fsck_err(c, FSCK_CAN_IGNORE|FSCK_NEED_FSCK,
+                             BCH_FSCK_ERR_bucket_metadata_type_mismatch,
                        "bucket %llu:%llu gen %u different types of data in same bucket: %s, %s\n"
                        "while marking %s",
                        iter.pos.inode, iter.pos.offset, a->v.gen,
@@ -2084,8 +2081,6 @@ int bch2_dev_buckets_resize(struct bch_fs *c, struct bch_dev *ca, u64 nbuckets)
        bucket_gens->first_bucket = ca->mi.first_bucket;
        bucket_gens->nbuckets   = nbuckets;
 
-       bch2_copygc_stop(c);
-
        if (resize) {
                down_write(&c->gc_lock);
                down_write(&ca->bucket_lock);