Message ID | 20210715033704.692967-107-willy@infradead.org (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | Memory folios | expand |
On Thu, Jul 15, 2021 at 04:36:32AM +0100, Matthew Wilcox (Oracle) wrote: > Writeback an entire folio at a time, and adjust some of the variables > to have more familiar names. > > Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org> > --- > fs/iomap/buffered-io.c | 49 +++++++++++++++++++----------------------- > 1 file changed, 22 insertions(+), 27 deletions(-) > > diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c > index 8e767aec8d07..0731e2c3f44b 100644 > --- a/fs/iomap/buffered-io.c > +++ b/fs/iomap/buffered-io.c > @@ -1296,9 +1296,8 @@ iomap_add_to_ioend(struct inode *inode, loff_t pos, struct folio *folio, > static int > iomap_writepage_map(struct iomap_writepage_ctx *wpc, > struct writeback_control *wbc, struct inode *inode, > - struct page *page, u64 end_offset) > + struct folio *folio, loff_t end_pos) > { > - struct folio *folio = page_folio(page); > struct iomap_page *iop = to_iomap_page(folio); > struct iomap_ioend *ioend, *next; > unsigned len = i_blocksize(inode); > @@ -1316,7 +1315,7 @@ iomap_writepage_map(struct iomap_writepage_ctx *wpc, > * invalid, grab a new one. > */ > for (i = 0; i < nblocks; i++, pos += len) { > - if (pos >= end_offset) > + if (pos >= end_pos) > break; > if (iop && !test_bit(i, iop->uptodate)) > continue; > @@ -1398,16 +1397,15 @@ iomap_writepage_map(struct iomap_writepage_ctx *wpc, > static int > iomap_do_writepage(struct page *page, struct writeback_control *wbc, void *data) I imagine at some point this will become iomap_do_writefolio and ther will be some sort of write_cache_folios() call? Or the equivalent while(get_next_folio_to_wrote()) iomap_write_folio(); type loop? Reviewed-by: Darrick J. Wong <djwong@kernel.org> --D > { > + struct folio *folio = page_folio(page); > struct iomap_writepage_ctx *wpc = data; > - struct inode *inode = page->mapping->host; > - pgoff_t end_index; > - u64 end_offset; > - loff_t offset; > + struct inode *inode = folio->mapping->host; > + loff_t end_pos, isize; > > - trace_iomap_writepage(inode, page_offset(page), PAGE_SIZE); > + trace_iomap_writepage(inode, folio_pos(folio), folio_size(folio)); > > /* > - * Refuse to write the page out if we are called from reclaim context. > + * Refuse to write the folio out if we are called from reclaim context. > * > * This avoids stack overflows when called from deeply used stacks in > * random callers for direct reclaim or memcg reclaim. We explicitly > @@ -1421,10 +1419,10 @@ iomap_do_writepage(struct page *page, struct writeback_control *wbc, void *data) > goto redirty; > > /* > - * Is this page beyond the end of the file? > + * Is this folio beyond the end of the file? > * > - * The page index is less than the end_index, adjust the end_offset > - * to the highest offset that this page should represent. > + * The folio index is less than the end_index, adjust the end_pos > + * to the highest offset that this folio should represent. > * ----------------------------------------------------- > * | file mapping | <EOF> | > * ----------------------------------------------------- > @@ -1433,11 +1431,9 @@ iomap_do_writepage(struct page *page, struct writeback_control *wbc, void *data) > * | desired writeback range | see else | > * ---------------------------------^------------------| > */ > - offset = i_size_read(inode); > - end_index = offset >> PAGE_SHIFT; > - if (page->index < end_index) > - end_offset = (loff_t)(page->index + 1) << PAGE_SHIFT; > - else { > + isize = i_size_read(inode); > + end_pos = folio_pos(folio) + folio_size(folio); > + if (end_pos - 1 >= isize) { > /* > * Check whether the page to write out is beyond or straddles > * i_size or not. > @@ -1449,7 +1445,8 @@ iomap_do_writepage(struct page *page, struct writeback_control *wbc, void *data) > * | | Straddles | > * ---------------------------------^-----------|--------| > */ > - unsigned offset_into_page = offset & (PAGE_SIZE - 1); > + size_t poff = offset_in_folio(folio, isize); > + pgoff_t end_index = isize >> PAGE_SHIFT; > > /* > * Skip the page if it is fully outside i_size, e.g. due to a > @@ -1468,8 +1465,8 @@ iomap_do_writepage(struct page *page, struct writeback_control *wbc, void *data) > * if the page to write is totally beyond the i_size or if it's > * offset is just equal to the EOF. > */ > - if (page->index > end_index || > - (page->index == end_index && offset_into_page == 0)) > + if (folio->index > end_index || > + (folio->index == end_index && poff == 0)) > goto redirty; > > /* > @@ -1480,17 +1477,15 @@ iomap_do_writepage(struct page *page, struct writeback_control *wbc, void *data) > * memory is zeroed when mapped, and writes to that region are > * not written out to the file." > */ > - zero_user_segment(page, offset_into_page, PAGE_SIZE); > - > - /* Adjust the end_offset to the end of file */ > - end_offset = offset; > + zero_user_segment(&folio->page, poff, folio_size(folio)); > + end_pos = isize; > } > > - return iomap_writepage_map(wpc, wbc, inode, page, end_offset); > + return iomap_writepage_map(wpc, wbc, inode, folio, end_pos); > > redirty: > - redirty_page_for_writepage(wbc, page); > - unlock_page(page); > + folio_redirty_for_writepage(wbc, folio); > + folio_unlock(folio); > return 0; > } > > -- > 2.30.2 >
On Thu, Jul 15, 2021 at 03:05:05PM -0700, Darrick J. Wong wrote: > On Thu, Jul 15, 2021 at 04:36:32AM +0100, Matthew Wilcox (Oracle) wrote: > > Writeback an entire folio at a time, and adjust some of the variables > > to have more familiar names. > > @@ -1398,16 +1397,15 @@ iomap_writepage_map(struct iomap_writepage_ctx *wpc, > > static int > > iomap_do_writepage(struct page *page, struct writeback_control *wbc, void *data) > > I imagine at some point this will become iomap_do_writefolio and ther > will be some sort of write_cache_folios() call? Or the equivalent > while(get_next_folio_to_wrote()) iomap_write_folio(); type loop? I hadn't quite got as far as planning out what to do next with a replacement for write_cache_pages(). At a minimum, that function is going to work on folios -- it does anyway; we don't tag tail pages in the xarray, so the tagged lookup done by write_cache_pages() only finds folios. So everything we do with a page there is definitely looking at a folio. I want to get a lot more filesystems converted to use folios before I undertake the write_cache_pages() interface overhaul (and I'll probably think of several things to do to it at the same time -- like working on a batch of pages all at once instead of calling one indirect function per folio).
diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c index 8e767aec8d07..0731e2c3f44b 100644 --- a/fs/iomap/buffered-io.c +++ b/fs/iomap/buffered-io.c @@ -1296,9 +1296,8 @@ iomap_add_to_ioend(struct inode *inode, loff_t pos, struct folio *folio, static int iomap_writepage_map(struct iomap_writepage_ctx *wpc, struct writeback_control *wbc, struct inode *inode, - struct page *page, u64 end_offset) + struct folio *folio, loff_t end_pos) { - struct folio *folio = page_folio(page); struct iomap_page *iop = to_iomap_page(folio); struct iomap_ioend *ioend, *next; unsigned len = i_blocksize(inode); @@ -1316,7 +1315,7 @@ iomap_writepage_map(struct iomap_writepage_ctx *wpc, * invalid, grab a new one. */ for (i = 0; i < nblocks; i++, pos += len) { - if (pos >= end_offset) + if (pos >= end_pos) break; if (iop && !test_bit(i, iop->uptodate)) continue; @@ -1398,16 +1397,15 @@ iomap_writepage_map(struct iomap_writepage_ctx *wpc, static int iomap_do_writepage(struct page *page, struct writeback_control *wbc, void *data) { + struct folio *folio = page_folio(page); struct iomap_writepage_ctx *wpc = data; - struct inode *inode = page->mapping->host; - pgoff_t end_index; - u64 end_offset; - loff_t offset; + struct inode *inode = folio->mapping->host; + loff_t end_pos, isize; - trace_iomap_writepage(inode, page_offset(page), PAGE_SIZE); + trace_iomap_writepage(inode, folio_pos(folio), folio_size(folio)); /* - * Refuse to write the page out if we are called from reclaim context. + * Refuse to write the folio out if we are called from reclaim context. * * This avoids stack overflows when called from deeply used stacks in * random callers for direct reclaim or memcg reclaim. We explicitly @@ -1421,10 +1419,10 @@ iomap_do_writepage(struct page *page, struct writeback_control *wbc, void *data) goto redirty; /* - * Is this page beyond the end of the file? + * Is this folio beyond the end of the file? * - * The page index is less than the end_index, adjust the end_offset - * to the highest offset that this page should represent. + * The folio index is less than the end_index, adjust the end_pos + * to the highest offset that this folio should represent. * ----------------------------------------------------- * | file mapping | <EOF> | * ----------------------------------------------------- @@ -1433,11 +1431,9 @@ iomap_do_writepage(struct page *page, struct writeback_control *wbc, void *data) * | desired writeback range | see else | * ---------------------------------^------------------| */ - offset = i_size_read(inode); - end_index = offset >> PAGE_SHIFT; - if (page->index < end_index) - end_offset = (loff_t)(page->index + 1) << PAGE_SHIFT; - else { + isize = i_size_read(inode); + end_pos = folio_pos(folio) + folio_size(folio); + if (end_pos - 1 >= isize) { /* * Check whether the page to write out is beyond or straddles * i_size or not. @@ -1449,7 +1445,8 @@ iomap_do_writepage(struct page *page, struct writeback_control *wbc, void *data) * | | Straddles | * ---------------------------------^-----------|--------| */ - unsigned offset_into_page = offset & (PAGE_SIZE - 1); + size_t poff = offset_in_folio(folio, isize); + pgoff_t end_index = isize >> PAGE_SHIFT; /* * Skip the page if it is fully outside i_size, e.g. due to a @@ -1468,8 +1465,8 @@ iomap_do_writepage(struct page *page, struct writeback_control *wbc, void *data) * if the page to write is totally beyond the i_size or if it's * offset is just equal to the EOF. */ - if (page->index > end_index || - (page->index == end_index && offset_into_page == 0)) + if (folio->index > end_index || + (folio->index == end_index && poff == 0)) goto redirty; /* @@ -1480,17 +1477,15 @@ iomap_do_writepage(struct page *page, struct writeback_control *wbc, void *data) * memory is zeroed when mapped, and writes to that region are * not written out to the file." */ - zero_user_segment(page, offset_into_page, PAGE_SIZE); - - /* Adjust the end_offset to the end of file */ - end_offset = offset; + zero_user_segment(&folio->page, poff, folio_size(folio)); + end_pos = isize; } - return iomap_writepage_map(wpc, wbc, inode, page, end_offset); + return iomap_writepage_map(wpc, wbc, inode, folio, end_pos); redirty: - redirty_page_for_writepage(wbc, page); - unlock_page(page); + folio_redirty_for_writepage(wbc, folio); + folio_unlock(folio); return 0; }
Writeback an entire folio at a time, and adjust some of the variables to have more familiar names. Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org> --- fs/iomap/buffered-io.c | 49 +++++++++++++++++++----------------------- 1 file changed, 22 insertions(+), 27 deletions(-)