Commit 07d7c4da authored by Kent Overstreet's avatar Kent Overstreet

bcachefs: bch2_bucket_ref_update() now takes bch_dev

Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent a7f1c26f
...@@ -700,15 +700,14 @@ int bch2_check_fix_ptrs(struct btree_trans *trans, ...@@ -700,15 +700,14 @@ int bch2_check_fix_ptrs(struct btree_trans *trans,
return ret; return ret;
} }
int bch2_bucket_ref_update(struct btree_trans *trans, int bch2_bucket_ref_update(struct btree_trans *trans, struct bch_dev *ca,
struct bkey_s_c k, struct bkey_s_c k,
const struct bch_extent_ptr *ptr, const struct bch_extent_ptr *ptr,
s64 sectors, enum bch_data_type ptr_data_type, s64 sectors, enum bch_data_type ptr_data_type,
u8 b_gen, u8 bucket_data_type, u8 b_gen, u8 bucket_data_type,
u32 *bucket_sectors) u32 *bucket_sectors)
{ {
struct bch_fs *c = trans->c; struct bch_fs *c = trans->c;
struct bch_dev *ca = bch2_dev_bkey_exists(c, ptr->dev);
size_t bucket_nr = PTR_BUCKET_NR(ca, ptr); size_t bucket_nr = PTR_BUCKET_NR(ca, ptr);
struct printbuf buf = PRINTBUF; struct printbuf buf = PRINTBUF;
bool inserting = sectors > 0; bool inserting = sectors > 0;
...@@ -939,7 +938,7 @@ int bch2_trans_fs_usage_apply(struct btree_trans *trans, ...@@ -939,7 +938,7 @@ int bch2_trans_fs_usage_apply(struct btree_trans *trans,
/* KEY_TYPE_extent: */ /* KEY_TYPE_extent: */
static int __mark_pointer(struct btree_trans *trans, static int __mark_pointer(struct btree_trans *trans, struct bch_dev *ca,
struct bkey_s_c k, struct bkey_s_c k,
const struct bch_extent_ptr *ptr, const struct bch_extent_ptr *ptr,
s64 sectors, enum bch_data_type ptr_data_type, s64 sectors, enum bch_data_type ptr_data_type,
...@@ -948,7 +947,7 @@ static int __mark_pointer(struct btree_trans *trans, ...@@ -948,7 +947,7 @@ static int __mark_pointer(struct btree_trans *trans,
u32 *dst_sectors = !ptr->cached u32 *dst_sectors = !ptr->cached
? &a->dirty_sectors ? &a->dirty_sectors
: &a->cached_sectors; : &a->cached_sectors;
int ret = bch2_bucket_ref_update(trans, k, ptr, sectors, ptr_data_type, int ret = bch2_bucket_ref_update(trans, ca, k, ptr, sectors, ptr_data_type,
a->gen, a->data_type, dst_sectors); a->gen, a->data_type, dst_sectors);
if (ret) if (ret)
...@@ -966,45 +965,51 @@ static int bch2_trigger_pointer(struct btree_trans *trans, ...@@ -966,45 +965,51 @@ static int bch2_trigger_pointer(struct btree_trans *trans,
enum btree_iter_update_trigger_flags flags) enum btree_iter_update_trigger_flags flags)
{ {
bool insert = !(flags & BTREE_TRIGGER_overwrite); bool insert = !(flags & BTREE_TRIGGER_overwrite);
int ret = 0;
struct bch_fs *c = trans->c;
struct bch_dev *ca = bch2_dev_tryget(c, p.ptr.dev);
if (unlikely(!ca)) {
if (insert)
ret = -EIO;
goto err;
}
struct bpos bucket; struct bpos bucket;
struct bch_backpointer bp; struct bch_backpointer bp;
bch2_extent_ptr_to_bp(trans->c, btree_id, level, k, p, entry, &bucket, &bp); bch2_extent_ptr_to_bp(trans->c, btree_id, level, k, p, entry, &bucket, &bp);
*sectors = insert ? bp.bucket_len : -((s64) bp.bucket_len); *sectors = insert ? bp.bucket_len : -((s64) bp.bucket_len);
if (flags & BTREE_TRIGGER_transactional) { if (flags & BTREE_TRIGGER_transactional) {
struct bkey_i_alloc_v4 *a = bch2_trans_start_alloc_update(trans, bucket); struct bkey_i_alloc_v4 *a = bch2_trans_start_alloc_update(trans, bucket);
int ret = PTR_ERR_OR_ZERO(a) ?: ret = PTR_ERR_OR_ZERO(a) ?:
__mark_pointer(trans, k, &p.ptr, *sectors, bp.data_type, &a->v); __mark_pointer(trans, ca, k, &p.ptr, *sectors, bp.data_type, &a->v);
if (ret) if (ret)
return ret; goto err;
if (!p.ptr.cached) { if (!p.ptr.cached) {
ret = bch2_bucket_backpointer_mod(trans, bucket, bp, k, insert); ret = bch2_bucket_backpointer_mod(trans, bucket, bp, k, insert);
if (ret) if (ret)
return ret; goto err;
} }
} }
if (flags & BTREE_TRIGGER_gc) { if (flags & BTREE_TRIGGER_gc) {
struct bch_fs *c = trans->c;
struct bch_dev *ca = bch2_dev_bkey_exists(c, p.ptr.dev);
percpu_down_read(&c->mark_lock); percpu_down_read(&c->mark_lock);
struct bucket *g = gc_bucket(ca, bucket.offset); struct bucket *g = gc_bucket(ca, bucket.offset);
bucket_lock(g); bucket_lock(g);
struct bch_alloc_v4 old = bucket_m_to_alloc(*g), new = old; struct bch_alloc_v4 old = bucket_m_to_alloc(*g), new = old;
int ret = __mark_pointer(trans, k, &p.ptr, *sectors, bp.data_type, &new); ret = __mark_pointer(trans, ca, k, &p.ptr, *sectors, bp.data_type, &new);
if (!ret) { if (!ret) {
alloc_to_bucket(g, new); alloc_to_bucket(g, new);
bch2_dev_usage_update(c, ca, &old, &new, 0, true); bch2_dev_usage_update(c, ca, &old, &new, 0, true);
} }
bucket_unlock(g); bucket_unlock(g);
percpu_up_read(&c->mark_lock); percpu_up_read(&c->mark_lock);
return ret;
} }
err:
return 0; bch2_dev_put(ca);
return ret;
} }
static int bch2_trigger_stripe_ptr(struct btree_trans *trans, static int bch2_trigger_stripe_ptr(struct btree_trans *trans,
......
...@@ -330,8 +330,8 @@ int bch2_replicas_deltas_realloc(struct btree_trans *, unsigned); ...@@ -330,8 +330,8 @@ int bch2_replicas_deltas_realloc(struct btree_trans *, unsigned);
void bch2_fs_usage_initialize(struct bch_fs *); void bch2_fs_usage_initialize(struct bch_fs *);
int bch2_bucket_ref_update(struct btree_trans *, struct bkey_s_c, int bch2_bucket_ref_update(struct btree_trans *, struct bch_dev *,
const struct bch_extent_ptr *, struct bkey_s_c, const struct bch_extent_ptr *,
s64, enum bch_data_type, u8, u8, u32 *); s64, enum bch_data_type, u8, u8, u32 *);
int bch2_check_fix_ptrs(struct btree_trans *, int bch2_check_fix_ptrs(struct btree_trans *,
......
...@@ -167,9 +167,9 @@ static int __mark_stripe_bucket(struct btree_trans *trans, ...@@ -167,9 +167,9 @@ static int __mark_stripe_bucket(struct btree_trans *trans,
struct bkey_s_c_stripe s, struct bkey_s_c_stripe s,
unsigned ptr_idx, bool deleting, unsigned ptr_idx, bool deleting,
struct bpos bucket, struct bpos bucket,
struct bch_alloc_v4 *a) struct bch_alloc_v4 *a,
enum btree_iter_update_trigger_flags flags)
{ {
struct bch_fs *c = trans->c;
const struct bch_extent_ptr *ptr = s.v->ptrs + ptr_idx; const struct bch_extent_ptr *ptr = s.v->ptrs + ptr_idx;
unsigned nr_data = s.v->nr_blocks - s.v->nr_redundant; unsigned nr_data = s.v->nr_blocks - s.v->nr_redundant;
bool parity = ptr_idx >= nr_data; bool parity = ptr_idx >= nr_data;
...@@ -178,6 +178,14 @@ static int __mark_stripe_bucket(struct btree_trans *trans, ...@@ -178,6 +178,14 @@ static int __mark_stripe_bucket(struct btree_trans *trans,
struct printbuf buf = PRINTBUF; struct printbuf buf = PRINTBUF;
int ret = 0; int ret = 0;
struct bch_fs *c = trans->c;
struct bch_dev *ca = bch2_dev_tryget(c, ptr->dev);
if (unlikely(!ca)) {
if (!(flags & BTREE_TRIGGER_overwrite))
ret = -EIO;
goto err;
}
if (deleting) if (deleting)
sectors = -sectors; sectors = -sectors;
...@@ -239,7 +247,7 @@ static int __mark_stripe_bucket(struct btree_trans *trans, ...@@ -239,7 +247,7 @@ static int __mark_stripe_bucket(struct btree_trans *trans,
} }
if (sectors) { if (sectors) {
ret = bch2_bucket_ref_update(trans, s.s_c, ptr, sectors, data_type, ret = bch2_bucket_ref_update(trans, ca, s.s_c, ptr, sectors, data_type,
a->gen, a->data_type, &a->dirty_sectors); a->gen, a->data_type, &a->dirty_sectors);
if (ret) if (ret)
goto err; goto err;
...@@ -255,6 +263,7 @@ static int __mark_stripe_bucket(struct btree_trans *trans, ...@@ -255,6 +263,7 @@ static int __mark_stripe_bucket(struct btree_trans *trans,
alloc_data_type_set(a, data_type); alloc_data_type_set(a, data_type);
err: err:
bch2_dev_put(ca);
printbuf_exit(&buf); printbuf_exit(&buf);
return ret; return ret;
} }
...@@ -272,7 +281,7 @@ static int mark_stripe_bucket(struct btree_trans *trans, ...@@ -272,7 +281,7 @@ static int mark_stripe_bucket(struct btree_trans *trans,
struct bkey_i_alloc_v4 *a = struct bkey_i_alloc_v4 *a =
bch2_trans_start_alloc_update(trans, bucket); bch2_trans_start_alloc_update(trans, bucket);
return PTR_ERR_OR_ZERO(a) ?: return PTR_ERR_OR_ZERO(a) ?:
__mark_stripe_bucket(trans, s, ptr_idx, deleting, bucket, &a->v); __mark_stripe_bucket(trans, s, ptr_idx, deleting, bucket, &a->v, flags);
} }
if (flags & BTREE_TRIGGER_gc) { if (flags & BTREE_TRIGGER_gc) {
...@@ -282,7 +291,7 @@ static int mark_stripe_bucket(struct btree_trans *trans, ...@@ -282,7 +291,7 @@ static int mark_stripe_bucket(struct btree_trans *trans,
struct bucket *g = gc_bucket(ca, bucket.offset); struct bucket *g = gc_bucket(ca, bucket.offset);
bucket_lock(g); bucket_lock(g);
struct bch_alloc_v4 old = bucket_m_to_alloc(*g), new = old; struct bch_alloc_v4 old = bucket_m_to_alloc(*g), new = old;
int ret = __mark_stripe_bucket(trans, s, ptr_idx, deleting, bucket, &new); int ret = __mark_stripe_bucket(trans, s, ptr_idx, deleting, bucket, &new, flags);
if (!ret) { if (!ret) {
alloc_to_bucket(g, new); alloc_to_bucket(g, new);
bch2_dev_usage_update(c, ca, &old, &new, 0, true); bch2_dev_usage_update(c, ca, &old, &new, 0, true);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment