9p: Convert to using the netfs helper lib to do reads and caching

Convert the 9p filesystem to use the netfs helper lib to handle readpage,
readahead and write_begin, converting those into a common issue_op for the
filesystem itself to handle.  The netfs helper lib also handles reading
from fscache if a cache is available, and interleaving reads from both
sources.

This change also switches from the old fscache I/O API to the new one,
meaning that fscache no longer keeps track of netfs pages and instead does
async DIO between the backing files and the 9p file pagecache.  As a part
of this change, the handling of PG_fscache changes.  It now just means that
the cache has a write I/O operation in progress on a page (PG_locked
is used for a read I/O op).

Note that this is a cut-down version of the fscache rewrite and does not
change any of the cookie and cache coherency handling.

Changes
=======
ver #4:
  - Rebase on top of folios.
  - Don't use wait_on_page_bit_killable().

ver #3:
  - v9fs_req_issue_op() needs to terminate the subrequest.
  - v9fs_write_end() needs to call SetPageUptodate() a bit more often.
  - It's not CONFIG_{AFS,V9FS}_FSCACHE[1]
  - v9fs_init_rreq() should take a ref on the p9_fid and the cleanup should
    drop it [from Dominique Martinet].

Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-and-tested-by: Dominique Martinet <asmadeus@codewreck.org>
cc: v9fs-developer@lists.sourceforge.net
cc: linux-cachefs@redhat.com
Link: https://lore.kernel.org/r/YUm+xucHxED+1MJp@codewreck.org/ [1]
Link: https://lore.kernel.org/r/163162772646.438332.16323773205855053535.stgit@warthog.procyon.org.uk/ # rfc
Link: https://lore.kernel.org/r/163189109885.2509237.7153668924503399173.stgit@warthog.procyon.org.uk/ # rfc v2
Link: https://lore.kernel.org/r/163363943896.1980952.1226527304649419689.stgit@warthog.procyon.org.uk/ # v3
Link: https://lore.kernel.org/r/163551662876.1877519.14706391695553204156.stgit@warthog.procyon.org.uk/ # v4
Link: https://lore.kernel.org/r/163584179557.4023316.11089762304657644342.stgit@warthog.procyon.org.uk # rebase on folio
Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
This commit is contained in:
David Howells
2021-11-02 08:29:55 +00:00
committed by Dominique Martinet
parent 0dc54bd4d6
commit eb497943fa
6 changed files with 128 additions and 340 deletions

View File

@@ -199,140 +199,3 @@ void v9fs_cache_inode_reset_cookie(struct inode *inode)
mutex_unlock(&v9inode->fscache_lock);
}
int __v9fs_fscache_release_page(struct page *page, gfp_t gfp)
{
struct inode *inode = page->mapping->host;
struct v9fs_inode *v9inode = V9FS_I(inode);
BUG_ON(!v9inode->fscache);
return fscache_maybe_release_page(v9inode->fscache, page, gfp);
}
void __v9fs_fscache_invalidate_page(struct page *page)
{
struct inode *inode = page->mapping->host;
struct v9fs_inode *v9inode = V9FS_I(inode);
BUG_ON(!v9inode->fscache);
if (PageFsCache(page)) {
fscache_wait_on_page_write(v9inode->fscache, page);
BUG_ON(!PageLocked(page));
fscache_uncache_page(v9inode->fscache, page);
}
}
static void v9fs_vfs_readpage_complete(struct page *page, void *data,
int error)
{
if (!error)
SetPageUptodate(page);
unlock_page(page);
}
/*
* __v9fs_readpage_from_fscache - read a page from cache
*
* Returns 0 if the pages are in cache and a BIO is submitted,
* 1 if the pages are not in cache and -error otherwise.
*/
int __v9fs_readpage_from_fscache(struct inode *inode, struct page *page)
{
int ret;
const struct v9fs_inode *v9inode = V9FS_I(inode);
p9_debug(P9_DEBUG_FSC, "inode %p page %p\n", inode, page);
if (!v9inode->fscache)
return -ENOBUFS;
ret = fscache_read_or_alloc_page(v9inode->fscache,
page,
v9fs_vfs_readpage_complete,
NULL,
GFP_KERNEL);
switch (ret) {
case -ENOBUFS:
case -ENODATA:
p9_debug(P9_DEBUG_FSC, "page/inode not in cache %d\n", ret);
return 1;
case 0:
p9_debug(P9_DEBUG_FSC, "BIO submitted\n");
return ret;
default:
p9_debug(P9_DEBUG_FSC, "ret %d\n", ret);
return ret;
}
}
/*
* __v9fs_readpages_from_fscache - read multiple pages from cache
*
* Returns 0 if the pages are in cache and a BIO is submitted,
* 1 if the pages are not in cache and -error otherwise.
*/
int __v9fs_readpages_from_fscache(struct inode *inode,
struct address_space *mapping,
struct list_head *pages,
unsigned *nr_pages)
{
int ret;
const struct v9fs_inode *v9inode = V9FS_I(inode);
p9_debug(P9_DEBUG_FSC, "inode %p pages %u\n", inode, *nr_pages);
if (!v9inode->fscache)
return -ENOBUFS;
ret = fscache_read_or_alloc_pages(v9inode->fscache,
mapping, pages, nr_pages,
v9fs_vfs_readpage_complete,
NULL,
mapping_gfp_mask(mapping));
switch (ret) {
case -ENOBUFS:
case -ENODATA:
p9_debug(P9_DEBUG_FSC, "pages/inodes not in cache %d\n", ret);
return 1;
case 0:
BUG_ON(!list_empty(pages));
BUG_ON(*nr_pages != 0);
p9_debug(P9_DEBUG_FSC, "BIO submitted\n");
return ret;
default:
p9_debug(P9_DEBUG_FSC, "ret %d\n", ret);
return ret;
}
}
/*
* __v9fs_readpage_to_fscache - write a page to the cache
*
*/
void __v9fs_readpage_to_fscache(struct inode *inode, struct page *page)
{
int ret;
const struct v9fs_inode *v9inode = V9FS_I(inode);
p9_debug(P9_DEBUG_FSC, "inode %p page %p\n", inode, page);
ret = fscache_write_page(v9inode->fscache, page,
i_size_read(&v9inode->vfs_inode), GFP_KERNEL);
p9_debug(P9_DEBUG_FSC, "ret = %d\n", ret);
if (ret != 0)
v9fs_uncache_page(inode, page);
}
/*
* wait for a page to complete writing to the cache
*/
void __v9fs_fscache_wait_on_page_write(struct inode *inode, struct page *page)
{
const struct v9fs_inode *v9inode = V9FS_I(inode);
p9_debug(P9_DEBUG_FSC, "inode %p page %p\n", inode, page);
if (PageFsCache(page))
fscache_wait_on_page_write(v9inode->fscache, page);
}