]> git.sesse.net Git - bcachefs-tools-debian/commitdiff
Update bcachefs sources to 8a65cc4951 bcachefs: Improve bch2_dev_freespace_init()
authorKent Overstreet <kent.overstreet@linux.dev>
Tue, 29 Nov 2022 06:15:08 +0000 (01:15 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Tue, 29 Nov 2022 06:15:08 +0000 (01:15 -0500)
27 files changed:
.bcachefs_revision
libbcachefs/alloc_background.c
libbcachefs/alloc_background.h
libbcachefs/alloc_foreground.c
libbcachefs/bkey.c
libbcachefs/bkey.h
libbcachefs/btree_gc.c
libbcachefs/btree_iter.c
libbcachefs/btree_iter.h
libbcachefs/btree_update_leaf.c
libbcachefs/buckets.c
libbcachefs/ec.c
libbcachefs/extent_update.c
libbcachefs/fs-io.c
libbcachefs/fsck.c
libbcachefs/inode.c
libbcachefs/inode.h
libbcachefs/io.c
libbcachefs/lru.c
libbcachefs/migrate.c
libbcachefs/move.c
libbcachefs/movinggc.c
libbcachefs/opts.c
libbcachefs/quota.c
libbcachefs/reflink.c
libbcachefs/subvolume.c
libbcachefs/tests.c

index eba22aa5db7546f69e47a08491189e00bce24113..2351d0c7954dbcd874550d36e43119635030d11d 100644 (file)
@@ -1 +1 @@
-5963d1b1a4a31af4282e6710c7948eb215160386
+8a65cc495143fa43fb3c100de3c2b14519d3135f
index 1acdee8226eb1debaa3e2c8070cdd7b2c4bc4809..702d6ec55a9310909a63d320f113cac03bef044c 100644 (file)
@@ -385,15 +385,10 @@ void bch2_alloc_v4_swab(struct bkey_s k)
 void bch2_alloc_to_text(struct printbuf *out, struct bch_fs *c, struct bkey_s_c k)
 {
        struct bch_alloc_v4 _a;
-       const struct bch_alloc_v4 *a = &_a;
+       const struct bch_alloc_v4 *a = bch2_alloc_to_v4(k, &_a);
        const struct bch_backpointer *bps;
        unsigned i;
 
-       if (k.k->type == KEY_TYPE_alloc_v4)
-               a = bkey_s_c_to_alloc_v4(k).v;
-       else
-               bch2_alloc_to_v4(k, &_a);
-
        prt_newline(out);
        printbuf_indent_add(out, 2);
 
@@ -430,7 +425,7 @@ void bch2_alloc_to_text(struct printbuf *out, struct bch_fs *c, struct bkey_s_c
        printbuf_indent_sub(out, 4);
 }
 
-void bch2_alloc_to_v4(struct bkey_s_c k, struct bch_alloc_v4 *out)
+void __bch2_alloc_to_v4(struct bkey_s_c k, struct bch_alloc_v4 *out)
 {
        if (k.k->type == KEY_TYPE_alloc_v4) {
                int d;
@@ -512,9 +507,11 @@ static inline struct bkey_i_alloc_v4 *bch2_alloc_to_v4_mut_inlined(struct btree_
                 * Not sketchy at doing it this way, nope...
                 */
                struct bkey_i_alloc_v4 *ret =
-                       bch2_trans_kmalloc(trans, bkey_bytes(k.k) + sizeof(struct bch_backpointer));
-               if (!IS_ERR(ret))
+                       bch2_trans_kmalloc_nomemzero(trans, bkey_bytes(k.k) + sizeof(struct bch_backpointer));
+               if (!IS_ERR(ret)) {
                        bkey_reassemble(&ret->k_i, k);
+                       memset((void *) ret + bkey_bytes(k.k), 0, sizeof(struct bch_backpointer));
+               }
                return ret;
        }
 
@@ -574,9 +571,8 @@ int bch2_alloc_read(struct bch_fs *c)
                        continue;
 
                ca = bch_dev_bkey_exists(c, k.k->p.inode);
-               bch2_alloc_to_v4(k, &a);
 
-               *bucket_gen(ca, k.k->p.offset) = a.gen;
+               *bucket_gen(ca, k.k->p.offset) = bch2_alloc_to_v4(k, &a)->gen;
        }
        bch2_trans_iter_exit(&trans, &iter);
 
@@ -610,7 +606,7 @@ static int bch2_bucket_do_index(struct btree_trans *trans,
            a->data_type != BCH_DATA_need_discard)
                return 0;
 
-       k = bch2_trans_kmalloc(trans, sizeof(*k));
+       k = bch2_trans_kmalloc_nomemzero(trans, sizeof(*k));
        if (IS_ERR(k))
                return PTR_ERR(k);
 
@@ -665,7 +661,8 @@ int bch2_trans_mark_alloc(struct btree_trans *trans,
                          unsigned flags)
 {
        struct bch_fs *c = trans->c;
-       struct bch_alloc_v4 old_a, *new_a;
+       struct bch_alloc_v4 old_a_convert, *new_a;
+       const struct bch_alloc_v4 *old_a;
        u64 old_lru, new_lru;
        int ret = 0;
 
@@ -675,13 +672,13 @@ int bch2_trans_mark_alloc(struct btree_trans *trans,
         */
        BUG_ON(new->k.type != KEY_TYPE_alloc_v4);
 
-       bch2_alloc_to_v4(old, &old_a);
+       old_a = bch2_alloc_to_v4(old, &old_a_convert);
        new_a = &bkey_i_to_alloc_v4(new)->v;
 
        new_a->data_type = alloc_data_type(*new_a, new_a->data_type);
 
-       if (new_a->dirty_sectors > old_a.dirty_sectors ||
-           new_a->cached_sectors > old_a.cached_sectors) {
+       if (new_a->dirty_sectors > old_a->dirty_sectors ||
+           new_a->cached_sectors > old_a->cached_sectors) {
                new_a->io_time[READ] = max_t(u64, 1, atomic64_read(&c->io_clock[READ].now));
                new_a->io_time[WRITE]= max_t(u64, 1, atomic64_read(&c->io_clock[WRITE].now));
                SET_BCH_ALLOC_V4_NEED_INC_GEN(new_a, true);
@@ -695,10 +692,10 @@ int bch2_trans_mark_alloc(struct btree_trans *trans,
                SET_BCH_ALLOC_V4_NEED_INC_GEN(new_a, false);
        }
 
-       if (old_a.data_type != new_a->data_type ||
+       if (old_a->data_type != new_a->data_type ||
            (new_a->data_type == BCH_DATA_free &&
-            alloc_freespace_genbits(old_a) != alloc_freespace_genbits(*new_a))) {
-               ret =   bch2_bucket_do_index(trans, old, &old_a, false) ?:
+            alloc_freespace_genbits(*old_a) != alloc_freespace_genbits(*new_a))) {
+               ret =   bch2_bucket_do_index(trans, old, old_a, false) ?:
                        bch2_bucket_do_index(trans, bkey_i_to_s_c(new), new_a, true);
                if (ret)
                        return ret;
@@ -708,7 +705,7 @@ int bch2_trans_mark_alloc(struct btree_trans *trans,
            !new_a->io_time[READ])
                new_a->io_time[READ] = max_t(u64, 1, atomic64_read(&c->io_clock[READ].now));
 
-       old_lru = alloc_lru_idx(old_a);
+       old_lru = alloc_lru_idx(*old_a);
        new_lru = alloc_lru_idx(*new_a);
 
        if (old_lru != new_lru) {
@@ -731,7 +728,8 @@ static int bch2_check_alloc_key(struct btree_trans *trans,
 {
        struct bch_fs *c = trans->c;
        struct bch_dev *ca;
-       struct bch_alloc_v4 a;
+       struct bch_alloc_v4 a_convert;
+       const struct bch_alloc_v4 *a;
        unsigned discard_key_type, freespace_key_type;
        struct bkey_s_c alloc_k, k;
        struct printbuf buf = PRINTBUF;
@@ -756,15 +754,15 @@ static int bch2_check_alloc_key(struct btree_trans *trans,
        if (!ca->mi.freespace_initialized)
                return 0;
 
-       bch2_alloc_to_v4(alloc_k, &a);
+       a = bch2_alloc_to_v4(alloc_k, &a_convert);
 
-       discard_key_type = a.data_type == BCH_DATA_need_discard
+       discard_key_type = a->data_type == BCH_DATA_need_discard
                ? KEY_TYPE_set : 0;
-       freespace_key_type = a.data_type == BCH_DATA_free
+       freespace_key_type = a->data_type == BCH_DATA_free
                ? KEY_TYPE_set : 0;
 
        bch2_btree_iter_set_pos(discard_iter, alloc_k.k->p);
-       bch2_btree_iter_set_pos(freespace_iter, alloc_freespace_pos(alloc_k.k->p, a));
+       bch2_btree_iter_set_pos(freespace_iter, alloc_freespace_pos(alloc_k.k->p, *a));
 
        k = bch2_btree_iter_peek_slot(discard_iter);
        ret = bkey_err(k);
@@ -835,7 +833,8 @@ static int bch2_check_discard_freespace_key(struct btree_trans *trans,
        struct bch_fs *c = trans->c;
        struct btree_iter alloc_iter;
        struct bkey_s_c alloc_k;
-       struct bch_alloc_v4 a;
+       struct bch_alloc_v4 a_convert;
+       const struct bch_alloc_v4 *a;
        u64 genbits;
        struct bpos pos;
        enum bch_data_type state = iter->btree_id == BTREE_ID_need_discard
@@ -860,16 +859,16 @@ static int bch2_check_discard_freespace_key(struct btree_trans *trans,
        if (ret)
                goto err;
 
-       bch2_alloc_to_v4(alloc_k, &a);
+       a = bch2_alloc_to_v4(alloc_k, &a_convert);
 
-       if (fsck_err_on(a.data_type != state ||
+       if (fsck_err_on(a->data_type != state ||
                        (state == BCH_DATA_free &&
-                        genbits != alloc_freespace_genbits(a)), c,
+                        genbits != alloc_freespace_genbits(*a)), c,
                        "%s\n  incorrectly set in %s index (free %u, genbits %llu should be %llu)",
                        (bch2_bkey_val_to_text(&buf, c, alloc_k), buf.buf),
                        bch2_btree_ids[iter->btree_id],
-                       a.data_type == state,
-                       genbits >> 56, alloc_freespace_genbits(a) >> 56))
+                       a->data_type == state,
+                       genbits >> 56, alloc_freespace_genbits(*a) >> 56))
                goto delete;
 out:
 err:
@@ -937,7 +936,8 @@ static int bch2_check_alloc_to_lru_ref(struct btree_trans *trans,
 {
        struct bch_fs *c = trans->c;
        struct btree_iter lru_iter;
-       struct bch_alloc_v4 a;
+       struct bch_alloc_v4 a_convert;
+       const struct bch_alloc_v4 *a;
        struct bkey_s_c alloc_k, k;
        struct printbuf buf = PRINTBUF;
        struct printbuf buf2 = PRINTBUF;
@@ -951,20 +951,20 @@ static int bch2_check_alloc_to_lru_ref(struct btree_trans *trans,
        if (ret)
                return ret;
 
-       bch2_alloc_to_v4(alloc_k, &a);
+       a = bch2_alloc_to_v4(alloc_k, &a_convert);
 
-       if (a.data_type != BCH_DATA_cached)
+       if (a->data_type != BCH_DATA_cached)
                return 0;
 
        bch2_trans_iter_init(trans, &lru_iter, BTREE_ID_lru,
-                            POS(alloc_k.k->p.inode, a.io_time[READ]), 0);
+                            POS(alloc_k.k->p.inode, a->io_time[READ]), 0);
 
        k = bch2_btree_iter_peek_slot(&lru_iter);
        ret = bkey_err(k);
        if (ret)
                goto err;
 
-       if (fsck_err_on(!a.io_time[READ], c,
+       if (fsck_err_on(!a->io_time[READ], c,
                        "cached bucket with read_time 0\n"
                        "  %s",
                (printbuf_reset(&buf),
@@ -977,26 +977,24 @@ static int bch2_check_alloc_to_lru_ref(struct btree_trans *trans,
                        (printbuf_reset(&buf),
                         bch2_bkey_val_to_text(&buf, c, alloc_k), buf.buf),
                        (bch2_bkey_val_to_text(&buf2, c, k), buf2.buf))) {
-               u64 read_time = a.io_time[READ];
-
-               if (!a.io_time[READ])
-                       a.io_time[READ] = atomic64_read(&c->io_clock[READ].now);
+               u64 read_time = a->io_time[READ] ?:
+                       atomic64_read(&c->io_clock[READ].now);
 
                ret = bch2_lru_set(trans,
                                   alloc_k.k->p.inode,
                                   alloc_k.k->p.offset,
-                                  &a.io_time[READ]);
+                                  &read_time);
                if (ret)
                        goto err;
 
-               if (a.io_time[READ] != read_time) {
+               if (a->io_time[READ] != read_time) {
                        struct bkey_i_alloc_v4 *a_mut =
                                bch2_alloc_to_v4_mut(trans, alloc_k);
                        ret = PTR_ERR_OR_ZERO(a_mut);
                        if (ret)
                                goto err;
 
-                       a_mut->v.io_time[READ] = a.io_time[READ];
+                       a_mut->v.io_time[READ] = read_time;
                        ret = bch2_trans_update(trans, alloc_iter,
                                                &a_mut->k_i, BTREE_TRIGGER_NORUN);
                        if (ret)
@@ -1302,34 +1300,110 @@ void bch2_do_invalidates(struct bch_fs *c)
                percpu_ref_put(&c->writes);
 }
 
-static int bucket_freespace_init(struct btree_trans *trans, struct btree_iter *iter,
-                                struct bkey_s_c k, struct bch_dev *ca)
-{
-       struct bch_alloc_v4 a;
-
-       if (iter->pos.offset >= ca->mi.nbuckets)
-               return 1;
-
-       bch2_alloc_to_v4(k, &a);
-       return bch2_bucket_do_index(trans, k, &a, true);
-}
-
 static int bch2_dev_freespace_init(struct bch_fs *c, struct bch_dev *ca)
 {
        struct btree_trans trans;
        struct btree_iter iter;
        struct bkey_s_c k;
+       struct bpos end = POS(ca->dev_idx, ca->mi.nbuckets);
        struct bch_member *m;
        int ret;
 
        bch2_trans_init(&trans, c, 0, 0);
 
-       ret = for_each_btree_key_commit(&trans, iter, BTREE_ID_alloc,
-                       POS(ca->dev_idx, ca->mi.first_bucket),
-                       BTREE_ITER_SLOTS|BTREE_ITER_PREFETCH, k,
-                       NULL, NULL, BTREE_INSERT_LAZY_RW,
-               bucket_freespace_init(&trans, &iter, k, ca));
+       bch2_trans_iter_init(&trans, &iter, BTREE_ID_alloc,
+                            POS(ca->dev_idx, ca->mi.first_bucket),
+                            BTREE_ITER_PREFETCH);
+       /*
+        * Scan the alloc btree for every bucket on @ca, and add buckets to the
+        * freespace/need_discard/need_gc_gens btrees as needed:
+        */
+       while (1) {
+               bch2_trans_begin(&trans);
+               ret = 0;
+
+               if (bkey_ge(iter.pos, end))
+                       break;
 
+               k = bch2_btree_iter_peek_slot(&iter);
+               ret = bkey_err(k);
+               if (ret)
+                       goto bkey_err;
+
+               if (k.k->type) {
+                       /*
+                        * We process live keys in the alloc btree one at a
+                        * time:
+                        */
+                       struct bch_alloc_v4 a_convert;
+                       const struct bch_alloc_v4 *a = bch2_alloc_to_v4(k, &a_convert);
+
+                       ret =   bch2_bucket_do_index(&trans, k, a, true) ?:
+                               bch2_trans_commit(&trans, NULL, NULL,
+                                                 BTREE_INSERT_LAZY_RW|
+                                                 BTREE_INSERT_NOFAIL);
+                       if (ret)
+                               goto bkey_err;
+
+                       bch2_btree_iter_advance(&iter);
+               } else {
+                       /*
+                        * When there's a hole, process a whole range of keys
+                        * all at once:
+                        *
+                        * This is similar to how extent btree iterators in
+                        * slots mode will synthesize a whole range - a
+                        * KEY_TYPE_deleted extent.
+                        *
+                        * But alloc keys aren't extents (they have zero size),
+                        * so we're open coding it here:
+                        */
+                       struct btree_iter iter2;
+                       struct bkey_i *freespace;
+                       struct bpos next;
+
+                       bch2_trans_copy_iter(&iter2, &iter);
+                       k = bch2_btree_iter_peek_upto(&iter2,
+                                       bkey_min(bkey_min(end,
+                                                         iter.path->l[0].b->key.k.p),
+                                                         POS(iter.pos.inode, iter.pos.offset + U32_MAX - 1)));
+                       next = iter2.pos;
+                       ret = bkey_err(k);
+                       bch2_trans_iter_exit(&trans, &iter2);
+
+                       BUG_ON(next.offset >= iter.pos.offset + U32_MAX);
+
+                       if (ret)
+                               goto bkey_err;
+
+                       freespace = bch2_trans_kmalloc(&trans, sizeof(*freespace));
+                       ret = PTR_ERR_OR_ZERO(freespace);
+                       if (ret)
+                               goto bkey_err;
+
+                       bkey_init(&freespace->k);
+                       freespace->k.type = KEY_TYPE_set;
+                       freespace->k.p = iter.pos;
+
+                       bch2_key_resize(&freespace->k, next.offset - iter.pos.offset);
+
+                       ret = __bch2_btree_insert(&trans, BTREE_ID_freespace, freespace) ?:
+                               bch2_trans_commit(&trans, NULL, NULL,
+                                                 BTREE_INSERT_LAZY_RW|
+                                                 BTREE_INSERT_NOFAIL);
+                       if (ret)
+                               goto bkey_err;
+
+                       bch2_btree_iter_set_pos(&iter, next);
+               }
+bkey_err:
+               if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
+                       continue;
+               if (ret)
+                       break;
+       }
+
+       bch2_trans_iter_exit(&trans, &iter);
        bch2_trans_exit(&trans);
 
        if (ret < 0) {
index ee683bdde956c7b08268feaf9d2bfe019d7b6ba8..7956d490a6e6afe112bab8b4061f077feb813edd 100644 (file)
@@ -89,7 +89,25 @@ static inline void set_alloc_v4_u64s(struct bkey_i_alloc_v4 *a)
 struct bkey_i_alloc_v4 *
 bch2_trans_start_alloc_update(struct btree_trans *, struct btree_iter *, struct bpos);
 
-void bch2_alloc_to_v4(struct bkey_s_c, struct bch_alloc_v4 *);
+void __bch2_alloc_to_v4(struct bkey_s_c, struct bch_alloc_v4 *);
+
+static inline const struct bch_alloc_v4 *bch2_alloc_to_v4(struct bkey_s_c k, struct bch_alloc_v4 *convert)
+{
+       const struct bch_alloc_v4 *ret;
+
+       if (unlikely(k.k->type != KEY_TYPE_alloc_v4))
+               goto slowpath;
+
+       ret = bkey_s_c_to_alloc_v4(k).v;
+       if (BCH_ALLOC_V4_BACKPOINTERS_START(ret) != BCH_ALLOC_V4_U64s)
+               goto slowpath;
+
+       return ret;
+slowpath:
+       __bch2_alloc_to_v4(k, convert);
+       return convert;
+}
+
 struct bkey_i_alloc_v4 *bch2_alloc_to_v4_mut(struct btree_trans *, struct bkey_s_c);
 
 int bch2_bucket_io_time_reset(struct btree_trans *, unsigned, size_t, int);
index a32aaf51bb3e36dac0d1c13efbd3f19e3e3df58c..46f215c8bced21fec6d3614ef69a6db1c411f483 100644 (file)
@@ -194,7 +194,7 @@ static inline unsigned open_buckets_reserved(enum alloc_reserve reserve)
 static struct open_bucket *__try_alloc_bucket(struct bch_fs *c, struct bch_dev *ca,
                                              u64 bucket,
                                              enum alloc_reserve reserve,
-                                             struct bch_alloc_v4 *a,
+                                             const struct bch_alloc_v4 *a,
                                              struct bucket_alloc_state *s,
                                              struct closure *cl)
 {
@@ -285,7 +285,8 @@ static struct open_bucket *try_alloc_bucket(struct btree_trans *trans, struct bc
        struct btree_iter iter = { NULL };
        struct bkey_s_c k;
        struct open_bucket *ob;
-       struct bch_alloc_v4 a;
+       struct bch_alloc_v4 a_convert;
+       const struct bch_alloc_v4 *a;
        u64 b = free_entry & ~(~0ULL << 56);
        unsigned genbits = free_entry >> 56;
        struct printbuf buf = PRINTBUF;
@@ -309,12 +310,12 @@ static struct open_bucket *try_alloc_bucket(struct btree_trans *trans, struct bc
                goto err;
        }
 
-       bch2_alloc_to_v4(k, &a);
+       a = bch2_alloc_to_v4(k, &a_convert);
 
-       if (genbits != (alloc_freespace_genbits(a) >> 56)) {
+       if (genbits != (alloc_freespace_genbits(*a) >> 56)) {
                prt_printf(&buf, "bucket in freespace btree with wrong genbits (got %u should be %llu)\n"
                       "  freespace key ",
-                      genbits, alloc_freespace_genbits(a) >> 56);
+                      genbits, alloc_freespace_genbits(*a) >> 56);
                bch2_bkey_val_to_text(&buf, c, freespace_k);
                prt_printf(&buf, "\n  ");
                bch2_bkey_val_to_text(&buf, c, k);
@@ -324,7 +325,7 @@ static struct open_bucket *try_alloc_bucket(struct btree_trans *trans, struct bc
 
        }
 
-       if (a.data_type != BCH_DATA_free) {
+       if (a->data_type != BCH_DATA_free) {
                prt_printf(&buf, "non free bucket in freespace btree\n"
                       "  freespace key ");
                bch2_bkey_val_to_text(&buf, c, freespace_k);
@@ -358,7 +359,7 @@ static struct open_bucket *try_alloc_bucket(struct btree_trans *trans, struct bc
                }
        }
 
-       ob = __try_alloc_bucket(c, ca, b, reserve, &a, s, cl);
+       ob = __try_alloc_bucket(c, ca, b, reserve, a, s, cl);
        if (!ob)
                iter.path->preserve = false;
 err:
@@ -417,7 +418,8 @@ bch2_bucket_alloc_early(struct btree_trans *trans,
 
        for_each_btree_key_norestart(trans, iter, BTREE_ID_alloc, POS(ca->dev_idx, s->cur_bucket),
                           BTREE_ITER_SLOTS, k, ret) {
-               struct bch_alloc_v4 a;
+               struct bch_alloc_v4 a_convert;
+               const struct bch_alloc_v4 *a;
 
                if (bkey_ge(k.k->p, POS(ca->dev_idx, ca->mi.nbuckets)))
                        break;
@@ -426,14 +428,14 @@ bch2_bucket_alloc_early(struct btree_trans *trans,
                    is_superblock_bucket(ca, k.k->p.offset))
                        continue;
 
-               bch2_alloc_to_v4(k, &a);
+               a = bch2_alloc_to_v4(k, &a_convert);
 
-               if (a.data_type != BCH_DATA_free)
+               if (a->data_type != BCH_DATA_free)
                        continue;
 
                s->buckets_seen++;
 
-               ob = __try_alloc_bucket(trans->c, ca, k.k->p.offset, reserve, &a, s, cl);
+               ob = __try_alloc_bucket(trans->c, ca, k.k->p.offset, reserve, a, s, cl);
                if (ob)
                        break;
        }
index 6ad4b818f9a5f7f69ea54dc7813c1abbdcb75191..ff5d01e6e6747226a96835ed7a05b50153786785 100644 (file)
@@ -323,15 +323,6 @@ bool bch2_bkey_pack_key(struct bkey_packed *out, const struct bkey *in,
 #define x(id, field)   if (!set_inc_field(&state, id, in->field)) return false;
        bkey_fields()
 #undef x
-
-       /*
-        * Extents - we have to guarantee that if an extent is packed, a trimmed
-        * version will also pack:
-        */
-       if (bkey_start_offset(in) <
-           le64_to_cpu(format->field_offset[BKEY_FIELD_OFFSET]))
-               return false;
-
        pack_state_finish(&state, out);
        out->u64s       = format->key_u64s + in->u64s - BKEY_U64s;
        out->format     = KEY_FORMAT_LOCAL_BTREE;
index 01687e48cdceceecad37a39b6747c44eaadfa25c..7698e7ec72479258d83d7c640ea359c4f34f91e6 100644 (file)
@@ -752,7 +752,6 @@ static inline void bch2_bkey_format_add_key(struct bkey_format_state *s, const s
 #define x(id, field) __bkey_format_add(s, id, k->field);
        bkey_fields()
 #undef x
-       __bkey_format_add(s, BKEY_FIELD_OFFSET, bkey_start_offset(k));
 }
 
 void bch2_bkey_format_add_pos(struct bkey_format_state *, struct bpos);
index 529db171b834883bfc6d0ed3644b872b94531880..055987a2a6a6a06804f06950084deb0901622674 100644 (file)
@@ -1340,15 +1340,16 @@ static int bch2_alloc_write_key(struct btree_trans *trans,
        struct bch_dev *ca = bch_dev_bkey_exists(c, iter->pos.inode);
        struct bucket gc, *b;
        struct bkey_i_alloc_v4 *a;
-       struct bch_alloc_v4 old, new;
+       struct bch_alloc_v4 old_convert, new;
+       const struct bch_alloc_v4 *old;
        enum bch_data_type type;
        int ret;
 
        if (bkey_ge(iter->pos, POS(ca->dev_idx, ca->mi.nbuckets)))
                return 1;
 
-       bch2_alloc_to_v4(k, &old);
-       new = old;
+       old = bch2_alloc_to_v4(k, &old_convert);
+       new = *old;
 
        percpu_down_read(&c->mark_lock);
        b = gc_bucket(ca, iter->pos.offset);
@@ -1360,7 +1361,7 @@ static int bch2_alloc_write_key(struct btree_trans *trans,
        type = __alloc_data_type(b->dirty_sectors,
                                 b->cached_sectors,
                                 b->stripe,
-                                old,
+                                *old,
                                 b->data_type);
        if (b->data_type != type) {
                struct bch_dev_usage *u;
@@ -1382,7 +1383,7 @@ static int bch2_alloc_write_key(struct btree_trans *trans,
            gc.data_type != BCH_DATA_btree)
                return 0;
 
-       if (gen_after(old.gen, gc.gen))
+       if (gen_after(old->gen, gc.gen))
                return 0;
 
 #define copy_bucket_field(_f)                                          \
@@ -1404,7 +1405,7 @@ static int bch2_alloc_write_key(struct btree_trans *trans,
        copy_bucket_field(stripe);
 #undef copy_bucket_field
 
-       if (!bch2_alloc_v4_cmp(old, new))
+       if (!bch2_alloc_v4_cmp(*old, new))
                return 0;
 
        a = bch2_alloc_to_v4_mut(trans, k);
@@ -1462,7 +1463,8 @@ static int bch2_gc_alloc_start(struct bch_fs *c, bool metadata_only)
        struct btree_iter iter;
        struct bkey_s_c k;
        struct bucket *g;
-       struct bch_alloc_v4 a;
+       struct bch_alloc_v4 a_convert;
+       const struct bch_alloc_v4 *a;
        unsigned i;
        int ret;
 
@@ -1488,20 +1490,20 @@ static int bch2_gc_alloc_start(struct bch_fs *c, bool metadata_only)
                ca = bch_dev_bkey_exists(c, k.k->p.inode);
                g = gc_bucket(ca, k.k->p.offset);
 
-               bch2_alloc_to_v4(k, &a);
+               a = bch2_alloc_to_v4(k, &a_convert);
 
                g->gen_valid    = 1;
-               g->gen          = a.gen;
+               g->gen          = a->gen;
 
                if (metadata_only &&
-                   (a.data_type == BCH_DATA_user ||
-                    a.data_type == BCH_DATA_cached ||
-                    a.data_type == BCH_DATA_parity)) {
-                       g->data_type            = a.data_type;
-                       g->dirty_sectors        = a.dirty_sectors;
-                       g->cached_sectors       = a.cached_sectors;
-                       g->stripe               = a.stripe;
-                       g->stripe_redundancy    = a.stripe_redundancy;
+                   (a->data_type == BCH_DATA_user ||
+                    a->data_type == BCH_DATA_cached ||
+                    a->data_type == BCH_DATA_parity)) {
+                       g->data_type            = a->data_type;
+                       g->dirty_sectors        = a->dirty_sectors;
+                       g->cached_sectors       = a->cached_sectors;
+                       g->stripe               = a->stripe;
+                       g->stripe_redundancy    = a->stripe_redundancy;
                }
        }
        bch2_trans_iter_exit(&trans, &iter);
@@ -1567,15 +1569,12 @@ static int bch2_gc_write_reflink_key(struct btree_trans *trans,
                        "  should be %u",
                        (bch2_bkey_val_to_text(&buf, c, k), buf.buf),
                        r->refcount)) {
-               struct bkey_i *new;
+               struct bkey_i *new = bch2_bkey_make_mut(trans, k);
 
-               new = bch2_trans_kmalloc(trans, bkey_bytes(k.k));
                ret = PTR_ERR_OR_ZERO(new);
                if (ret)
                        return ret;
 
-               bkey_reassemble(new, k);
-
                if (!r->refcount)
                        new->k.type = KEY_TYPE_deleted;
                else
@@ -1889,13 +1888,11 @@ static int gc_btree_gens_key(struct btree_trans *trans,
        percpu_up_read(&c->mark_lock);
        return 0;
 update:
-       u = bch2_trans_kmalloc(trans, bkey_bytes(k.k));
+       u = bch2_bkey_make_mut(trans, k);
        ret = PTR_ERR_OR_ZERO(u);
        if (ret)
                return ret;
 
-       bkey_reassemble(u, k);
-
        bch2_extent_normalize(c, bkey_i_to_s(u));
        return bch2_trans_update(trans, iter, u, 0);
 }
@@ -1904,13 +1901,12 @@ static int bch2_alloc_write_oldest_gen(struct btree_trans *trans, struct btree_i
                                       struct bkey_s_c k)
 {
        struct bch_dev *ca = bch_dev_bkey_exists(trans->c, iter->pos.inode);
-       struct bch_alloc_v4 a;
+       struct bch_alloc_v4 a_convert;
+       const struct bch_alloc_v4 *a = bch2_alloc_to_v4(k, &a_convert);
        struct bkey_i_alloc_v4 *a_mut;
        int ret;
 
-       bch2_alloc_to_v4(k, &a);
-
-       if (a.oldest_gen == ca->oldest_gen[iter->pos.offset])
+       if (a->oldest_gen == ca->oldest_gen[iter->pos.offset])
                return 0;
 
        a_mut = bch2_alloc_to_v4_mut(trans, k);
index d98cf6f63476c11cbc19445f1621fe77bfa2103d..e0cd6c5ef3080714227a2d507d2cd7c20194ee76 100644 (file)
@@ -1975,6 +1975,7 @@ struct bkey_s_c bch2_btree_iter_peek_upto(struct btree_iter *iter, struct bpos e
        int ret;
 
        EBUG_ON(iter->flags & BTREE_ITER_ALL_LEVELS);
+       EBUG_ON((iter->flags & BTREE_ITER_FILTER_SNAPSHOTS) && bkey_eq(end, POS_MAX));
 
        if (iter->update_path) {
                bch2_path_put_nokeep(trans, iter->update_path,
@@ -1986,7 +1987,9 @@ struct bkey_s_c bch2_btree_iter_peek_upto(struct btree_iter *iter, struct bpos e
 
        while (1) {
                k = __bch2_btree_iter_peek(iter, search_key);
-               if (!k.k || bkey_err(k))
+               if (unlikely(!k.k))
+                       goto end;
+               if (unlikely(bkey_err(k)))
                        goto out_no_locked;
 
                /*
@@ -1999,11 +2002,10 @@ struct bkey_s_c bch2_btree_iter_peek_upto(struct btree_iter *iter, struct bpos e
                else
                        iter_pos = bkey_max(iter->pos, bkey_start_pos(k.k));
 
-               if (bkey_gt(iter_pos, end)) {
-                       bch2_btree_iter_set_pos(iter, end);
-                       k = bkey_s_c_null;
-                       goto out_no_locked;
-               }
+               if (unlikely(!(iter->flags & BTREE_ITER_IS_EXTENTS)
+                            ? bkey_gt(iter_pos, end)
+                            : bkey_ge(iter_pos, end)))
+                       goto end;
 
                if (iter->update_path &&
                    !bkey_eq(iter->update_path->pos, k.k->p)) {
@@ -2087,6 +2089,10 @@ out_no_locked:
        bch2_btree_iter_verify_entry_exit(iter);
 
        return k;
+end:
+       bch2_btree_iter_set_pos(iter, end);
+       k = bkey_s_c_null;
+       goto out_no_locked;
 }
 
 /**
@@ -2399,15 +2405,15 @@ struct bkey_s_c bch2_btree_iter_peek_slot(struct btree_iter *iter)
                        goto out_no_locked;
        } else {
                struct bpos next;
+               struct bpos end = iter->pos;
+
+               if (iter->flags & BTREE_ITER_IS_EXTENTS)
+                       end.offset = U64_MAX;
 
                EBUG_ON(iter->path->level);
 
                if (iter->flags & BTREE_ITER_INTENT) {
                        struct btree_iter iter2;
-                       struct bpos end = iter->pos;
-
-                       if (iter->flags & BTREE_ITER_IS_EXTENTS)
-                               end.offset = U64_MAX;
 
                        bch2_trans_copy_iter(&iter2, iter);
                        k = bch2_btree_iter_peek_upto(&iter2, end);
@@ -2420,7 +2426,7 @@ struct bkey_s_c bch2_btree_iter_peek_slot(struct btree_iter *iter)
                } else {
                        struct bpos pos = iter->pos;
 
-                       k = bch2_btree_iter_peek(iter);
+                       k = bch2_btree_iter_peek_upto(iter, end);
                        if (unlikely(bkey_err(k)))
                                bch2_btree_iter_set_pos(iter, pos);
                        else
index ff29478e6163189baa473c86d4210cf252791377..c630ab56a8757c5c5f35bc6ecc3cd99923d4c8ad 100644 (file)
@@ -397,19 +397,76 @@ void *__bch2_trans_kmalloc(struct btree_trans *, size_t);
 
 static inline void *bch2_trans_kmalloc(struct btree_trans *trans, size_t size)
 {
-       unsigned new_top = trans->mem_top + size;
-       void *p = trans->mem + trans->mem_top;
+       size = roundup(size, 8);
+
+       if (likely(trans->mem_top + size <= trans->mem_bytes)) {
+               void *p = trans->mem + trans->mem_top;
 
-       if (likely(new_top <= trans->mem_bytes)) {
                trans->mem_top += size;
                memset(p, 0, size);
                return p;
        } else {
                return __bch2_trans_kmalloc(trans, size);
+       }
+}
+
+static inline void *bch2_trans_kmalloc_nomemzero(struct btree_trans *trans, size_t size)
+{
+       size = roundup(size, 8);
+
+       if (likely(trans->mem_top + size <= trans->mem_bytes)) {
+               void *p = trans->mem + trans->mem_top;
 
+               trans->mem_top += size;
+               return p;
+       } else {
+               return __bch2_trans_kmalloc(trans, size);
        }
 }
 
+static inline struct bkey_i *bch2_bkey_make_mut(struct btree_trans *trans, struct bkey_s_c k)
+{
+       struct bkey_i *mut = bch2_trans_kmalloc_nomemzero(trans, bkey_bytes(k.k));
+
+       if (!IS_ERR(mut))
+               bkey_reassemble(mut, k);
+       return mut;
+}
+
+static inline struct bkey_i *bch2_bkey_get_mut(struct btree_trans *trans,
+                                              struct btree_iter *iter)
+{
+       struct bkey_s_c k = bch2_btree_iter_peek_slot(iter);
+
+       return unlikely(IS_ERR(k.k))
+               ? ERR_CAST(k.k)
+               : bch2_bkey_make_mut(trans, k);
+}
+
+#define bch2_bkey_get_mut_typed(_trans, _iter, _type)                  \
+({                                                                     \
+       struct bkey_i *_k = bch2_bkey_get_mut(_trans, _iter);           \
+       struct bkey_i_##_type *_ret;                                    \
+                                                                       \
+       if (IS_ERR(_k))                                                 \
+               _ret = ERR_CAST(_k);                                    \
+       else if (unlikely(_k->k.type != KEY_TYPE_##_type))              \
+               _ret = ERR_PTR(-ENOENT);                                \
+       else                                                            \
+               _ret = bkey_i_to_##_type(_k);                           \
+       _ret;                                                           \
+})
+
+#define bch2_bkey_alloc(_trans, _iter, _type)                          \
+({                                                                     \
+       struct bkey_i_##_type *_k = bch2_trans_kmalloc(_trans, sizeof(*_k));\
+       if (!IS_ERR(_k)) {                                              \
+               bkey_##_type##_init(&_k->k_i);                          \
+               _k->k.p = (_iter)->pos;                                 \
+       }                                                               \
+       _k;                                                             \
+})
+
 u32 bch2_trans_begin(struct btree_trans *);
 
 static inline struct btree *
@@ -575,6 +632,36 @@ __bch2_btree_iter_peek_and_restart(struct btree_trans *trans,
        _ret;                                                           \
 })
 
+#define for_each_btree_key2_upto(_trans, _iter, _btree_id,             \
+                           _start, _end, _flags, _k, _do)              \
+({                                                                     \
+       int _ret = 0;                                                   \
+                                                                       \
+       bch2_trans_iter_init((_trans), &(_iter), (_btree_id),           \
+                            (_start), (_flags));                       \
+                                                                       \
+       while (1) {                                                     \
+               u32 _restart_count = bch2_trans_begin(_trans);          \
+                                                                       \
+               _ret = 0;                                               \
+               (_k) = bch2_btree_iter_peek_upto_type(&(_iter), _end, (_flags));\
+               if (!(_k).k)                                            \
+                       break;                                          \
+                                                                       \
+               _ret = bkey_err(_k) ?: (_do);                           \
+               if (bch2_err_matches(_ret, BCH_ERR_transaction_restart))\
+                       continue;                                       \
+               if (_ret)                                               \
+                       break;                                          \
+               bch2_trans_verify_not_restarted(_trans, _restart_count);\
+               if (!bch2_btree_iter_advance(&(_iter)))                 \
+                       break;                                          \
+       }                                                               \
+                                                                       \
+       bch2_trans_iter_exit((_trans), &(_iter));                       \
+       _ret;                                                           \
+})
+
 #define for_each_btree_key_reverse(_trans, _iter, _btree_id,           \
                                   _start, _flags, _k, _do)             \
 ({                                                                     \
@@ -613,6 +700,14 @@ __bch2_btree_iter_peek_and_restart(struct btree_trans *trans,
                            (_do) ?: bch2_trans_commit(_trans, (_disk_res),\
                                        (_journal_seq), (_commit_flags)))
 
+#define for_each_btree_key_upto_commit(_trans, _iter, _btree_id,       \
+                                 _start, _end, _iter_flags, _k,        \
+                                 _disk_res, _journal_seq, _commit_flags,\
+                                 _do)                                  \
+       for_each_btree_key2_upto(_trans, _iter, _btree_id, _start, _end, _iter_flags, _k,\
+                           (_do) ?: bch2_trans_commit(_trans, (_disk_res),\
+                                       (_journal_seq), (_commit_flags)))
+
 #define for_each_btree_key(_trans, _iter, _btree_id,                   \
                           _start, _flags, _k, _ret)                    \
        for (bch2_trans_iter_init((_trans), &(_iter), (_btree_id),      \
@@ -649,6 +744,12 @@ __bch2_btree_iter_peek_and_restart(struct btree_trans *trans,
             !((_ret) = bkey_err(_k)) && (_k).k;                        \
             bch2_btree_iter_advance(&(_iter)))
 
+#define for_each_btree_key_upto_continue_norestart(_iter, _end, _flags, _k, _ret)\
+       for (;                                                                  \
+            (_k) = bch2_btree_iter_peek_upto_type(&(_iter), _end, _flags),     \
+            !((_ret) = bkey_err(_k)) && (_k).k;                                \
+            bch2_btree_iter_advance(&(_iter)))
+
 /* new multiple iterator interface: */
 
 void bch2_trans_updates_to_text(struct printbuf *, struct btree_trans *);
index aa8b205a72a1564ccbc5ff7c72e841db5d810ac9..cd23d7df9f751ccfea6cd6a5be78511036ee6cd0 100644 (file)
@@ -1199,12 +1199,10 @@ int bch2_trans_update_extent(struct btree_trans *trans,
                if (ret)
                        goto nomerge1;
 
-               update = bch2_trans_kmalloc(trans, bkey_bytes(k.k));
+               update = bch2_bkey_make_mut(trans, k);
                if ((ret = PTR_ERR_OR_ZERO(update)))
                        goto err;
 
-               bkey_reassemble(update, k);
-
                if (bch2_bkey_merge(c, bkey_i_to_s(update), bkey_i_to_s_c(insert))) {
                        ret = bch2_btree_delete_at(trans, &iter, flags);
                        if (ret)
@@ -1234,12 +1232,10 @@ nomerge1:
                        trans->extra_journal_res += compressed_sectors;
 
                if (front_split) {
-                       update = bch2_trans_kmalloc(trans, bkey_bytes(k.k));
+                       update = bch2_bkey_make_mut(trans, k);
                        if ((ret = PTR_ERR_OR_ZERO(update)))
                                goto err;
 
-                       bkey_reassemble(update, k);
-
                        bch2_cut_back(start, update);
 
                        bch2_trans_iter_init(trans, &update_iter, btree_id, update->k.p,
@@ -1258,12 +1254,10 @@ nomerge1:
 
                if (k.k->p.snapshot != insert->k.p.snapshot &&
                    (front_split || back_split)) {
-                       update = bch2_trans_kmalloc(trans, bkey_bytes(k.k));
+                       update = bch2_bkey_make_mut(trans, k);
                        if ((ret = PTR_ERR_OR_ZERO(update)))
                                goto err;
 
-                       bkey_reassemble(update, k);
-
                        bch2_cut_front(start, update);
                        bch2_cut_back(insert->k.p, update);
 
@@ -1307,11 +1301,10 @@ nomerge1:
                }
 
                if (back_split) {
-                       update = bch2_trans_kmalloc(trans, bkey_bytes(k.k));
+                       update = bch2_bkey_make_mut(trans, k);
                        if ((ret = PTR_ERR_OR_ZERO(update)))
                                goto err;
 
-                       bkey_reassemble(update, k);
                        bch2_cut_front(insert->k.p, update);
 
                        ret = bch2_trans_update_by_path(trans, iter.path, update,
@@ -1652,7 +1645,7 @@ int bch2_btree_delete_range_trans(struct btree_trans *trans, enum btree_id id,
        int ret = 0;
 
        bch2_trans_iter_init(trans, &iter, id, start, BTREE_ITER_INTENT);
-       while ((k = bch2_btree_iter_peek(&iter)).k) {
+       while ((k = bch2_btree_iter_peek_upto(&iter, end)).k) {
                struct disk_reservation disk_res =
                        bch2_disk_reservation_init(trans->c, 0);
                struct bkey_i delete;
@@ -1661,9 +1654,6 @@ int bch2_btree_delete_range_trans(struct btree_trans *trans, enum btree_id id,
                if (ret)
                        goto err;
 
-               if (bkey_ge(iter.pos, end))
-                       break;
-
                bkey_init(&delete.k);
 
                /*
index bf01837e13623a302c2a3ef58d791d71b83f861a..428c2be670a1887a0c2c538e911769b088b0833f 100644 (file)
@@ -486,8 +486,10 @@ int bch2_mark_alloc(struct btree_trans *trans,
 {
        bool gc = flags & BTREE_TRIGGER_GC;
        u64 journal_seq = trans->journal_res.seq;
+       u64 bucket_journal_seq;
        struct bch_fs *c = trans->c;
-       struct bch_alloc_v4 old_a, new_a;
+       struct bch_alloc_v4 old_a_convert, new_a_convert;
+       const struct bch_alloc_v4 *old_a, *new_a;
        struct bch_dev *ca;
        int ret = 0;
 
@@ -504,36 +506,38 @@ int bch2_mark_alloc(struct btree_trans *trans,
 
        ca = bch_dev_bkey_exists(c, new.k->p.inode);
 
-       bch2_alloc_to_v4(old, &old_a);
-       bch2_alloc_to_v4(new, &new_a);
+       old_a = bch2_alloc_to_v4(old, &old_a_convert);
+       new_a = bch2_alloc_to_v4(new, &new_a_convert);
+
+       bucket_journal_seq = new_a->journal_seq;
 
        if ((flags & BTREE_TRIGGER_INSERT) &&
-           data_type_is_empty(old_a.data_type) !=
-           data_type_is_empty(new_a.data_type) &&
+           data_type_is_empty(old_a->data_type) !=
+           data_type_is_empty(new_a->data_type) &&
            new.k->type == KEY_TYPE_alloc_v4) {
                struct bch_alloc_v4 *v = (struct bch_alloc_v4 *) new.v;
 
-               BUG_ON(!journal_seq);
+               EBUG_ON(!journal_seq);
 
                /*
                 * If the btree updates referring to a bucket weren't flushed
                 * before the bucket became empty again, then the we don't have
                 * to wait on a journal flush before we can reuse the bucket:
                 */
-               new_a.journal_seq = data_type_is_empty(new_a.data_type) &&
+               v->journal_seq = bucket_journal_seq =
+                       data_type_is_empty(new_a->data_type) &&
                        (journal_seq == v->journal_seq ||
                         bch2_journal_noflush_seq(&c->journal, v->journal_seq))
                        ? 0 : journal_seq;
-               v->journal_seq = new_a.journal_seq;
        }
 
-       if (!data_type_is_empty(old_a.data_type) &&
-           data_type_is_empty(new_a.data_type) &&
-           new_a.journal_seq) {
+       if (!data_type_is_empty(old_a->data_type) &&
+           data_type_is_empty(new_a->data_type) &&
+           bucket_journal_seq) {
                ret = bch2_set_bucket_needs_journal_commit(&c->buckets_waiting_for_journal,
                                c->journal.flushed_seq_ondisk,
                                new.k->p.inode, new.k->p.offset,
-                               new_a.journal_seq);
+                               bucket_journal_seq);
                if (ret) {
                        bch2_fs_fatal_error(c,
                                "error setting bucket_needs_journal_commit: %i", ret);
@@ -542,10 +546,10 @@ int bch2_mark_alloc(struct btree_trans *trans,
        }
 
        percpu_down_read(&c->mark_lock);
-       if (!gc && new_a.gen != old_a.gen)
-               *bucket_gen(ca, new.k->p.offset) = new_a.gen;
+       if (!gc && new_a->gen != old_a->gen)
+               *bucket_gen(ca, new.k->p.offset) = new_a->gen;
 
-       bch2_dev_usage_update(c, ca, old_a, new_a, journal_seq, gc);
+       bch2_dev_usage_update(c, ca, *old_a, *new_a, journal_seq, gc);
 
        if (gc) {
                struct bucket *g = gc_bucket(ca, new.k->p.offset);
@@ -553,12 +557,12 @@ int bch2_mark_alloc(struct btree_trans *trans,
                bucket_lock(g);
 
                g->gen_valid            = 1;
-               g->gen                  = new_a.gen;
-               g->data_type            = new_a.data_type;
-               g->stripe               = new_a.stripe;
-               g->stripe_redundancy    = new_a.stripe_redundancy;
-               g->dirty_sectors        = new_a.dirty_sectors;
-               g->cached_sectors       = new_a.cached_sectors;
+               g->gen                  = new_a->gen;
+               g->data_type            = new_a->data_type;
+               g->stripe               = new_a->stripe;
+               g->stripe_redundancy    = new_a->stripe_redundancy;
+               g->dirty_sectors        = new_a->dirty_sectors;
+               g->cached_sectors       = new_a->cached_sectors;
 
                bucket_unlock(g);
        }
@@ -570,9 +574,9 @@ int bch2_mark_alloc(struct btree_trans *trans,
         */
 
        if ((flags & BTREE_TRIGGER_BUCKET_INVALIDATE) &&
-           old_a.cached_sectors) {
+           old_a->cached_sectors) {
                ret = update_cached_sectors(c, new, ca->dev_idx,
-                                           -((s64) old_a.cached_sectors),
+                                           -((s64) old_a->cached_sectors),
                                            journal_seq, gc);
                if (ret) {
                        bch2_fs_fatal_error(c, "%s(): no replicas entry while updating cached sectors",
@@ -581,20 +585,20 @@ int bch2_mark_alloc(struct btree_trans *trans,
                }
        }
 
-       if (new_a.data_type == BCH_DATA_free &&
-           (!new_a.journal_seq || new_a.journal_seq < c->journal.flushed_seq_ondisk))
+       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);
 
-       if (new_a.data_type == BCH_DATA_need_discard &&
-           (!new_a.journal_seq || new_a.journal_seq < c->journal.flushed_seq_ondisk))
+       if (new_a->data_type == BCH_DATA_need_discard &&
+           (!bucket_journal_seq || bucket_journal_seq < c->journal.flushed_seq_ondisk))
                bch2_do_discards(c);
 
-       if (old_a.data_type != BCH_DATA_cached &&
-           new_a.data_type == BCH_DATA_cached &&
+       if (old_a->data_type != BCH_DATA_cached &&
+           new_a->data_type == BCH_DATA_cached &&
            should_invalidate_buckets(ca, bch2_dev_usage_read(ca)))
                bch2_do_invalidates(c);
 
-       if (new_a.data_type == BCH_DATA_need_gc_gens)
+       if (new_a->data_type == BCH_DATA_need_gc_gens)
                bch2_do_gc_gens(c);
 
        return 0;
@@ -1409,7 +1413,6 @@ static int bch2_trans_mark_stripe_ptr(struct btree_trans *trans,
                        s64 sectors, enum bch_data_type data_type)
 {
        struct btree_iter iter;
-       struct bkey_s_c k;
        struct bkey_i_stripe *s;
        struct bch_replicas_padded r;
        int ret = 0;
@@ -1417,20 +1420,16 @@ static int bch2_trans_mark_stripe_ptr(struct btree_trans *trans,
        bch2_trans_iter_init(trans, &iter, BTREE_ID_stripes, POS(0, p.ec.idx),
                             BTREE_ITER_INTENT|
                             BTREE_ITER_WITH_UPDATES);
-       k = bch2_btree_iter_peek_slot(&iter);
-       ret = bkey_err(k);
-       if (ret)
-               goto err;
-
-       if (k.k->type != KEY_TYPE_stripe) {
-               bch2_trans_inconsistent(trans,
+       s = bch2_bkey_get_mut_typed(trans, &iter, stripe);
+       ret = PTR_ERR_OR_ZERO(s);
+       if (unlikely(ret)) {
+               bch2_trans_inconsistent_on(ret == -ENOENT, trans,
                        "pointer to nonexistent stripe %llu",
                        (u64) p.ec.idx);
-               ret = -EIO;
                goto err;
        }
 
-       if (!bch2_ptr_matches_stripe(bkey_s_c_to_stripe(k).v, p)) {
+       if (!bch2_ptr_matches_stripe(&s->v, p)) {
                bch2_trans_inconsistent(trans,
                        "stripe pointer doesn't match stripe %llu",
                        (u64) p.ec.idx);
@@ -1438,12 +1437,6 @@ static int bch2_trans_mark_stripe_ptr(struct btree_trans *trans,
                goto err;
        }
 
-       s = bch2_trans_kmalloc(trans, bkey_bytes(k.k));
-       ret = PTR_ERR_OR_ZERO(s);
-       if (ret)
-               goto err;
-
-       bkey_reassemble(&s->k_i, k);
        stripe_blockcount_set(&s->v, p.ec.block,
                stripe_blockcount_get(&s->v, p.ec.block) +
                sectors);
@@ -1718,8 +1711,7 @@ static int __bch2_trans_mark_reflink_p(struct btree_trans *trans,
 {
        struct bch_fs *c = trans->c;
        struct btree_iter iter;
-       struct bkey_s_c k;
-       struct bkey_i *n;
+       struct bkey_i *k;
        __le64 *refcount;
        int add = !(flags & BTREE_TRIGGER_OVERWRITE) ? 1 : -1;
        struct printbuf buf = PRINTBUF;
@@ -1728,19 +1720,12 @@ static int __bch2_trans_mark_reflink_p(struct btree_trans *trans,
        bch2_trans_iter_init(trans, &iter, BTREE_ID_reflink, POS(0, *idx),
                             BTREE_ITER_INTENT|
                             BTREE_ITER_WITH_UPDATES);
-       k = bch2_btree_iter_peek_slot(&iter);
-       ret = bkey_err(k);
+       k = bch2_bkey_get_mut(trans, &iter);
+       ret = PTR_ERR_OR_ZERO(k);
        if (ret)
                goto err;
 
-       n = bch2_trans_kmalloc(trans, bkey_bytes(k.k));
-       ret = PTR_ERR_OR_ZERO(n);
-       if (ret)
-               goto err;
-
-       bkey_reassemble(n, k);
-
-       refcount = bkey_refcount(n);
+       refcount = bkey_refcount(k);
        if (!refcount) {
                bch2_bkey_val_to_text(&buf, c, p.s_c);
                bch2_trans_inconsistent(trans,
@@ -1764,12 +1749,12 @@ static int __bch2_trans_mark_reflink_p(struct btree_trans *trans,
                u64 pad;
 
                pad = max_t(s64, le32_to_cpu(v->front_pad),
-                           le64_to_cpu(v->idx) - bkey_start_offset(k.k));
+                           le64_to_cpu(v->idx) - bkey_start_offset(&k->k));
                BUG_ON(pad > U32_MAX);
                v->front_pad = cpu_to_le32(pad);
 
                pad = max_t(s64, le32_to_cpu(v->back_pad),
-                           k.k->p.offset - p.k->size - le64_to_cpu(v->idx));
+                           k->k.p.offset - p.k->size - le64_to_cpu(v->idx));
                BUG_ON(pad > U32_MAX);
                v->back_pad = cpu_to_le32(pad);
        }
@@ -1777,11 +1762,11 @@ static int __bch2_trans_mark_reflink_p(struct btree_trans *trans,
        le64_add_cpu(refcount, add);
 
        bch2_btree_iter_set_pos_to_extent_start(&iter);
-       ret = bch2_trans_update(trans, &iter, n, 0);
+       ret = bch2_trans_update(trans, &iter, k, 0);
        if (ret)
                goto err;
 
-       *idx = k.k->p.offset;
+       *idx = k->k.p.offset;
 err:
        bch2_trans_iter_exit(trans, &iter);
        printbuf_exit(&buf);
index cab088bb5413d82ac382d5ee26eaab2a6e3db678..53f0d8209a271e993792ceba7dd3bca27a5db49c 100644 (file)
@@ -684,7 +684,7 @@ static int ec_stripe_delete(struct bch_fs *c, size_t idx)
 {
        return bch2_btree_delete_range(c, BTREE_ID_stripes,
                                       POS(0, idx),
-                                      POS(0, idx + 1),
+                                      POS(0, idx),
                                       0, NULL);
 }
 
@@ -841,13 +841,11 @@ static int ec_stripe_update_extent(struct btree_trans *trans,
 
        dev = s->key.v.ptrs[block].dev;
 
-       n = bch2_trans_kmalloc(trans, bkey_bytes(k.k));
+       n = bch2_bkey_make_mut(trans, k);
        ret = PTR_ERR_OR_ZERO(n);
        if (ret)
                return ret;
 
-       bkey_reassemble(n, k);
-
        bch2_bkey_drop_ptrs(bkey_i_to_s(n), ptr, ptr->dev != dev);
        ec_ptr = (void *) bch2_bkey_has_device(bkey_i_to_s_c(n), dev);
        BUG_ON(!ec_ptr);
index 21d6f88c7397cd96d27e3a978c83c46266d11922..21af6fb8cecff150908724c238f434bc54a9dd6d 100644 (file)
@@ -128,12 +128,9 @@ int bch2_extent_atomic_end(struct btree_trans *trans,
 
        bch2_trans_copy_iter(&copy, iter);
 
-       for_each_btree_key_continue_norestart(copy, 0, k, ret) {
+       for_each_btree_key_upto_continue_norestart(copy, insert->k.p, 0, k, ret) {
                unsigned offset = 0;
 
-               if (bkey_ge(bkey_start_pos(k.k), *end))
-                       break;
-
                if (bkey_gt(bkey_start_pos(&insert->k), bkey_start_pos(k.k)))
                        offset = bkey_start_offset(&insert->k) -
                                bkey_start_offset(k.k);
index 1ce0c93126c17162c8b7f95dd29631c14caf5493..e7ebb01b4d09edc09dedd625c9a6e53166923024 100644 (file)
@@ -2607,15 +2607,11 @@ retry:
        if (ret)
                goto err;
 
-       for_each_btree_key_norestart(&trans, iter, BTREE_ID_extents, start, 0, k, ret) {
-               if (bkey_ge(bkey_start_pos(k.k), end))
-                       break;
-
+       for_each_btree_key_upto_norestart(&trans, iter, BTREE_ID_extents, start, end, 0, k, ret)
                if (bkey_extent_is_data(k.k)) {
                        ret = 1;
                        break;
                }
-       }
        start = iter.pos;
        bch2_trans_iter_exit(&trans, &iter);
 err:
@@ -2655,8 +2651,8 @@ static int __bch2_truncate_page(struct bch_inode_info *inode,
                 * page
                 */
                ret = range_has_data(c, inode->ei_subvol,
-                               POS(inode->v.i_ino, index << PAGE_SECTORS_SHIFT),
-                               POS(inode->v.i_ino, (index + 1) << PAGE_SECTORS_SHIFT));
+                               POS(inode->v.i_ino, (index << PAGE_SECTORS_SHIFT)),
+                               POS(inode->v.i_ino, (index << PAGE_SECTORS_SHIFT) + PAGE_SECTORS));
                if (ret <= 0)
                        return ret;
 
@@ -3038,7 +3034,7 @@ static long bchfs_fcollapse_finsert(struct bch_inode_info *inode,
 
                k = insert
                        ? bch2_btree_iter_peek_prev(&src)
-                       : bch2_btree_iter_peek(&src);
+                       : bch2_btree_iter_peek_upto(&src, POS(inode->v.i_ino, U64_MAX));
                if ((ret = bkey_err(k)))
                        continue;
 
@@ -3313,6 +3309,10 @@ err:
        return bch2_err_class(ret);
 }
 
+/*
+ * Take a quota reservation for unallocated blocks in a given file range
+ * Does not check pagecache
+ */
 static int quota_reserve_range(struct bch_inode_info *inode,
                               struct quota_res *res,
                               u64 start, u64 end)
@@ -3528,11 +3528,11 @@ retry:
        if (ret)
                goto err;
 
-       for_each_btree_key_norestart(&trans, iter, BTREE_ID_extents,
-                          SPOS(inode->v.i_ino, offset >> 9, snapshot), 0, k, ret) {
-               if (k.k->p.inode != inode->v.i_ino) {
-                       break;
-               } else if (bkey_extent_is_data(k.k)) {
+       for_each_btree_key_upto_norestart(&trans, iter, BTREE_ID_extents,
+                          SPOS(inode->v.i_ino, offset >> 9, snapshot),
+                          POS(inode->v.i_ino, U64_MAX),
+                          0, k, ret) {
+               if (bkey_extent_is_data(k.k)) {
                        next_data = max(offset, bkey_start_offset(k.k) << 9);
                        break;
                } else if (k.k->p.offset >> 9 > isize)
index d8e6cbd8f7f2746cb74b1cd4fb58a51f437dfd62..cd0a8d0483990de40cde7e8a1ad127ff856d2231 100644 (file)
@@ -779,12 +779,10 @@ static int hash_redo_key(struct btree_trans *trans,
        if (IS_ERR(delete))
                return PTR_ERR(delete);
 
-       tmp = bch2_trans_kmalloc(trans, bkey_bytes(k.k));
+       tmp = bch2_bkey_make_mut(trans, k);
        if (IS_ERR(tmp))
                return PTR_ERR(tmp);
 
-       bkey_reassemble(tmp, k);
-
        bkey_init(&delete->k);
        delete->k.p = k_iter->pos;
        return  bch2_btree_iter_traverse(k_iter) ?:
index a63ff3df34c4aa843fa882ff2644bbe4b1e456c4..938c7b43d0b468dab3c1fc1a8eb7804d6f1d1599 100644 (file)
@@ -364,22 +364,25 @@ int bch2_inode_write(struct btree_trans *trans,
        return bch2_trans_update(trans, iter, &inode_p->inode.k_i, 0);
 }
 
-struct bkey_s_c bch2_inode_to_v3(struct btree_trans *trans, struct bkey_s_c k)
+struct bkey_i *bch2_inode_to_v3(struct btree_trans *trans, struct bkey_i *k)
 {
        struct bch_inode_unpacked u;
        struct bkey_inode_buf *inode_p;
        int ret;
 
+       if (!bkey_is_inode(&k->k))
+               return ERR_PTR(-ENOENT);
+
        inode_p = bch2_trans_kmalloc(trans, sizeof(*inode_p));
        if (IS_ERR(inode_p))
-               return bkey_s_c_err(PTR_ERR(inode_p));
+               return ERR_CAST(inode_p);
 
-       ret = bch2_inode_unpack(k, &u);
+       ret = bch2_inode_unpack(bkey_i_to_s_c(k), &u);
        if (ret)
-               return bkey_s_c_err(ret);
+               return ERR_PTR(ret);
 
        bch2_inode_pack(inode_p, &u);
-       return bkey_i_to_s_c(&inode_p->inode.k_i);
+       return &inode_p->inode.k_i;
 }
 
 static int __bch2_inode_invalid(struct bkey_s_c k, struct printbuf *err)
index 88dfae42ff7be5e60a7b6966d1a072522cd98304..b753e1b254e4679c932f0f96a0e5f1c039e92b72 100644 (file)
@@ -82,7 +82,7 @@ struct bkey_inode_buf {
 
 void bch2_inode_pack(struct bkey_inode_buf *, const struct bch_inode_unpacked *);
 int bch2_inode_unpack(struct bkey_s_c, struct bch_inode_unpacked *);
-struct bkey_s_c bch2_inode_to_v3(struct btree_trans *, struct bkey_s_c);
+struct bkey_i *bch2_inode_to_v3(struct btree_trans *, struct bkey_i *);
 
 void bch2_inode_unpacked_to_text(struct printbuf *, struct bch_inode_unpacked *);
 
index 3ba3fd6097dcc6470d7b036dc6d1876055063882..f0fca861b90122f7882af40ac9ba86d4b1e9a170 100644 (file)
@@ -239,9 +239,8 @@ static inline int bch2_extent_update_i_size_sectors(struct btree_trans *trans,
                                                    s64 i_sectors_delta)
 {
        struct btree_iter iter;
-       struct bkey_s_c inode_k;
-       struct bkey_s_c_inode_v3 inode;
-       struct bkey_i_inode_v3 *new_inode;
+       struct bkey_i *k;
+       struct bkey_i_inode_v3 *inode;
        int ret;
 
        bch2_trans_iter_init(trans, &iter, BTREE_ID_inodes,
@@ -249,40 +248,29 @@ static inline int bch2_extent_update_i_size_sectors(struct btree_trans *trans,
                                  extent_iter->pos.inode,
                                  extent_iter->snapshot),
                             BTREE_ITER_INTENT|BTREE_ITER_CACHED);
-       inode_k = bch2_btree_iter_peek_slot(&iter);
-       ret = bkey_err(inode_k);
-       if (unlikely(ret))
-               goto err;
-
-       ret = bkey_is_inode(inode_k.k) ? 0 : -ENOENT;
+       k = bch2_bkey_get_mut(trans, &iter);
+       ret = PTR_ERR_OR_ZERO(k);
        if (unlikely(ret))
                goto err;
 
-       if (unlikely(inode_k.k->type != KEY_TYPE_inode_v3)) {
-               inode_k = bch2_inode_to_v3(trans, inode_k);
-               ret = bkey_err(inode_k);
+       if (unlikely(k->k.type != KEY_TYPE_inode_v3)) {
+               k = bch2_inode_to_v3(trans, k);
+               ret = PTR_ERR_OR_ZERO(k);
                if (unlikely(ret))
                        goto err;
        }
 
-       inode = bkey_s_c_to_inode_v3(inode_k);
-
-       new_inode = bch2_trans_kmalloc(trans, bkey_bytes(inode_k.k));
-       ret = PTR_ERR_OR_ZERO(new_inode);
-       if (unlikely(ret))
-               goto err;
-
-       bkey_reassemble(&new_inode->k_i, inode.s_c);
+       inode = bkey_i_to_inode_v3(k);
 
-       if (!(le64_to_cpu(inode.v->bi_flags) & BCH_INODE_I_SIZE_DIRTY) &&
-           new_i_size > le64_to_cpu(inode.v->bi_size))
-               new_inode->v.bi_size = cpu_to_le64(new_i_size);
+       if (!(le64_to_cpu(inode->v.bi_flags) & BCH_INODE_I_SIZE_DIRTY) &&
+           new_i_size > le64_to_cpu(inode->v.bi_size))
+               inode->v.bi_size = cpu_to_le64(new_i_size);
 
-       le64_add_cpu(&new_inode->v.bi_sectors, i_sectors_delta);
+       le64_add_cpu(&inode->v.bi_sectors, i_sectors_delta);
 
-       new_inode->k.p.snapshot = iter.snapshot;
+       inode->k.p.snapshot = iter.snapshot;
 
-       ret = bch2_trans_update(trans, &iter, &new_inode->k_i,
+       ret = bch2_trans_update(trans, &iter, &inode->k_i,
                                BTREE_UPDATE_INTERNAL_SNAPSHOT_NODE);
 err:
        bch2_trans_iter_exit(trans, &iter);
@@ -513,16 +501,19 @@ int bch2_fpunch_at(struct btree_trans *trans, struct btree_iter *iter,
 
                bch2_btree_iter_set_snapshot(iter, snapshot);
 
-               k = bch2_btree_iter_peek(iter);
-               if (bkey_ge(iter->pos, end_pos)) {
-                       bch2_btree_iter_set_pos(iter, end_pos);
+               /*
+                * peek_upto() doesn't have ideal semantics for extents:
+                */
+               k = bch2_btree_iter_peek_upto(iter, end_pos);
+               if (!k.k)
                        break;
-               }
 
                ret = bkey_err(k);
                if (ret)
                        continue;
 
+               BUG_ON(bkey_ge(iter->pos, end_pos));
+
                bkey_init(&delete.k);
                delete.k.p = iter->pos;
 
@@ -535,6 +526,8 @@ int bch2_fpunch_at(struct btree_trans *trans, struct btree_iter *iter,
                bch2_disk_reservation_put(c, &disk_res);
        }
 
+       BUG_ON(bkey_gt(iter->pos, end_pos));
+
        return ret ?: ret2;
 }
 
@@ -1323,13 +1316,11 @@ static int bch2_nocow_write_convert_one_unwritten(struct btree_trans *trans,
                return 0;
        }
 
-       new = bch2_trans_kmalloc(trans, bkey_bytes(k.k));
+       new = bch2_bkey_make_mut(trans, k);
        ret = PTR_ERR_OR_ZERO(new);
        if (ret)
                return ret;
 
-       bkey_reassemble(new, k);
-
        bch2_cut_front(bkey_start_pos(&orig->k), new);
        bch2_cut_back(orig->k.p, new);
 
@@ -1362,12 +1353,11 @@ static void bch2_nocow_write_convert_unwritten(struct bch_write_op *op)
        bch2_trans_init(&trans, c, 0, 0);
 
        for_each_keylist_key(&op->insert_keys, orig) {
-               ret = for_each_btree_key_commit(&trans, iter, BTREE_ID_extents,
-                                    bkey_start_pos(&orig->k),
+               ret = for_each_btree_key_upto_commit(&trans, iter, BTREE_ID_extents,
+                                    bkey_start_pos(&orig->k), orig->k.p,
                                     BTREE_ITER_INTENT, k,
                                     NULL, NULL, BTREE_INSERT_NOFAIL, ({
-                       if (bkey_ge(bkey_start_pos(k.k), orig->k.p))
-                               break;
+                       BUG_ON(bkey_ge(bkey_start_pos(k.k), orig->k.p));
 
                        bch2_nocow_write_convert_one_unwritten(&trans, &iter, orig, k, op->new_i_size);
                }));
index db1674ef1d22687a56cbdabccc02b89eb6d0ca8c..e16686b3b45aa00d018c068de1bb30a84b92ec43 100644 (file)
@@ -101,14 +101,12 @@ int bch2_lru_set(struct btree_trans *trans, u64 lru_id, u64 idx, u64 *time)
        BUG_ON(iter.pos.inode != lru_id);
        *time = iter.pos.offset;
 
-       lru = bch2_trans_kmalloc(trans, sizeof(*lru));
+       lru = bch2_bkey_alloc(trans, &iter, lru);
        ret = PTR_ERR_OR_ZERO(lru);
        if (ret)
                goto err;
 
-       bkey_lru_init(&lru->k_i);
-       lru->k.p        = iter.pos;
-       lru->v.idx      = cpu_to_le64(idx);
+       lru->v.idx = cpu_to_le64(idx);
 
        ret = bch2_trans_update(trans, &iter, &lru->k_i, 0);
        if (ret)
@@ -164,17 +162,7 @@ static int bch2_check_lru_key(struct btree_trans *trans,
                        "  for %s",
                        (bch2_bkey_val_to_text(&buf1, c, lru_k), buf1.buf),
                        (bch2_bkey_val_to_text(&buf2, c, k), buf2.buf))) {
-               struct bkey_i *update =
-                       bch2_trans_kmalloc(trans, sizeof(*update));
-
-               ret = PTR_ERR_OR_ZERO(update);
-               if (ret)
-                       goto err;
-
-               bkey_init(&update->k);
-               update->k.p = lru_iter->pos;
-
-               ret = bch2_trans_update(trans, lru_iter, update, 0);
+               ret = bch2_btree_delete_at(trans, lru_iter, 0);
                if (ret)
                        goto err;
        }
index 8b258d966d042f73e9448a3086373d8d8a1d6b5f..e3e39127b40a0aa4708735bcc3f2d2d91bf367f3 100644 (file)
@@ -49,13 +49,11 @@ static int bch2_dev_usrdata_drop_key(struct btree_trans *trans,
        if (!bch2_bkey_has_device(k, dev_idx))
                return 0;
 
-       n = bch2_trans_kmalloc(trans, bkey_bytes(k.k));
+       n = bch2_bkey_make_mut(trans, k);
        ret = PTR_ERR_OR_ZERO(n);
        if (ret)
                return ret;
 
-       bkey_reassemble(n, k);
-
        ret = drop_dev_ptrs(c, bkey_i_to_s(n), dev_idx, flags, false);
        if (ret)
                return ret;
index 11e25a31ed7f329d500df0a01d8502289d4a2c09..47b77b3c3e686309e87336b2604b8dafeb290858 100644 (file)
@@ -198,13 +198,11 @@ static int bch2_extent_drop_ptrs(struct btree_trans *trans,
        struct bkey_i *n;
        int ret;
 
-       n = bch2_trans_kmalloc(trans, bkey_bytes(k.k));
+       n = bch2_bkey_make_mut(trans, k);
        ret = PTR_ERR_OR_ZERO(n);
        if (ret)
                return ret;
 
-       bkey_reassemble(n, k);
-
        while (data_opts.kill_ptrs) {
                unsigned i = 0, drop = __fls(data_opts.kill_ptrs);
                struct bch_extent_ptr *ptr;
index 63bc692f550ec9b73e26fbbb908d5d6bedf1afd3..fbc8043e0bf97b261e7ca93442e1fd6a8581e671 100644 (file)
@@ -44,7 +44,6 @@ static int find_buckets_to_copygc(struct bch_fs *c)
        struct btree_trans trans;
        struct btree_iter iter;
        struct bkey_s_c k;
-       struct bch_alloc_v4 a;
        int ret;
 
        bch2_trans_init(&trans, c, 0, 0);
@@ -61,22 +60,24 @@ static int find_buckets_to_copygc(struct bch_fs *c)
                           BTREE_ITER_PREFETCH, k, ret) {
                struct bch_dev *ca = bch_dev_bkey_exists(c, iter.pos.inode);
                struct copygc_heap_entry e;
+               struct bch_alloc_v4 a_convert;
+               const struct bch_alloc_v4 *a;
 
-               bch2_alloc_to_v4(k, &a);
+               a = bch2_alloc_to_v4(k, &a_convert);
 
-               if ((a.data_type != BCH_DATA_btree &&
-                    a.data_type != BCH_DATA_user) ||
-                   a.dirty_sectors >= ca->mi.bucket_size ||
+               if ((a->data_type != BCH_DATA_btree &&
+                    a->data_type != BCH_DATA_user) ||
+                   a->dirty_sectors >= ca->mi.bucket_size ||
                    bch2_bucket_is_open(c, iter.pos.inode, iter.pos.offset))
                        continue;
 
                e = (struct copygc_heap_entry) {
                        .dev            = iter.pos.inode,
-                       .gen            = a.gen,
-                       .replicas       = 1 + a.stripe_redundancy,
-                       .fragmentation  = div_u64((u64) a.dirty_sectors * (1ULL << 31),
+                       .gen            = a->gen,
+                       .replicas       = 1 + a->stripe_redundancy,
+                       .fragmentation  = div_u64((u64) a->dirty_sectors * (1ULL << 31),
                                                  ca->mi.bucket_size),
-                       .sectors        = a.dirty_sectors,
+                       .sectors        = a->dirty_sectors,
                        .bucket         = iter.pos.offset,
                };
                heap_add_or_replace(h, e, -fragmentation_cmp, NULL);
index c49fff6e39f2ab32213efc0c95b2ff84afd73cd4..555e63730a968ebfb6431671d1861fb01f26ffe7 100644 (file)
@@ -271,8 +271,9 @@ int bch2_opt_parse(struct bch_fs *c,
        case BCH_OPT_BOOL:
                ret = kstrtou64(val, 10, res);
                if (ret < 0 || (*res != 0 && *res != 1)) {
-                       prt_printf(err, "%s: must be bool",
-                              opt->attr.name);
+                       if (err)
+                               prt_printf(err, "%s: must be bool",
+                                          opt->attr.name);
                        return ret;
                }
                break;
index ededc826e9a05a5cd4676b4d480cfe19cc443fe2..4b663f320bfc904fbab9578b7ff208f3f871d473 100644 (file)
@@ -709,7 +709,7 @@ static int bch2_quota_remove(struct super_block *sb, unsigned uflags)
 
                ret = bch2_btree_delete_range(c, BTREE_ID_quotas,
                                              POS(QTYP_USR, 0),
-                                             POS(QTYP_USR + 1, 0),
+                                             POS(QTYP_USR, U64_MAX),
                                              0, NULL);
                if (ret)
                        return ret;
@@ -721,7 +721,7 @@ static int bch2_quota_remove(struct super_block *sb, unsigned uflags)
 
                ret = bch2_btree_delete_range(c, BTREE_ID_quotas,
                                              POS(QTYP_GRP, 0),
-                                             POS(QTYP_GRP + 1, 0),
+                                             POS(QTYP_GRP, U64_MAX),
                                              0, NULL);
                if (ret)
                        return ret;
@@ -733,7 +733,7 @@ static int bch2_quota_remove(struct super_block *sb, unsigned uflags)
 
                ret = bch2_btree_delete_range(c, BTREE_ID_quotas,
                                              POS(QTYP_PRJ, 0),
-                                             POS(QTYP_PRJ + 1, 0),
+                                             POS(QTYP_PRJ, U64_MAX),
                                              0, NULL);
                if (ret)
                        return ret;
index eed4ad38b21d348ca7aca6677aae36014f84eaad..ec672fedbd168911b19594df5815afd668019344 100644 (file)
@@ -251,10 +251,7 @@ static struct bkey_s_c get_next_src(struct btree_iter *iter, struct bpos end)
        struct bkey_s_c k;
        int ret;
 
-       for_each_btree_key_continue_norestart(*iter, 0, k, ret) {
-               if (bkey_ge(iter->pos, end))
-                       break;
-
+       for_each_btree_key_upto_continue_norestart(*iter, end, 0, k, ret) {
                if (bkey_extent_is_unwritten(k))
                        continue;
 
index f19f6f8d32337eefc7214ada938bb090c2899316..d090a74bd05286c467af5f063cacdac8e77d7598 100644 (file)
@@ -377,33 +377,22 @@ int bch2_fs_snapshots_start(struct bch_fs *c)
 static int bch2_snapshot_node_set_deleted(struct btree_trans *trans, u32 id)
 {
        struct btree_iter iter;
-       struct bkey_s_c k;
        struct bkey_i_snapshot *s;
        int ret = 0;
 
        bch2_trans_iter_init(trans, &iter, BTREE_ID_snapshots, POS(0, id),
                             BTREE_ITER_INTENT);
-       k = bch2_btree_iter_peek_slot(&iter);
-       ret = bkey_err(k);
-       if (ret)
-               goto err;
-
-       if (k.k->type != KEY_TYPE_snapshot) {
-               bch2_fs_inconsistent(trans->c, "missing snapshot %u", id);
-               ret = -ENOENT;
+       s = bch2_bkey_get_mut_typed(trans, &iter, snapshot);
+       ret = PTR_ERR_OR_ZERO(s);
+       if (unlikely(ret)) {
+               bch2_fs_inconsistent_on(ret == -ENOENT, trans->c, "missing snapshot %u", id);
                goto err;
        }
 
        /* already deleted? */
-       if (BCH_SNAPSHOT_DELETED(bkey_s_c_to_snapshot(k).v))
+       if (BCH_SNAPSHOT_DELETED(&s->v))
                goto err;
 
-       s = bch2_trans_kmalloc(trans, sizeof(*s));
-       ret = PTR_ERR_OR_ZERO(s);
-       if (ret)
-               goto err;
-
-       bkey_reassemble(&s->k_i, k);
        SET_BCH_SNAPSHOT_DELETED(&s->v, true);
        SET_BCH_SNAPSHOT_SUBVOL(&s->v, false);
        s->v.subvol = 0;
@@ -421,7 +410,6 @@ static int bch2_snapshot_node_delete(struct btree_trans *trans, u32 id)
        struct btree_iter iter, p_iter = (struct btree_iter) { NULL };
        struct bkey_s_c k;
        struct bkey_s_c_snapshot s;
-       struct bkey_i_snapshot *parent;
        u32 parent_id;
        unsigned i;
        int ret = 0;
@@ -445,26 +433,17 @@ static int bch2_snapshot_node_delete(struct btree_trans *trans, u32 id)
        parent_id = le32_to_cpu(s.v->parent);
 
        if (parent_id) {
+               struct bkey_i_snapshot *parent;
+
                bch2_trans_iter_init(trans, &p_iter, BTREE_ID_snapshots,
                                     POS(0, parent_id),
                                     BTREE_ITER_INTENT);
-               k = bch2_btree_iter_peek_slot(&p_iter);
-               ret = bkey_err(k);
-               if (ret)
-                       goto err;
-
-               if (k.k->type != KEY_TYPE_snapshot) {
-                       bch2_fs_inconsistent(trans->c, "missing snapshot %u", parent_id);
-                       ret = -ENOENT;
-                       goto err;
-               }
-
-               parent = bch2_trans_kmalloc(trans, sizeof(*parent));
+               parent = bch2_bkey_get_mut_typed(trans, &p_iter, snapshot);
                ret = PTR_ERR_OR_ZERO(parent);
-               if (ret)
+               if (unlikely(ret)) {
+                       bch2_fs_inconsistent_on(ret == -ENOENT, trans->c, "missing snapshot %u", parent_id);
                        goto err;
-
-               bkey_reassemble(&parent->k_i, k);
+               }
 
                for (i = 0; i < 2; i++)
                        if (le32_to_cpu(parent->v.children[i]) == id)
@@ -522,13 +501,11 @@ int bch2_snapshot_node_create(struct btree_trans *trans, u32 parent,
                        goto err;
                }
 
-               n = bch2_trans_kmalloc(trans, sizeof(*n));
+               n = bch2_bkey_alloc(trans, &iter, snapshot);
                ret = PTR_ERR_OR_ZERO(n);
                if (ret)
                        goto err;
 
-               bkey_snapshot_init(&n->k_i);
-               n->k.p          = iter.pos;
                n->v.flags      = 0;
                n->v.parent     = cpu_to_le32(parent);
                n->v.subvol     = cpu_to_le32(snapshot_subvols[i]);
@@ -545,23 +522,13 @@ int bch2_snapshot_node_create(struct btree_trans *trans, u32 parent,
 
        if (parent) {
                bch2_btree_iter_set_pos(&iter, POS(0, parent));
-               k = bch2_btree_iter_peek(&iter);
-               ret = bkey_err(k);
-               if (ret)
-                       goto err;
-
-               if (k.k->type != KEY_TYPE_snapshot) {
-                       bch_err(trans->c, "snapshot %u not found", parent);
-                       ret = -ENOENT;
-                       goto err;
-               }
-
-               n = bch2_trans_kmalloc(trans, sizeof(*n));
+               n = bch2_bkey_get_mut_typed(trans, &iter, snapshot);
                ret = PTR_ERR_OR_ZERO(n);
-               if (ret)
+               if (unlikely(ret)) {
+                       if (ret == -ENOENT)
+                               bch_err(trans->c, "snapshot %u not found", parent);
                        goto err;
-
-               bkey_reassemble(&n->k_i, k);
+               }
 
                if (n->v.children[0] || n->v.children[1]) {
                        bch_err(trans->c, "Trying to add child snapshot nodes to parent that already has children");
@@ -967,7 +934,6 @@ int bch2_subvolume_wait_for_pagecache_and_delete_hook(struct btree_trans *trans,
 int bch2_subvolume_unlink(struct btree_trans *trans, u32 subvolid)
 {
        struct btree_iter iter;
-       struct bkey_s_c k;
        struct bkey_i_subvolume *n;
        struct subvolume_unlink_hook *h;
        int ret = 0;
@@ -976,23 +942,13 @@ int bch2_subvolume_unlink(struct btree_trans *trans, u32 subvolid)
                             POS(0, subvolid),
                             BTREE_ITER_CACHED|
                             BTREE_ITER_INTENT);
-       k = bch2_btree_iter_peek_slot(&iter);
-       ret = bkey_err(k);
-       if (ret)
-               goto err;
-
-       if (k.k->type != KEY_TYPE_subvolume) {
-               bch2_fs_inconsistent(trans->c, "missing subvolume %u", subvolid);
-               ret = -EIO;
-               goto err;
-       }
-
-       n = bch2_trans_kmalloc(trans, sizeof(*n));
+       n = bch2_bkey_get_mut_typed(trans, &iter, subvolume);
        ret = PTR_ERR_OR_ZERO(n);
-       if (ret)
+       if (unlikely(ret)) {
+               bch2_fs_inconsistent_on(ret == -ENOENT, trans->c, "missing subvolume %u", subvolid);
                goto err;
+       }
 
-       bkey_reassemble(&n->k_i, k);
        SET_BCH_SUBVOLUME_UNLINKED(&n->v, true);
 
        ret = bch2_trans_update(trans, &iter, &n->k_i, 0);
@@ -1049,27 +1005,19 @@ found_slot:
 
        if (src_subvolid) {
                /* Creating a snapshot: */
-               src_subvol = bch2_trans_kmalloc(trans, sizeof(*src_subvol));
-               ret = PTR_ERR_OR_ZERO(src_subvol);
-               if (ret)
-                       goto err;
 
                bch2_trans_iter_init(trans, &src_iter, BTREE_ID_subvolumes,
                                     POS(0, src_subvolid),
                                     BTREE_ITER_CACHED|
                                     BTREE_ITER_INTENT);
-               k = bch2_btree_iter_peek_slot(&src_iter);
-               ret = bkey_err(k);
-               if (ret)
-                       goto err;
-
-               if (k.k->type != KEY_TYPE_subvolume) {
-                       bch_err(c, "subvolume %u not found", src_subvolid);
-                       ret = -ENOENT;
+               src_subvol = bch2_bkey_get_mut_typed(trans, &src_iter, subvolume);
+               ret = PTR_ERR_OR_ZERO(src_subvol);
+               if (unlikely(ret)) {
+                       bch2_fs_inconsistent_on(ret == -ENOENT, trans->c,
+                                               "subvolume %u not found", src_subvolid);
                        goto err;
                }
 
-               bkey_reassemble(&src_subvol->k_i, k);
                parent = le32_to_cpu(src_subvol->v.snapshot);
        }
 
@@ -1086,18 +1034,16 @@ found_slot:
                        goto err;
        }
 
-       new_subvol = bch2_trans_kmalloc(trans, sizeof(*new_subvol));
+       new_subvol = bch2_bkey_alloc(trans, &dst_iter, subvolume);
        ret = PTR_ERR_OR_ZERO(new_subvol);
        if (ret)
                goto err;
 
-       bkey_subvolume_init(&new_subvol->k_i);
        new_subvol->v.flags     = 0;
        new_subvol->v.snapshot  = cpu_to_le32(new_nodes[0]);
        new_subvol->v.inode     = cpu_to_le64(inode);
        SET_BCH_SUBVOLUME_RO(&new_subvol->v, ro);
        SET_BCH_SUBVOLUME_SNAP(&new_subvol->v, src_subvolid != 0);
-       new_subvol->k.p         = dst_iter.pos;
        ret = bch2_trans_update(trans, &dst_iter, &new_subvol->k_i, 0);
        if (ret)
                goto err;
index 43f974eb9b7e1fdd43b01066c85ee5da30075cbc..b99a9e421f98b8cb1a61ca12b0cfbcc34a6fcb40 100644 (file)
@@ -15,13 +15,14 @@ static void delete_test_keys(struct bch_fs *c)
        int ret;
 
        ret = bch2_btree_delete_range(c, BTREE_ID_extents,
-                                     SPOS(0, 0, U32_MAX), SPOS_MAX,
-                                     0,
-                                     NULL);
+                                     SPOS(0, 0, U32_MAX),
+                                     POS(0, U64_MAX),
+                                     0, NULL);
        BUG_ON(ret);
 
        ret = bch2_btree_delete_range(c, BTREE_ID_xattrs,
-                                     SPOS(0, 0, U32_MAX), SPOS_MAX,
+                                     SPOS(0, 0, U32_MAX),
+                                     POS(0, U64_MAX),
                                      0, NULL);
        BUG_ON(ret);
 }
@@ -145,8 +146,9 @@ static int test_iterate(struct bch_fs *c, u64 nr)
 
        i = 0;
 
-       ret = for_each_btree_key2(&trans, iter, BTREE_ID_xattrs,
-                                 SPOS(0, 0, U32_MAX), 0, k, ({
+       ret = for_each_btree_key2_upto(&trans, iter, BTREE_ID_xattrs,
+                                 SPOS(0, 0, U32_MAX), POS(0, U64_MAX),
+                                 0, k, ({
                BUG_ON(k.k->p.offset != i++);
                0;
        }));
@@ -211,8 +213,9 @@ static int test_iterate_extents(struct bch_fs *c, u64 nr)
 
        i = 0;
 
-       ret = for_each_btree_key2(&trans, iter, BTREE_ID_extents,
-                                 SPOS(0, 0, U32_MAX), 0, k, ({
+       ret = for_each_btree_key2_upto(&trans, iter, BTREE_ID_extents,
+                                 SPOS(0, 0, U32_MAX), POS(0, U64_MAX),
+                                 0, k, ({
                BUG_ON(bkey_start_offset(k.k) != i);
                i = k.k->p.offset;
                0;
@@ -278,8 +281,9 @@ static int test_iterate_slots(struct bch_fs *c, u64 nr)
 
        i = 0;
 
-       ret = for_each_btree_key2(&trans, iter, BTREE_ID_xattrs,
-                                 SPOS(0, 0, U32_MAX), 0, k, ({
+       ret = for_each_btree_key2_upto(&trans, iter, BTREE_ID_xattrs,
+                                 SPOS(0, 0, U32_MAX), POS(0, U64_MAX),
+                                 0, k, ({
                BUG_ON(k.k->p.offset != i);
                i += 2;
                0;
@@ -295,8 +299,8 @@ static int test_iterate_slots(struct bch_fs *c, u64 nr)
 
        i = 0;
 
-       ret = for_each_btree_key2(&trans, iter, BTREE_ID_xattrs,
-                                 SPOS(0, 0, U32_MAX),
+       ret = for_each_btree_key2_upto(&trans, iter, BTREE_ID_xattrs,
+                                 SPOS(0, 0, U32_MAX), POS(0, U64_MAX),
                                  BTREE_ITER_SLOTS, k, ({
                if (i >= nr * 2)
                        break;
@@ -351,8 +355,9 @@ static int test_iterate_slots_extents(struct bch_fs *c, u64 nr)
 
        i = 0;
 
-       ret = for_each_btree_key2(&trans, iter, BTREE_ID_extents,
-                                 SPOS(0, 0, U32_MAX), 0, k, ({
+       ret = for_each_btree_key2_upto(&trans, iter, BTREE_ID_extents,
+                                 SPOS(0, 0, U32_MAX), POS(0, U64_MAX),
+                                 0, k, ({
                BUG_ON(bkey_start_offset(k.k) != i + 8);
                BUG_ON(k.k->size != 8);
                i += 16;
@@ -369,8 +374,8 @@ static int test_iterate_slots_extents(struct bch_fs *c, u64 nr)
 
        i = 0;
 
-       ret = for_each_btree_key2(&trans, iter, BTREE_ID_extents,
-                                SPOS(0, 0, U32_MAX),
+       ret = for_each_btree_key2_upto(&trans, iter, BTREE_ID_extents,
+                                SPOS(0, 0, U32_MAX), POS(0, U64_MAX),
                                 BTREE_ITER_SLOTS, k, ({
                if (i == nr)
                        break;
@@ -405,10 +410,10 @@ static int test_peek_end(struct bch_fs *c, u64 nr)
        bch2_trans_iter_init(&trans, &iter, BTREE_ID_xattrs,
                             SPOS(0, 0, U32_MAX), 0);
 
-       lockrestart_do(&trans, bkey_err(k = bch2_btree_iter_peek(&iter)));
+       lockrestart_do(&trans, bkey_err(k = bch2_btree_iter_peek_upto(&iter, POS(0, U64_MAX))));
        BUG_ON(k.k);
 
-       lockrestart_do(&trans, bkey_err(k = bch2_btree_iter_peek(&iter)));
+       lockrestart_do(&trans, bkey_err(k = bch2_btree_iter_peek_upto(&iter, POS(0, U64_MAX))));
        BUG_ON(k.k);
 
        bch2_trans_iter_exit(&trans, &iter);
@@ -426,10 +431,10 @@ static int test_peek_end_extents(struct bch_fs *c, u64 nr)
        bch2_trans_iter_init(&trans, &iter, BTREE_ID_extents,
                             SPOS(0, 0, U32_MAX), 0);
 
-       lockrestart_do(&trans, bkey_err(k = bch2_btree_iter_peek(&iter)));
+       lockrestart_do(&trans, bkey_err(k = bch2_btree_iter_peek_upto(&iter, POS(0, U64_MAX))));
        BUG_ON(k.k);
 
-       lockrestart_do(&trans, bkey_err(k = bch2_btree_iter_peek(&iter)));
+       lockrestart_do(&trans, bkey_err(k = bch2_btree_iter_peek_upto(&iter, POS(0, U64_MAX))));
        BUG_ON(k.k);
 
        bch2_trans_iter_exit(&trans, &iter);
@@ -519,7 +524,7 @@ static int test_snapshot_filter(struct bch_fs *c, u32 snapid_lo, u32 snapid_hi)
        bch2_trans_init(&trans, c, 0, 0);
        bch2_trans_iter_init(&trans, &iter, BTREE_ID_xattrs,
                             SPOS(0, 0, snapid_lo), 0);
-       lockrestart_do(&trans, bkey_err(k = bch2_btree_iter_peek(&iter)));
+       lockrestart_do(&trans, bkey_err(k = bch2_btree_iter_peek_upto(&iter, POS(0, U64_MAX))));
 
        BUG_ON(k.k->p.snapshot != U32_MAX);
 
@@ -798,8 +803,9 @@ static int seq_lookup(struct bch_fs *c, u64 nr)
 
        bch2_trans_init(&trans, c, 0, 0);
 
-       ret = for_each_btree_key2(&trans, iter, BTREE_ID_xattrs,
-                                 SPOS(0, 0, U32_MAX), 0, k,
+       ret = for_each_btree_key2_upto(&trans, iter, BTREE_ID_xattrs,
+                                 SPOS(0, 0, U32_MAX), POS(0, U64_MAX),
+                                 0, k,
                0);
        if (ret)
                bch_err(c, "%s(): error %s", __func__, bch2_err_str(ret));
@@ -839,7 +845,8 @@ static int seq_delete(struct bch_fs *c, u64 nr)
        int ret;
 
        ret = bch2_btree_delete_range(c, BTREE_ID_xattrs,
-                                     SPOS(0, 0, U32_MAX), SPOS_MAX,
+                                     SPOS(0, 0, U32_MAX),
+                                     POS(0, U64_MAX),
                                      0, NULL);
        if (ret)
                bch_err(c, "%s(): error %s", __func__, bch2_err_str(ret));