summaryrefslogtreecommitdiff
path: root/fs/bcachefs/fs-io.c
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2019-10-25 18:54:58 -0400
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-22 17:08:30 -0400
commit406d6d5a0733f3eacbcd4c33905bf63c5b2f4c07 (patch)
treead46d529c76693d301194f7d4c3f1e3dc6475c37 /fs/bcachefs/fs-io.c
parent92384391c8d04642bb2be1e0c34f744675f50abc (diff)
downloadlwn-406d6d5a0733f3eacbcd4c33905bf63c5b2f4c07.tar.gz
lwn-406d6d5a0733f3eacbcd4c33905bf63c5b2f4c07.zip
bcachefs: Fix an error path race
On IO error, bch2_writepages_io_done() will set the page state to indicate nothing's already reserved (since the write didn't happen, we don't know what's already reserved). This can race with the buffered IO path, in between getting a disk reservation and calling bch2_set_page_dirty(). Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs/bcachefs/fs-io.c')
-rw-r--r--fs/bcachefs/fs-io.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/fs/bcachefs/fs-io.c b/fs/bcachefs/fs-io.c
index c539ed3aa48d..93f6cdbbf7c7 100644
--- a/fs/bcachefs/fs-io.c
+++ b/fs/bcachefs/fs-io.c
@@ -491,7 +491,12 @@ static void bch2_set_page_dirty(struct bch_fs *c,
unsigned sectors = sectors_to_reserve(&s->s[i],
res->disk.nr_replicas);
- BUG_ON(sectors > res->disk.sectors);
+ /*
+ * This can happen if we race with the error path in
+ * bch2_writepage_io_done():
+ */
+ sectors = min_t(unsigned, sectors, res->disk.sectors);
+
s->s[i].replicas_reserved += sectors;
res->disk.sectors -= sectors;