Re: [PATCH 07/14] iomap: Support THPs in readpage

Matthew Wilcox
2020-10-14T17:35:03Z

On Wed, Oct 14, 2020 at 09:39:36AM -0700, Darrick J. Wong wrote:
> On Wed, Oct 14, 2020 at 04:03:50AM +0100, Matthew Wilcox (Oracle) wrote:
> > +/*
> > + * The page that was passed in has become Uptodate. This may be due to
> > + * the storage being synchronous or due to a page split finding the page
> > + * is actually uptodate. The page is still locked.
> > + * Lift this into the VFS at some point.
> > + */
> > +#define AOP_UPDATED_PAGE (AOP_TRUNCATED_PAGE + 1)
>
> Er... why not lift it now?
>
> "Because touching fs.h causes the whole kernel to be rebuilt and that's
> annoying"? :D

Hah! Because I already have a patch series out that does lift it to
the VFS:

https://lore.kernel.org/linux-fsdevel/20201009143104.22673-1-willy@infradead.org/

which I'm kind of hoping gets merged first. Then I can adjust this patch.

> > +static int iomap_split_page(struct inode *inode, struct page *page)
> > +{
> > + struct page *head = thp_head(page);
> > + bool uptodate = iomap_range_uptodate(inode, head,
> > + (page - head) * PAGE_SIZE, PAGE_SIZE);
> > +
> > + iomap_page_release(head);
> > + if (split_huge_page(page) < 0) {
> > + unlock_page(page);
> > + return AOP_TRUNCATED_PAGE;
> > + }
> > + if (!uptodate)
> > + return 0;
> > + SetPageUptodate(page);
> > + return AOP_UPDATED_PAGE;
> > +}
> > +
> > int
> > iomap_readpage(struct page *page, const struct iomap_ops *ops)
> > {
> > struct iomap_readpage_ctx ctx = { .cur_page = page };
> > - struct inode *inode = page->mapping->host;
> > + struct inode *inode = thp_head(page)->mapping->host;
> > unsigned poff;
> > loff_t ret;
> >
> > - trace_iomap_readpage(page->mapping->host, 1);
> > + trace_iomap_readpage(inode, 1);
> > +
> > + if (PageTransCompound(page)) {
> > + int status = iomap_split_page(inode, page);
> > + if (status == AOP_UPDATED_PAGE) {
> > + unlock_page(page);
>
> /me wonders why not do the unlock in iomap_split_page?

This is working around AOP_UPDATED_PAGE not existing in the VFS. So
adjusting this patch becomes:

int status = iomap_split_page(inode, page);
if (status)
return status;