summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2016-05-03 05:54:08 -0800
committerKent Overstreet <kent.overstreet@gmail.com>2016-07-26 00:24:45 -0800
commit9bc2a1eb04a1e26fa6790e29c91584db63bcd29a (patch)
treee9f13eeed2accf3bb4306f7645728b1dd994ffe3
parentd6ab1221916b2957320c6197d307e337316b6ec5 (diff)
bcachefs: fix a writepage race
set_page_dirty() can happen again while a page is undergoing writeback, so we if we're doing a compressed write we need to mark pages as unallocated before unlocking
-rw-r--r--drivers/md/bcache/fs-io.c10
1 files changed, 4 insertions, 6 deletions
diff --git a/drivers/md/bcache/fs-io.c b/drivers/md/bcache/fs-io.c
index 36c45cccd1fe..ffe9c65a7005 100644
--- a/drivers/md/bcache/fs-io.c
+++ b/drivers/md/bcache/fs-io.c
@@ -799,11 +799,6 @@ static void bch_writepage_io_done(struct closure *cl)
struct bch_page_state old, new;
old = page_state_cmpxchg(page_state(page), new, {
- new.alloc_state =
- (io->op.op.compression_type ==
- BCH_COMPRESSION_NONE)
- ? BCH_PAGE_ALLOCATED
- : BCH_PAGE_UNALLOCATED;
new.sectors = PAGE_SECTORS;
new.dirty_sectors = 0;
});
@@ -935,7 +930,10 @@ do_io:
(new.sectors != PAGE_SECTORS ||
new.alloc_state != BCH_PAGE_ALLOCATED));
- if (!new.reserved)
+ if (new.alloc_state == BCH_PAGE_ALLOCATED &&
+ w->io->op.op.compression_type != BCH_COMPRESSION_NONE)
+ new.alloc_state = BCH_PAGE_UNALLOCATED;
+ else if (!new.reserved)
goto out;
new.reserved = 0;
});