bcachefs: Rework of cut_front & cut_back
authorKent Overstreet <kent.overstreet@gmail.com>
Sun, 10 Nov 2019 00:02:48 +0000 (19:02 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:08:32 +0000 (17:08 -0400)
This changes bch2_cut_front and bch2_cut_back so that they're able to
shorten the size of the value, and it also changes the extent update
path to update the accounting in the btree node when this happens.

When the size of the value is shortened, they zero out the space that's
no longer used, so it's interpreted as noops (as implemented in the last
patch).

Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/bkey_sort.c
fs/bcachefs/bset.h
fs/bcachefs/btree_update_leaf.c
fs/bcachefs/extents.c
fs/bcachefs/extents.h
fs/bcachefs/fs-io.c
fs/bcachefs/io.c
fs/bcachefs/move.c
fs/bcachefs/recovery.c
fs/bcachefs/reflink.c

index 5f9f3d2e6906a747fddf6966361a655fd8a56288..daef8e5c599f25a7b864f9710d15c2e6928f5c07 100644 (file)
@@ -350,7 +350,7 @@ struct btree_nr_keys bch2_extent_sort_fix_overlapping(struct bch_fs *c,
                        if (bkey_cmp(l.k->p, r.k->p) >= 0) {
                                sort_key_next(iter, b, _r);
                        } else {
-                               __bch2_cut_front(l.k->p, r);
+                               bch2_cut_front_s(l.k->p, r);
                                extent_save(b, rk, r.k);
                        }
 
@@ -362,9 +362,9 @@ struct btree_nr_keys bch2_extent_sort_fix_overlapping(struct bch_fs *c,
                         * r wins, but it overlaps in the middle of l - split l:
                         */
                        bkey_reassemble(split.k, l.s_c);
-                       bch2_cut_back(bkey_start_pos(r.k), &split.k->k);
+                       bch2_cut_back(bkey_start_pos(r.k), split.k);
 
-                       __bch2_cut_front(r.k->p, l);
+                       bch2_cut_front_s(r.k->p, l);
                        extent_save(b, lk, l.k);
 
                        extent_sort_sift(iter, b, 0);
@@ -372,7 +372,7 @@ struct btree_nr_keys bch2_extent_sort_fix_overlapping(struct bch_fs *c,
                        extent_sort_append(c, f, &nr, dst->start,
                                           &prev, bkey_i_to_s(split.k));
                } else {
-                       bch2_cut_back(bkey_start_pos(r.k), l.k);
+                       bch2_cut_back_s(bkey_start_pos(r.k), l);
                        extent_save(b, lk, l.k);
                }
        }
index 0e9bd8022d3553062b2ee885a66e98f50dda71de..b93c4f287480e558a70baeba2fdb8f6a1a2758bd 100644 (file)
@@ -584,6 +584,16 @@ static inline void btree_keys_account_key(struct btree_nr_keys *n,
                n->unpacked_keys += sign;
 }
 
+static inline void btree_keys_account_val_delta(struct btree *b,
+                                               struct bkey_packed *k,
+                                               int delta)
+{
+       struct bset_tree *t = bch2_bkey_to_bset(b, k);
+
+       b->nr.live_u64s                 += delta;
+       b->nr.bset_u64s[t - b->set]     += delta;
+}
+
 #define btree_keys_account_key_add(_nr, _bset_idx, _k)         \
        btree_keys_account_key(_nr, _bset_idx, _k, 1)
 #define btree_keys_account_key_drop(_nr, _bset_idx, _k)        \
index 85580e63b5cad739bf8617fcfab9dc84e9764965..a774fce027c23cb4164e509f2ff6dcbedd9a9e95 100644 (file)
@@ -884,7 +884,7 @@ retry:
 
                        /* create the biggest key we can */
                        bch2_key_resize(&delete.k, max_sectors);
-                       bch2_cut_back(end, &delete.k);
+                       bch2_cut_back(end, &delete);
 
                        ret = bch2_extent_trim_atomic(&delete, iter);
                        if (ret)
index 46eeaa574e860a0f9b5f4e49a662ad3f604e8b7d..6c1cc90ab320a3f71cea756f5e2163e2262eaaab 100644 (file)
@@ -720,12 +720,14 @@ void bch2_btree_ptr_to_text(struct printbuf *out, struct bch_fs *c,
 
 /* Extents */
 
-void __bch2_cut_front(struct bpos where, struct bkey_s k)
+int bch2_cut_front_s(struct bpos where, struct bkey_s k)
 {
+       unsigned new_val_u64s = bkey_val_u64s(k.k);
+       int val_u64s_delta;
        u64 sub;
 
        if (bkey_cmp(where, bkey_start_pos(k.k)) <= 0)
-               return;
+               return 0;
 
        EBUG_ON(bkey_cmp(where, k.k->p) > 0);
 
@@ -733,8 +735,10 @@ void __bch2_cut_front(struct bpos where, struct bkey_s k)
 
        k.k->size -= sub;
 
-       if (!k.k->size)
+       if (!k.k->size) {
                k.k->type = KEY_TYPE_deleted;
+               new_val_u64s = 0;
+       }
 
        switch (k.k->type) {
        case KEY_TYPE_deleted:
@@ -784,26 +788,42 @@ void __bch2_cut_front(struct bpos where, struct bkey_s k)
        default:
                BUG();
        }
+
+       val_u64s_delta = bkey_val_u64s(k.k) - new_val_u64s;
+       BUG_ON(val_u64s_delta < 0);
+
+       set_bkey_val_u64s(k.k, new_val_u64s);
+       memset(bkey_val_end(k), 0, val_u64s_delta * sizeof(u64));
+       return -val_u64s_delta;
 }
 
-bool bch2_cut_back(struct bpos where, struct bkey *k)
+int bch2_cut_back_s(struct bpos where, struct bkey_s k)
 {
+       unsigned new_val_u64s = bkey_val_u64s(k.k);
+       int val_u64s_delta;
        u64 len = 0;
 
-       if (bkey_cmp(where, k->p) >= 0)
-               return false;
+       if (bkey_cmp(where, k.k->p) >= 0)
+               return 0;
 
-       EBUG_ON(bkey_cmp(where, bkey_start_pos(k)) < 0);
+       EBUG_ON(bkey_cmp(where, bkey_start_pos(k.k)) < 0);
 
-       len = where.offset - bkey_start_offset(k);
+       len = where.offset - bkey_start_offset(k.k);
 
-       k->p = where;
-       k->size = len;
+       k.k->p = where;
+       k.k->size = len;
 
-       if (!len)
-               k->type = KEY_TYPE_deleted;
+       if (!len) {
+               k.k->type = KEY_TYPE_deleted;
+               new_val_u64s = 0;
+       }
+
+       val_u64s_delta = bkey_val_u64s(k.k) - new_val_u64s;
+       BUG_ON(val_u64s_delta < 0);
 
-       return true;
+       set_bkey_val_u64s(k.k, new_val_u64s);
+       memset(bkey_val_end(k), 0, val_u64s_delta * sizeof(u64));
+       return -val_u64s_delta;
 }
 
 static unsigned bch2_bkey_nr_alloc_ptrs(struct bkey_s_c k)
@@ -942,7 +962,7 @@ int bch2_extent_trim_atomic(struct bkey_i *k, struct btree_iter *iter)
        if (ret)
                return ret;
 
-       bch2_cut_back(end, &k->k);
+       bch2_cut_back(end, k);
        return 0;
 }
 
@@ -1085,11 +1105,14 @@ extent_squash(struct bch_fs *c, struct btree_iter *iter,
              enum bch_extent_overlap overlap)
 {
        struct btree_iter_level *l = &iter->l[0];
+       int u64s_delta;
 
        switch (overlap) {
        case BCH_EXTENT_OVERLAP_FRONT:
                /* insert overlaps with start of k: */
-               __bch2_cut_front(insert->k.p, k);
+               u64s_delta = bch2_cut_front_s(insert->k.p, k);
+               btree_keys_account_val_delta(l->b, _k, u64s_delta);
+
                EBUG_ON(bkey_deleted(k.k));
                extent_save(l->b, _k, k.k);
                bch2_btree_iter_fix_key_modified(iter, l->b, _k);
@@ -1097,7 +1120,9 @@ extent_squash(struct bch_fs *c, struct btree_iter *iter,
 
        case BCH_EXTENT_OVERLAP_BACK:
                /* insert overlaps with end of k: */
-               bch2_cut_back(bkey_start_pos(&insert->k), k.k);
+               u64s_delta = bch2_cut_back_s(bkey_start_pos(&insert->k), k);
+               btree_keys_account_val_delta(l->b, _k, u64s_delta);
+
                EBUG_ON(bkey_deleted(k.k));
                extent_save(l->b, _k, k.k);
 
@@ -1155,10 +1180,12 @@ extent_squash(struct bch_fs *c, struct btree_iter *iter,
                bkey_reassemble(split.k, k.s_c);
                split.k->k.needs_whiteout |= bkey_written(l->b, _k);
 
-               bch2_cut_back(bkey_start_pos(&insert->k), &split.k->k);
+               bch2_cut_back(bkey_start_pos(&insert->k), split.k);
                BUG_ON(bkey_deleted(&split.k->k));
 
-               __bch2_cut_front(insert->k.p, k);
+               u64s_delta = bch2_cut_front_s(insert->k.p, k);
+               btree_keys_account_val_delta(l->b, _k, u64s_delta);
+
                BUG_ON(bkey_deleted(k.k));
                extent_save(l->b, _k, k.k);
                bch2_btree_iter_fix_key_modified(iter, l->b, _k);
@@ -1748,7 +1775,7 @@ enum merge_result bch2_reservation_merge(struct bch_fs *c,
 
        if ((u64) l.k->size + r.k->size > KEY_SIZE_MAX) {
                bch2_key_resize(l.k, KEY_SIZE_MAX);
-               __bch2_cut_front(l.k->p, r.s);
+               bch2_cut_front_s(l.k->p, r.s);
                return BCH_MERGE_PARTIAL;
        }
 
index f334b6f763e343f0734dae0e12bbaa9377d7b3de..6e893c37c2871a8c8ecfa465e49355b46e5671df 100644 (file)
@@ -534,14 +534,18 @@ do {                                                                      \
        }                                                               \
 } while (0)
 
-void __bch2_cut_front(struct bpos, struct bkey_s);
+int bch2_cut_front_s(struct bpos, struct bkey_s);
+int bch2_cut_back_s(struct bpos, struct bkey_s);
 
 static inline void bch2_cut_front(struct bpos where, struct bkey_i *k)
 {
-       __bch2_cut_front(where, bkey_i_to_s(k));
+       bch2_cut_front_s(where, bkey_i_to_s(k));
 }
 
-bool bch2_cut_back(struct bpos, struct bkey *);
+static inline void bch2_cut_back(struct bpos where, struct bkey_i *k)
+{
+       bch2_cut_back_s(where, bkey_i_to_s(k));
+}
 
 /**
  * bch_key_resize - adjust size of @k
index 478630fdf643924077f537c62c6eb757db91502b..8b8442f9a81c581e7aa5361b82b0b942f02ac795 100644 (file)
@@ -2485,7 +2485,7 @@ reassemble:
                                move_pos.offset -= shift >> 9;
                                goto reassemble;
                        } else {
-                               bch2_cut_back(atomic_end, &copy.k->k);
+                               bch2_cut_back(atomic_end, copy.k);
                        }
                }
 
@@ -2505,7 +2505,7 @@ reassemble:
                 */
                if (insert &&
                    bkey_cmp(bkey_start_pos(&copy.k->k), delete.k.p) < 0) {
-                       bch2_cut_back(bkey_start_pos(&copy.k->k), &delete.k);
+                       bch2_cut_back(bkey_start_pos(&copy.k->k), &delete);
                } else if (!insert &&
                           bkey_cmp(copy.k->k.p,
                                    bkey_start_pos(&delete.k)) > 0) {
@@ -2652,8 +2652,8 @@ static long bchfs_fallocate(struct bch_inode_info *inode, int mode,
                reservation.k.p         = k.k->p;
                reservation.k.size      = k.k->size;
 
-               bch2_cut_front(iter->pos, &reservation.k_i);
-               bch2_cut_back(end_pos, &reservation.k);
+               bch2_cut_front(iter->pos,       &reservation.k_i);
+               bch2_cut_back(end_pos,          &reservation.k_i);
 
                sectors = reservation.k.size;
                reservation.v.nr_replicas = bch2_bkey_nr_dirty_ptrs(k);
index 4fe61705ae75b54f65c73516474cb88a086d3813..0f1be5c5543d54f5b83ef97b2cc4398755d9d51a 100644 (file)
@@ -345,7 +345,7 @@ int bch2_fpunch_at(struct btree_trans *trans, struct btree_iter *iter,
 
                /* create the biggest key we can */
                bch2_key_resize(&delete.k, max_sectors);
-               bch2_cut_back(end, &delete.k);
+               bch2_cut_back(end, &delete);
 
                bch2_trans_begin_updates(trans);
 
@@ -414,6 +414,7 @@ int bch2_write_index_default(struct bch_write_op *op)
 
                bkey_on_stack_realloc(&sk, c, k->k.u64s);
                bkey_copy(sk.k, k);
+               bch2_cut_front(iter->pos, sk.k);
 
                bch2_trans_begin_updates(&trans);
 
@@ -425,9 +426,7 @@ int bch2_write_index_default(struct bch_write_op *op)
                if (ret)
                        break;
 
-               if (bkey_cmp(iter->pos, k->k.p) < 0)
-                       bch2_cut_front(iter->pos, k);
-               else
+               if (bkey_cmp(iter->pos, k->k.p) >= 0)
                        bch2_keylist_pop_front(keys);
        } while (!bch2_keylist_empty(keys));
 
index dbe35d16e7ddc9e8496699771f9d66aa86ec7d09..5fd44dbe27225d902e1f56a0a91624885fc8451b 100644 (file)
@@ -96,10 +96,11 @@ static int bch2_migrate_index_update(struct bch_write_op *op)
 
                bkey_copy(&_new.k, bch2_keylist_front(keys));
                new = bkey_i_to_extent(&_new.k);
+               bch2_cut_front(iter->pos, &new->k_i);
 
-               bch2_cut_front(iter->pos, insert);
-               bch2_cut_back(new->k.p, &insert->k);
-               bch2_cut_back(insert->k.p, &new->k);
+               bch2_cut_front(iter->pos,       insert);
+               bch2_cut_back(new->k.p,         insert);
+               bch2_cut_back(insert->k.p,      &new->k_i);
 
                if (m->data_cmd == DATA_REWRITE)
                        bch2_bkey_drop_device(bkey_i_to_s(insert),
@@ -168,8 +169,6 @@ next:
                        if (bch2_keylist_empty(keys))
                                goto out;
                }
-
-               bch2_cut_front(iter->pos, bch2_keylist_front(keys));
                continue;
 nomatch:
                if (m->ctxt)
index d1184bf62cae4e120cc61adf56df7351e2ff1921..2efe023b2f0d386b44403c5c8b7d2b247dbc0d56 100644 (file)
@@ -177,7 +177,7 @@ static struct journal_keys journal_keys_sort(struct list_head *journal_entries)
                        if ((cmp_int(i[0].journal_seq, i[1].journal_seq) ?:
                             cmp_int(i[0].journal_offset, i[1].journal_offset)) < 0) {
                                if (bkey_cmp(i[0].k->k.p, i[1].k->k.p) <= 0) {
-                                       bch2_cut_back(bkey_start_pos(&i[1].k->k), &i[0].k->k);
+                                       bch2_cut_back(bkey_start_pos(&i[1].k->k), i[0].k);
                                } else {
                                        struct bkey_i *split =
                                                kmalloc(bkey_bytes(i[0].k), GFP_KERNEL);
@@ -186,7 +186,7 @@ static struct journal_keys journal_keys_sort(struct list_head *journal_entries)
                                                goto err;
 
                                        bkey_copy(split, i[0].k);
-                                       bch2_cut_back(bkey_start_pos(&i[1].k->k), &split->k);
+                                       bch2_cut_back(bkey_start_pos(&i[1].k->k), split);
                                        keys_deduped.d[keys_deduped.nr++] = (struct journal_key) {
                                                .btree_id       = i[0].btree_id,
                                                .allocated      = true,
@@ -298,7 +298,7 @@ retry:
 
                bkey_copy(split, k);
                bch2_cut_front(split_iter->pos, split);
-               bch2_cut_back(atomic_end, &split->k);
+               bch2_cut_back(atomic_end, split);
 
                bch2_trans_update(&trans, split_iter, split);
                bch2_btree_iter_set_pos(iter, split->k.p);
index 6d21086c3254ef693074d0e8ed6bff57f3efde00..4de65bf70362e8d0354538bdea61c8bd80475249 100644 (file)
@@ -40,7 +40,7 @@ enum merge_result bch2_reflink_p_merge(struct bch_fs *c,
 
        if ((u64) l.k->size + r.k->size > KEY_SIZE_MAX) {
                bch2_key_resize(l.k, KEY_SIZE_MAX);
-               __bch2_cut_front(l.k->p, _r);
+               bch2_cut_front_s(l.k->p, _r);
                return BCH_MERGE_PARTIAL;
        }
 
@@ -230,7 +230,7 @@ s64 bch2_remap_range(struct bch_fs *c,
                        src_k = bkey_i_to_s_c(new_src.k);
 
                        bch2_cut_front(src_iter->pos,   new_src.k);
-                       bch2_cut_back(src_end,          &new_src.k->k);
+                       bch2_cut_back(src_end,          new_src.k);
 
                        ret = bch2_make_extent_indirect(&trans, src_iter,
                                                bkey_i_to_extent(new_src.k));