Add a function to begin an cache read or write operation from a netfslib I/O request. This function can then be pointed to directly by the network filesystem's netfs_request_ops::begin_cache_operation op pointer. Ideally, netfslib would just call into fscache directly, but that would cause dependency cycles as fscache calls into netfslib directly. Signed-off-by: David Howells <dhowells@xxxxxxxxxx> cc: Jeff Layton <jlayton@xxxxxxxxxx> cc: linux-cachefs@xxxxxxxxxx cc: linux-fsdevel@xxxxxxxxxxxxxxx cc: linux-mm@xxxxxxxxx --- fs/9p/vfs_addr.c | 18 ++---------------- fs/afs/file.c | 14 +------------- fs/ceph/addr.c | 2 +- fs/ceph/cache.h | 12 ------------ fs/fscache/io.c | 42 +++++++++++++++++++++++++++++++++++++++++ include/linux/fscache.h | 6 ++++++ 6 files changed, 52 insertions(+), 42 deletions(-) diff --git a/fs/9p/vfs_addr.c b/fs/9p/vfs_addr.c index 18a666c43e4a..516572bad412 100644 --- a/fs/9p/vfs_addr.c +++ b/fs/9p/vfs_addr.c @@ -17,6 +17,7 @@ #include <linux/swap.h> #include <linux/uio.h> #include <linux/netfs.h> +#include <linux/fscache.h> #include <net/9p/9p.h> #include <net/9p/client.h> @@ -82,25 +83,10 @@ static void v9fs_free_request(struct netfs_io_request *rreq) p9_fid_put(fid); } -/** - * v9fs_begin_cache_operation - Begin a cache operation for a read - * @rreq: The read request - */ -static int v9fs_begin_cache_operation(struct netfs_io_request *rreq) -{ -#ifdef CONFIG_9P_FSCACHE - struct fscache_cookie *cookie = v9fs_inode_cookie(V9FS_I(rreq->inode)); - - return fscache_begin_read_operation(&rreq->cache_resources, cookie); -#else - return -ENOBUFS; -#endif -} - const struct netfs_request_ops v9fs_req_ops = { .init_request = v9fs_init_request, .free_request = v9fs_free_request, - .begin_cache_operation = v9fs_begin_cache_operation, + .begin_cache_operation = fscache_begin_cache_operation, .issue_read = v9fs_issue_read, }; diff --git a/fs/afs/file.c b/fs/afs/file.c index 3e39a2ebcad6..5bb78d874292 100644 --- a/fs/afs/file.c +++ b/fs/afs/file.c @@ -360,18 +360,6 @@ static int afs_init_request(struct netfs_io_request *rreq, struct file *file) return 0; } -static int afs_begin_cache_operation(struct netfs_io_request *rreq) -{ -#ifdef CONFIG_AFS_FSCACHE - struct afs_vnode *vnode = AFS_FS_I(rreq->inode); - - return fscache_begin_read_operation(&rreq->cache_resources, - afs_vnode_cache(vnode)); -#else - return -ENOBUFS; -#endif -} - static int afs_check_write_begin(struct file *file, loff_t pos, unsigned len, struct folio **foliop, void **_fsdata) { @@ -388,7 +376,7 @@ static void afs_free_request(struct netfs_io_request *rreq) const struct netfs_request_ops afs_req_ops = { .init_request = afs_init_request, .free_request = afs_free_request, - .begin_cache_operation = afs_begin_cache_operation, + .begin_cache_operation = fscache_begin_cache_operation, .check_write_begin = afs_check_write_begin, .issue_read = afs_issue_read, }; diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c index 92a5ddcd9a76..4841b06df78c 100644 --- a/fs/ceph/addr.c +++ b/fs/ceph/addr.c @@ -488,7 +488,7 @@ static void ceph_netfs_free_request(struct netfs_io_request *rreq) const struct netfs_request_ops ceph_netfs_ops = { .init_request = ceph_init_request, .free_request = ceph_netfs_free_request, - .begin_cache_operation = ceph_begin_cache_operation, + .begin_cache_operation = fscache_begin_cache_operation, .issue_read = ceph_netfs_issue_read, .expand_readahead = ceph_netfs_expand_readahead, .clamp_length = ceph_netfs_clamp_length, diff --git a/fs/ceph/cache.h b/fs/ceph/cache.h index dc502daac49a..b804f1094764 100644 --- a/fs/ceph/cache.h +++ b/fs/ceph/cache.h @@ -57,13 +57,6 @@ static inline int ceph_fscache_dirty_folio(struct address_space *mapping, return fscache_dirty_folio(mapping, folio, ceph_fscache_cookie(ci)); } -static inline int ceph_begin_cache_operation(struct netfs_io_request *rreq) -{ - struct fscache_cookie *cookie = ceph_fscache_cookie(ceph_inode(rreq->inode)); - - return fscache_begin_read_operation(&rreq->cache_resources, cookie); -} - static inline bool ceph_is_cache_enabled(struct inode *inode) { return fscache_cookie_enabled(ceph_fscache_cookie(ceph_inode(inode))); @@ -135,11 +128,6 @@ static inline bool ceph_is_cache_enabled(struct inode *inode) return false; } -static inline int ceph_begin_cache_operation(struct netfs_io_request *rreq) -{ - return -ENOBUFS; -} - static inline void ceph_fscache_note_page_release(struct inode *inode) { } diff --git a/fs/fscache/io.c b/fs/fscache/io.c index 0d2b8dec8f82..cb602dd651e6 100644 --- a/fs/fscache/io.c +++ b/fs/fscache/io.c @@ -158,6 +158,48 @@ int __fscache_begin_write_operation(struct netfs_cache_resources *cres, } EXPORT_SYMBOL(__fscache_begin_write_operation); +/** + * fscache_begin_cache_operation - Begin a cache op for netfslib + * @rreq: The netfs request that wants to access the cache. + * + * Begin an I/O operation on behalf of the netfs helper library, read or write. + * @rreq indicates the netfs operation that wishes to access the cache. + * + * This is intended to be pointed to directly by the ->begin_cache_operation() + * netfs lib operation for the network filesystem. + * + * @cres->inval_counter is set from @cookie->inval_counter for comparison at + * the end of the operation. This allows invalidation during the operation to + * be detected by the caller. + * + * Returns: + * * 0 - Success + * * -ENOBUFS - No caching available + * * Other error code from the cache, such as -ENOMEM. + */ +int fscache_begin_cache_operation(struct netfs_io_request *rreq) +{ + struct netfs_inode *ctx = netfs_inode(rreq->inode); + + switch (rreq->origin) { + case NETFS_READAHEAD: + case NETFS_READPAGE: + case NETFS_READ_FOR_WRITE: + return fscache_begin_operation(&rreq->cache_resources, + netfs_i_cookie(ctx), + FSCACHE_WANT_PARAMS, + fscache_access_io_read); + case NETFS_WRITEBACK: + return fscache_begin_operation(&rreq->cache_resources, + netfs_i_cookie(ctx), + FSCACHE_WANT_PARAMS, + fscache_access_io_write); + default: + return -ENOBUFS; + } +} +EXPORT_SYMBOL(fscache_begin_cache_operation); + /** * fscache_dirty_folio - Mark folio dirty and pin a cache object for writeback * @mapping: The mapping the folio belongs to. diff --git a/include/linux/fscache.h b/include/linux/fscache.h index 8e312c8323a8..9c389adaf286 100644 --- a/include/linux/fscache.h +++ b/include/linux/fscache.h @@ -177,6 +177,12 @@ extern void __fscache_write_to_cache(struct fscache_cookie *, struct address_spa bool); extern void __fscache_clear_page_bits(struct address_space *, loff_t, size_t); +#if __fscache_available +extern int fscache_begin_cache_operation(struct netfs_io_request *rreq); +#else +#define fscache_begin_cache_operation NULL +#endif + /** * fscache_acquire_volume - Register a volume as desiring caching services * @volume_key: An identification string for the volume