On Thu, Jul 30, 2020 at 09:19:01AM +0800, Yu Kuai wrote: > +++ b/fs/iomap/buffered-io.c > @@ -29,7 +29,9 @@ struct iomap_page { > atomic_t read_count; > atomic_t write_count; > spinlock_t uptodate_lock; > + spinlock_t dirty_lock; No need for a separate spinlock. Just rename uptodate_lock. Maybe 'bitmap_lock'. > DECLARE_BITMAP(uptodate, PAGE_SIZE / 512); > + DECLARE_BITMAP(dirty, PAGE_SIZE / 512); This is inefficient and poses difficulties for the THP patchset. Maybe let the discussion on removing the ->uptodate array finish before posting another patch for review? > +static void > +iomap_iop_set_or_clear_range_dirty( > + struct page *page, > + unsigned int off, > + unsigned int len, > + bool is_set) Please follow normal kernel programming style. This isn't XFS. Also 'set or clear' with a bool to indicate which to do is horrible style. Separate functions! > @@ -1386,7 +1432,8 @@ iomap_writepage_map(struct iomap_writepage_ctx *wpc, > for (i = 0, file_offset = page_offset(page); > i < (PAGE_SIZE >> inode->i_blkbits) && file_offset < end_offset; > i++, file_offset += len) { > - if (iop && !test_bit(i, iop->uptodate)) > + if (iop && (!test_bit(i, iop->uptodate) || > + !test_bit(i, iop->dirty))) > continue; Surely we don't need to test ->uptodate here at all. Why would we write back a block which isn't dirty?