Skip to content

Commit 18dad45

Browse files
author
Kent Overstreet
committed
bcachefs: Replace rcu_read_lock() with guards
The new guard(), scoped_guard() allow for more natural code. Some of the uses with creative flow control have been left. Signed-off-by: Kent Overstreet <[email protected]>
1 parent 9cb49fb commit 18dad45

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+344
-525
lines changed

fs/bcachefs/alloc_background.c

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1000,14 +1000,11 @@ int bch2_trigger_alloc(struct btree_trans *trans,
10001000
}
10011001

10021002
if (new_a->gen != old_a->gen) {
1003-
rcu_read_lock();
1003+
guard(rcu)();
10041004
u8 *gen = bucket_gen(ca, new.k->p.offset);
1005-
if (unlikely(!gen)) {
1006-
rcu_read_unlock();
1005+
if (unlikely(!gen))
10071006
goto invalid_bucket;
1008-
}
10091007
*gen = new_a->gen;
1010-
rcu_read_unlock();
10111008
}
10121009

10131010
#define eval_state(_a, expr) ({ const struct bch_alloc_v4 *a = _a; expr; })
@@ -1033,15 +1030,12 @@ int bch2_trigger_alloc(struct btree_trans *trans,
10331030
}
10341031

10351032
if ((flags & BTREE_TRIGGER_gc) && (flags & BTREE_TRIGGER_insert)) {
1036-
rcu_read_lock();
1033+
guard(rcu)();
10371034
struct bucket *g = gc_bucket(ca, new.k->p.offset);
1038-
if (unlikely(!g)) {
1039-
rcu_read_unlock();
1035+
if (unlikely(!g))
10401036
goto invalid_bucket;
1041-
}
10421037
g->gen_valid = 1;
10431038
g->gen = new_a->gen;
1044-
rcu_read_unlock();
10451039
}
10461040
err:
10471041
fsck_err:
@@ -1117,13 +1111,12 @@ static bool next_bucket(struct bch_fs *c, struct bch_dev **ca, struct bpos *buck
11171111
bucket->offset = 0;
11181112
}
11191113

1120-
rcu_read_lock();
1114+
guard(rcu)();
11211115
*ca = __bch2_next_dev_idx(c, bucket->inode, NULL);
11221116
if (*ca) {
11231117
*bucket = POS((*ca)->dev_idx, (*ca)->mi.first_bucket);
11241118
bch2_dev_get(*ca);
11251119
}
1126-
rcu_read_unlock();
11271120

11281121
return *ca != NULL;
11291122
}
@@ -2514,7 +2507,7 @@ void bch2_recalc_capacity(struct bch_fs *c)
25142507

25152508
lockdep_assert_held(&c->state_lock);
25162509

2517-
rcu_read_lock();
2510+
guard(rcu)();
25182511
for_each_member_device_rcu(c, ca, NULL) {
25192512
struct block_device *bdev = READ_ONCE(ca->disk_sb.bdev);
25202513
if (bdev)
@@ -2559,7 +2552,6 @@ void bch2_recalc_capacity(struct bch_fs *c)
25592552
bucket_size_max = max_t(unsigned, bucket_size_max,
25602553
ca->mi.bucket_size);
25612554
}
2562-
rcu_read_unlock();
25632555

25642556
bch2_set_ra_pages(c, ra_pages);
25652557

@@ -2584,10 +2576,9 @@ u64 bch2_min_rw_member_capacity(struct bch_fs *c)
25842576
{
25852577
u64 ret = U64_MAX;
25862578

2587-
rcu_read_lock();
2579+
guard(rcu)();
25882580
for_each_rw_member_rcu(c, ca)
25892581
ret = min(ret, ca->mi.nbuckets * ca->mi.bucket_size);
2590-
rcu_read_unlock();
25912582
return ret;
25922583
}
25932584

fs/bcachefs/alloc_background.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,9 @@
1313

1414
static inline bool bch2_dev_bucket_exists(struct bch_fs *c, struct bpos pos)
1515
{
16-
rcu_read_lock();
16+
guard(rcu)();
1717
struct bch_dev *ca = bch2_dev_rcu_noerror(c, pos.inode);
18-
bool ret = ca && bucket_valid(ca, pos.offset);
19-
rcu_read_unlock();
20-
return ret;
18+
return ca && bucket_valid(ca, pos.offset);
2119
}
2220

2321
static inline u64 bucket_to_u64(struct bpos bucket)

fs/bcachefs/alloc_foreground.c

