Skip to content

Commit 16dbfae

Browse files
committed
Merge tag 'bcachefs-2024-05-19' of https://evilpiepirate.org/git/bcachefs
Pull bcachefs updates from Kent Overstreet: - More safety fixes, primarily found by syzbot - Run the upgrade/downgrade paths in nochnages mode. Nochanges mode is primarily for testing fsck/recovery in dry run mode, so it shouldn't change anything besides disabling writes and holding dirty metadata in memory. The idea here was to reduce the amount of activity if we can't write anything out, so that bringing up a filesystem in "super ro" mode would be more lilkely to work for data recovery - but norecovery is the correct option for this. - btree_trans->locked; we now track whether a btree_trans has any btree nodes locked, and this is used for improved assertions related to trans_unlock() and trans_relock(). We'll also be using it for improving how we work with lockdep in the future: we don't want lockdep to be tracking individual btree node locks because we take too many for lockdep to track, and it's not necessary since we have a cycle detector. - Trigger improvements that are prep work for online fsck - BTREE_TRIGGER_check_repair; this regularizes how we do some repair work for extents that goes with running triggers in fsck, and fixes some subtle issues with transaction restarts there. - bch2_snapshot_equiv() has now been ripped out of fsck.c; snapshot equivalence classes are for when snapshot deletion leaves behind redundant snapshot nodes, but snapshot deletion now cleans this up right away, so the abstraction doesn't need to leak. - Improvements to how we resume writing to the journal in recovery. The code for picking the new place to write when reading the journal is greatly simplified and we also store the position in the superblock for when we don't read the journal; this means that we preserve more of the journal for list_journal debugging. - Improvements to sysfs btree_cache and btree_node_cache, for debugging memory reclaim. - We now detect when we've blocked for 10 seconds on the allocator in the write path and dump some useful info. - Safety fixes for devices references: this is a big series that changes almost all device lookups to properly check if the device exists and take a reference to it. Previously we assumed that if a bkey exists that references a device then the device must exist, and this was enforced in .invalid methods, but this was incorrect because it meant device removal relied on accounting being correct to not leave keys pointing to invalid devices, and that's not something we can assume. Getting the "pointer to invalid device" checks out of our .invalid() methods fixes some long standing device removal bugs; the only outstanding bug with device removal now is a race between the discard path and deleting alloc info, which should be easily fixed. - The allocator now prefers not to expand the new member_info.btree_allocated bitmap, meaning if repair ever requires scanning for btree nodes (because of a corrupt interior nodes) we won't have to scan the whole device(s). - New coding style document, which among other things talks about the correct usage of assertions * tag 'bcachefs-2024-05-19' of https://evilpiepirate.org/git/bcachefs: (155 commits) bcachefs: add no_invalid_checks flag bcachefs: add counters for failed shrinker reclaim bcachefs: Fix sb_field_downgrade validation bcachefs: Plumb bch_validate_flags to sb_field_ops.validate() bcachefs: s/bkey_invalid_flags/bch_validate_flags bcachefs: fsync() should not return -EROFS bcachefs: Invalid devices are now checked for by fsck, not .invalid methods bcachefs: kill bch2_dev_bkey_exists() in bch2_check_fix_ptrs() bcachefs: kill bch2_dev_bkey_exists() in bch2_read_endio() bcachefs: bch2_dev_get_ioref() checks for device not present bcachefs: bch2_dev_get_ioref2(); io_read.c bcachefs: bch2_dev_get_ioref2(); debug.c bcachefs: bch2_dev_get_ioref2(); journal_io.c bcachefs: bch2_dev_get_ioref2(); io_write.c bcachefs: bch2_dev_get_ioref2(); btree_io.c bcachefs: bch2_dev_get_ioref2(); backpointers.c bcachefs: bch2_dev_get_ioref2(); alloc_background.c bcachefs: for_each_bset() declares loop iter bcachefs: Move BCACHEFS_STATFS_MAGIC value to UAPI magic.h bcachefs: Improve sysfs internal/btree_cache ...
2 parents a90f1cd + 07f9a27 commit 16dbfae

File tree

123 files changed

+4632
-4324
lines changed

Some content is hidden

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

123 files changed

