summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2019-10-25 18:54:58 -0400
committerKent Overstreet <kent.overstreet@gmail.com>2019-10-25 18:57:12 -0400
commit54fe05c8243a99e16af2bff75ec157b7204e9010 (patch)
tree2e06c948a4e6f71c7c4e01470f98df12f76d0c05
parent66925f93919ae7b419926dba33afdca7fad3408b (diff)
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@gmail.com>
-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 fea469a4f0b8..6098ed7d8f96 100644
--- a/fs/bcachefs/fs-io.c
+++ b/fs/bcachefs/fs-io.c
@@ -483,7 +483,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;