History

netfs: Add a netfs inode context

Add a netfs_i_context struct that should be included in the network filesystem's own inode struct wrapper, directly after the VFS's inode struct, e.g.: struct my_inode { struct { /* These must be contiguous */ struct inode vfs_inode; struct netfs_i_context netfs_ctx; }; }; The netfs_i_context struct so far contains a single field for the network filesystem to use - the cache cookie: struct netfs_i_context { ... struct fscache_cookie *cache; }; Three functions are provided to help with this: (1) void netfs_i_context_init(struct inode *inode, const struct netfs_request_ops *ops); Initialise the netfs context and set the operations. (2) struct netfs_i_context *netfs_i_context(struct inode *inode); Find the netfs context from the VFS inode. (3) struct inode *netfs_inode(struct netfs_i_context *ctx); Find the VFS inode from the netfs context. Changes ======= ver #4) - Fix netfs_is_cache_enabled() to check cookie->cache_priv to see if a cache is present[3]. - Fix netfs_skip_folio_read() to zero out all of the page, not just some of it[3]. ver #3) - Split out the bit to move ceph cap-getting on readahead into ceph_init_request()[1]. - Stick in a comment to the netfs inode structs indicating the contiguity requirements[2]. ver #2) - Adjust documentation to match. - Use "#if IS_ENABLED()" in netfs_i_cookie(), not "#ifdef". - Move the cap check from ceph_readahead() to ceph_init_request() to be called from netfslib. - Remove ceph_readahead() and use netfs_readahead() directly instead. Signed-off-by: David Howells <dhowells@redhat.com> Acked-by: Jeff Layton <jlayton@kernel.org> cc: linux-cachefs@redhat.com

David Howells committed 5 years ago

Commit bc899ee1 parent a5c9dc425 files · +318 −278Browse files

Unified · Split

25 files
  1. Documentation/filesystems/netfs_library.rst +72 −29
  2. fs/9p/cache.c +4 −6
  3. fs/9p/v9fs.c +1 −3
  4. fs/9p/v9fs.h +8 −5
  5. fs/9p/vfs_addr.c +4 −39
  6. fs/9p/vfs_inode.c +10 −3
  7. fs/afs/dynroot.c +1 −0
  8. fs/afs/file.c +2 −24
  9. fs/afs/inode.c +20 −11
  10. fs/afs/internal.h +14 −5
  11. fs/afs/super.c +1 −3
  12. fs/afs/write.c +1 −2
  13. fs/ceph/addr.c +4 −27
  14. fs/ceph/cache.c +14 −14
  15. fs/ceph/cache.h +1 −10
  16. fs/ceph/inode.c +3 −3
  17. fs/ceph/super.h +8 −9
  18. fs/cifs/cifsglob.h +6 −4
  19. fs/cifs/fscache.c +6 −5
  20. fs/cifs/fscache.h +1 −1
  21. fs/netfs/internal.h +16 −2
  22. fs/netfs/objects.c +6 −6
  23. fs/netfs/read_helper.c +45 −55
  24. fs/netfs/stats.c +0 −1
  25. include/linux/netfs.h +70 −11