+4632
-4324
lines changed
Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
.. SPDX-License-Identifier: GPL-2.0
2+
3+
bcachefs coding style
4+
=====================
5+
6+
Good development is like gardening, and codebases are our gardens. Tend to them
7+
every day; look for little things that are out of place or in need of tidying.
8+
A little weeding here and there goes a long way; don't wait until things have
9+
spiraled out of control.
10+
11+
Things don't always have to be perfect - nitpicking often does more harm than
12+
good. But appreciate beauty when you see it - and let people know.
13+
14+
The code that you are afraid to touch is the code most in need of refactoring.
15+
16+
A little organizing here and there goes a long way.
17+
18+
Put real thought into how you organize things.
19+
20+
Good code is readable code, where the structure is simple and leaves nowhere
21+
for bugs to hide.
22+
23+
Assertions are one of our most important tools for writing reliable code. If in
24+
the course of writing a patchset you encounter a condition that shouldn't
25+
happen (and will have unpredictable or undefined behaviour if it does), or
26+
you're not sure if it can happen and not sure how to handle it yet - make it a
27+
BUG_ON(). Don't leave undefined or unspecified behavior lurking in the codebase.
28+
29+
By the time you finish the patchset, you should understand better which
30+
assertions need to be handled and turned into checks with error paths, and
31+
which should be logically impossible. Leave the BUG_ON()s in for the ones which
32+
are logically impossible. (Or, make them debug mode assertions if they're
33+
expensive - but don't turn everything into a debug mode assertion, so that
34+
we're not stuck debugging undefined behaviour should it turn out that you were
35+
wrong).
36+
37+
Assertions are documentation that can't go out of date. Good assertions are
38+
wonderful.
39+
40+
Good assertions drastically and dramatically reduce the amount of testing
41+
required to shake out bugs.
42+
43+
Good assertions are based on state, not logic. To write good assertions, you
44+
have to think about what the invariants on your state are.
45+
46+
Good invariants and assertions will hold everywhere in your codebase. This
47+
means that you can run them in only a few places in the checked in version, but
48+
should you need to debug something that caused the assertion to fail, you can
49+
quickly shotgun them everywhere to find the codepath that broke the invariant.
50+
51+
A good assertion checks something that the compiler could check for us, and
52+
elide - if we were working in a language with embedded correctness proofs that
53+
the compiler could check. This is something that exists today, but it'll likely
54+
still be a few decades before it comes to systems programming languages. But we
55+
can still incorporate that kind of thinking into our code and document the
56+
invariants with runtime checks - much like the way people working in
57+
dynamically typed languages may add type annotations, gradually making their
58+
code statically typed.
59+
60+
Looking for ways to make your assertions simpler - and higher level - will
61+
often nudge you towards making the entire system simpler and more robust.
62+
63+
Good code is code where you can poke around and see what it's doing -
64+
introspection. We can't debug anything if we can't see what's going on.
65+
66+
Whenever we're debugging, and the solution isn't immediately obvious, if the
67+
issue is that we don't know where the issue is because we can't see what's
68+
going on - fix that first.
69+
70+
We have the tools to make anything visible at runtime, efficiently - RCU and
71+
percpu data structures among them. Don't let things stay hidden.
72+
73+
The most important tool for introspection is the humble pretty printer - in
74+
bcachefs, this means `*_to_text()` functions, which output to printbufs.
75+
76+
Pretty printers are wonderful, because they compose and you can use them
77+
everywhere. Having functions to print whatever object you're working with will
78+
make your error messages much easier to write (therefore they will actually
79+
exist) and much more informative. And they can be used from sysfs/debugfs, as
80+
well as tracepoints.
81+
82+
Runtime info and debugging tools should come with clear descriptions and
83+
labels, and good structure - we don't want files with a list of bare integers,
84+
like in procfs. Part of the job of the debugging tools is to educate users and
85+
new developers as to how the system works.
86+
87+
Error messages should, whenever possible, tell you everything you need to debug
88+
the issue. It's worth putting effort into them.
89+
90+
Tracepoints shouldn't be the first thing you reach for. They're an important
91+
tool, but always look for more immediate ways to make things visible. When we
92+
have to rely on tracing, we have to know which tracepoints we're looking for,
93+
and then we have to run the troublesome workload, and then we have to sift
94+
through logs. This is a lot of steps to go through when a user is hitting
95+
something, and if it's intermittent it may not even be possible.
96+
97+
The humble counter is an incredibly useful tool. They're cheap and simple to
98+
use, and many complicated internal operations with lots of things that can
99+
behave weirdly (anything involving memory reclaim, for example) become
100+
shockingly easy to debug once you have counters on every distinct codepath.
101+
102+
Persistent counters are even better.
103+
104+
When debugging, try to get the most out of every bug you come across; don't
105+
rush to fix the initial issue. Look for things that will make related bugs
106+
easier the next time around - introspection, new assertions, better error
107+
messages, new debug tools, and do those first. Look for ways to make the system
108+
better behaved; often one bug will uncover several other bugs through
109+
downstream effects.
110+
111+
Fix all that first, and then the original bug last - even if that means keeping
112+
a user waiting. They'll thank you in the long run, and when they understand
113+
what you're doing you'll be amazed at how patient they're happy to be. Users
114+
like to help - otherwise they wouldn't be reporting the bug in the first place.
115+
116+
Talk to your users. Don't isolate yourself.
117+
118+
Users notice all sorts of interesting things, and by just talking to them and
119+
interacting with them you can benefit from their experience.
120+
121+
Spend time doing support and helpdesk stuff. Don't just write code - code isn't
122+
finished until it's being used trouble free.
123+
124+
This will also motivate you to make your debugging tools as good as possible,
125+
and perhaps even your documentation, too. Like anything else in life, the more
126+
time you spend at it the better you'll get, and you the developer are the
127+
person most able to improve the tools to make debugging quick and easy.
128+
129+
Be wary of how you take on and commit to big projects. Don't let development
130+
become product-manager focused. Often time an idea is a good one but needs to
131+
wait for its proper time - but you won't know if it's the proper time for an
132+
idea until you start writing code.
133+
134+
Expect to throw a lot of things away, or leave them half finished for later.
135+
Nobody writes all perfect code that all gets shipped, and you'll be much more
136+
productive in the long run if you notice this early and shift to something
137+
else. The experience gained and lessons learned will be valuable for all the
138+
other work you do.
139+
140+
But don't be afraid to tackle projects that require significant rework of
141+
existing code. Sometimes these can be the best projects, because they can lead
142+
us to make existing code more general, more flexible, more multipurpose and
143+
perhaps more robust. Just don't hesitate to abandon the idea if it looks like
144+
it's going to make a mess of things.
145+
146+
Complicated features can often be done as a series of refactorings, with the
147+
final change that actually implements the feature as a quite small patch at the
148+
end. It's wonderful when this happens, especially when those refactorings are
149+
things that improve the codebase in their own right. When that happens there's
150+
much less risk of wasted effort if the feature you were going for doesn't work
151+
out.
152+
153+
Always strive to work incrementally. Always strive to turn the big projects
154+
into little bite sized projects that can prove their own merits.
155+
156+
Instead of always tackling those big projects, look for little things that
157+
will be useful, and make the big projects easier.
158+
159+
The question of what's likely to be useful is where junior developers most
160+
often go astray - doing something because it seems like it'll be useful often
161+
leads to overengineering. Knowing what's useful comes from many years of
162+
experience, or talking with people who have that experience - or from simply
163+
reading lots of code and looking for common patterns and issues. Don't be
164+
afraid to throw things away and do something simpler.
165+
166+
Talk about your ideas with your fellow developers; often times the best things
167+
come from relaxed conversations where people aren't afraid to say "what if?".
168+
169+
Don't neglect your tools.
170+
171+
The most important tools (besides the compiler and our text editor) are the
172+
tools we use for testing. The shortest possible edit/test/debug cycle is
173+
essential for working productively. We learn, gain experience, and discover the
174+
errors in our thinking by running our code and seeing what happens. If your
175+
time is being wasted because your tools are bad or too slow - don't accept it,
176+
fix it.
177+
178+
Put effort into your documentation, commmit messages, and code comments - but
179+
don't go overboard. A good commit message is wonderful - but if the information
180+
was important enough to go in a commit message, ask yourself if it would be
181+
even better as a code comment.
182+
183+
A good code comment is wonderful, but even better is the comment that didn't
184+
need to exist because the code was so straightforward as to be obvious;
185+
organized into small clean and tidy modules, with clear and descriptive names
186+
for functions and variable, where every line of code has a clear purpose.

