If the filesystem has block size < page size and we end up calling iomap_page_create() in iomap_page_mkwrite_actor(), the uptodate bits would be zero, which causes us to skip writeback of blocks which are !uptodate in iomap_writepage_map(). This can lead to user data loss. Found using generic/127 with the THP patches. I don't think this can be reproduced on mainline using that test (the THP code causes iomap_pages to be discarded more frequently), but inspection shows it can happen with an appropriate series of operations. Fixes: 9dc55f1389f9 ("iomap: add support for sub-pagesize buffered I/O without buffer heads") Signed-off-by: Matthew Wilcox (Oracle) <willy@xxxxxxxxxxxxx> --- fs/iomap/buffered-io.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c index a2b3b5455219..f0c5027bf33f 100644 --- a/fs/iomap/buffered-io.c +++ b/fs/iomap/buffered-io.c @@ -53,7 +53,10 @@ iomap_page_create(struct inode *inode, struct page *page) atomic_set(&iop->read_count, 0); atomic_set(&iop->write_count, 0); spin_lock_init(&iop->uptodate_lock); - bitmap_zero(iop->uptodate, PAGE_SIZE / SECTOR_SIZE); + if (PageUptodate(page)) + bitmap_fill(iop->uptodate, PAGE_SIZE / SECTOR_SIZE); + else + bitmap_zero(iop->uptodate, PAGE_SIZE / SECTOR_SIZE); /* * migrate_page_move_mapping() assumes that pages with private data have @@ -72,6 +75,8 @@ iomap_page_release(struct page *page) return; WARN_ON_ONCE(atomic_read(&iop->read_count)); WARN_ON_ONCE(atomic_read(&iop->write_count)); + WARN_ON_ONCE(bitmap_full(iop->uptodate, PAGE_SIZE / SECTOR_SIZE) != + PageUptodate(page)); kfree(iop); } -- 2.27.0