summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fs/bcachefs/bkey_sort.c8
-rw-r--r--fs/bcachefs/bset.h10
-rw-r--r--fs/bcachefs/btree_update_leaf.c2
-rw-r--r--fs/bcachefs/extents.c65
-rw-r--r--fs/bcachefs/extents.h10
-rw-r--r--fs/bcachefs/fs-io.c8
-rw-r--r--fs/bcachefs/io.c7
-rw-r--r--fs/bcachefs/move.c9
-rw-r--r--fs/bcachefs/recovery.c6
-rw-r--r--fs/bcachefs/reflink.c4
10 files changed, 84 insertions, 45 deletions
diff --git a/fs/bcachefs/bkey_sort.c b/fs/bcachefs/bkey_sort.c
index 5f9f3d2e6906..daef8e5c599f 100644
--- a/fs/bcachefs/bkey_sort.c
+++ b/fs/bcachefs/bkey_sort.c
@@ -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);
}
}
diff --git a/fs/bcachefs/bset.h b/fs/bcachefs/bset.h
index 0e9bd8022d35..b93c4f287480 100644
--- a/fs/bcachefs/bset.h
+++ b/fs/bcachefs/bset.h
@@ -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) \
diff --git a/fs/bcachefs/btree_update_leaf.c b/fs/bcachefs/btree_update_leaf.c
index 85580e63b5ca..a774fce027c2 100644
--- a/fs/bcachefs/btree_update_leaf.c
+++ b/fs/bcachefs/btree_update_leaf.c
@@ -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)
diff --git a/fs/bcachefs/extents.c b/fs/bcachefs/extents.c
index 46eeaa574e86..6c1cc90ab320 100644
--- a/fs/bcachefs/extents.c
+++ b/fs/bcachefs/extents.c
@@ -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;
}
diff --git a/fs/bcachefs/extents.h b/fs/bcachefs/extents.h
index f334b6f763e3..6e893c37c287 100644
--- a/fs/bcachefs/extents.h
+++ b/fs/bcachefs/extents.h
@@ -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
diff --git a/fs/bcachefs/fs-io.c b/fs/bcachefs/fs-io.c
index 478630fdf643..8b8442f9a81c 100644
--- a/fs/bcachefs/fs-io.c
+++ b/fs/bcachefs/fs-io.c
@@ -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);
diff --git a/fs/bcachefs/io.c b/fs/bcachefs/io.c
index 4fe61705ae75..0f1be5c5543d 100644
--- a/fs/bcachefs/io.c
+++ b/fs/bcachefs/io.c
@@ -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));
diff --git a/fs/bcachefs/move.c b/fs/bcachefs/move.c
index dbe35d16e7dd..5fd44dbe2722 100644
--- a/fs/bcachefs/move.c
+++ b/fs/bcachefs/move.c
@@ -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)
diff --git a/fs/bcachefs/recovery.c b/fs/bcachefs/recovery.c
index d1184bf62cae..2efe023b2f0d 100644
--- a/fs/bcachefs/recovery.c
+++ b/fs/bcachefs/recovery.c
@@ -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);
diff --git a/fs/bcachefs/reflink.c b/fs/bcachefs/reflink.c
index 6d21086c3254..4de65bf70362 100644
--- a/fs/bcachefs/reflink.c
+++ b/fs/bcachefs/reflink.c
@@ -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));