Documentation/filesystems/netfs_library.rst+72−29
@@ -7,6 +7,8 @@ Network Filesystem Helper Library · 6 unmodified lines
77 .. Contents:
88
99 - Overview.
10+ - Per-inode context.
11+ - Inode context helper functions.
1012 - Buffered read helpers.
1113 - Read helper functions.
1214 - Read helper structures.
@@ -28,6 +30,69 @@ Note that the library module doesn't link against local caching directly, so · 15 unmodified lines
2830 access must be provided by the netfs.
2931
3032
33+Per-Inode Context
34+=================
35+
36+The network filesystem helper library needs a place to store a bit of state for
37+its use on each netfs inode it is helping to manage. To this end, a context
38+structure is defined::
39+
40+ struct netfs_i_context {
41+ const struct netfs_request_ops *ops;
42+ struct fscache_cookie *cache;
43+ };
44+
45+A network filesystem that wants to use netfs lib must place one of these
46+directly after the VFS ``struct inode`` it allocates, usually as part of its
47+own struct. This can be done in a way similar to the following::
48+
49+ struct my_inode {
50+ struct {
51+ /* These must be contiguous */
52+ struct inode vfs_inode;
53+ struct netfs_i_context netfs_ctx;
54+ };
55+ ...
56+ };
57+
58+This allows netfslib to find its state by simple offset from the inode pointer,
59+thereby allowing the netfslib helper functions to be pointed to directly by the
60+VFS/VM operation tables.
61+
62+The structure contains the following fields:
63+
64+ * ``ops``
65+
66+ The set of operations provided by the network filesystem to netfslib.
67+
68+ * ``cache``
69+
70+ Local caching cookie, or NULL if no caching is enabled. This field does not
71+ exist if fscache is disabled.
72+
73+
74+Inode Context Helper Functions
75+------------------------------
76+
77+To help deal with the per-inode context, a number helper functions are
78+provided. Firstly, a function to perform basic initialisation on a context and
79+set the operations table pointer::
80+
81+ void netfs_i_context_init(struct inode *inode,
82+ const struct netfs_request_ops *ops);
83+
84+then two functions to cast between the VFS inode structure and the netfs
85+context::
86+
87+ struct netfs_i_context *netfs_i_context(struct inode *inode);
88+ struct inode *netfs_inode(struct netfs_i_context *ctx);
89+
90+and finally, a function to get the cache cookie pointer from the context
91+attached to an inode (or NULL if fscache is disabled)::
92+
93+ struct fscache_cookie *netfs_i_cookie(struct inode *inode);
94+
95+
3196 Buffered Read Helpers
3297 =====================
3398
@@ -70,38 +135,22 @@ Read Helper Functions · 36 unmodified lines
70135
71136 Three read helpers are provided::
72137
73− void netfs_readahead(struct readahead_control *ractl,
74− const struct netfs_request_ops *ops,
75− void *netfs_priv);
138+ void netfs_readahead(struct readahead_control *ractl);
76139 int netfs_readpage(struct file *file,
77− struct folio *folio,
78− const struct netfs_request_ops *ops,
79− void *netfs_priv);
140+ struct page *page);
80141 int netfs_write_begin(struct file *file,
81142 struct address_space *mapping,
82143 loff_t pos,
83144 unsigned int len,
84145 unsigned int flags,
85146 struct folio **_folio,
86− void **_fsdata,
87− const struct netfs_request_ops *ops,
88− void *netfs_priv);
89−
90−Each corresponds to a VM operation, with the addition of a couple of parameters
91−for the use of the read helpers:
147+ void **_fsdata);
92148
93− * ``ops``
94−
95− A table of operations through which the helpers can talk to the filesystem.
96−
97− * ``netfs_priv``
149+Each corresponds to a VM address space operation. These operations use the
150+state in the per-inode context.
98151
99− Filesystem private data (can be NULL).
100−
101−Both of these values will be stored into the read request structure.
102−
103−For ->readahead() and ->readpage(), the network filesystem should just jump
104−into the corresponding read helper; whereas for ->write_begin(), it may be a
152+For ->readahead() and ->readpage(), the network filesystem just point directly
153+at the corresponding read helper; whereas for ->write_begin(), it may be a
105154 little more complicated as the network filesystem might want to flush
106155 conflicting writes or track dirty data and needs to put the acquired folio if
107156 an error occurs after calling the helper.
@@ -246,7 +295,6 @@ through which it can issue requests and negotiate:: · 138 unmodified lines
246295
247296 struct netfs_request_ops {
248297 void (*init_request)(struct netfs_io_request *rreq, struct file *file);
249− bool (*is_cache_enabled)(struct inode *inode);
250298 int (*begin_cache_operation)(struct netfs_io_request *rreq);
251299 void (*expand_readahead)(struct netfs_io_request *rreq);
252300 bool (*clamp_length)(struct netfs_io_subrequest *subreq);
@@ -265,11 +313,6 @@ The operations are as follows: · 12 unmodified lines
265313 [Optional] This is called to initialise the request structure. It is given
266314 the file for reference and can modify the ->netfs_priv value.
267315
268− * ``is_cache_enabled()``
269−
270− [Required] This is called by netfs_write_begin() to ask if the file is being
271− cached. It should return true if it is being cached and false otherwise.
272−
273316 * ``begin_cache_operation()``
274317
275318 [Optional] This is called to ask the network filesystem to call into the
fs/9p/cache.c+4−6
@@ -49,22 +49,20 @@ int v9fs_cache_session_get_cookie(struct v9fs_session_info *v9ses, · 48 unmodified lines
4949
5050 void v9fs_cache_inode_get_cookie(struct inode *inode)
5151 {
52− struct v9fs_inode *v9inode;
52+ struct v9fs_inode *v9inode = V9FS_I(inode);
5353 struct v9fs_session_info *v9ses;
5454 __le32 version;
5555 __le64 path;
5656
5757 if (!S_ISREG(inode->i_mode))
5858 return;
59−
60− v9inode = V9FS_I(inode);
61− if (WARN_ON(v9inode->fscache))
59+ if (WARN_ON(v9fs_inode_cookie(v9inode)))
6260 return;
6361
6462 version = cpu_to_le32(v9inode->qid.version);
6563 path = cpu_to_le64(v9inode->qid.path);
6664 v9ses = v9fs_inode2v9ses(inode);
67− v9inode->fscache =
65+ v9inode->netfs_ctx.cache =
6866 fscache_acquire_cookie(v9fs_session_cache(v9ses),
6967 0,
7068 &path, sizeof(path),
@@ -72,5 +70,5 @@ void v9fs_cache_inode_get_cookie(struct inode *inode) · 1 unmodified line
7270 i_size_read(&v9inode->vfs_inode));
7371
7472 p9_debug(P9_DEBUG_FSC, "inode %p get cookie %p\n",
75− inode, v9inode->fscache);
73+ inode, v9fs_inode_cookie(v9inode));
7674 }
fs/9p/v9fs.c+1−3
@@ -623,9 +623,7 @@ static void v9fs_sysfs_cleanup(void) · 622 unmodified lines
623623 static void v9fs_inode_init_once(void *foo)
624624 {
625625 struct v9fs_inode *v9inode = (struct v9fs_inode *)foo;
626−#ifdef CONFIG_9P_FSCACHE
627− v9inode->fscache = NULL;
628−#endif
626+
629627 memset(&v9inode->qid, 0, sizeof(v9inode->qid));
630628 inode_init_once(&v9inode->vfs_inode);
631629 }
fs/9p/v9fs.h+8−5
@@ -9,6 +9,7 @@ · 8 unmodified lines
99 #define FS_9P_V9FS_H
1010
1111 #include <linux/backing-dev.h>
12+#include <linux/netfs.h>
1213
1314 /**
1415 * enum p9_session_flags - option flags for each 9P session
@@ -108,14 +109,15 @@ struct v9fs_session_info { · 93 unmodified lines
108109 #define V9FS_INO_INVALID_ATTR 0x01
109110
110111 struct v9fs_inode {
111−#ifdef CONFIG_9P_FSCACHE
112− struct fscache_cookie *fscache;
113−#endif
112+ struct {
113+ /* These must be contiguous */
114+ struct inode vfs_inode; /* the VFS's inode record */
115+ struct netfs_i_context netfs_ctx; /* Netfslib context */
116+ };
114117 struct p9_qid qid;
115118 unsigned int cache_validity;
116119 struct p9_fid *writeback_fid;
117120 struct mutex v_mutex;
118− struct inode vfs_inode;
119121 };
120122
121123 static inline struct v9fs_inode *V9FS_I(const struct inode *inode)
@@ -126,7 +128,7 @@ static inline struct v9fs_inode *V9FS_I(const struct inode *inode) · 4 unmodified lines
126128 static inline struct fscache_cookie *v9fs_inode_cookie(struct v9fs_inode *v9inode)
127129 {
128130 #ifdef CONFIG_9P_FSCACHE
129− return v9inode->fscache;
131+ return netfs_i_cookie(&v9inode->vfs_inode);
130132 #else
131133 return NULL;
132134 #endif
@@ -163,6 +165,7 @@ extern struct inode *v9fs_inode_from_fid(struct v9fs_session_info *v9ses, · 30 unmodified lines
163165 extern const struct inode_operations v9fs_dir_inode_operations_dotl;
164166 extern const struct inode_operations v9fs_file_inode_operations_dotl;
165167 extern const struct inode_operations v9fs_symlink_inode_operations_dotl;
168+extern const struct netfs_request_ops v9fs_req_ops;
166169 extern struct inode *v9fs_inode_from_fid_dotl(struct v9fs_session_info *v9ses,
167170 struct p9_fid *fid,
168171 struct super_block *sb, int new);
fs/9p/vfs_addr.c+4−39
@@ -77,17 +77,6 @@ static void v9fs_req_cleanup(struct address_space *mapping, void *priv) · 76 unmodified lines
7777 p9_client_clunk(fid);
7878 }
7979
80−/**
81− * v9fs_is_cache_enabled - Determine if caching is enabled for an inode
82− * @inode: The inode to check
83− */
84−static bool v9fs_is_cache_enabled(struct inode *inode)
85−{
86− struct fscache_cookie *cookie = v9fs_inode_cookie(V9FS_I(inode));
87−
88− return fscache_cookie_enabled(cookie) && cookie->cache_priv;
89−}
90−
9180 /**
9281 * v9fs_begin_cache_operation - Begin a cache operation for a read
9382 * @rreq: The read request
@@ -103,36 +92,13 @@ static int v9fs_begin_cache_operation(struct netfs_io_request *rreq) · 9 unmodified lines
10392 #endif
10493 }
10594
106−static const struct netfs_request_ops v9fs_req_ops = {
95+const struct netfs_request_ops v9fs_req_ops = {
10796 .init_request = v9fs_init_request,
108− .is_cache_enabled = v9fs_is_cache_enabled,
10997 .begin_cache_operation = v9fs_begin_cache_operation,
11098 .issue_read = v9fs_issue_read,
11199 .cleanup = v9fs_req_cleanup,
112100 };
113101
114−/**
115− * v9fs_vfs_readpage - read an entire page in from 9P
116− * @file: file being read
117− * @page: structure to page
118− *
119− */
120−static int v9fs_vfs_readpage(struct file *file, struct page *page)
121−{
122− struct folio *folio = page_folio(page);
123−
124− return netfs_readpage(file, folio, &v9fs_req_ops, NULL);
125−}
126−
127−/**
128− * v9fs_vfs_readahead - read a set of pages from 9P
129− * @ractl: The readahead parameters
130− */
131−static void v9fs_vfs_readahead(struct readahead_control *ractl)
132−{
133− netfs_readahead(ractl, &v9fs_req_ops, NULL);
134−}
135−
136102 /**
137103 * v9fs_release_page - release the private state associated with a page
138104 * @page: The page to be released
@@ -326,8 +292,7 @@ static int v9fs_write_begin(struct file *filp, struct address_space *mapping, · 187 unmodified lines
326292 * file. We need to do this before we get a lock on the page in case
327293 * there's more than one writer competing for the same cache block.
328294 */
329− retval = netfs_write_begin(filp, mapping, pos, len, flags, &folio, fsdata,
330− &v9fs_req_ops, NULL);
295+ retval = netfs_write_begin(filp, mapping, pos, len, flags, &folio, fsdata);
331296 if (retval < 0)
332297 return retval;
333298
@@ -388,8 +353,8 @@ static int v9fs_set_page_dirty(struct page *page) · 54 unmodified lines
388353 #endif
389354
390355 const struct address_space_operations v9fs_addr_operations = {
391− .readpage = v9fs_vfs_readpage,
392− .readahead = v9fs_vfs_readahead,
356+ .readpage = netfs_readpage,
357+ .readahead = netfs_readahead,
393358 .set_page_dirty = v9fs_set_page_dirty,
394359 .writepage = v9fs_vfs_writepage,
395360 .write_begin = v9fs_write_begin,
fs/9p/vfs_inode.c+10−3
@@ -231,9 +231,6 @@ struct inode *v9fs_alloc_inode(struct super_block *sb) · 230 unmodified lines
231231 v9inode = kmem_cache_alloc(v9fs_inode_cache, GFP_KERNEL);
232232 if (!v9inode)
233233 return NULL;
234−#ifdef CONFIG_9P_FSCACHE
235− v9inode->fscache = NULL;
236−#endif
237234 v9inode->writeback_fid = NULL;
238235 v9inode->cache_validity = 0;
239236 mutex_init(&v9inode->v_mutex);
@@ -250,6 +247,14 @@ void v9fs_free_inode(struct inode *inode) · 10 unmodified lines
250247 kmem_cache_free(v9fs_inode_cache, V9FS_I(inode));
251248 }
252249
250+/*
251+ * Set parameters for the netfs library
252+ */
253+static void v9fs_set_netfs_context(struct inode *inode)
254+{
255+ netfs_i_context_init(inode, &v9fs_req_ops);
256+}
257+
253258 int v9fs_init_inode(struct v9fs_session_info *v9ses,
254259 struct inode *inode, umode_t mode, dev_t rdev)
255260 {
@@ -338,6 +343,8 @@ int v9fs_init_inode(struct v9fs_session_info *v9ses, · 82 unmodified lines
338343 err = -EINVAL;
339344 goto error;
340345 }
346+
347+ v9fs_set_netfs_context(inode);
341348 error:
342349 return err;
343350
fs/afs/dynroot.c+1−0
@@ -76,6 +76,7 @@ struct inode *afs_iget_pseudo_dir(struct super_block *sb, bool root) · 75 unmodified lines
7676 /* there shouldn't be an existing inode */
7777 BUG_ON(!(inode->i_state & I_NEW));
7878
79+ netfs_i_context_init(inode, NULL);
7980 inode->i_size = 0;
8081 inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
8182 if (root) {
fs/afs/file.c+2−24
@@ -19,13 +19,11 @@ · 18 unmodified lines
1919 #include "internal.h"
2020
2121 static int afs_file_mmap(struct file *file, struct vm_area_struct *vma);
22−static int afs_readpage(struct file *file, struct page *page);
2322 static int afs_symlink_readpage(struct file *file, struct page *page);
2423 static void afs_invalidatepage(struct page *page, unsigned int offset,
2524 unsigned int length);
2625 static int afs_releasepage(struct page *page, gfp_t gfp_flags);
2726
28−static void afs_readahead(struct readahead_control *ractl);
2927 static ssize_t afs_file_read_iter(struct kiocb *iocb, struct iov_iter *iter);
3028 static void afs_vm_open(struct vm_area_struct *area);
3129 static void afs_vm_close(struct vm_area_struct *area);
@@ -52,8 +50,8 @@ const struct inode_operations afs_file_inode_operations = { · 20 unmodified lines
5250 };
5351
5452 const struct address_space_operations afs_file_aops = {
55− .readpage = afs_readpage,
56− .readahead = afs_readahead,
53+ .readpage = netfs_readpage,
54+ .readahead = netfs_readahead,
5755 .set_page_dirty = afs_set_page_dirty,
5856 .launder_page = afs_launder_page,
5957 .releasepage = afs_releasepage,
@@ -365,13 +363,6 @@ static int afs_init_request(struct netfs_io_request *rreq, struct file *file) · 305 unmodified lines
365363 return 0;
366364 }
367365
368−static bool afs_is_cache_enabled(struct inode *inode)
369−{
370− struct fscache_cookie *cookie = afs_vnode_cache(AFS_FS_I(inode));
371−
372− return fscache_cookie_enabled(cookie) && cookie->cache_priv;
373−}
374−
375366 static int afs_begin_cache_operation(struct netfs_io_request *rreq)
376367 {
377368 #ifdef CONFIG_AFS_FSCACHE
@@ -399,25 +390,12 @@ static void afs_priv_cleanup(struct address_space *mapping, void *netfs_priv) · 21 unmodified lines
399390
400391 const struct netfs_request_ops afs_req_ops = {
401392 .init_request = afs_init_request,
402− .is_cache_enabled = afs_is_cache_enabled,
403393 .begin_cache_operation = afs_begin_cache_operation,
404394 .check_write_begin = afs_check_write_begin,
405395 .issue_read = afs_issue_read,
406396 .cleanup = afs_priv_cleanup,
407397 };
408398
409−static int afs_readpage(struct file *file, struct page *page)
410−{
411− struct folio *folio = page_folio(page);
412−
413− return netfs_readpage(file, folio, &afs_req_ops, NULL);
414−}
415−
416−static void afs_readahead(struct readahead_control *ractl)
417−{
418− netfs_readahead(ractl, &afs_req_ops, NULL);
419−}
420−
421399 int afs_write_inode(struct inode *inode, struct writeback_control *wbc)
422400 {
423401 fscache_unpin_writeback(wbc, afs_vnode_cache(AFS_FS_I(inode)));
fs/afs/inode.c+20−11
@@ -53,6 +53,14 @@ static noinline void dump_vnode(struct afs_vnode *vnode, struct afs_vnode *paren · 52 unmodified lines
5353 dump_stack();
5454 }
5555
56+/*
57+ * Set parameters for the netfs library
58+ */
59+static void afs_set_netfs_context(struct afs_vnode *vnode)
60+{
61+ netfs_i_context_init(&vnode->vfs_inode, &afs_req_ops);
62+}
63+
5664 /*
5765 * Initialise an inode from the vnode status.
5866 */
@@ -128,6 +136,7 @@ static int afs_inode_init_from_status(struct afs_operation *op, · 69 unmodified lines
128136 }
129137
130138 afs_set_i_size(vnode, status->size);
139+ afs_set_netfs_context(vnode);
131140
132141 vnode->invalid_before = status->data_version;
133142 inode_set_iversion_raw(&vnode->vfs_inode, status->data_version);
@@ -420,7 +429,7 @@ static void afs_get_inode_cache(struct afs_vnode *vnode) · 286 unmodified lines
420429 struct afs_vnode_cache_aux aux;
421430
422431 if (vnode->status.type != AFS_FTYPE_FILE) {
423− vnode->cache = NULL;
432+ vnode->netfs_ctx.cache = NULL;
424433 return;
425434 }
426435
@@ -430,12 +439,14 @@ static void afs_get_inode_cache(struct afs_vnode *vnode) · 3 unmodified lines
430439 key.vnode_id_ext[1] = htonl(vnode->fid.vnode_hi);
431440 afs_set_cache_aux(vnode, &aux);
432441
433− vnode->cache = fscache_acquire_cookie(
434− vnode->volume->cache,
435− vnode->status.type == AFS_FTYPE_FILE ? 0 : FSCACHE_ADV_SINGLE_CHUNK,
436− &key, sizeof(key),
437− &aux, sizeof(aux),
438− vnode->status.size);
442+ afs_vnode_set_cache(vnode,
443+ fscache_acquire_cookie(
444+ vnode->volume->cache,
445+ vnode->status.type == AFS_FTYPE_FILE ?
446+ 0 : FSCACHE_ADV_SINGLE_CHUNK,
447+ &key, sizeof(key),
448+ &aux, sizeof(aux),
449+ vnode->status.size));
439450 #endif
440451 }
441452
@@ -528,6 +539,7 @@ struct inode *afs_root_iget(struct super_block *sb, struct key *key) · 86 unmodified lines
528539
529540 vnode = AFS_FS_I(inode);
530541 vnode->cb_v_break = as->volume->cb_v_break,
542+ afs_set_netfs_context(vnode);
531543
532544 op = afs_alloc_operation(key, as->volume);
533545 if (IS_ERR(op)) {
@@ -786,11 +798,8 @@ void afs_evict_inode(struct inode *inode) · 252 unmodified lines
786798 afs_put_wb_key(wbk);
787799 }
788800
789−#ifdef CONFIG_AFS_FSCACHE
790− fscache_relinquish_cookie(vnode->cache,
801+ fscache_relinquish_cookie(afs_vnode_cache(vnode),
791802 test_bit(AFS_VNODE_DELETED, &vnode->flags));
792− vnode->cache = NULL;
793−#endif
794803
795804 afs_prune_wb_keys(vnode);
796805 afs_put_permits(rcu_access_pointer(vnode->permit_cache));
fs/afs/internal.h+14−5
@@ -619,15 +619,16 @@ enum afs_lock_state { · 618 unmodified lines
619619 * leak from one inode to another.
620620 */
621621 struct afs_vnode {
622− struct inode vfs_inode; /* the VFS's inode record */
622+ struct {
623+ /* These must be contiguous */
624+ struct inode vfs_inode; /* the VFS's inode record */
625+ struct netfs_i_context netfs_ctx; /* Netfslib context */
626+ };
623627
624628 struct afs_volume *volume; /* volume on which vnode resides */
625629 struct afs_fid fid; /* the file identifier for this inode */
626630 struct afs_file_status status; /* AFS status info for this file */
627631 afs_dataversion_t invalid_before; /* Child dentries are invalid before this */
628−#ifdef CONFIG_AFS_FSCACHE
629− struct fscache_cookie *cache; /* caching cookie */
630−#endif
631632 struct afs_permits __rcu *permit_cache; /* cache of permits so far obtained */
632633 struct mutex io_lock; /* Lock for serialising I/O on this mutex */
633634 struct rw_semaphore validate_lock; /* lock for validating this vnode */
@@ -674,12 +675,20 @@ struct afs_vnode { · 40 unmodified lines
674675 static inline struct fscache_cookie *afs_vnode_cache(struct afs_vnode *vnode)
675676 {
676677 #ifdef CONFIG_AFS_FSCACHE
677− return vnode->cache;
678+ return netfs_i_cookie(&vnode->vfs_inode);
678679 #else
679680 return NULL;
680681 #endif
681682 }
682683
684+static inline void afs_vnode_set_cache(struct afs_vnode *vnode,
685+ struct fscache_cookie *cookie)
686+{
687+#ifdef CONFIG_AFS_FSCACHE
688+ vnode->netfs_ctx.cache = cookie;
689+#endif
690+}
691+
683692 /*
684693 * cached security record for one user's attempt to access a vnode
685694 */
fs/afs/super.c+1−3
@@ -688,13 +688,11 @@ static struct inode *afs_alloc_inode(struct super_block *sb) · 687 unmodified lines
688688 /* Reset anything that shouldn't leak from one inode to the next. */
689689 memset(&vnode->fid, 0, sizeof(vnode->fid));
690690 memset(&vnode->status, 0, sizeof(vnode->status));
691+ afs_vnode_set_cache(vnode, NULL);
691692
692693 vnode->volume = NULL;
693694 vnode->lock_key = NULL;
694695 vnode->permit_cache = NULL;
695−#ifdef CONFIG_AFS_FSCACHE
696− vnode->cache = NULL;
697−#endif
698696
699697 vnode->flags = 1 << AFS_VNODE_UNSET;
700698 vnode->lock_state = AFS_VNODE_LOCK_NONE;
fs/afs/write.c+1−2
@@ -59,8 +59,7 @@ int afs_write_begin(struct file *file, struct address_space *mapping, · 58 unmodified lines
5959 * file. We need to do this before we get a lock on the page in case
6060 * there's more than one writer competing for the same cache block.
6161 */
62− ret = netfs_write_begin(file, mapping, pos, len, flags, &folio, fsdata,
63− &afs_req_ops, NULL);
62+ ret = netfs_write_begin(file, mapping, pos, len, flags, &folio, fsdata);
6463 if (ret < 0)
6564 return ret;
6665
fs/ceph/addr.c+4−27
@@ -403,7 +403,7 @@ static void ceph_readahead_cleanup(struct address_space *mapping, void *priv) · 402 unmodified lines
403403 ceph_put_cap_refs(ci, got);
404404 }
405405
406−static const struct netfs_request_ops ceph_netfs_read_ops = {
406+const struct netfs_request_ops ceph_netfs_ops = {
407407 .init_request = ceph_init_request,
408408 .begin_cache_operation = ceph_begin_cache_operation,
409409 .issue_read = ceph_netfs_issue_read,
@@ -413,28 +413,6 @@ static const struct netfs_request_ops ceph_netfs_read_ops = { · 3 unmodified lines
413413 .cleanup = ceph_readahead_cleanup,
414414 };
415415
416−/* read a single page, without unlocking it. */
417−static int ceph_readpage(struct file *file, struct page *subpage)
418−{
419− struct folio *folio = page_folio(subpage);
420− struct inode *inode = file_inode(file);
421− struct ceph_inode_info *ci = ceph_inode(inode);
422− struct ceph_vino vino = ceph_vino(inode);
423− size_t len = folio_size(folio);
424− u64 off = folio_file_pos(folio);
425−
426− dout("readpage ino %llx.%llx file %p off %llu len %zu folio %p index %lu\n inline %d",
427− vino.ino, vino.snap, file, off, len, folio, folio_index(folio),
428− ci->i_inline_version != CEPH_INLINE_NONE);
429−
430− return netfs_readpage(file, folio, &ceph_netfs_read_ops, NULL);
431−}
432−
433−static void ceph_readahead(struct readahead_control *ractl)
434−{
435− netfs_readahead(ractl, &ceph_netfs_read_ops, NULL);
436−}
437−
438416 #ifdef CONFIG_CEPH_FSCACHE
439417 static void ceph_set_page_fscache(struct page *page)
440418 {
@@ -1333,8 +1311,7 @@ static int ceph_write_begin(struct file *file, struct address_space *mapping, · 892 unmodified lines
13331311 struct folio *folio = NULL;
13341312 int r;
13351313
1336− r = netfs_write_begin(file, inode->i_mapping, pos, len, 0, &folio, NULL,
1337− &ceph_netfs_read_ops, NULL);
1314+ r = netfs_write_begin(file, inode->i_mapping, pos, len, 0, &folio, NULL);
13381315 if (r == 0)
13391316 folio_wait_fscache(folio);
13401317 if (r < 0) {
@@ -1388,8 +1365,8 @@ out: · 47 unmodified lines
13881365 }
13891366
13901367 const struct address_space_operations ceph_aops = {
1391− .readpage = ceph_readpage,
1392− .readahead = ceph_readahead,
1368+ .readpage = netfs_readpage,
1369+ .readahead = netfs_readahead,
13931370 .writepage = ceph_writepage,
13941371 .writepages = ceph_writepages_start,
13951372 .write_begin = ceph_write_begin,
fs/ceph/cache.c+14−14
@@ -29,26 +29,25 @@ void ceph_fscache_register_inode_cookie(struct inode *inode) · 28 unmodified lines
2929 if (!(inode->i_state & I_NEW))
3030 return;
3131
32− WARN_ON_ONCE(ci->fscache);
32+ WARN_ON_ONCE(ci->netfs_ctx.cache);
3333
34− ci->fscache = fscache_acquire_cookie(fsc->fscache, 0,
35− &ci->i_vino, sizeof(ci->i_vino),
36− &ci->i_version, sizeof(ci->i_version),
37− i_size_read(inode));
34+ ci->netfs_ctx.cache =
35+ fscache_acquire_cookie(fsc->fscache, 0,
36+ &ci->i_vino, sizeof(ci->i_vino),
37+ &ci->i_version, sizeof(ci->i_version),
38+ i_size_read(inode));
3839 }
3940
40−void ceph_fscache_unregister_inode_cookie(struct ceph_inode_info* ci)
41+void ceph_fscache_unregister_inode_cookie(struct ceph_inode_info *ci)
4142 {
42− struct fscache_cookie *cookie = ci->fscache;
43−
44− fscache_relinquish_cookie(cookie, false);
43+ fscache_relinquish_cookie(ceph_fscache_cookie(ci), false);
4544 }
4645
4746 void ceph_fscache_use_cookie(struct inode *inode, bool will_modify)
4847 {
4948 struct ceph_inode_info *ci = ceph_inode(inode);
5049
51− fscache_use_cookie(ci->fscache, will_modify);
50+ fscache_use_cookie(ceph_fscache_cookie(ci), will_modify);
5251 }
5352
5453 void ceph_fscache_unuse_cookie(struct inode *inode, bool update)
@@ -58,9 +57,10 @@ void ceph_fscache_unuse_cookie(struct inode *inode, bool update) · 3 unmodified lines
5857 if (update) {
5958 loff_t i_size = i_size_read(inode);
6059
61− fscache_unuse_cookie(ci->fscache, &ci->i_version, &i_size);
60+ fscache_unuse_cookie(ceph_fscache_cookie(ci),
61+ &ci->i_version, &i_size);
6262 } else {
63− fscache_unuse_cookie(ci->fscache, NULL, NULL);
63+ fscache_unuse_cookie(ceph_fscache_cookie(ci), NULL, NULL);
6464 }
6565 }
6666
@@ -69,14 +69,14 @@ void ceph_fscache_update(struct inode *inode) · 2 unmodified lines
6969 struct ceph_inode_info *ci = ceph_inode(inode);
7070 loff_t i_size = i_size_read(inode);
7171
72− fscache_update_cookie(ci->fscache, &ci->i_version, &i_size);
72+ fscache_update_cookie(ceph_fscache_cookie(ci), &ci->i_version, &i_size);
7373 }
7474
7575 void ceph_fscache_invalidate(struct inode *inode, bool dio_write)
7676 {
7777 struct ceph_inode_info *ci = ceph_inode(inode);
7878
79− fscache_invalidate(ceph_inode(inode)->fscache,
79+ fscache_invalidate(ceph_fscache_cookie(ci),
8080 &ci->i_version, i_size_read(inode),
8181 dio_write ? FSCACHE_INVAL_DIO_WRITE : 0);
8282 }
fs/ceph/cache.h+1−10
@@ -26,14 +26,9 @@ void ceph_fscache_unuse_cookie(struct inode *inode, bool update); · 25 unmodified lines
2626 void ceph_fscache_update(struct inode *inode);
2727 void ceph_fscache_invalidate(struct inode *inode, bool dio_write);
2828
29−static inline void ceph_fscache_inode_init(struct ceph_inode_info *ci)
30−{
31− ci->fscache = NULL;
32−}
33−
3429 static inline struct fscache_cookie *ceph_fscache_cookie(struct ceph_inode_info *ci)
3530 {
36− return ci->fscache;
31+ return netfs_i_cookie(&ci->vfs_inode);
3732 }
3833
3934 static inline void ceph_fscache_resize(struct inode *inode, loff_t to)
@@ -91,10 +86,6 @@ static inline void ceph_fscache_unregister_fs(struct ceph_fs_client* fsc) · 51 unmodified lines
9186 {
9287 }
9388
94−static inline void ceph_fscache_inode_init(struct ceph_inode_info *ci)
95−{
96−}
97−
9889 static inline void ceph_fscache_register_inode_cookie(struct inode *inode)
9990 {
10091 }
fs/ceph/inode.c+3−3
@@ -453,6 +453,9 @@ struct inode *ceph_alloc_inode(struct super_block *sb) · 452 unmodified lines
453453
454454 dout("alloc_inode %p\n", &ci->vfs_inode);
455455
456+ /* Set parameters for the netfs library */
457+ netfs_i_context_init(&ci->vfs_inode, &ceph_netfs_ops);
458+
456459 spin_lock_init(&ci->i_ceph_lock);
457460
458461 ci->i_version = 0;
@@ -538,9 +541,6 @@ struct inode *ceph_alloc_inode(struct super_block *sb) · 79 unmodified lines
538541 INIT_WORK(&ci->i_work, ceph_inode_work);
539542 ci->i_work_mask = 0;
540543 memset(&ci->i_btime, '\0', sizeof(ci->i_btime));
541−
542− ceph_fscache_inode_init(ci);
543−
544544 return &ci->vfs_inode;
545545 }
546546
fs/ceph/super.h+8−9
@@ -17,13 +17,11 @@ · 16 unmodified lines
1717 #include <linux/posix_acl.h>
1818 #include <linux/refcount.h>
1919 #include <linux/security.h>
20+#include <linux/netfs.h>
21+#include <linux/fscache.h>
2022
2123 #include <linux/ceph/libceph.h>
2224
23−#ifdef CONFIG_CEPH_FSCACHE
24−#include <linux/fscache.h>
25−#endif
26−
2725 /* large granularity for statfs utilization stats to facilitate
2826 * large volume sizes on 32-bit machines. */
2927 #define CEPH_BLOCK_SHIFT 22 /* 4 MB */
@@ -317,6 +315,11 @@ struct ceph_inode_xattrs_info { · 287 unmodified lines
317315 * Ceph inode.
318316 */
319317 struct ceph_inode_info {
318+ struct {
319+ /* These must be contiguous */
320+ struct inode vfs_inode;
321+ struct netfs_i_context netfs_ctx; /* Netfslib context */
322+ };
320323 struct ceph_vino i_vino; /* ceph ino + snap */
321324
322325 spinlock_t i_ceph_lock;
@@ -427,11 +430,6 @@ struct ceph_inode_info { · 104 unmodified lines
427430
428431 struct work_struct i_work;
429432 unsigned long i_work_mask;
430−
431−#ifdef CONFIG_CEPH_FSCACHE
432− struct fscache_cookie *fscache;
433−#endif
434− struct inode vfs_inode; /* at end */
435433 };
436434
437435 static inline struct ceph_inode_info *
@@ -1215,6 +1213,7 @@ extern void __ceph_touch_fmode(struct ceph_inode_info *ci, · 777 unmodified lines
12151213
12161214 /* addr.c */
12171215 extern const struct address_space_operations ceph_aops;
1216+extern const struct netfs_request_ops ceph_netfs_ops;
12181217 extern int ceph_mmap(struct file *file, struct vm_area_struct *vma);
12191218 extern int ceph_uninline_data(struct file *file);
12201219 extern int ceph_pool_perm_check(struct inode *inode, int need);
fs/cifs/cifsglob.h+6−4
@@ -16,6 +16,7 @@ · 15 unmodified lines
1616 #include <linux/mempool.h>
1717 #include <linux/workqueue.h>
1818 #include <linux/utsname.h>
19+#include <linux/netfs.h>
1920 #include "cifs_fs_sb.h"
2021 #include "cifsacl.h"
2122 #include <crypto/internal/hash.h>
@@ -1402,6 +1403,11 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file); · 1380 unmodified lines
14021403 */
14031404
14041405 struct cifsInodeInfo {
1406+ struct {
1407+ /* These must be contiguous */
1408+ struct inode vfs_inode; /* the VFS's inode record */
1409+ struct netfs_i_context netfs_ctx; /* Netfslib context */
1410+ };
14051411 bool can_cache_brlcks;
14061412 struct list_head llist; /* locks helb by this inode */
14071413 /*
@@ -1432,10 +1438,6 @@ struct cifsInodeInfo { · 24 unmodified lines
14321438 u64 uniqueid; /* server inode number */
14331439 u64 createtime; /* creation time on server */
14341440 __u8 lease_key[SMB2_LEASE_KEY_SIZE]; /* lease key for this inode */
1435−#ifdef CONFIG_CIFS_FSCACHE
1436− struct fscache_cookie *fscache;
1437−#endif
1438− struct inode vfs_inode;
14391441 struct list_head deferred_closes; /* list of deferred closes */
14401442 spinlock_t deferred_lock; /* protection on deferred list */
14411443 bool lease_granted; /* Flag to indicate whether lease or oplock is granted. */
fs/cifs/fscache.c+6−5
@@ -103,7 +103,7 @@ void cifs_fscache_get_inode_cookie(struct inode *inode) · 102 unmodified lines
103103
104104 cifs_fscache_fill_coherency(&cifsi->vfs_inode, &cd);
105105
106− cifsi->fscache =
106+ cifsi->netfs_ctx.cache =
107107 fscache_acquire_cookie(tcon->fscache, 0,
108108 &cifsi->uniqueid, sizeof(cifsi->uniqueid),
109109 &cd, sizeof(cd),
@@ -126,11 +126,12 @@ void cifs_fscache_unuse_inode_cookie(struct inode *inode, bool update) · 16 unmodified lines
126126 void cifs_fscache_release_inode_cookie(struct inode *inode)
127127 {
128128 struct cifsInodeInfo *cifsi = CIFS_I(inode);
129+ struct fscache_cookie *cookie = cifs_inode_cookie(inode);
129130
130− if (cifsi->fscache) {
131− cifs_dbg(FYI, "%s: (0x%p)\n", __func__, cifsi->fscache);
132− fscache_relinquish_cookie(cifsi->fscache, false);
133− cifsi->fscache = NULL;
131+ if (cookie) {
132+ cifs_dbg(FYI, "%s: (0x%p)\n", __func__, cookie);
133+ fscache_relinquish_cookie(cookie, false);
134+ cifsi->netfs_ctx.cache = NULL;
134135 }
135136 }
136137
fs/cifs/fscache.h+1−1
@@ -61,7 +61,7 @@ void cifs_fscache_fill_coherency(struct inode *inode, · 60 unmodified lines
6161
6262 static inline struct fscache_cookie *cifs_inode_cookie(struct inode *inode)
6363 {
64− return CIFS_I(inode)->fscache;
64+ return netfs_i_cookie(inode);
6565 }
6666
6767 static inline void cifs_invalidate_cache(struct inode *inode, unsigned int flags)
fs/netfs/internal.h+16−2
@@ -6,6 +6,7 @@ · 5 unmodified lines
66 */
77
88 #include <linux/netfs.h>
9+#include <linux/fscache.h>
910 #include <trace/events/netfs.h>
1011
1112 #ifdef pr_fmt
@@ -19,8 +20,6 @@ · 7 unmodified lines
1920 */
2021 struct netfs_io_request *netfs_alloc_request(struct address_space *mapping,
2122 struct file *file,
22− const struct netfs_request_ops *ops,
23− void *netfs_priv,
2423 loff_t start, size_t len,
2524 enum netfs_io_origin origin);
2625 void netfs_get_request(struct netfs_io_request *rreq, enum netfs_rreq_ref_trace what);
@@ -81,6 +80,21 @@ static inline void netfs_stat_d(atomic_t *stat) · 54 unmodified lines
8180 #define netfs_stat_d(x) do {} while(0)
8281 #endif
8382
83+/*
84+ * Miscellaneous functions.
85+ */
86+static inline bool netfs_is_cache_enabled(struct netfs_i_context *ctx)
87+{
88+#if IS_ENABLED(CONFIG_FSCACHE)
89+ struct fscache_cookie *cookie = ctx->cache;
90+
91+ return fscache_cookie_valid(cookie) && cookie->cache_priv &&
92+ fscache_cookie_enabled(cookie);
93+#else
94+ return false;
95+#endif
96+}
97+
8498 /*****************************************************************************/
8599 /*
86100 * debug tracing
fs/netfs/objects.c+6−6
@@ -13,12 +13,12 @@ · 12 unmodified lines
1313 */
1414 struct netfs_io_request *netfs_alloc_request(struct address_space *mapping,
1515 struct file *file,
16− const struct netfs_request_ops *ops,
17− void *netfs_priv,
1816 loff_t start, size_t len,
1917 enum netfs_io_origin origin)
2018 {
2119 static atomic_t debug_ids;
20+ struct inode *inode = file ? file_inode(file) : mapping->host;
21+ struct netfs_i_context *ctx = netfs_i_context(inode);
2222 struct netfs_io_request *rreq;
2323 int ret;
2424
@@ -29,11 +29,10 @@ struct netfs_io_request *netfs_alloc_request(struct address_space *mapping, · 4 unmodified lines
2929 rreq->start = start;
3030 rreq->len = len;
3131 rreq->origin = origin;
32− rreq->netfs_ops = ops;
33− rreq->netfs_priv = netfs_priv;
32+ rreq->netfs_ops = ctx->ops;
3433 rreq->mapping = mapping;
35− rreq->inode = file_inode(file);
36− rreq->i_size = i_size_read(rreq->inode);
34+ rreq->inode = inode;
35+ rreq->i_size = i_size_read(inode);
3736 rreq->debug_id = atomic_inc_return(&debug_ids);
3837 INIT_LIST_HEAD(&rreq->subrequests);
3938 INIT_WORK(&rreq->work, netfs_rreq_work);
@@ -76,6 +75,7 @@ static void netfs_free_request(struct work_struct *work) · 36 unmodified lines
7675 {
7776 struct netfs_io_request *rreq =
7877 container_of(work, struct netfs_io_request, work);
78+
7979 netfs_clear_subrequests(rreq, false);
8080 if (rreq->netfs_priv)
8181 rreq->netfs_ops->cleanup(rreq->mapping, rreq->netfs_priv);
fs/netfs/read_helper.c+45−55
@@ -14,7 +14,6 @@ · 13 unmodified lines
1414 #include <linux/uio.h>
1515 #include <linux/sched/mm.h>
1616 #include <linux/task_io_accounting_ops.h>
17−#include <linux/netfs.h>
1817 #include "internal.h"
1918 #define CREATE_TRACE_POINTS
2019 #include <trace/events/netfs.h>
@@ -735,8 +734,6 @@ static void netfs_rreq_expand(struct netfs_io_request *rreq, · 714 unmodified lines
735734 /**
736735 * netfs_readahead - Helper to manage a read request
737736 * @ractl: The description of the readahead request
738− * @ops: The network filesystem's operations for the helper to use
739− * @netfs_priv: Private netfs data to be retained in the request
740737 *
741738 * Fulfil a readahead request by drawing data from the cache if possible, or
742739 * the netfs if not. Space beyond the EOF is zero-filled. Multiple I/O
@@ -744,35 +741,32 @@ static void netfs_rreq_expand(struct netfs_io_request *rreq, · 1 unmodified line
744741 * readahead window can be expanded in either direction to a more convenient
745742 * alighment for RPC efficiency or to make storage in the cache feasible.
746743 *
747− * The calling netfs must provide a table of operations, only one of which,
748− * issue_op, is mandatory. It may also be passed a private token, which will
749− * be retained in rreq->netfs_priv and will be cleaned up by ops->cleanup().
744+ * The calling netfs must initialise a netfs context contiguous to the vfs
745+ * inode before calling this.
750746 *
751747 * This is usable whether or not caching is enabled.
752748 */
753−void netfs_readahead(struct readahead_control *ractl,
754− const struct netfs_request_ops *ops,
755− void *netfs_priv)
749+void netfs_readahead(struct readahead_control *ractl)
756750 {
757751 struct netfs_io_request *rreq;
752+ struct netfs_i_context *ctx = netfs_i_context(ractl->mapping->host);
758753 unsigned int debug_index = 0;
759754 int ret;
760755
761756 _enter("%lx,%x", readahead_index(ractl), readahead_count(ractl));
762757
763758 if (readahead_count(ractl) == 0)
764− goto cleanup;
759+ return;
765760
766761 rreq = netfs_alloc_request(ractl->mapping, ractl->file,
767− ops, netfs_priv,
768762 readahead_pos(ractl),
769763 readahead_length(ractl),
770764 NETFS_READAHEAD);
771765 if (IS_ERR(rreq))
772− goto cleanup;
766+ return;
773767
774− if (ops->begin_cache_operation) {
775− ret = ops->begin_cache_operation(rreq);
768+ if (ctx->ops->begin_cache_operation) {
769+ ret = ctx->ops->begin_cache_operation(rreq);
776770 if (ret == -ENOMEM || ret == -EINTR || ret == -ERESTARTSYS)
777771 goto cleanup_free;
778772 }
@@ -804,42 +798,35 @@ void netfs_readahead(struct readahead_control *ractl, · 25 unmodified lines
804798 cleanup_free:
805799 netfs_put_request(rreq, false, netfs_rreq_trace_put_failed);
806800 return;
807−cleanup:
808− if (netfs_priv)
809− ops->cleanup(ractl->mapping, netfs_priv);
810− return;
811801 }
812802 EXPORT_SYMBOL(netfs_readahead);
813803
814804 /**
815805 * netfs_readpage - Helper to manage a readpage request
816806 * @file: The file to read from
817− * @folio: The folio to read
818− * @ops: The network filesystem's operations for the helper to use
819− * @netfs_priv: Private netfs data to be retained in the request
807+ * @subpage: A subpage of the folio to read
820808 *
821809 * Fulfil a readpage request by drawing data from the cache if possible, or the
822810 * netfs if not. Space beyond the EOF is zero-filled. Multiple I/O requests
823811 * from different sources will get munged together.
824812 *
825− * The calling netfs must provide a table of operations, only one of which,
826− * issue_op, is mandatory. It may also be passed a private token, which will
827− * be retained in rreq->netfs_priv and will be cleaned up by ops->cleanup().
813+ * The calling netfs must initialise a netfs context contiguous to the vfs
814+ * inode before calling this.
828815 *
829816 * This is usable whether or not caching is enabled.
830817 */
831−int netfs_readpage(struct file *file,
832− struct folio *folio,
833− const struct netfs_request_ops *ops,
834− void *netfs_priv)
818+int netfs_readpage(struct file *file, struct page *subpage)
835819 {
820+ struct folio *folio = page_folio(subpage);
821+ struct address_space *mapping = folio->mapping;
836822 struct netfs_io_request *rreq;
823+ struct netfs_i_context *ctx = netfs_i_context(mapping->host);
837824 unsigned int debug_index = 0;
838825 int ret;
839826
840827 _enter("%lx", folio_index(folio));
841828
842− rreq = netfs_alloc_request(folio->mapping, file, ops, netfs_priv,
829+ rreq = netfs_alloc_request(mapping, file,
843830 folio_file_pos(folio), folio_size(folio),
844831 NETFS_READPAGE);
845832 if (IS_ERR(rreq)) {
@@ -847,8 +834,8 @@ int netfs_readpage(struct file *file, · 1 unmodified line
847834 goto alloc_error;
848835 }
849836
850− if (ops->begin_cache_operation) {
851− ret = ops->begin_cache_operation(rreq);
837+ if (ctx->ops->begin_cache_operation) {
838+ ret = ctx->ops->begin_cache_operation(rreq);
852839 if (ret == -ENOMEM || ret == -EINTR || ret == -ERESTARTSYS) {
853840 folio_unlock(folio);
854841 goto out;
@@ -886,8 +873,6 @@ out: · 31 unmodified lines
886873 netfs_put_request(rreq, false, netfs_rreq_trace_put_hold);
887874 return ret;
888875 alloc_error:
889− if (netfs_priv)
890− ops->cleanup(folio_file_mapping(folio), netfs_priv);
891876 folio_unlock(folio);
892877 return ret;
893878 }
@@ -898,6 +883,7 @@ EXPORT_SYMBOL(netfs_readpage); · 4 unmodified lines
898883 * @folio: The folio being prepared
899884 * @pos: starting position for the write
900885 * @len: length of write
886+ * @always_fill: T if the folio should always be completely filled/cleared
901887 *
902888 * In some cases, write_begin doesn't need to read at all:
903889 * - full folio write
@@ -907,17 +893,27 @@ EXPORT_SYMBOL(netfs_readpage); · 3 unmodified lines
907893 * If any of these criteria are met, then zero out the unwritten parts
908894 * of the folio and return true. Otherwise, return false.
909895 */
910−static bool netfs_skip_folio_read(struct folio *folio, loff_t pos, size_t len)
896+static bool netfs_skip_folio_read(struct folio *folio, loff_t pos, size_t len,
897+ bool always_fill)
911898 {
912899 struct inode *inode = folio_inode(folio);
913900 loff_t i_size = i_size_read(inode);
914901 size_t offset = offset_in_folio(folio, pos);
902+ size_t plen = folio_size(folio);
903+
904+ if (unlikely(always_fill)) {
905+ if (pos - offset + len <= i_size)
906+ return false; /* Page entirely before EOF */
907+ zero_user_segment(&folio->page, 0, plen);
908+ folio_mark_uptodate(folio);
909+ return true;
910+ }
915911
916912 /* Full folio write */
917− if (offset == 0 && len >= folio_size(folio))
913+ if (offset == 0 && len >= plen)
918914 return true;
919915
920− /* pos beyond last folio in the file */
916+ /* Page entirely beyond the end of the file */
921917 if (pos - offset >= i_size)
922918 goto zero_out;
923919
@@ -927,7 +923,7 @@ static bool netfs_skip_folio_read(struct folio *folio, loff_t pos, size_t len) · 3 unmodified lines
927923
928924 return false;
929925 zero_out:
930− zero_user_segments(&folio->page, 0, offset, offset + len, folio_size(folio));
926+ zero_user_segments(&folio->page, 0, offset, offset + len, plen);
931927 return true;
932928 }
933929
@@ -940,8 +936,6 @@ zero_out: · 6 unmodified lines
940936 * @aop_flags: AOP_* flags
941937 * @_folio: Where to put the resultant folio
942938 * @_fsdata: Place for the netfs to store a cookie
943− * @ops: The network filesystem's operations for the helper to use
944− * @netfs_priv: Private netfs data to be retained in the request
945939 *
946940 * Pre-read data for a write-begin request by drawing data from the cache if
947941 * possible, or the netfs if not. Space beyond the EOF is zero-filled.
@@ -960,17 +954,18 @@ zero_out: · 12 unmodified lines
960954 * should go ahead; unlock the folio and return -EAGAIN to cause the folio to
961955 * be regot; or return an error.
962956 *
957+ * The calling netfs must initialise a netfs context contiguous to the vfs
958+ * inode before calling this.
959+ *
963960 * This is usable whether or not caching is enabled.
964961 */
965962 int netfs_write_begin(struct file *file, struct address_space *mapping,
966963 loff_t pos, unsigned int len, unsigned int aop_flags,
967− struct folio **_folio, void **_fsdata,
968− const struct netfs_request_ops *ops,
969− void *netfs_priv)
964+ struct folio **_folio, void **_fsdata)
970965 {
971966 struct netfs_io_request *rreq;
967+ struct netfs_i_context *ctx = netfs_i_context(file_inode(file ));
972968 struct folio *folio;
973− struct inode *inode = file_inode(file);
974969 unsigned int debug_index = 0, fgp_flags;
975970 pgoff_t index = pos >> PAGE_SHIFT;
976971 int ret;
@@ -986,9 +981,9 @@ retry: · 9 unmodified lines
986981 if (!folio)
987982 return -ENOMEM;
988983
989− if (ops->check_write_begin) {
984+ if (ctx->ops->check_write_begin) {
990985 /* Allow the netfs (eg. ceph) to flush conflicts. */
991− ret = ops->check_write_begin(file, pos, len, folio, _fsdata);
986+ ret = ctx->ops->check_write_begin(file, pos, len, folio, _fsdata);
992987 if (ret < 0) {
993988 trace_netfs_failure(NULL, NULL, ret, netfs_fail_check_write_begin);
994989 if (ret == -EAGAIN)
@@ -1004,13 +999,13 @@ retry: · 9 unmodified lines
1004999 * within the cache granule containing the EOF, in which case we need
10051000 * to preload the granule.
10061001 */
1007− if (!ops->is_cache_enabled(inode) &&
1008− netfs_skip_folio_read(folio, pos, len)) {
1002+ if (!netfs_is_cache_enabled(ctx) &&
1003+ netfs_skip_folio_read(folio, pos, len, false)) {
10091004 netfs_stat(&netfs_n_rh_write_zskip);
10101005 goto have_folio_no_wait;
10111006 }
10121007
1013− rreq = netfs_alloc_request(mapping, file, ops, netfs_priv,
1008+ rreq = netfs_alloc_request(mapping, file,
10141009 folio_file_pos(folio), folio_size(folio),
10151010 NETFS_READ_FOR_WRITE);
10161011 if (IS_ERR(rreq)) {
@@ -1019,10 +1014,9 @@ retry: · 2 unmodified lines
10191014 }
10201015 rreq->no_unlock_folio = folio_index(folio);
10211016 __set_bit(NETFS_RREQ_NO_UNLOCK_FOLIO, &rreq->flags);
1022− netfs_priv = NULL;
10231017
1024− if (ops->begin_cache_operation) {
1025− ret = ops->begin_cache_operation(rreq);
1018+ if (ctx->ops->begin_cache_operation) {
1019+ ret = ctx->ops->begin_cache_operation(rreq);
10261020 if (ret == -ENOMEM || ret == -EINTR || ret == -ERESTARTSYS)
10271021 goto error_put;
10281022 }
@@ -1076,8 +1070,6 @@ have_folio: · 47 unmodified lines
10761070 if (ret < 0)
10771071 goto error;
10781072 have_folio_no_wait:
1079− if (netfs_priv)
1080− ops->cleanup(mapping, netfs_priv);
10811073 *_folio = folio;
10821074 _leave(" = 0");
10831075 return 0;
@@ -1087,8 +1079,6 @@ error_put: · 3 unmodified lines
10871079 error:
10881080 folio_unlock(folio);
10891081 folio_put(folio);
1090− if (netfs_priv)
1091− ops->cleanup(mapping, netfs_priv);
10921082 _leave(" = %d", ret);
10931083 return ret;
10941084 }
fs/netfs/stats.c+0−1
@@ -7,7 +7,6 @@ · 6 unmodified lines
77
88 #include <linux/export.h>
99 #include <linux/seq_file.h>
10−#include <linux/netfs.h>
1110 #include "internal.h"
1211
1312 atomic_t netfs_n_rh_readahead;
include/linux/netfs.h+70−11
@@ -118,6 +118,16 @@ enum netfs_io_source { · 117 unmodified lines
118118 typedef void (*netfs_io_terminated_t)(void *priv, ssize_t transferred_or_error,
119119 bool was_async);
120120
121+/*
122+ * Per-inode description. This must be directly after the inode struct.
123+ */
124+struct netfs_i_context {
125+ const struct netfs_request_ops *ops;
126+#if IS_ENABLED(CONFIG_FSCACHE)
127+ struct fscache_cookie *cache;
128+#endif
129+};
130+
121131 /*
122132 * Resources required to do operations on a cache.
123133 */
@@ -192,7 +202,6 @@ struct netfs_io_request { · 68 unmodified lines
192202 * Operations the network filesystem can/must provide to the helpers.
193203 */
194204 struct netfs_request_ops {
195− bool (*is_cache_enabled)(struct inode *inode);
196205 int (*init_request)(struct netfs_io_request *rreq, struct file *file);
197206 int (*begin_cache_operation)(struct netfs_io_request *rreq);
198207 void (*expand_readahead)(struct netfs_io_request *rreq);
@@ -263,18 +272,11 @@ struct netfs_cache_ops { · 64 unmodified lines
263272 };
264273
265274 struct readahead_control;
266−extern void netfs_readahead(struct readahead_control *,
267− const struct netfs_request_ops *,
268− void *);
269−extern int netfs_readpage(struct file *,
270− struct folio *,
271− const struct netfs_request_ops *,
272− void *);
275+extern void netfs_readahead(struct readahead_control *);
276+extern int netfs_readpage(struct file *, struct page *);
273277 extern int netfs_write_begin(struct file *, struct address_space *,
274278 loff_t, unsigned int, unsigned int, struct folio **,
275− void **,
276− const struct netfs_request_ops *,
277− void *);
279+ void **);
278280
279281 extern void netfs_subreq_terminated(struct netfs_io_subrequest *, ssize_t, bool);
280282 extern void netfs_get_subrequest(struct netfs_io_subrequest *subreq,
@@ -283,4 +285,61 @@ extern void netfs_put_subrequest(struct netfs_io_subrequest *subreq, · 2 unmodified lines
283285 bool was_async, enum netfs_sreq_ref_trace what);
284286 extern void netfs_stats_show(struct seq_file *);
285287
288+/**
289+ * netfs_i_context - Get the netfs inode context from the inode
290+ * @inode: The inode to query
291+ *
292+ * Get the netfs lib inode context from the network filesystem's inode. The
293+ * context struct is expected to directly follow on from the VFS inode struct.
294+ */
295+static inline struct netfs_i_context *netfs_i_context(struct inode *inode)
296+{
297+ return (struct netfs_i_context *)(inode + 1);
298+}
299+
300+/**
301+ * netfs_inode - Get the netfs inode from the inode context
302+ * @ctx: The context to query
303+ *
304+ * Get the netfs inode from the netfs library's inode context. The VFS inode
305+ * is expected to directly precede the context struct.
306+ */
307+static inline struct inode *netfs_inode(struct netfs_i_context *ctx)
308+{
309+ return ((struct inode *)ctx) - 1;
310+}
311+
312+/**
313+ * netfs_i_context_init - Initialise a netfs lib context
314+ * @inode: The inode with which the context is associated
315+ * @ops: The netfs's operations list
316+ *
317+ * Initialise the netfs library context struct. This is expected to follow on
318+ * directly from the VFS inode struct.
319+ */
320+static inline void netfs_i_context_init(struct inode *inode,
321+ const struct netfs_request_ops *ops)
322+{
323+ struct netfs_i_context *ctx = netfs_i_context(inode);
324+
325+ memset(ctx, 0, sizeof(*ctx));
326+ ctx->ops = ops;
327+}
328+
329+/**
330+ * netfs_i_cookie - Get the cache cookie from the inode
331+ * @inode: The inode to query
332+ *
333+ * Get the caching cookie (if enabled) from the network filesystem's inode.
334+ */
335+static inline struct fscache_cookie *netfs_i_cookie(struct inode *inode)
336+{
337+#if IS_ENABLED(CONFIG_FSCACHE)
338+ struct netfs_i_context *ctx = netfs_i_context(inode);
339+ return ctx->cache;
340+#else
341+ return NULL;
342+#endif
343+}
344+
286345 #endif /* _LINUX_NETFS_H */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t