summaryrefslogtreecommitdiff
path: root/libbcachefs/alloc_background.c
diff options
context:
space:
mode:
Diffstat (limited to 'libbcachefs/alloc_background.c')
-rw-r--r--libbcachefs/alloc_background.c65
1 files changed, 37 insertions, 28 deletions
diff --git a/libbcachefs/alloc_background.c b/libbcachefs/alloc_background.c
index 009a85bc..aef796b5 100644
--- a/libbcachefs/alloc_background.c
+++ b/libbcachefs/alloc_background.c
@@ -451,6 +451,8 @@ void __bch2_alloc_to_v4(struct bkey_s_c k, struct bch_alloc_v4 *out)
if (src < dst)
memset(src, 0, dst - src);
+
+ SET_BCH_ALLOC_V4_NR_BACKPOINTERS(out, 0);
} else {
struct bkey_alloc_unpacked u = bch2_alloc_unpack(k);
@@ -476,38 +478,26 @@ static noinline struct bkey_i_alloc_v4 *
__bch2_alloc_to_v4_mut(struct btree_trans *trans, struct bkey_s_c k)
{
struct bkey_i_alloc_v4 *ret;
+
+ ret = bch2_trans_kmalloc(trans, sizeof(struct bkey_i_alloc_v4));
+ if (IS_ERR(ret))
+ return ret;
+
if (k.k->type == KEY_TYPE_alloc_v4) {
- struct bkey_s_c_alloc_v4 a = bkey_s_c_to_alloc_v4(k);
- unsigned bytes = sizeof(struct bkey_i_alloc_v4) +
- BCH_ALLOC_V4_NR_BACKPOINTERS(a.v) *
- sizeof(struct bch_backpointer);
void *src, *dst;
- /*
- * Reserve space for one more backpointer here:
- * Not sketchy at doing it this way, nope...
- */
- ret = bch2_trans_kmalloc(trans, bytes + sizeof(struct bch_backpointer));
- if (IS_ERR(ret))
- return ret;
-
bkey_reassemble(&ret->k_i, k);
src = alloc_v4_backpointers(&ret->v);
SET_BCH_ALLOC_V4_BACKPOINTERS_START(&ret->v, BCH_ALLOC_V4_U64s);
dst = alloc_v4_backpointers(&ret->v);
- memmove(dst, src, BCH_ALLOC_V4_NR_BACKPOINTERS(&ret->v) *
- sizeof(struct bch_backpointer));
if (src < dst)
memset(src, 0, dst - src);
+
+ SET_BCH_ALLOC_V4_NR_BACKPOINTERS(&ret->v, 0);
set_alloc_v4_u64s(ret);
} else {
- ret = bch2_trans_kmalloc(trans, sizeof(struct bkey_i_alloc_v4) +
- sizeof(struct bch_backpointer));
- if (IS_ERR(ret))
- return ret;
-
bkey_alloc_v4_init(&ret->k_i);
ret->k.p = k.k->p;
bch2_alloc_to_v4(k, &ret->v);
@@ -517,8 +507,12 @@ __bch2_alloc_to_v4_mut(struct btree_trans *trans, struct bkey_s_c k)
static inline struct bkey_i_alloc_v4 *bch2_alloc_to_v4_mut_inlined(struct btree_trans *trans, struct bkey_s_c k)
{
+ struct bkey_s_c_alloc_v4 a;
+
if (likely(k.k->type == KEY_TYPE_alloc_v4) &&
- BCH_ALLOC_V4_BACKPOINTERS_START(bkey_s_c_to_alloc_v4(k).v) == BCH_ALLOC_V4_U64s) {
+ ((a = bkey_s_c_to_alloc_v4(k), true) &&
+ BCH_ALLOC_V4_BACKPOINTERS_START(a.v) == BCH_ALLOC_V4_U64s &&
+ BCH_ALLOC_V4_NR_BACKPOINTERS(a.v) == 0)) {
/*
* Reserve space for one more backpointer here:
* Not sketchy at doing it this way, nope...
@@ -962,10 +956,17 @@ struct bkey_s_c bch2_get_key_or_hole(struct btree_iter *iter, struct bpos end, s
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)));
+
+ if (!bpos_eq(iter->path->l[0].b->key.k.p, SPOS_MAX))
+ end = bkey_min(end, bpos_nosnap_successor(iter->path->l[0].b->key.k.p));
+
+ end = bkey_min(end, POS(iter->pos.inode, iter->pos.offset + U32_MAX - 1));
+
+ /*
+ * btree node min/max is a closed interval, upto takes a half
+ * open interval:
+ */
+ k = bch2_btree_iter_peek_upto(&iter2, end);
next = iter2.pos;
bch2_trans_iter_exit(iter->trans, &iter2);
@@ -1760,7 +1761,7 @@ static void bch2_do_discards_work(struct work_struct *work)
void bch2_do_discards(struct bch_fs *c)
{
if (bch2_write_ref_tryget(c, BCH_WRITE_REF_discard) &&
- !queue_work(system_long_wq, &c->discard_work))
+ !queue_work(c->write_ref_wq, &c->discard_work))
bch2_write_ref_put(c, BCH_WRITE_REF_discard);
}
@@ -1886,11 +1887,12 @@ err:
void bch2_do_invalidates(struct bch_fs *c)
{
if (bch2_write_ref_tryget(c, BCH_WRITE_REF_invalidate) &&
- !queue_work(system_long_wq, &c->invalidate_work))
+ !queue_work(c->write_ref_wq, &c->invalidate_work))
bch2_write_ref_put(c, BCH_WRITE_REF_invalidate);
}
-static int bch2_dev_freespace_init(struct bch_fs *c, struct bch_dev *ca)
+static int bch2_dev_freespace_init(struct bch_fs *c, struct bch_dev *ca,
+ unsigned long *last_updated)
{
struct btree_trans trans;
struct btree_iter iter;
@@ -1910,6 +1912,12 @@ static int bch2_dev_freespace_init(struct bch_fs *c, struct bch_dev *ca)
* freespace/need_discard/need_gc_gens btrees as needed:
*/
while (1) {
+ if (*last_updated + HZ * 10 < jiffies) {
+ bch_info(ca, "%s: currently at %llu/%llu",
+ __func__, iter.pos.offset, ca->mi.nbuckets);
+ *last_updated = jiffies;
+ }
+
bch2_trans_begin(&trans);
if (bkey_ge(iter.pos, end)) {
@@ -1989,6 +1997,7 @@ int bch2_fs_freespace_init(struct bch_fs *c)
unsigned i;
int ret = 0;
bool doing_init = false;
+ unsigned long last_updated = jiffies;
/*
* We can crash during the device add path, so we need to check this on
@@ -2004,7 +2013,7 @@ int bch2_fs_freespace_init(struct bch_fs *c)
doing_init = true;
}
- ret = bch2_dev_freespace_init(c, ca);
+ ret = bch2_dev_freespace_init(c, ca, &last_updated);
if (ret) {
percpu_ref_put(&ca->ref);
return ret;