Documentation/filesystems/bcachefs/index.rst

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

11+
CodingStyle
1112
errorcodes

fs/bcachefs/acl.c

Lines changed: 13 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -282,18 +282,12 @@ struct posix_acl *bch2_get_acl(struct mnt_idmap *idmap,
282282
struct btree_trans *trans = bch2_trans_get(c);
283283
struct btree_iter iter = { NULL };
284284
struct posix_acl *acl = NULL;
285-
struct bkey_s_c k;
286-
int ret;
287285
retry:
288286
bch2_trans_begin(trans);
289287

290-
ret = bch2_hash_lookup(trans, &iter, bch2_xattr_hash_desc,
291-
&hash, inode_inum(inode), &search, 0);
292-
if (ret)
293-
goto err;
294-
295-
k = bch2_btree_iter_peek_slot(&iter);
296-
ret = bkey_err(k);
288+
struct bkey_s_c k = bch2_hash_lookup(trans, &iter, bch2_xattr_hash_desc,
289+
&hash, inode_inum(inode), &search, 0);
290+
int ret = bkey_err(k);
297291
if (ret)
298292
goto err;
299293

@@ -366,7 +360,7 @@ int bch2_set_acl(struct mnt_idmap *idmap,
366360

367361
ret = bch2_subvol_is_ro_trans(trans, inode->ei_subvol) ?:
368362
bch2_inode_peek(trans, &inode_iter, &inode_u, inode_inum(inode),
369-
BTREE_ITER_INTENT);
363+
BTREE_ITER_intent);
370364
if (ret)
371365
goto btree_err;
372366

@@ -414,39 +408,30 @@ int bch2_acl_chmod(struct btree_trans *trans, subvol_inum inum,
414408
struct bch_hash_info hash_info = bch2_hash_info_init(trans->c, inode);
415409
struct xattr_search_key search = X_SEARCH(KEY_TYPE_XATTR_INDEX_POSIX_ACL_ACCESS, "", 0);
416410
struct btree_iter iter;
417-
struct bkey_s_c_xattr xattr;
418-
struct bkey_i_xattr *new;
419411
struct posix_acl *acl = NULL;
420-
struct bkey_s_c k;
421-
int ret;
422412

423-
ret = bch2_hash_lookup(trans, &iter, bch2_xattr_hash_desc,
424-
&hash_info, inum, &search, BTREE_ITER_INTENT);
413+
struct bkey_s_c k = bch2_hash_lookup(trans, &iter, bch2_xattr_hash_desc,
414+
&hash_info, inum, &search, BTREE_ITER_intent);
415+
int ret = bkey_err(k);
425416
if (ret)
426417
return bch2_err_matches(ret, ENOENT) ? 0 : ret;
427418

428-
k = bch2_btree_iter_peek_slot(&iter);
429-
ret = bkey_err(k);
430-
if (ret)
431-
goto err;
432-
xattr = bkey_s_c_to_xattr(k);
419+
struct bkey_s_c_xattr xattr = bkey_s_c_to_xattr(k);
433420

434421
acl = bch2_acl_from_disk(trans, xattr_val(xattr.v),
435422
le16_to_cpu(xattr.v->x_val_len));
436423
ret = PTR_ERR_OR_ZERO(acl);
437-
if (IS_ERR_OR_NULL(acl))
424+
if (ret)
438425
goto err;
439426

440-
ret = allocate_dropping_locks_errcode(trans,
441-
__posix_acl_chmod(&acl, _gfp, mode));
427+
ret = allocate_dropping_locks_errcode(trans, __posix_acl_chmod(&acl, _gfp, mode));
442428
if (ret)
443429
goto err;
444430

445-
new = bch2_acl_to_xattr(trans, acl, ACL_TYPE_ACCESS);
446-
if (IS_ERR(new)) {
447-
ret = PTR_ERR(new);
431+
struct bkey_i_xattr *new = bch2_acl_to_xattr(trans, acl, ACL_TYPE_ACCESS);
432+
ret = PTR_ERR_OR_ZERO(new);
433+
if (ret)
448434
goto err;
449-
}
450435

451436
new->k.p = iter.pos;
452437
ret = bch2_trans_update(trans, &iter, &new->k_i, 0);

0 commit comments

Comments
 (0)