Skip to content

Commit 805ddc2

Browse files
author
Kent Overstreet
committed
bcachefs: bch2_dev_rcu_noerror()
bch2_dev_rcu() now properly errors if the device is invalid Signed-off-by: Kent Overstreet <[email protected]>
1 parent b99a94f commit 805ddc2

File tree

6 files changed

+22
-13
lines changed

6 files changed

+22
-13
lines changed

fs/bcachefs/alloc_background.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ enum bch_validate_flags;
1616
static inline bool bch2_dev_bucket_exists(struct bch_fs *c, struct bpos pos)
1717
{
1818
rcu_read_lock();
19-
struct bch_dev *ca = bch2_dev_rcu(c, pos.inode);
19+
struct bch_dev *ca = bch2_dev_rcu_noerror(c, pos.inode);
2020
bool ret = ca && bucket_valid(ca, pos.offset);
2121
rcu_read_unlock();
2222
return ret;

fs/bcachefs/backpointers.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ int bch2_backpointer_validate(struct bch_fs *c, struct bkey_s_c k,
5555
struct bkey_s_c_backpointer bp = bkey_s_c_to_backpointer(k);
5656

5757
rcu_read_lock();
58-
struct bch_dev *ca = bch2_dev_rcu(c, bp.k->p.inode);
58+
struct bch_dev *ca = bch2_dev_rcu_noerror(c, bp.k->p.inode);
5959
if (!ca) {
6060
/* these will be caught by fsck */
6161
rcu_read_unlock();
@@ -89,7 +89,7 @@ void bch2_backpointer_to_text(struct printbuf *out, const struct bch_backpointer
8989
void bch2_backpointer_k_to_text(struct printbuf *out, struct bch_fs *c, struct bkey_s_c k)
9090
{
9191
rcu_read_lock();
92-
struct bch_dev *ca = bch2_dev_rcu(c, k.k->p.inode);
92+
struct bch_dev *ca = bch2_dev_rcu_noerror(c, k.k->p.inode);
9393
if (ca) {
9494
struct bpos bucket = bp_pos_to_bucket(ca, k.k->p);
9595
rcu_read_unlock();
@@ -673,7 +673,7 @@ static int check_extent_to_backpointers(struct btree_trans *trans,
673673
continue;
674674

675675
rcu_read_lock();
676-
struct bch_dev *ca = bch2_dev_rcu(c, p.ptr.dev);
676+
struct bch_dev *ca = bch2_dev_rcu_noerror(c, p.ptr.dev);
677677
if (ca)
678678
bch2_extent_ptr_to_bp(c, ca, btree, level, k, p, entry, &bucket_pos, &bp);
679679
rcu_read_unlock();

fs/bcachefs/buckets.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ int bch2_check_fix_ptrs(struct btree_trans *trans,
281281
goto err;
282282

283283
rcu_read_lock();
284-
bch2_bkey_drop_ptrs(bkey_i_to_s(new), ptr, !bch2_dev_rcu(c, ptr->dev));
284+
bch2_bkey_drop_ptrs(bkey_i_to_s(new), ptr, !bch2_dev_exists(c, ptr->dev));
285285
rcu_read_unlock();
286286

287287
if (level) {

fs/bcachefs/extents.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1021,7 +1021,7 @@ void bch2_extent_ptr_to_text(struct printbuf *out, struct bch_fs *c, const struc
10211021
{
10221022
out->atomic++;
10231023
rcu_read_lock();
1024-
struct bch_dev *ca = bch2_dev_rcu(c, ptr->dev);
1024+
struct bch_dev *ca = bch2_dev_rcu_noerror(c, ptr->dev);
10251025
if (!ca) {
10261026
prt_printf(out, "ptr: %u:%llu gen %u%s", ptr->dev,
10271027
(u64) ptr->offset, ptr->gen,
@@ -1125,8 +1125,9 @@ static int extent_ptr_validate(struct bch_fs *c,
11251125
{
11261126
int ret = 0;
11271127

1128+
/* bad pointers are repaired by check_fix_ptrs(): */
11281129
rcu_read_lock();
1129-
struct bch_dev *ca = bch2_dev_rcu(c, ptr->dev);
1130+
struct bch_dev *ca = bch2_dev_rcu_noerror(c, ptr->dev);
11301131
if (!ca) {
11311132
rcu_read_unlock();
11321133
return 0;

fs/bcachefs/replicas.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -795,7 +795,7 @@ bool bch2_have_enough_devs(struct bch_fs *c, struct bch_devs_mask devs,
795795
for (unsigned i = 0; i < e->nr_devs; i++) {
796796
nr_online += test_bit(e->devs[i], devs.d);
797797

798-
struct bch_dev *ca = bch2_dev_rcu(c, e->devs[i]);
798+
struct bch_dev *ca = bch2_dev_rcu_noerror(c, e->devs[i]);
799799
nr_failed += !ca || ca->mi.state == BCH_MEMBER_STATE_failed;
800800
}
801801
rcu_read_unlock();

fs/bcachefs/sb-members.h

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -198,29 +198,37 @@ static inline struct bch_dev *bch2_dev_locked(struct bch_fs *c, unsigned dev)
198198
lockdep_is_held(&c->state_lock));
199199
}
200200

201-
static inline struct bch_dev *bch2_dev_rcu(struct bch_fs *c, unsigned dev)
201+
static inline struct bch_dev *bch2_dev_rcu_noerror(struct bch_fs *c, unsigned dev)
202202
{
203203
return c && dev < c->sb.nr_devices
204204
? rcu_dereference(c->devs[dev])
205205
: NULL;
206206
}
207207

208+
void bch2_dev_missing(struct bch_fs *, unsigned);
209+
210+
static inline struct bch_dev *bch2_dev_rcu(struct bch_fs *c, unsigned dev)
211+
{
212+
struct bch_dev *ca = bch2_dev_rcu_noerror(c, dev);
213+
if (unlikely(!ca))
214+
bch2_dev_missing(c, dev);
215+
return ca;
216+
}
217+
208218
static inline struct bch_dev *bch2_dev_tryget_noerror(struct bch_fs *c, unsigned dev)
209219
{
210220
rcu_read_lock();
211-
struct bch_dev *ca = bch2_dev_rcu(c, dev);
221+
struct bch_dev *ca = bch2_dev_rcu_noerror(c, dev);
212222
if (ca)
213223
bch2_dev_get(ca);
214224
rcu_read_unlock();
215225
return ca;
216226
}
217227

218-
void bch2_dev_missing(struct bch_fs *, unsigned);
219-
220228
static inline struct bch_dev *bch2_dev_tryget(struct bch_fs *c, unsigned dev)
221229
{
222230
struct bch_dev *ca = bch2_dev_tryget_noerror(c, dev);
223-
if (!ca)
231+
if (unlikely(!ca))
224232
bch2_dev_missing(c, dev);
225233
return ca;
226234
}

0 commit comments

Comments
 (0)