diff options
-rw-r--r-- | fs/bcachefs/bkey_sort.c | 8 | ||||
-rw-r--r-- | fs/bcachefs/bset.h | 10 | ||||
-rw-r--r-- | fs/bcachefs/btree_update_leaf.c | 2 | ||||
-rw-r--r-- | fs/bcachefs/extents.c | 65 | ||||
-rw-r--r-- | fs/bcachefs/extents.h | 10 | ||||
-rw-r--r-- | fs/bcachefs/fs-io.c | 8 | ||||
-rw-r--r-- | fs/bcachefs/io.c | 7 | ||||
-rw-r--r-- | fs/bcachefs/move.c | 9 | ||||
-rw-r--r-- | fs/bcachefs/recovery.c | 6 | ||||
-rw-r--r-- | fs/bcachefs/reflink.c | 4 |
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, ©.k->k); + bch2_cut_back(atomic_end, copy.k); } } @@ -2505,7 +2505,7 @@ reassemble: */ if (insert && bkey_cmp(bkey_start_pos(©.k->k), delete.k.p) < 0) { - bch2_cut_back(bkey_start_pos(©.k->k), &delete.k); + bch2_cut_back(bkey_start_pos(©.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)); |