diff options
author | Kent Overstreet <kent.overstreet@linux.dev> | 2024-04-30 23:20:49 +0300 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2024-05-09 00:29:23 +0300 |
commit | 07d7c4da7bd1faefd338f4073846632fbac54880 (patch) | |
tree | 252e8ca0271c17672c12463694381dc93fc530a4 | |
parent | a7f1c26f5907dde57f58c329ef0c532643092e71 (diff) | |
download | linux-07d7c4da7bd1faefd338f4073846632fbac54880.tar.xz |
bcachefs: bch2_bucket_ref_update() now takes bch_dev
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
-rw-r--r-- | fs/bcachefs/buckets.c | 47 | ||||
-rw-r--r-- | fs/bcachefs/buckets.h | 4 | ||||
-rw-r--r-- | fs/bcachefs/ec.c | 19 |
3 files changed, 42 insertions, 28 deletions
diff --git a/fs/bcachefs/buckets.c b/fs/bcachefs/buckets.c index 525a7548fab7..68f2d5952abd 100644 --- a/fs/bcachefs/buckets.c +++ b/fs/bcachefs/buckets.c @@ -700,15 +700,14 @@ fsck_err: return ret; } -int bch2_bucket_ref_update(struct btree_trans *trans, - struct bkey_s_c k, - const struct bch_extent_ptr *ptr, - s64 sectors, enum bch_data_type ptr_data_type, - u8 b_gen, u8 bucket_data_type, - u32 *bucket_sectors) +int bch2_bucket_ref_update(struct btree_trans *trans, struct bch_dev *ca, + struct bkey_s_c k, + const struct bch_extent_ptr *ptr, + s64 sectors, enum bch_data_type ptr_data_type, + u8 b_gen, u8 bucket_data_type, + u32 *bucket_sectors) { 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); struct printbuf buf = PRINTBUF; bool inserting = sectors > 0; @@ -939,7 +938,7 @@ need_mark: /* 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, const struct bch_extent_ptr *ptr, s64 sectors, enum bch_data_type ptr_data_type, @@ -948,7 +947,7 @@ static int __mark_pointer(struct btree_trans *trans, u32 *dst_sectors = !ptr->cached ? &a->dirty_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); if (ret) @@ -966,45 +965,51 @@ static int bch2_trigger_pointer(struct btree_trans *trans, enum btree_iter_update_trigger_flags flags) { 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 bch_backpointer 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); if (flags & BTREE_TRIGGER_transactional) { struct bkey_i_alloc_v4 *a = bch2_trans_start_alloc_update(trans, bucket); - int ret = PTR_ERR_OR_ZERO(a) ?: - __mark_pointer(trans, k, &p.ptr, *sectors, bp.data_type, &a->v); + ret = PTR_ERR_OR_ZERO(a) ?: + __mark_pointer(trans, ca, k, &p.ptr, *sectors, bp.data_type, &a->v); if (ret) - return ret; + goto err; if (!p.ptr.cached) { ret = bch2_bucket_backpointer_mod(trans, bucket, bp, k, insert); if (ret) - return ret; + goto err; } } 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); struct bucket *g = gc_bucket(ca, bucket.offset); bucket_lock(g); 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) { alloc_to_bucket(g, new); bch2_dev_usage_update(c, ca, &old, &new, 0, true); } bucket_unlock(g); percpu_up_read(&c->mark_lock); - return ret; } - - return 0; +err: + bch2_dev_put(ca); + return ret; } static int bch2_trigger_stripe_ptr(struct btree_trans *trans, diff --git a/fs/bcachefs/buckets.h b/fs/bcachefs/buckets.h index 95cf3c290734..46bf66d6b254 100644 --- a/fs/bcachefs/buckets.h +++ b/fs/bcachefs/buckets.h @@ -330,8 +330,8 @@ int bch2_replicas_deltas_realloc(struct btree_trans *, unsigned); void bch2_fs_usage_initialize(struct bch_fs *); -int bch2_bucket_ref_update(struct btree_trans *, struct bkey_s_c, - const struct bch_extent_ptr *, +int bch2_bucket_ref_update(struct btree_trans *, struct bch_dev *, + struct bkey_s_c, const struct bch_extent_ptr *, s64, enum bch_data_type, u8, u8, u32 *); int bch2_check_fix_ptrs(struct btree_trans *, diff --git a/fs/bcachefs/ec.c b/fs/bcachefs/ec.c index 330c3da70b96..ea10f838d9cc 100644 --- a/fs/bcachefs/ec.c +++ b/fs/bcachefs/ec.c @@ -167,9 +167,9 @@ static int __mark_stripe_bucket(struct btree_trans *trans, struct bkey_s_c_stripe s, unsigned ptr_idx, bool deleting, 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; unsigned nr_data = s.v->nr_blocks - s.v->nr_redundant; bool parity = ptr_idx >= nr_data; @@ -178,6 +178,14 @@ static int __mark_stripe_bucket(struct btree_trans *trans, struct printbuf buf = PRINTBUF; 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) sectors = -sectors; @@ -239,7 +247,7 @@ static int __mark_stripe_bucket(struct btree_trans *trans, } 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); if (ret) goto err; @@ -255,6 +263,7 @@ static int __mark_stripe_bucket(struct btree_trans *trans, alloc_data_type_set(a, data_type); err: + bch2_dev_put(ca); printbuf_exit(&buf); return ret; } @@ -272,7 +281,7 @@ static int mark_stripe_bucket(struct btree_trans *trans, struct bkey_i_alloc_v4 *a = bch2_trans_start_alloc_update(trans, bucket); 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) { @@ -282,7 +291,7 @@ static int mark_stripe_bucket(struct btree_trans *trans, struct bucket *g = gc_bucket(ca, bucket.offset); bucket_lock(g); 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) { alloc_to_bucket(g, new); bch2_dev_usage_update(c, ca, &old, &new, 0, true); |