Lines changed: 18 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,9 @@ const char * const bch2_watermarks[] = {
6969

7070
void bch2_reset_alloc_cursors(struct bch_fs *c)
7171
{
72-
rcu_read_lock();
72+
guard(rcu)();
7373
for_each_member_device_rcu(c, ca, NULL)
7474
memset(ca->alloc_cursor, 0, sizeof(ca->alloc_cursor));
75-
rcu_read_unlock();
7675
}
7776

7877
static void bch2_open_bucket_hash_add(struct bch_fs *c, struct open_bucket *ob)
@@ -166,9 +165,8 @@ static void open_bucket_free_unused(struct bch_fs *c, struct open_bucket *ob)
166165
ARRAY_SIZE(c->open_buckets_partial));
167166

168167
spin_lock(&c->freelist_lock);
169-
rcu_read_lock();
170-
bch2_dev_rcu(c, ob->dev)->nr_partial_buckets++;
171-
rcu_read_unlock();
168+
scoped_guard(rcu)
169+
bch2_dev_rcu(c, ob->dev)->nr_partial_buckets++;
172170

173171
ob->on_partial_list = true;
174172
c->open_buckets_partial[c->open_buckets_partial_nr++] =
@@ -873,9 +871,8 @@ static int bucket_alloc_set_partial(struct bch_fs *c,
873871
i);
874872
ob->on_partial_list = false;
875873

876-
rcu_read_lock();
877-
bch2_dev_rcu(c, ob->dev)->nr_partial_buckets--;
878-
rcu_read_unlock();
874+
scoped_guard(rcu)
875+
bch2_dev_rcu(c, ob->dev)->nr_partial_buckets--;
879876

