Skip to content

Commit 94b481f

Browse files
committed
Merge tag 'bcachefs-2025-02-06.2' of git://evilpiepirate.org/bcachefs
Pull bcachefs fixes from Kent Overstreet: "Nothing major, things continue to be fairly quiet over here. - add a SubmittingPatches to clarify that patches submitted for bcachefs do, in fact, need to be tested - discard path now correctly issues journal flushes when needed, this fixes performance issues when the filesystem is nearly full and we're bottlenecked on copygc - fix a bug that could cause the pending rebalance work accounting to be off when devices are being onlined/offlined; users should report if they are still seeing this - and a few more trivial ones" * tag 'bcachefs-2025-02-06.2' of git://evilpiepirate.org/bcachefs: bcachefs: bch2_bkey_sectors_need_rebalance() now only depends on bch_extent_rebalance bcachefs: Fix rcu imbalance in bch2_fs_btree_key_cache_exit() bcachefs: Fix discard path journal flushing bcachefs: fix deadlock in journal_entry_open() bcachefs: fix incorrect pointer check in __bch2_subvolume_delete() bcachefs docs: SubmittingPatches.rst
2 parents 1b3291f + 4be214c commit 94b481f

20 files changed

+215
-59
lines changed
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
Submitting patches to bcachefs:
2+
===============================
3+
4+
Patches must be tested before being submitted, either with the xfstests suite
5+
[0], or the full bcachefs test suite in ktest [1], depending on what's being
6+
touched. Note that ktest wraps xfstests and will be an easier method to running
7+
it for most users; it includes single-command wrappers for all the mainstream
8+
in-kernel local filesystems.
9+
10+
Patches will undergo more testing after being merged (including
11+
lockdep/kasan/preempt/etc. variants), these are not generally required to be
12+
run by the submitter - but do put some thought into what you're changing and
13+
which tests might be relevant, e.g. are you dealing with tricky memory layout
14+
work? kasan, are you doing locking work? then lockdep; and ktest includes
15+
single-command variants for the debug build types you'll most likely need.
16+
17+
The exception to this rule is incomplete WIP/RFC patches: if you're working on
18+
something nontrivial, it's encouraged to send out a WIP patch to let people
19+
know what you're doing and make sure you're on the right track. Just make sure
20+
it includes a brief note as to what's done and what's incomplete, to avoid
21+
confusion.
22+
23+
Rigorous checkpatch.pl adherence is not required (many of its warnings are
24+
considered out of date), but try not to deviate too much without reason.
25+
26+
Focus on writing code that reads well and is organized well; code should be
27+
aesthetically pleasing.
28+
29+
CI:
30+
===
31+
32+
Instead of running your tests locally, when running the full test suite it's
33+
prefereable to let a server farm do it in parallel, and then have the results
34+
in a nice test dashboard (which can tell you which failures are new, and
35+
presents results in a git log view, avoiding the need for most bisecting).
36+
37+
That exists [2], and community members may request an account. If you work for
38+
a big tech company, you'll need to help out with server costs to get access -
39+
but the CI is not restricted to running bcachefs tests: it runs any ktest test
40+
(which generally makes it easy to wrap other tests that can run in qemu).
41+
42+
Other things to think about:
43+
============================
44+
45+
- How will we debug this code? Is there sufficient introspection to diagnose
46+
when something starts acting wonky on a user machine?
47+
48+
We don't necessarily need every single field of every data structure visible
49+
with introspection, but having the important fields of all the core data
50+
types wired up makes debugging drastically easier - a bit of thoughtful
51+
foresight greatly reduces the need to have people build custom kernels with
52+
debug patches.
53+
54+
More broadly, think about all the debug tooling that might be needed.
55+
56+
- Does it make the codebase more or less of a mess? Can we also try to do some
57+
organizing, too?
58+
59+
- Do new tests need to be written? New assertions? How do we know and verify
60+
that the code is correct, and what happens if something goes wrong?
61+
62+
We don't yet have automated code coverage analysis or easy fault injection -
63+
but for now, pretend we did and ask what they might tell us.
64+
65+
Assertions are hugely important, given that we don't yet have a systems
66+
language that can do ergonomic embedded correctness proofs. Hitting an assert
67+
in testing is much better than wandering off into undefined behaviour la-la
68+
land - use them. Use them judiciously, and not as a replacement for proper
69+
error handling, but use them.
70+
71+
- Does it need to be performance tested? Should we add new peformance counters?
72+
73+
bcachefs has a set of persistent runtime counters which can be viewed with
74+
the 'bcachefs fs top' command; this should give users a basic idea of what
75+
their filesystem is currently doing. If you're doing a new feature or looking
76+
at old code, think if anything should be added.
77+
78+
- If it's a new on disk format feature - have upgrades and downgrades been
79+
tested? (Automated tests exists but aren't in the CI, due to the hassle of
80+
disk image management; coordinate to have them run.)
81+
82+
Mailing list, IRC:
83+
==================
84+
85+
Patches should hit the list [3], but much discussion and code review happens on
86+
IRC as well [4]; many people appreciate the more conversational approach and
87+
quicker feedback.
88+
89+
Additionally, we have a lively user community doing excellent QA work, which
90+
exists primarily on IRC. Please make use of that resource; user feedback is
91+
important for any nontrivial feature, and documenting it in commit messages
92+
would be a good idea.
93+
94+
[0]: git://git.kernel.org/pub/scm/fs/xfs/xfstests-dev.git
95+
[1]: https://evilpiepirate.org/git/ktest.git/
96+
[2]: https://evilpiepirate.org/~testdashboard/ci/
97+
98+
[4]: irc.oftc.net#bcache, #bcachefs-dev

