diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2021-06-10 23:33:27 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2021-06-13 16:06:11 -0400 |
commit | 936a6444d62856003f17e8ea857e2817d4582ae0 (patch) | |
tree | 23535220aa2f23939e02197efa93af720a5c7d2c | |
parent | 9e9ad82b7c6a48b73d43901add294efe385c3c8d (diff) |
bcachefs: Don't underflow c->sectors_available
This rarely used error path should've been checking for underflow -
oops.
Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
-rw-r--r-- | fs/bcachefs/buckets.c | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/fs/bcachefs/buckets.c b/fs/bcachefs/buckets.c index 6d5fe398007a..84f280b8525c 100644 --- a/fs/bcachefs/buckets.c +++ b/fs/bcachefs/buckets.c @@ -1433,7 +1433,14 @@ void bch2_trans_fs_usage_apply(struct btree_trans *trans, */ should_not_have_added = added - (s64) disk_res_sectors; if (unlikely(should_not_have_added > 0)) { - atomic64_sub(should_not_have_added, &c->sectors_available); + u64 old, new, v = atomic64_read(&c->sectors_available); + + do { + old = v; + new = max_t(s64, 0, old - should_not_have_added); + } while ((v = atomic64_cmpxchg(&c->sectors_available, + old, new)) != old); + added -= should_not_have_added; warn = true; } |