880877
ret = add_new_bucket(c, req, ob);
881878
if (ret)
@@ -1057,9 +1054,8 @@ void bch2_open_buckets_stop(struct bch_fs *c, struct bch_dev *ca,
10571054

10581055
ob->on_partial_list = false;
10591056

1060-
rcu_read_lock();
1061-
bch2_dev_rcu(c, ob->dev)->nr_partial_buckets--;
1062-
rcu_read_unlock();
1057+
scoped_guard(rcu)
1058+
bch2_dev_rcu(c, ob->dev)->nr_partial_buckets--;
10631059

10641060
spin_unlock(&c->freelist_lock);
10651061
bch2_open_bucket_put(c, ob);
@@ -1087,14 +1083,11 @@ static struct write_point *__writepoint_find(struct hlist_head *head,
10871083
{
10881084
struct write_point *wp;
10891085

1090-
rcu_read_lock();
1086+
guard(rcu)();
10911087
hlist_for_each_entry_rcu(wp, head, node)
10921088
if (wp->write_point == write_point)
1093-
goto out;
1094-
wp = NULL;
1095-
out:
1096-
rcu_read_unlock();
1097-
return wp;
1089+
return wp;
1090+
return NULL;
10981091
}
10991092

11001093
static inline bool too_many_writepoints(struct bch_fs *c, unsigned factor)
@@ -1638,19 +1631,16 @@ static noinline void bch2_print_allocator_stuck(struct bch_fs *c)
16381631

16391632
bch2_printbuf_make_room(&buf, 4096);
16401633

1641-
rcu_read_lock();
16421634
buf.atomic++;
1643-
1644-
for_each_online_member_rcu(c, ca) {
1645-
prt_printf(&buf, "Dev %u:\n", ca->dev_idx);
1646-
printbuf_indent_add(&buf, 2);
1647-
bch2_dev_alloc_debug_to_text(&buf, ca);
1648-
printbuf_indent_sub(&buf, 2);
1649-
prt_newline(&buf);
1650-
}
1651-
1635+
scoped_guard(rcu)
1636+
for_each_online_member_rcu(c, ca) {
1637+
prt_printf(&buf, "Dev %u:\n", ca->dev_idx);
1638+
printbuf_indent_add(&buf, 2);
1639+
bch2_dev_alloc_debug_to_text(&buf, ca);
1640+
printbuf_indent_sub(&buf, 2);
1641+
prt_newline(&buf);
1642+
}
16521643
--buf.atomic;
1653-
rcu_read_unlock();
16541644

16551645
prt_printf(&buf, "Copygc debug:\n");
16561646
printbuf_indent_add(&buf, 2);

fs/bcachefs/backpointers.c

Lines changed: 27 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -48,17 +48,19 @@ void bch2_backpointer_to_text(struct printbuf *out, struct bch_fs *c, struct bke
4848
{
4949
struct bkey_s_c_backpointer bp = bkey_s_c_to_backpointer(k);
5050

51-
rcu_read_lock();
52-
struct bch_dev *ca = bch2_dev_rcu_noerror(c, bp.k->p.inode);
53-
if (ca) {
54-
u32 bucket_offset;
55-
struct bpos bucket = bp_pos_to_bucket_and_offset(ca, bp.k->p, &bucket_offset);
56-
rcu_read_unlock();
51+
struct bch_dev *ca;
52+
u32 bucket_offset;
53+
struct bpos bucket;
54+
scoped_guard(rcu) {
55+
ca = bch2_dev_rcu_noerror(c, bp.k->p.inode);
56+
if (ca)
57+
bucket = bp_pos_to_bucket_and_offset(ca, bp.k->p, &bucket_offset);
58+
}
59+
60+
if (ca)
5761
prt_printf(out, "bucket=%llu:%llu:%u ", bucket.inode, bucket.offset, bucket_offset);
58-
} else {
59-
rcu_read_unlock();
62+
else
6063
prt_printf(out, "sector=%llu:%llu ", bp.k->p.inode, bp.k->p.offset >> MAX_EXTENT_COMPRESS_RATIO_SHIFT);
61-
}
6264

6365
bch2_btree_id_level_to_text(out, bp.v->btree_id, bp.v->level);
6466
prt_str(out, " data_type=");
@@ -591,6 +593,7 @@ static int check_bp_exists(struct btree_trans *trans,
591593
bkey_for_each_ptr(other_extent_ptrs, ptr)
592594
if (ptr->dev == bp->k.p.inode &&
593595
dev_ptr_stale_rcu(ca, ptr)) {
596+
rcu_read_unlock();
594597
ret = drop_dev_and_update(trans, other_bp.v->btree_id,
595598
other_extent, bp->k.p.inode);
596599
if (ret)
@@ -679,26 +682,23 @@ static int check_extent_to_backpointers(struct btree_trans *trans,
679682
if (p.ptr.dev == BCH_SB_MEMBER_INVALID)
680683
continue;
681684

682-
rcu_read_lock();
683-
struct bch_dev *ca = bch2_dev_rcu_noerror(c, p.ptr.dev);
684-
if (!ca) {
685-
rcu_read_unlock();
686-
continue;
687-
}
685+
bool empty;
686+
{
687+
/* scoped_guard() is a loop, so it breaks continue */
688+
guard(rcu)();
689+
struct bch_dev *ca = bch2_dev_rcu_noerror(c, p.ptr.dev);
690+
if (!ca)
691+
continue;
688692

689-
if (p.ptr.cached && dev_ptr_stale_rcu(ca, &p.ptr)) {
690-
rcu_read_unlock();
691-
continue;
692-
}
693+
if (p.ptr.cached && dev_ptr_stale_rcu(ca, &p.ptr))
694+
continue;
693695

694-
u64 b = PTR_BUCKET_NR(ca, &p.ptr);
695-
if (!bch2_bucket_bitmap_test(&ca->bucket_backpointer_mismatch, b)) {
696-
rcu_read_unlock();
697-
continue;
698-
}
696+
u64 b = PTR_BUCKET_NR(ca, &p.ptr);
697+
if (!bch2_bucket_bitmap_test(&ca->bucket_backpointer_mismatch, b))
698+
continue;
699699

700-
bool empty = bch2_bucket_bitmap_test(&ca->bucket_backpointer_empty, b);
701-
rcu_read_unlock();
700+
empty = bch2_bucket_bitmap_test(&ca->bucket_backpointer_empty, b);
701+
}
702702

703703
struct bkey_i_backpointer bp;
704704
bch2_extent_ptr_to_bp(c, btree, level, k, p, entry, &bp);
@@ -981,7 +981,7 @@ static bool backpointer_node_has_missing(struct bch_fs *c, struct bkey_s_c k)
981981
case KEY_TYPE_btree_ptr_v2: {
982982
bool ret = false;
983983

984-
rcu_read_lock();
984+
guard(rcu)();
985985
struct bpos pos = bkey_s_c_to_btree_ptr_v2(k).v->min_key;
986986
while (pos.inode <= k.k->p.inode) {
987987
if (pos.inode >= c->sb.nr_devices)
@@ -1009,7 +1009,6 @@ static bool backpointer_node_has_missing(struct bch_fs *c, struct bkey_s_c k)
10091009
next:
10101010
pos = SPOS(pos.inode + 1, 0, 0);
10111011
}
1012-
rcu_read_unlock();
10131012

10141013
return ret;
10151014
}

fs/bcachefs/backpointers.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,10 @@ static inline struct bpos bp_pos_to_bucket_and_offset(const struct bch_dev *ca,
5353

5454
static inline bool bp_pos_to_bucket_nodev_noerror(struct bch_fs *c, struct bpos bp_pos, struct bpos *bucket)
5555
{
56-
rcu_read_lock();
56+
guard(rcu)();
5757
struct bch_dev *ca = bch2_dev_rcu_noerror(c, bp_pos.inode);
5858
if (ca)
5959
*bucket = bp_pos_to_bucket(ca, bp_pos);
60-
rcu_read_unlock();
6160
return ca != NULL;
6261
}
6362

fs/bcachefs/btree_gc.c

Lines changed: 24 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1093,42 +1093,41 @@ static int gc_btree_gens_key(struct btree_trans *trans,
10931093
{
10941094
struct bch_fs *c = trans->c;
10951095
struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k);
1096-
struct bkey_i *u;
1097-
int ret;
10981096

10991097
if (unlikely(test_bit(BCH_FS_going_ro, &c->flags)))
11001098
return -EROFS;
11011099

1102-
rcu_read_lock();
1103-
bkey_for_each_ptr(ptrs, ptr) {
1104-
struct bch_dev *ca = bch2_dev_rcu(c, ptr->dev);
1105-
if (!ca)
1106-
continue;
1100+
bool too_stale = false;
1101+
scoped_guard(rcu) {
1102+
bkey_for_each_ptr(ptrs, ptr) {
1103+
struct bch_dev *ca = bch2_dev_rcu(c, ptr->dev);
1104+
if (!ca)
1105+
continue;
11071106

1108-
if (dev_ptr_stale(ca, ptr) > 16) {
1109-
rcu_read_unlock();
1110-
goto update;
1107+
too_stale |= dev_ptr_stale(ca, ptr) > 16;
11111108
}
1109+
1110+
if (!too_stale)
1111+
bkey_for_each_ptr(ptrs, ptr) {
1112+
struct bch_dev *ca = bch2_dev_rcu(c, ptr->dev);
1113+
if (!ca)
1114+
continue;
1115+
1116+
u8 *gen = &ca->oldest_gen[PTR_BUCKET_NR(ca, ptr)];
1117+
if (gen_after(*gen, ptr->gen))
1118+
*gen = ptr->gen;
1119+
}
11121120
}
11131121

1114-
bkey_for_each_ptr(ptrs, ptr) {
1115-
struct bch_dev *ca = bch2_dev_rcu(c, ptr->dev);
1116-
if (!ca)
1117-
continue;
1122+
if (too_stale) {
1123+
struct bkey_i *u = bch2_bkey_make_mut(trans, iter, &k, 0);
1124+
int ret = PTR_ERR_OR_ZERO(u);
1125+
if (ret)
1126+
return ret;
11181127

1119-
u8 *gen = &ca->oldest_gen[PTR_BUCKET_NR(ca, ptr)];
1120-
if (gen_after(*gen, ptr->gen))
1121-
*gen = ptr->gen;
1128+
bch2_extent_normalize(c, bkey_i_to_s(u));
11221129
}
1123-
rcu_read_unlock();
1124-
return 0;
1125-
update:
1126-
u = bch2_bkey_make_mut(trans, iter, &k, 0);
1127-
ret = PTR_ERR_OR_ZERO(u);
1128-
if (ret)
1129-
return ret;
11301130

1131-
bch2_extent_normalize(c, bkey_i_to_s(u));
11321131
return 0;
11331132
}
11341133

fs/bcachefs/btree_io.c

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1325,14 +1325,13 @@ int bch2_btree_node_read_done(struct bch_fs *c, struct bch_dev *ca,
13251325

13261326
btree_node_reset_sib_u64s(b);
13271327

1328-
rcu_read_lock();
1329-
bkey_for_each_ptr(bch2_bkey_ptrs(bkey_i_to_s(&b->key)), ptr) {
1330-
struct bch_dev *ca2 = bch2_dev_rcu(c, ptr->dev);
1328+
scoped_guard(rcu)
1329+
bkey_for_each_ptr(bch2_bkey_ptrs(bkey_i_to_s(&b->key)), ptr) {
1330+
struct bch_dev *ca2 = bch2_dev_rcu(c, ptr->dev);
13311331

1332-
if (!ca2 || ca2->mi.state != BCH_MEMBER_STATE_rw)
1333-
set_btree_node_need_rewrite(b);
1334-
}
1335-
rcu_read_unlock();
1332+
if (!ca2 || ca2->mi.state != BCH_MEMBER_STATE_rw)
1333+
set_btree_node_need_rewrite(b);
1334+
}
13361335

13371336
if (!ptr_written)
13381337
set_btree_node_need_rewrite(b);

0 commit comments

Comments
 (0)