Documentation/filesystems/bcachefs/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,5 @@ bcachefs Documentation
99
:numbered:
1010

1111
CodingStyle
12+
SubmittingPatches
1213
errorcodes

MAINTAINERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3954,6 +3954,7 @@ M: Kent Overstreet <[email protected]>
39543954
39553955
S: Supported
39563956
C: irc://irc.oftc.net/bcache
3957+
P: Documentation/filesystems/bcachefs/SubmittingPatches.rst
39573958
T: git https://evilpiepirate.org/git/bcachefs.git
39583959
F: fs/bcachefs/
39593960
F: Documentation/filesystems/bcachefs/

fs/bcachefs/alloc_background.c

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1803,7 +1803,6 @@ struct discard_buckets_state {
18031803
u64 open;
18041804
u64 need_journal_commit;
18051805
u64 discarded;
1806-
u64 need_journal_commit_this_dev;
18071806
};
18081807

18091808
static int bch2_discard_one_bucket(struct btree_trans *trans,
@@ -1827,11 +1826,11 @@ static int bch2_discard_one_bucket(struct btree_trans *trans,
18271826
goto out;
18281827
}
18291828

1830-
if (bch2_bucket_needs_journal_commit(&c->buckets_waiting_for_journal,
1831-
c->journal.flushed_seq_ondisk,
1832-
pos.inode, pos.offset)) {
1833-
s->need_journal_commit++;
1834-
s->need_journal_commit_this_dev++;
1829+
u64 seq_ready = bch2_bucket_journal_seq_ready(&c->buckets_waiting_for_journal,
1830+
pos.inode, pos.offset);
1831+
if (seq_ready > c->journal.flushed_seq_ondisk) {
1832+
if (seq_ready > c->journal.flushing_seq)
1833+
s->need_journal_commit++;
18351834
goto out;
18361835
}
18371836

@@ -1865,23 +1864,24 @@ static int bch2_discard_one_bucket(struct btree_trans *trans,
18651864
discard_locked = true;
18661865
}
18671866

1868-
if (!bkey_eq(*discard_pos_done, iter.pos) &&
1869-
ca->mi.discard && !c->opts.nochanges) {
1870-
/*
1871-
* This works without any other locks because this is the only
1872-
* thread that removes items from the need_discard tree
1873-
*/
1874-
bch2_trans_unlock_long(trans);
1875-
blkdev_issue_discard(ca->disk_sb.bdev,
1876-
k.k->p.offset * ca->mi.bucket_size,
1877-
ca->mi.bucket_size,
1878-
GFP_KERNEL);
1879-
*discard_pos_done = iter.pos;
1867+
if (!bkey_eq(*discard_pos_done, iter.pos)) {
18801868
s->discarded++;
1869+
*discard_pos_done = iter.pos;
18811870

1882-
ret = bch2_trans_relock_notrace(trans);
1883-
if (ret)
1884-
goto out;
1871+
if (ca->mi.discard && !c->opts.nochanges) {
1872+
/*
1873+
* This works without any other locks because this is the only
1874+
* thread that removes items from the need_discard tree
1875+
*/
1876+
bch2_trans_unlock_long(trans);
1877+
blkdev_issue_discard(ca->disk_sb.bdev,
1878+
k.k->p.offset * ca->mi.bucket_size,
1879+
ca->mi.bucket_size,
1880+
GFP_KERNEL);
1881+
ret = bch2_trans_relock_notrace(trans);
1882+
if (ret)
1883+
goto out;
1884+
}
18851885
}
18861886

18871887
SET_BCH_ALLOC_V4_NEED_DISCARD(&a->v, false);
@@ -1929,6 +1929,9 @@ static void bch2_do_discards_work(struct work_struct *work)
19291929
POS(ca->dev_idx, U64_MAX), 0, k,
19301930
bch2_discard_one_bucket(trans, ca, &iter, &discard_pos_done, &s, false)));
19311931

1932+
if (s.need_journal_commit > dev_buckets_available(ca, BCH_WATERMARK_normal))
1933+
bch2_journal_flush_async(&c->journal, NULL);
1934+
19321935
trace_discard_buckets(c, s.seen, s.open, s.need_journal_commit, s.discarded,
19331936
bch2_err_str(ret));
19341937

@@ -2024,7 +2027,7 @@ static void bch2_do_discards_fast_work(struct work_struct *work)
20242027
break;
20252028
}
20262029

2027-
trace_discard_buckets(c, s.seen, s.open, s.need_journal_commit, s.discarded, bch2_err_str(ret));
2030+
trace_discard_buckets_fast(c, s.seen, s.open, s.need_journal_commit, s.discarded, bch2_err_str(ret));
20282031

20292032
bch2_trans_put(trans);
20302033
percpu_ref_put(&ca->io_ref);

fs/bcachefs/alloc_foreground.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -205,8 +205,12 @@ static inline bool may_alloc_bucket(struct bch_fs *c,
205205
return false;
206206
}
207207

208-
if (bch2_bucket_needs_journal_commit(&c->buckets_waiting_for_journal,
209-
c->journal.flushed_seq_ondisk, bucket.inode, bucket.offset)) {
208+
u64 journal_seq_ready =
209+
bch2_bucket_journal_seq_ready(&c->buckets_waiting_for_journal,
210+
bucket.inode, bucket.offset);
211+
if (journal_seq_ready > c->journal.flushed_seq_ondisk) {
212+
if (journal_seq_ready > c->journal.flushing_seq)
213+
s->need_journal_commit++;
210214
s->skipped_need_journal_commit++;
211215
return false;
212216
}
@@ -570,7 +574,7 @@ static struct open_bucket *bch2_bucket_alloc_trans(struct btree_trans *trans,
570574
? bch2_bucket_alloc_freelist(trans, ca, watermark, &s, cl)
571575
: bch2_bucket_alloc_early(trans, ca, watermark, &s, cl);
572576

573-
if (s.skipped_need_journal_commit * 2 > avail)
577+
if (s.need_journal_commit * 2 > avail)
574578
bch2_journal_flush_async(&c->journal, NULL);
575579

576580
if (!ob && s.btree_bitmap != BTREE_BITMAP_ANY) {

fs/bcachefs/alloc_types.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ struct bucket_alloc_state {
1818
u64 buckets_seen;
1919
u64 skipped_open;
2020
u64 skipped_need_journal_commit;
21+
u64 need_journal_commit;
2122
u64 skipped_nocow;
2223
u64 skipped_nouse;
2324
u64 skipped_mi_btree_bitmap;

fs/bcachefs/btree_key_cache.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -748,7 +748,6 @@ void bch2_fs_btree_key_cache_exit(struct btree_key_cache *bc)
748748
rcu_read_unlock();
749749
mutex_lock(&bc->table.mutex);
750750
mutex_unlock(&bc->table.mutex);
751-
rcu_read_lock();
752751
continue;
753752
}
754753
for (i = 0; i < tbl->size; i++)

fs/bcachefs/buckets_waiting_for_journal.c

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,23 +22,21 @@ static void bucket_table_init(struct buckets_waiting_for_journal_table *t, size_
2222
memset(t->d, 0, sizeof(t->d[0]) << t->bits);
2323
}
2424

25-
bool bch2_bucket_needs_journal_commit(struct buckets_waiting_for_journal *b,
26-
u64 flushed_seq,
27-
unsigned dev, u64 bucket)
25+
u64 bch2_bucket_journal_seq_ready(struct buckets_waiting_for_journal *b,
26+
unsigned dev, u64 bucket)
2827
{
2928
struct buckets_waiting_for_journal_table *t;
3029
u64 dev_bucket = (u64) dev << 56 | bucket;
31-
bool ret = false;
32-
unsigned i;
30+
u64 ret = 0;
3331

3432
mutex_lock(&b->lock);
3533
t = b->t;
3634

37-
for (i = 0; i < ARRAY_SIZE(t->hash_seeds); i++) {
35+
for (unsigned i = 0; i < ARRAY_SIZE(t->hash_seeds); i++) {
3836
struct bucket_hashed *h = bucket_hash(t, i, dev_bucket);
3937

4038
if (h->dev_bucket == dev_bucket) {
41-
ret = h->journal_seq > flushed_seq;
39+
ret = h->journal_seq;
4240
break;
4341
}
4442
}

fs/bcachefs/buckets_waiting_for_journal.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44

55
#include "buckets_waiting_for_journal_types.h"
66

7-
bool bch2_bucket_needs_journal_commit(struct buckets_waiting_for_journal *,
8-
u64, unsigned, u64);
7+
u64 bch2_bucket_journal_seq_ready(struct buckets_waiting_for_journal *,
8+
unsigned, u64);
99
int bch2_set_bucket_needs_journal_commit(struct buckets_waiting_for_journal *,
1010
u64, unsigned, u64, u64);
1111

fs/bcachefs/inode.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,12 +285,14 @@ void bch2_inode_opts_get(struct bch_io_opts *, struct bch_fs *,
285285
struct bch_inode_unpacked *);
286286
int bch2_inum_opts_get(struct btree_trans*, subvol_inum, struct bch_io_opts *);
287287

288+
#include "rebalance.h"
289+
288290
static inline struct bch_extent_rebalance
289291
bch2_inode_rebalance_opts_get(struct bch_fs *c, struct bch_inode_unpacked *inode)
290292
{
291293
struct bch_io_opts io_opts;
292294
bch2_inode_opts_get(&io_opts, c, inode);
293-
return io_opts_to_rebalance_opts(&io_opts);
295+
return io_opts_to_rebalance_opts(c, &io_opts);
294296
}
295297

296298
int bch2_inode_rm_snapshot(struct btree_trans *, u64, u32);

0 commit comments

Comments
 (0)