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
7.. Contents:7.. Contents:
8 8
9 - Overview.9 - Overview.
10 - Per-inode context.
11 - Inode context helper functions.
10 - Buffered read helpers.12 - Buffered read helpers.
11 - Read helper functions.13 - Read helper functions.
12 - Read helper structures.14 - Read helper structures.
@@ -28,6 +30,69 @@ Note that the library module doesn't link against local caching directly, so · 15 unmodified lines
28access must be provided by the netfs.30access must be provided by the netfs.
29 31
30 32
33Per-Inode Context
34=================
35
36The network filesystem helper library needs a place to store a bit of state for
37its use on each netfs inode it is helping to manage. To this end, a context
38structure is defined::
39
40 struct netfs_i_context {
41 const struct netfs_request_ops *ops;
42 struct fscache_cookie *cache;
43 };
44
45A network filesystem that wants to use netfs lib must place one of these
46directly after the VFS ``struct inode`` it allocates, usually as part of its
47own 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
58This allows netfslib to find its state by simple offset from the inode pointer,
59thereby allowing the netfslib helper functions to be pointed to directly by the
60VFS/VM operation tables.
61
62The 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
74Inode Context Helper Functions
75------------------------------
76
77To help deal with the per-inode context, a number helper functions are
78provided. Firstly, a function to perform basic initialisation on a context and
79set the operations table pointer::
80
81 void netfs_i_context_init(struct inode *inode,
82 const struct netfs_request_ops *ops);
83
84then two functions to cast between the VFS inode structure and the netfs
85context::
86
87 struct netfs_i_context *netfs_i_context(struct inode *inode);
88 struct inode *netfs_inode(struct netfs_i_context *ctx);
89
90and finally, a function to get the cache cookie pointer from the context
91attached to an inode (or NULL if fscache is disabled)::
92
93 struct fscache_cookie *netfs_i_cookie(struct inode *inode);
94
95
31Buffered Read Helpers96Buffered Read Helpers
32=====================97=====================
33 98
@@ -70,38 +135,22 @@ Read Helper Functions · 36 unmodified lines
70 135
71Three read helpers are provided::136Three read helpers are provided::
72 137
73 void netfs_readahead(struct readahead_control *ractl,138 void netfs_readahead(struct readahead_control *ractl);
74 const struct netfs_request_ops *ops,
75 void *netfs_priv);
76 int netfs_readpage(struct file *file,139 int netfs_readpage(struct file *file,
77 struct folio *folio,140 struct page *page);
78 const struct netfs_request_ops *ops,
79 void *netfs_priv);
80 int netfs_write_begin(struct file *file,141 int netfs_write_begin(struct file *file,
81 struct address_space *mapping,142 struct address_space *mapping,
82 loff_t pos,143 loff_t pos,
83 unsigned int len,144 unsigned int len,
84 unsigned int flags,145 unsigned int flags,
85 struct folio **_folio,146 struct folio **_folio,
86 void **_fsdata,147 void **_fsdata);
87 const struct netfs_request_ops *ops,
88 void *netfs_priv);
89
90Each corresponds to a VM operation, with the addition of a couple of parameters
91for the use of the read helpers:
92 148
93 * ``ops``149Each corresponds to a VM address space operation. These operations use the
94 150state in the per-inode context.
95 A table of operations through which the helpers can talk to the filesystem.
96
97 * ``netfs_priv``
98 151
99 Filesystem private data (can be NULL).152For ->readahead() and ->readpage(), the network filesystem just point directly
100 153at the corresponding read helper; whereas for ->write_begin(), it may be a
101Both of these values will be stored into the read request structure.
102
103For ->readahead() and ->readpage(), the network filesystem should just jump
104into the corresponding read helper; whereas for ->write_begin(), it may be a
105little more complicated as the network filesystem might want to flush154little more complicated as the network filesystem might want to flush
106conflicting writes or track dirty data and needs to put the acquired folio if155conflicting writes or track dirty data and needs to put the acquired folio if
107an error occurs after calling the helper.156an error occurs after calling the helper.
@@ -246,7 +295,6 @@ through which it can issue requests and negotiate:: · 138 unmodified lines
246 295
247 struct netfs_request_ops {296 struct netfs_request_ops {
248 void (*init_request)(struct netfs_io_request *rreq, struct file *file);297 void (*init_request)(struct netfs_io_request *rreq, struct file *file);
249 bool (*is_cache_enabled)(struct inode *inode);
250 int (*begin_cache_operation)(struct netfs_io_request *rreq);298 int (*begin_cache_operation)(struct netfs_io_request *rreq);
251 void (*expand_readahead)(struct netfs_io_request *rreq);299 void (*expand_readahead)(struct netfs_io_request *rreq);
252 bool (*clamp_length)(struct netfs_io_subrequest *subreq);300 bool (*clamp_length)(struct netfs_io_subrequest *subreq);
@@ -265,11 +313,6 @@ The operations are as follows: · 12 unmodified lines
265 [Optional] This is called to initialise the request structure. It is given313 [Optional] This is called to initialise the request structure. It is given
266 the file for reference and can modify the ->netfs_priv value.314 the file for reference and can modify the ->netfs_priv value.
267 315
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
273 * ``begin_cache_operation()``316 * ``begin_cache_operation()``
274 317
275 [Optional] This is called to ask the network filesystem to call into the318 [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
49 49
50void v9fs_cache_inode_get_cookie(struct inode *inode)50void v9fs_cache_inode_get_cookie(struct inode *inode)
51{51{
52 struct v9fs_inode *v9inode;52 struct v9fs_inode *v9inode = V9FS_I(inode);
53 struct v9fs_session_info *v9ses;53 struct v9fs_session_info *v9ses;
54 __le32 version;54 __le32 version;
55 __le64 path;55 __le64 path;
56 56
57 if (!S_ISREG(inode->i_mode))57 if (!S_ISREG(inode->i_mode))
58 return;58 return;
59 59 if (WARN_ON(v9fs_inode_cookie(v9inode)))
60 v9inode = V9FS_I(inode);
61 if (WARN_ON(v9inode->fscache))
62 return;60 return;
63 61
64 version = cpu_to_le32(v9inode->qid.version);62 version = cpu_to_le32(v9inode->qid.version);
65 path = cpu_to_le64(v9inode->qid.path);63 path = cpu_to_le64(v9inode->qid.path);
66 v9ses = v9fs_inode2v9ses(inode);64 v9ses = v9fs_inode2v9ses(inode);
67 v9inode->fscache =65 v9inode->netfs_ctx.cache =
68 fscache_acquire_cookie(v9fs_session_cache(v9ses),66 fscache_acquire_cookie(v9fs_session_cache(v9ses),
69 0,67 0,
70 &path, sizeof(path),68 &path, sizeof(path),
@@ -72,5 +70,5 @@ void v9fs_cache_inode_get_cookie(struct inode *inode) · 1 unmodified line
72 i_size_read(&v9inode->vfs_inode));70 i_size_read(&v9inode->vfs_inode));
73 71
74 p9_debug(P9_DEBUG_FSC, "inode %p get cookie %p\n",72 p9_debug(P9_DEBUG_FSC, "inode %p get cookie %p\n",
75 inode, v9inode->fscache);73 inode, v9fs_inode_cookie(v9inode));
76}74}
fs/9p/v9fs.c+1−3
@@ -623,9 +623,7 @@ static void v9fs_sysfs_cleanup(void) · 622 unmodified lines
623static void v9fs_inode_init_once(void *foo)623static void v9fs_inode_init_once(void *foo)
624{624{
625 struct v9fs_inode *v9inode = (struct v9fs_inode *)foo;625 struct v9fs_inode *v9inode = (struct v9fs_inode *)foo;
626#ifdef CONFIG_9P_FSCACHE626
627 v9inode->fscache = NULL;
628#endif
629 memset(&v9inode->qid, 0, sizeof(v9inode->qid));627 memset(&v9inode->qid, 0, sizeof(v9inode->qid));
630 inode_init_once(&v9inode->vfs_inode);628 inode_init_once(&v9inode->vfs_inode);
631}629}
fs/9p/v9fs.h+8−5
@@ -9,6 +9,7 @@ · 8 unmodified lines
9#define FS_9P_V9FS_H9#define FS_9P_V9FS_H
10 10
11#include <linux/backing-dev.h>11#include <linux/backing-dev.h>
12#include <linux/netfs.h>
12 13
13/**14/**
14 * enum p9_session_flags - option flags for each 9P session15 * enum p9_session_flags - option flags for each 9P session
@@ -108,14 +109,15 @@ struct v9fs_session_info { · 93 unmodified lines
108#define V9FS_INO_INVALID_ATTR 0x01109#define V9FS_INO_INVALID_ATTR 0x01
109 110
110struct v9fs_inode {111struct v9fs_inode {
111#ifdef CONFIG_9P_FSCACHE112 struct {
112 struct fscache_cookie *fscache;113 /* These must be contiguous */
113#endif114 struct inode vfs_inode; /* the VFS's inode record */
115 struct netfs_i_context netfs_ctx; /* Netfslib context */
116 };
114 struct p9_qid qid;117 struct p9_qid qid;
115 unsigned int cache_validity;118 unsigned int cache_validity;
116 struct p9_fid *writeback_fid;119 struct p9_fid *writeback_fid;
117 struct mutex v_mutex;120 struct mutex v_mutex;
118 struct inode vfs_inode;
119};121};
120 122
121static inline struct v9fs_inode *V9FS_I(const struct inode *inode)123static 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
126static inline struct fscache_cookie *v9fs_inode_cookie(struct v9fs_inode *v9inode)128static inline struct fscache_cookie *v9fs_inode_cookie(struct v9fs_inode *v9inode)
127{129{
128#ifdef CONFIG_9P_FSCACHE130#ifdef CONFIG_9P_FSCACHE
129 return v9inode->fscache;131 return netfs_i_cookie(&v9inode->vfs_inode);
130#else132#else
131 return NULL;133 return NULL;
132#endif134#endif
@@ -163,6 +165,7 @@ extern struct inode *v9fs_inode_from_fid(struct v9fs_session_info *v9ses, · 30 unmodified lines
163extern const struct inode_operations v9fs_dir_inode_operations_dotl;165extern const struct inode_operations v9fs_dir_inode_operations_dotl;
164extern const struct inode_operations v9fs_file_inode_operations_dotl;166extern const struct inode_operations v9fs_file_inode_operations_dotl;
165extern const struct inode_operations v9fs_symlink_inode_operations_dotl;167extern const struct inode_operations v9fs_symlink_inode_operations_dotl;
168extern const struct netfs_request_ops v9fs_req_ops;
166extern struct inode *v9fs_inode_from_fid_dotl(struct v9fs_session_info *v9ses,169extern struct inode *v9fs_inode_from_fid_dotl(struct v9fs_session_info *v9ses,
167 struct p9_fid *fid,170 struct p9_fid *fid,
168 struct super_block *sb, int new);171 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
77 p9_client_clunk(fid);77 p9_client_clunk(fid);
78}78}
79 79
80/**
81 * v9fs_is_cache_enabled - Determine if caching is enabled for an inode
82 * @inode: The inode to check
83 */
84static 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
91/**80/**
92 * v9fs_begin_cache_operation - Begin a cache operation for a read81 * v9fs_begin_cache_operation - Begin a cache operation for a read
93 * @rreq: The read request82 * @rreq: The read request
@@ -103,36 +92,13 @@ static int v9fs_begin_cache_operation(struct netfs_io_request *rreq) · 9 unmodified lines
103#endif92#endif
104}93}
105 94
106static const struct netfs_request_ops v9fs_req_ops = {95const struct netfs_request_ops v9fs_req_ops = {
107 .init_request = v9fs_init_request,96 .init_request = v9fs_init_request,
108 .is_cache_enabled = v9fs_is_cache_enabled,
109 .begin_cache_operation = v9fs_begin_cache_operation,97 .begin_cache_operation = v9fs_begin_cache_operation,
110 .issue_read = v9fs_issue_read,98 .issue_read = v9fs_issue_read,
111 .cleanup = v9fs_req_cleanup,99 .cleanup = v9fs_req_cleanup,
112};100};
113 101
114/**
115 * v9fs_vfs_readpage - read an entire page in from 9P
116 * @file: file being read
117 * @page: structure to page
118 *
119 */
120static 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 */
131static void v9fs_vfs_readahead(struct readahead_control *ractl)
132{
133 netfs_readahead(ractl, &v9fs_req_ops, NULL);
134}
135
136/**102/**
137 * v9fs_release_page - release the private state associated with a page103 * v9fs_release_page - release the private state associated with a page
138 * @page: The page to be released104 * @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
326 * file. We need to do this before we get a lock on the page in case292 * file. We need to do this before we get a lock on the page in case
327 * there's more than one writer competing for the same cache block.293 * there's more than one writer competing for the same cache block.
328 */294 */
329 retval = netfs_write_begin(filp, mapping, pos, len, flags, &folio, fsdata,295 retval = netfs_write_begin(filp, mapping, pos, len, flags, &folio, fsdata);
330 &v9fs_req_ops, NULL);
331 if (retval < 0)296 if (retval < 0)
332 return retval;297 return retval;
333 298
@@ -388,8 +353,8 @@ static int v9fs_set_page_dirty(struct page *page) · 54 unmodified lines
388#endif353#endif
389 354
390const struct address_space_operations v9fs_addr_operations = {355const struct address_space_operations v9fs_addr_operations = {
391 .readpage = v9fs_vfs_readpage,356 .readpage = netfs_readpage,
392 .readahead = v9fs_vfs_readahead,357 .readahead = netfs_readahead,
393 .set_page_dirty = v9fs_set_page_dirty,358 .set_page_dirty = v9fs_set_page_dirty,
394 .writepage = v9fs_vfs_writepage,359 .writepage = v9fs_vfs_writepage,
395 .write_begin = v9fs_write_begin,360 .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
231 v9inode = kmem_cache_alloc(v9fs_inode_cache, GFP_KERNEL);231 v9inode = kmem_cache_alloc(v9fs_inode_cache, GFP_KERNEL);
232 if (!v9inode)232 if (!v9inode)
233 return NULL;233 return NULL;
234#ifdef CONFIG_9P_FSCACHE
235 v9inode->fscache = NULL;
236#endif
237 v9inode->writeback_fid = NULL;234 v9inode->writeback_fid = NULL;
238 v9inode->cache_validity = 0;235 v9inode->cache_validity = 0;
239 mutex_init(&v9inode->v_mutex);236 mutex_init(&v9inode->v_mutex);
@@ -250,6 +247,14 @@ void v9fs_free_inode(struct inode *inode) · 10 unmodified lines
250 kmem_cache_free(v9fs_inode_cache, V9FS_I(inode));247 kmem_cache_free(v9fs_inode_cache, V9FS_I(inode));
251}248}
252 249
250/*
251 * Set parameters for the netfs library
252 */
253static void v9fs_set_netfs_context(struct inode *inode)
254{
255 netfs_i_context_init(inode, &v9fs_req_ops);
256}
257
253int v9fs_init_inode(struct v9fs_session_info *v9ses,258int v9fs_init_inode(struct v9fs_session_info *v9ses,
254 struct inode *inode, umode_t mode, dev_t rdev)259 struct inode *inode, umode_t mode, dev_t rdev)
255{260{
@@ -338,6 +343,8 @@ int v9fs_init_inode(struct v9fs_session_info *v9ses, · 82 unmodified lines
338 err = -EINVAL;343 err = -EINVAL;
339 goto error;344 goto error;
340 }345 }
346
347 v9fs_set_netfs_context(inode);
341error:348error:
342 return err;349 return err;
343 350
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
76 /* there shouldn't be an existing inode */76 /* there shouldn't be an existing inode */
77 BUG_ON(!(inode->i_state & I_NEW));77 BUG_ON(!(inode->i_state & I_NEW));
78 78
79 netfs_i_context_init(inode, NULL);
79 inode->i_size = 0;80 inode->i_size = 0;
80 inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;81 inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
81 if (root) {82 if (root) {
fs/afs/file.c+2−24
@@ -19,13 +19,11 @@ · 18 unmodified lines
19#include "internal.h"19#include "internal.h"
20 20
21static int afs_file_mmap(struct file *file, struct vm_area_struct *vma);21static int afs_file_mmap(struct file *file, struct vm_area_struct *vma);
22static int afs_readpage(struct file *file, struct page *page);
23static int afs_symlink_readpage(struct file *file, struct page *page);22static int afs_symlink_readpage(struct file *file, struct page *page);
24static void afs_invalidatepage(struct page *page, unsigned int offset,23static void afs_invalidatepage(struct page *page, unsigned int offset,
25 unsigned int length);24 unsigned int length);
26static int afs_releasepage(struct page *page, gfp_t gfp_flags);25static int afs_releasepage(struct page *page, gfp_t gfp_flags);
27 26
28static void afs_readahead(struct readahead_control *ractl);
29static ssize_t afs_file_read_iter(struct kiocb *iocb, struct iov_iter *iter);27static ssize_t afs_file_read_iter(struct kiocb *iocb, struct iov_iter *iter);
30static void afs_vm_open(struct vm_area_struct *area);28static void afs_vm_open(struct vm_area_struct *area);
31static void afs_vm_close(struct vm_area_struct *area);29static void afs_vm_close(struct vm_area_struct *area);
@@ -52,8 +50,8 @@ const struct inode_operations afs_file_inode_operations = { · 20 unmodified lines
52};50};
53 51
54const struct address_space_operations afs_file_aops = {52const struct address_space_operations afs_file_aops = {
55 .readpage = afs_readpage,53 .readpage = netfs_readpage,
56 .readahead = afs_readahead,54 .readahead = netfs_readahead,
57 .set_page_dirty = afs_set_page_dirty,55 .set_page_dirty = afs_set_page_dirty,
58 .launder_page = afs_launder_page,56 .launder_page = afs_launder_page,
59 .releasepage = afs_releasepage,57 .releasepage = afs_releasepage,
@@ -365,13 +363,6 @@ static int afs_init_request(struct netfs_io_request *rreq, struct file *file) · 305 unmodified lines
365 return 0;363 return 0;
366}364}
367 365
368static 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
375static int afs_begin_cache_operation(struct netfs_io_request *rreq)366static int afs_begin_cache_operation(struct netfs_io_request *rreq)
376{367{
377#ifdef CONFIG_AFS_FSCACHE368#ifdef CONFIG_AFS_FSCACHE
@@ -399,25 +390,12 @@ static void afs_priv_cleanup(struct address_space *mapping, void *netfs_priv) · 21 unmodified lines
399 390
400const struct netfs_request_ops afs_req_ops = {391const struct netfs_request_ops afs_req_ops = {
401 .init_request = afs_init_request,392 .init_request = afs_init_request,
402 .is_cache_enabled = afs_is_cache_enabled,
403 .begin_cache_operation = afs_begin_cache_operation,393 .begin_cache_operation = afs_begin_cache_operation,
404 .check_write_begin = afs_check_write_begin,394 .check_write_begin = afs_check_write_begin,
405 .issue_read = afs_issue_read,395 .issue_read = afs_issue_read,
406 .cleanup = afs_priv_cleanup,396 .cleanup = afs_priv_cleanup,
407};397};
408 398
409static 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
416static void afs_readahead(struct readahead_control *ractl)
417{
418 netfs_readahead(ractl, &afs_req_ops, NULL);
419}
420
421int afs_write_inode(struct inode *inode, struct writeback_control *wbc)399int afs_write_inode(struct inode *inode, struct writeback_control *wbc)
422{400{
423 fscache_unpin_writeback(wbc, afs_vnode_cache(AFS_FS_I(inode)));401 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
53 dump_stack();53 dump_stack();
54}54}
55 55
56/*
57 * Set parameters for the netfs library
58 */
59static void afs_set_netfs_context(struct afs_vnode *vnode)
60{
61 netfs_i_context_init(&vnode->vfs_inode, &afs_req_ops);
62}
63
56/*64/*
57 * Initialise an inode from the vnode status.65 * Initialise an inode from the vnode status.
58 */66 */
@@ -128,6 +136,7 @@ static int afs_inode_init_from_status(struct afs_operation *op, · 69 unmodified lines
128 }136 }
129 137
130 afs_set_i_size(vnode, status->size);138 afs_set_i_size(vnode, status->size);
139 afs_set_netfs_context(vnode);
131 140
132 vnode->invalid_before = status->data_version;141 vnode->invalid_before = status->data_version;
133 inode_set_iversion_raw(&vnode->vfs_inode, status->data_version);142 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
420 struct afs_vnode_cache_aux aux;429 struct afs_vnode_cache_aux aux;
421 430
422 if (vnode->status.type != AFS_FTYPE_FILE) {431 if (vnode->status.type != AFS_FTYPE_FILE) {
423 vnode->cache = NULL;432 vnode->netfs_ctx.cache = NULL;
424 return;433 return;
425 }434 }
426 435
@@ -430,12 +439,14 @@ static void afs_get_inode_cache(struct afs_vnode *vnode) · 3 unmodified lines
430 key.vnode_id_ext[1] = htonl(vnode->fid.vnode_hi);439 key.vnode_id_ext[1] = htonl(vnode->fid.vnode_hi);
431 afs_set_cache_aux(vnode, &aux);440 afs_set_cache_aux(vnode, &aux);
432 441
433 vnode->cache = fscache_acquire_cookie(442 afs_vnode_set_cache(vnode,
434 vnode->volume->cache,443 fscache_acquire_cookie(
435 vnode->status.type == AFS_FTYPE_FILE ? 0 : FSCACHE_ADV_SINGLE_CHUNK,444 vnode->volume->cache,
436 &key, sizeof(key),445 vnode->status.type == AFS_FTYPE_FILE ?
437 &aux, sizeof(aux),446 0 : FSCACHE_ADV_SINGLE_CHUNK,
438 vnode->status.size);447 &key, sizeof(key),
448 &aux, sizeof(aux),
449 vnode->status.size));
439#endif450#endif
440}451}
441 452
@@ -528,6 +539,7 @@ struct inode *afs_root_iget(struct super_block *sb, struct key *key) · 86 unmodified lines
528 539
529 vnode = AFS_FS_I(inode);540 vnode = AFS_FS_I(inode);
530 vnode->cb_v_break = as->volume->cb_v_break,541 vnode->cb_v_break = as->volume->cb_v_break,
542 afs_set_netfs_context(vnode);
531 543
532 op = afs_alloc_operation(key, as->volume);544 op = afs_alloc_operation(key, as->volume);
533 if (IS_ERR(op)) {545 if (IS_ERR(op)) {
@@ -786,11 +798,8 @@ void afs_evict_inode(struct inode *inode) · 252 unmodified lines
786 afs_put_wb_key(wbk);798 afs_put_wb_key(wbk);
787 }799 }
788 800
789#ifdef CONFIG_AFS_FSCACHE801 fscache_relinquish_cookie(afs_vnode_cache(vnode),
790 fscache_relinquish_cookie(vnode->cache,
791 test_bit(AFS_VNODE_DELETED, &vnode->flags));802 test_bit(AFS_VNODE_DELETED, &vnode->flags));
792 vnode->cache = NULL;
793#endif
794 803
795 afs_prune_wb_keys(vnode);804 afs_prune_wb_keys(vnode);
796 afs_put_permits(rcu_access_pointer(vnode->permit_cache));805 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
619 * leak from one inode to another.619 * leak from one inode to another.
620 */620 */
621struct afs_vnode {621struct 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 };
623 627
624 struct afs_volume *volume; /* volume on which vnode resides */628 struct afs_volume *volume; /* volume on which vnode resides */
625 struct afs_fid fid; /* the file identifier for this inode */629 struct afs_fid fid; /* the file identifier for this inode */
626 struct afs_file_status status; /* AFS status info for this file */630 struct afs_file_status status; /* AFS status info for this file */
627 afs_dataversion_t invalid_before; /* Child dentries are invalid before this */631 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
631 struct afs_permits __rcu *permit_cache; /* cache of permits so far obtained */632 struct afs_permits __rcu *permit_cache; /* cache of permits so far obtained */
632 struct mutex io_lock; /* Lock for serialising I/O on this mutex */633 struct mutex io_lock; /* Lock for serialising I/O on this mutex */
633 struct rw_semaphore validate_lock; /* lock for validating this vnode */634 struct rw_semaphore validate_lock; /* lock for validating this vnode */
@@ -674,12 +675,20 @@ struct afs_vnode { · 40 unmodified lines
674static inline struct fscache_cookie *afs_vnode_cache(struct afs_vnode *vnode)675static inline struct fscache_cookie *afs_vnode_cache(struct afs_vnode *vnode)
675{676{
676#ifdef CONFIG_AFS_FSCACHE677#ifdef CONFIG_AFS_FSCACHE
677 return vnode->cache;678 return netfs_i_cookie(&vnode->vfs_inode);
678#else679#else
679 return NULL;680 return NULL;
680#endif681#endif
681}682}
682 683
684static 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
683/*692/*
684 * cached security record for one user's attempt to access a vnode693 * cached security record for one user's attempt to access a vnode
685 */694 */
fs/afs/super.c+1−3
@@ -688,13 +688,11 @@ static struct inode *afs_alloc_inode(struct super_block *sb) · 687 unmodified lines
688 /* Reset anything that shouldn't leak from one inode to the next. */688 /* Reset anything that shouldn't leak from one inode to the next. */
689 memset(&vnode->fid, 0, sizeof(vnode->fid));689 memset(&vnode->fid, 0, sizeof(vnode->fid));
690 memset(&vnode->status, 0, sizeof(vnode->status));690 memset(&vnode->status, 0, sizeof(vnode->status));
691 afs_vnode_set_cache(vnode, NULL);
691 692
692 vnode->volume = NULL;693 vnode->volume = NULL;
693 vnode->lock_key = NULL;694 vnode->lock_key = NULL;
694 vnode->permit_cache = NULL;695 vnode->permit_cache = NULL;
695#ifdef CONFIG_AFS_FSCACHE
696 vnode->cache = NULL;
697#endif
698 696
699 vnode->flags = 1 << AFS_VNODE_UNSET;697 vnode->flags = 1 << AFS_VNODE_UNSET;
700 vnode->lock_state = AFS_VNODE_LOCK_NONE;698 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
59 * file. We need to do this before we get a lock on the page in case59 * file. We need to do this before we get a lock on the page in case
60 * there's more than one writer competing for the same cache block.60 * there's more than one writer competing for the same cache block.
61 */61 */
62 ret = netfs_write_begin(file, mapping, pos, len, flags, &folio, fsdata,62 ret = netfs_write_begin(file, mapping, pos, len, flags, &folio, fsdata);
63 &afs_req_ops, NULL);
64 if (ret < 0)63 if (ret < 0)
65 return ret;64 return ret;
66 65
fs/ceph/addr.c+4−27
@@ -403,7 +403,7 @@ static void ceph_readahead_cleanup(struct address_space *mapping, void *priv) · 402 unmodified lines
403 ceph_put_cap_refs(ci, got);403 ceph_put_cap_refs(ci, got);
404}404}
405 405
406static const struct netfs_request_ops ceph_netfs_read_ops = {406const struct netfs_request_ops ceph_netfs_ops = {
407 .init_request = ceph_init_request,407 .init_request = ceph_init_request,
408 .begin_cache_operation = ceph_begin_cache_operation,408 .begin_cache_operation = ceph_begin_cache_operation,
409 .issue_read = ceph_netfs_issue_read,409 .issue_read = ceph_netfs_issue_read,
@@ -413,28 +413,6 @@ static const struct netfs_request_ops ceph_netfs_read_ops = { · 3 unmodified lines
413 .cleanup = ceph_readahead_cleanup,413 .cleanup = ceph_readahead_cleanup,
414};414};
415 415
416/* read a single page, without unlocking it. */
417static 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
433static void ceph_readahead(struct readahead_control *ractl)
434{
435 netfs_readahead(ractl, &ceph_netfs_read_ops, NULL);
436}
437
438#ifdef CONFIG_CEPH_FSCACHE416#ifdef CONFIG_CEPH_FSCACHE
439static void ceph_set_page_fscache(struct page *page)417static void ceph_set_page_fscache(struct page *page)
440{418{
@@ -1333,8 +1311,7 @@ static int ceph_write_begin(struct file *file, struct address_space *mapping, · 892 unmodified lines
1333 struct folio *folio = NULL;1311 struct folio *folio = NULL;
1334 int r;1312 int r;
1335 1313
1336 r = netfs_write_begin(file, inode->i_mapping, pos, len, 0, &folio, NULL,1314 r = netfs_write_begin(file, inode->i_mapping, pos, len, 0, &folio, NULL);
1337 &ceph_netfs_read_ops, NULL);
1338 if (r == 0)1315 if (r == 0)
1339 folio_wait_fscache(folio);1316 folio_wait_fscache(folio);
1340 if (r < 0) {1317 if (r < 0) {
@@ -1388,8 +1365,8 @@ out: · 47 unmodified lines
1388}1365}
1389 1366
1390const struct address_space_operations ceph_aops = {1367const struct address_space_operations ceph_aops = {
1391 .readpage = ceph_readpage,1368 .readpage = netfs_readpage,
1392 .readahead = ceph_readahead,1369 .readahead = netfs_readahead,
1393 .writepage = ceph_writepage,1370 .writepage = ceph_writepage,
1394 .writepages = ceph_writepages_start,1371 .writepages = ceph_writepages_start,
1395 .write_begin = ceph_write_begin,1372 .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
29 if (!(inode->i_state & I_NEW))29 if (!(inode->i_state & I_NEW))
30 return;30 return;
31 31
32 WARN_ON_ONCE(ci->fscache);32 WARN_ON_ONCE(ci->netfs_ctx.cache);
33 33
34 ci->fscache = fscache_acquire_cookie(fsc->fscache, 0,34 ci->netfs_ctx.cache =
35 &ci->i_vino, sizeof(ci->i_vino),35 fscache_acquire_cookie(fsc->fscache, 0,
36 &ci->i_version, sizeof(ci->i_version),36 &ci->i_vino, sizeof(ci->i_vino),
37 i_size_read(inode));37 &ci->i_version, sizeof(ci->i_version),
38 i_size_read(inode));
38}39}
39 40
40void ceph_fscache_unregister_inode_cookie(struct ceph_inode_info* ci)41void ceph_fscache_unregister_inode_cookie(struct ceph_inode_info *ci)
41{42{
42 struct fscache_cookie *cookie = ci->fscache;43 fscache_relinquish_cookie(ceph_fscache_cookie(ci), false);
43
44 fscache_relinquish_cookie(cookie, false);
45}44}
46 45
47void ceph_fscache_use_cookie(struct inode *inode, bool will_modify)46void ceph_fscache_use_cookie(struct inode *inode, bool will_modify)
48{47{
49 struct ceph_inode_info *ci = ceph_inode(inode);48 struct ceph_inode_info *ci = ceph_inode(inode);
50 49
51 fscache_use_cookie(ci->fscache, will_modify);50 fscache_use_cookie(ceph_fscache_cookie(ci), will_modify);
52}51}
53 52
54void ceph_fscache_unuse_cookie(struct inode *inode, bool update)53void 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
58 if (update) {57 if (update) {
59 loff_t i_size = i_size_read(inode);58 loff_t i_size = i_size_read(inode);
60 59
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);
62 } else {62 } else {
63 fscache_unuse_cookie(ci->fscache, NULL, NULL);63 fscache_unuse_cookie(ceph_fscache_cookie(ci), NULL, NULL);
64 }64 }
65}65}
66 66
@@ -69,14 +69,14 @@ void ceph_fscache_update(struct inode *inode) · 2 unmodified lines
69 struct ceph_inode_info *ci = ceph_inode(inode);69 struct ceph_inode_info *ci = ceph_inode(inode);
70 loff_t i_size = i_size_read(inode);70 loff_t i_size = i_size_read(inode);
71 71
72 fscache_update_cookie(ci->fscache, &ci->i_version, &i_size);72 fscache_update_cookie(ceph_fscache_cookie(ci), &ci->i_version, &i_size);
73}73}
74 74
75void ceph_fscache_invalidate(struct inode *inode, bool dio_write)75void ceph_fscache_invalidate(struct inode *inode, bool dio_write)
76{76{
77 struct ceph_inode_info *ci = ceph_inode(inode);77 struct ceph_inode_info *ci = ceph_inode(inode);
78 78
79 fscache_invalidate(ceph_inode(inode)->fscache,79 fscache_invalidate(ceph_fscache_cookie(ci),
80 &ci->i_version, i_size_read(inode),80 &ci->i_version, i_size_read(inode),
81 dio_write ? FSCACHE_INVAL_DIO_WRITE : 0);81 dio_write ? FSCACHE_INVAL_DIO_WRITE : 0);
82}82}
fs/ceph/cache.h+1−10
@@ -26,14 +26,9 @@ void ceph_fscache_unuse_cookie(struct inode *inode, bool update); · 25 unmodified lines
26void ceph_fscache_update(struct inode *inode);26void ceph_fscache_update(struct inode *inode);
27void ceph_fscache_invalidate(struct inode *inode, bool dio_write);27void ceph_fscache_invalidate(struct inode *inode, bool dio_write);
28 28
29static inline void ceph_fscache_inode_init(struct ceph_inode_info *ci)
30{
31 ci->fscache = NULL;
32}
33
34static inline struct fscache_cookie *ceph_fscache_cookie(struct ceph_inode_info *ci)29static inline struct fscache_cookie *ceph_fscache_cookie(struct ceph_inode_info *ci)
35{30{
36 return ci->fscache;31 return netfs_i_cookie(&ci->vfs_inode);
37}32}
38 33
39static inline void ceph_fscache_resize(struct inode *inode, loff_t to)34static 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
91{86{
92}87}
93 88
94static inline void ceph_fscache_inode_init(struct ceph_inode_info *ci)
95{
96}
97
98static inline void ceph_fscache_register_inode_cookie(struct inode *inode)89static inline void ceph_fscache_register_inode_cookie(struct inode *inode)
99{90{
100}91}
fs/ceph/inode.c+3−3
@@ -453,6 +453,9 @@ struct inode *ceph_alloc_inode(struct super_block *sb) · 452 unmodified lines
453 453
454 dout("alloc_inode %p\n", &ci->vfs_inode);454 dout("alloc_inode %p\n", &ci->vfs_inode);
455 455
456 /* Set parameters for the netfs library */
457 netfs_i_context_init(&ci->vfs_inode, &ceph_netfs_ops);
458
456 spin_lock_init(&ci->i_ceph_lock);459 spin_lock_init(&ci->i_ceph_lock);
457 460
458 ci->i_version = 0;461 ci->i_version = 0;
@@ -538,9 +541,6 @@ struct inode *ceph_alloc_inode(struct super_block *sb) · 79 unmodified lines
538 INIT_WORK(&ci->i_work, ceph_inode_work);541 INIT_WORK(&ci->i_work, ceph_inode_work);
539 ci->i_work_mask = 0;542 ci->i_work_mask = 0;
540 memset(&ci->i_btime, '\0', sizeof(ci->i_btime));543 memset(&ci->i_btime, '\0', sizeof(ci->i_btime));
541
542 ceph_fscache_inode_init(ci);
543
544 return &ci->vfs_inode;544 return &ci->vfs_inode;
545}545}
546 546
fs/ceph/super.h+8−9
@@ -17,13 +17,11 @@ · 16 unmodified lines
17#include <linux/posix_acl.h>17#include <linux/posix_acl.h>
18#include <linux/refcount.h>18#include <linux/refcount.h>
19#include <linux/security.h>19#include <linux/security.h>
20#include <linux/netfs.h>
21#include <linux/fscache.h>
20 22
21#include <linux/ceph/libceph.h>23#include <linux/ceph/libceph.h>
22 24
23#ifdef CONFIG_CEPH_FSCACHE
24#include <linux/fscache.h>
25#endif
26
27/* large granularity for statfs utilization stats to facilitate25/* large granularity for statfs utilization stats to facilitate
28 * large volume sizes on 32-bit machines. */26 * large volume sizes on 32-bit machines. */
29#define CEPH_BLOCK_SHIFT 22 /* 4 MB */27#define CEPH_BLOCK_SHIFT 22 /* 4 MB */
@@ -317,6 +315,11 @@ struct ceph_inode_xattrs_info { · 287 unmodified lines
317 * Ceph inode.315 * Ceph inode.
318 */316 */
319struct ceph_inode_info {317struct 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 };
320 struct ceph_vino i_vino; /* ceph ino + snap */323 struct ceph_vino i_vino; /* ceph ino + snap */
321 324
322 spinlock_t i_ceph_lock;325 spinlock_t i_ceph_lock;
@@ -427,11 +430,6 @@ struct ceph_inode_info { · 104 unmodified lines
427 430
428 struct work_struct i_work;431 struct work_struct i_work;
429 unsigned long i_work_mask;432 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 */
435};433};
436 434
437static inline struct ceph_inode_info *435static inline struct ceph_inode_info *
@@ -1215,6 +1213,7 @@ extern void __ceph_touch_fmode(struct ceph_inode_info *ci, · 777 unmodified lines
1215 1213
1216/* addr.c */1214/* addr.c */
1217extern const struct address_space_operations ceph_aops;1215extern const struct address_space_operations ceph_aops;
1216extern const struct netfs_request_ops ceph_netfs_ops;
1218extern int ceph_mmap(struct file *file, struct vm_area_struct *vma);1217extern int ceph_mmap(struct file *file, struct vm_area_struct *vma);
1219extern int ceph_uninline_data(struct file *file);1218extern int ceph_uninline_data(struct file *file);
1220extern int ceph_pool_perm_check(struct inode *inode, int need);1219extern int ceph_pool_perm_check(struct inode *inode, int need);
fs/cifs/cifsglob.h+6−4
@@ -16,6 +16,7 @@ · 15 unmodified lines
16#include <linux/mempool.h>16#include <linux/mempool.h>
17#include <linux/workqueue.h>17#include <linux/workqueue.h>
18#include <linux/utsname.h>18#include <linux/utsname.h>
19#include <linux/netfs.h>
19#include "cifs_fs_sb.h"20#include "cifs_fs_sb.h"
20#include "cifsacl.h"21#include "cifsacl.h"
21#include <crypto/internal/hash.h>22#include <crypto/internal/hash.h>
@@ -1402,6 +1403,11 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file); · 1380 unmodified lines
1402 */1403 */
1403 1404
1404struct cifsInodeInfo {1405struct 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 };
1405 bool can_cache_brlcks;1411 bool can_cache_brlcks;
1406 struct list_head llist; /* locks helb by this inode */1412 struct list_head llist; /* locks helb by this inode */
1407 /*1413 /*
@@ -1432,10 +1438,6 @@ struct cifsInodeInfo { · 24 unmodified lines
1432 u64 uniqueid; /* server inode number */1438 u64 uniqueid; /* server inode number */
1433 u64 createtime; /* creation time on server */1439 u64 createtime; /* creation time on server */
1434 __u8 lease_key[SMB2_LEASE_KEY_SIZE]; /* lease key for this inode */1440 __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;
1439 struct list_head deferred_closes; /* list of deferred closes */1441 struct list_head deferred_closes; /* list of deferred closes */
1440 spinlock_t deferred_lock; /* protection on deferred list */1442 spinlock_t deferred_lock; /* protection on deferred list */
1441 bool lease_granted; /* Flag to indicate whether lease or oplock is granted. */1443 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
103 103
104 cifs_fscache_fill_coherency(&cifsi->vfs_inode, &cd);104 cifs_fscache_fill_coherency(&cifsi->vfs_inode, &cd);
105 105
106 cifsi->fscache =106 cifsi->netfs_ctx.cache =
107 fscache_acquire_cookie(tcon->fscache, 0,107 fscache_acquire_cookie(tcon->fscache, 0,
108 &cifsi->uniqueid, sizeof(cifsi->uniqueid),108 &cifsi->uniqueid, sizeof(cifsi->uniqueid),
109 &cd, sizeof(cd),109 &cd, sizeof(cd),
@@ -126,11 +126,12 @@ void cifs_fscache_unuse_inode_cookie(struct inode *inode, bool update) · 16 unmodified lines
126void cifs_fscache_release_inode_cookie(struct inode *inode)126void cifs_fscache_release_inode_cookie(struct inode *inode)
127{127{
128 struct cifsInodeInfo *cifsi = CIFS_I(inode);128 struct cifsInodeInfo *cifsi = CIFS_I(inode);
129 struct fscache_cookie *cookie = cifs_inode_cookie(inode);
129 130
130 if (cifsi->fscache) {131 if (cookie) {
131 cifs_dbg(FYI, "%s: (0x%p)\n", __func__, cifsi->fscache);132 cifs_dbg(FYI, "%s: (0x%p)\n", __func__, cookie);
132 fscache_relinquish_cookie(cifsi->fscache, false);133 fscache_relinquish_cookie(cookie, false);
133 cifsi->fscache = NULL;134 cifsi->netfs_ctx.cache = NULL;
134 }135 }
135}136}
136 137
fs/cifs/fscache.h+1−1
@@ -61,7 +61,7 @@ void cifs_fscache_fill_coherency(struct inode *inode, · 60 unmodified lines
61 61
62static inline struct fscache_cookie *cifs_inode_cookie(struct inode *inode)62static inline struct fscache_cookie *cifs_inode_cookie(struct inode *inode)
63{63{
64 return CIFS_I(inode)->fscache;64 return netfs_i_cookie(inode);
65}65}
66 66
67static inline void cifs_invalidate_cache(struct inode *inode, unsigned int flags)67static inline void cifs_invalidate_cache(struct inode *inode, unsigned int flags)
fs/netfs/internal.h+16−2
@@ -6,6 +6,7 @@ · 5 unmodified lines
6 */6 */
7 7
8#include <linux/netfs.h>8#include <linux/netfs.h>
9#include <linux/fscache.h>
9#include <trace/events/netfs.h>10#include <trace/events/netfs.h>
10 11
11#ifdef pr_fmt12#ifdef pr_fmt
@@ -19,8 +20,6 @@ · 7 unmodified lines
19 */20 */
20struct netfs_io_request *netfs_alloc_request(struct address_space *mapping,21struct netfs_io_request *netfs_alloc_request(struct address_space *mapping,
21 struct file *file,22 struct file *file,
22 const struct netfs_request_ops *ops,
23 void *netfs_priv,
24 loff_t start, size_t len,23 loff_t start, size_t len,
25 enum netfs_io_origin origin);24 enum netfs_io_origin origin);
26void netfs_get_request(struct netfs_io_request *rreq, enum netfs_rreq_ref_trace what);25void 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
81#define netfs_stat_d(x) do {} while(0)80#define netfs_stat_d(x) do {} while(0)
82#endif81#endif
83 82
83/*
84 * Miscellaneous functions.
85 */
86static 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
84/*****************************************************************************/98/*****************************************************************************/
85/*99/*
86 * debug tracing100 * debug tracing
fs/netfs/objects.c+6−6
@@ -13,12 +13,12 @@ · 12 unmodified lines
13 */13 */
14struct netfs_io_request *netfs_alloc_request(struct address_space *mapping,14struct netfs_io_request *netfs_alloc_request(struct address_space *mapping,
15 struct file *file,15 struct file *file,
16 const struct netfs_request_ops *ops,
17 void *netfs_priv,
18 loff_t start, size_t len,16 loff_t start, size_t len,
19 enum netfs_io_origin origin)17 enum netfs_io_origin origin)
20{18{
21 static atomic_t debug_ids;19 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);
22 struct netfs_io_request *rreq;22 struct netfs_io_request *rreq;
23 int ret;23 int ret;
24 24
@@ -29,11 +29,10 @@ struct netfs_io_request *netfs_alloc_request(struct address_space *mapping, · 4 unmodified lines
29 rreq->start = start;29 rreq->start = start;
30 rreq->len = len;30 rreq->len = len;
31 rreq->origin = origin;31 rreq->origin = origin;
32 rreq->netfs_ops = ops;32 rreq->netfs_ops = ctx->ops;
33 rreq->netfs_priv = netfs_priv;
34 rreq->mapping = mapping;33 rreq->mapping = mapping;
35 rreq->inode = file_inode(file);34 rreq->inode = inode;
36 rreq->i_size = i_size_read(rreq->inode);35 rreq->i_size = i_size_read(inode);
37 rreq->debug_id = atomic_inc_return(&debug_ids);36 rreq->debug_id = atomic_inc_return(&debug_ids);
38 INIT_LIST_HEAD(&rreq->subrequests);37 INIT_LIST_HEAD(&rreq->subrequests);
39 INIT_WORK(&rreq->work, netfs_rreq_work);38 INIT_WORK(&rreq->work, netfs_rreq_work);
@@ -76,6 +75,7 @@ static void netfs_free_request(struct work_struct *work) · 36 unmodified lines
76{75{
77 struct netfs_io_request *rreq =76 struct netfs_io_request *rreq =
78 container_of(work, struct netfs_io_request, work);77 container_of(work, struct netfs_io_request, work);
78
79 netfs_clear_subrequests(rreq, false);79 netfs_clear_subrequests(rreq, false);
80 if (rreq->netfs_priv)80 if (rreq->netfs_priv)
81 rreq->netfs_ops->cleanup(rreq->mapping, rreq->netfs_priv);81 rreq->netfs_ops->cleanup(rreq->mapping, rreq->netfs_priv);
fs/netfs/read_helper.c+45−55
@@ -14,7 +14,6 @@ · 13 unmodified lines
14#include <linux/uio.h>14#include <linux/uio.h>
15#include <linux/sched/mm.h>15#include <linux/sched/mm.h>
16#include <linux/task_io_accounting_ops.h>16#include <linux/task_io_accounting_ops.h>
17#include <linux/netfs.h>
18#include "internal.h"17#include "internal.h"
19#define CREATE_TRACE_POINTS18#define CREATE_TRACE_POINTS
20#include <trace/events/netfs.h>19#include <trace/events/netfs.h>
@@ -735,8 +734,6 @@ static void netfs_rreq_expand(struct netfs_io_request *rreq, · 714 unmodified lines
735/**734/**
736 * netfs_readahead - Helper to manage a read request735 * netfs_readahead - Helper to manage a read request
737 * @ractl: The description of the readahead request736 * @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
740 *737 *
741 * Fulfil a readahead request by drawing data from the cache if possible, or738 * Fulfil a readahead request by drawing data from the cache if possible, or
742 * the netfs if not. Space beyond the EOF is zero-filled. Multiple I/O739 * 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
744 * readahead window can be expanded in either direction to a more convenient741 * readahead window can be expanded in either direction to a more convenient
745 * alighment for RPC efficiency or to make storage in the cache feasible.742 * alighment for RPC efficiency or to make storage in the cache feasible.
746 *743 *
747 * The calling netfs must provide a table of operations, only one of which,744 * The calling netfs must initialise a netfs context contiguous to the vfs
748 * issue_op, is mandatory. It may also be passed a private token, which will745 * inode before calling this.
749 * be retained in rreq->netfs_priv and will be cleaned up by ops->cleanup().
750 *746 *
751 * This is usable whether or not caching is enabled.747 * This is usable whether or not caching is enabled.
752 */748 */
753void netfs_readahead(struct readahead_control *ractl,749void netfs_readahead(struct readahead_control *ractl)
754 const struct netfs_request_ops *ops,
755 void *netfs_priv)
756{750{
757 struct netfs_io_request *rreq;751 struct netfs_io_request *rreq;
752 struct netfs_i_context *ctx = netfs_i_context(ractl->mapping->host);
758 unsigned int debug_index = 0;753 unsigned int debug_index = 0;
759 int ret;754 int ret;
760 755
761 _enter("%lx,%x", readahead_index(ractl), readahead_count(ractl));756 _enter("%lx,%x", readahead_index(ractl), readahead_count(ractl));
762 757
763 if (readahead_count(ractl) == 0)758 if (readahead_count(ractl) == 0)
764 goto cleanup;759 return;
765 760
766 rreq = netfs_alloc_request(ractl->mapping, ractl->file,761 rreq = netfs_alloc_request(ractl->mapping, ractl->file,
767 ops, netfs_priv,
768 readahead_pos(ractl),762 readahead_pos(ractl),
769 readahead_length(ractl),763 readahead_length(ractl),
770 NETFS_READAHEAD);764 NETFS_READAHEAD);
771 if (IS_ERR(rreq))765 if (IS_ERR(rreq))
772 goto cleanup;766 return;
773 767
774 if (ops->begin_cache_operation) {768 if (ctx->ops->begin_cache_operation) {
775 ret = ops->begin_cache_operation(rreq);769 ret = ctx->ops->begin_cache_operation(rreq);
776 if (ret == -ENOMEM || ret == -EINTR || ret == -ERESTARTSYS)770 if (ret == -ENOMEM || ret == -EINTR || ret == -ERESTARTSYS)
777 goto cleanup_free;771 goto cleanup_free;
778 }772 }
@@ -804,42 +798,35 @@ void netfs_readahead(struct readahead_control *ractl, · 25 unmodified lines
804cleanup_free:798cleanup_free:
805 netfs_put_request(rreq, false, netfs_rreq_trace_put_failed);799 netfs_put_request(rreq, false, netfs_rreq_trace_put_failed);
806 return;800 return;
807cleanup:
808 if (netfs_priv)
809 ops->cleanup(ractl->mapping, netfs_priv);
810 return;
811}801}
812EXPORT_SYMBOL(netfs_readahead);802EXPORT_SYMBOL(netfs_readahead);
813 803
814/**804/**
815 * netfs_readpage - Helper to manage a readpage request805 * netfs_readpage - Helper to manage a readpage request
816 * @file: The file to read from806 * @file: The file to read from
817 * @folio: The folio to read807 * @subpage: A subpage of 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
820 *808 *
821 * Fulfil a readpage request by drawing data from the cache if possible, or the809 * Fulfil a readpage request by drawing data from the cache if possible, or the
822 * netfs if not. Space beyond the EOF is zero-filled. Multiple I/O requests810 * netfs if not. Space beyond the EOF is zero-filled. Multiple I/O requests
823 * from different sources will get munged together.811 * from different sources will get munged together.
824 *812 *
825 * The calling netfs must provide a table of operations, only one of which,813 * The calling netfs must initialise a netfs context contiguous to the vfs
826 * issue_op, is mandatory. It may also be passed a private token, which will814 * inode before calling this.
827 * be retained in rreq->netfs_priv and will be cleaned up by ops->cleanup().
828 *815 *
829 * This is usable whether or not caching is enabled.816 * This is usable whether or not caching is enabled.
830 */817 */
831int netfs_readpage(struct file *file,818int netfs_readpage(struct file *file, struct page *subpage)
832 struct folio *folio,
833 const struct netfs_request_ops *ops,
834 void *netfs_priv)
835{819{
820 struct folio *folio = page_folio(subpage);
821 struct address_space *mapping = folio->mapping;
836 struct netfs_io_request *rreq;822 struct netfs_io_request *rreq;
823 struct netfs_i_context *ctx = netfs_i_context(mapping->host);
837 unsigned int debug_index = 0;824 unsigned int debug_index = 0;
838 int ret;825 int ret;
839 826
840 _enter("%lx", folio_index(folio));827 _enter("%lx", folio_index(folio));
841 828
842 rreq = netfs_alloc_request(folio->mapping, file, ops, netfs_priv,829 rreq = netfs_alloc_request(mapping, file,
843 folio_file_pos(folio), folio_size(folio),830 folio_file_pos(folio), folio_size(folio),
844 NETFS_READPAGE);831 NETFS_READPAGE);
845 if (IS_ERR(rreq)) {832 if (IS_ERR(rreq)) {
@@ -847,8 +834,8 @@ int netfs_readpage(struct file *file, · 1 unmodified line
847 goto alloc_error;834 goto alloc_error;
848 }835 }
849 836
850 if (ops->begin_cache_operation) {837 if (ctx->ops->begin_cache_operation) {
851 ret = ops->begin_cache_operation(rreq);838 ret = ctx->ops->begin_cache_operation(rreq);
852 if (ret == -ENOMEM || ret == -EINTR || ret == -ERESTARTSYS) {839 if (ret == -ENOMEM || ret == -EINTR || ret == -ERESTARTSYS) {
853 folio_unlock(folio);840 folio_unlock(folio);
854 goto out;841 goto out;
@@ -886,8 +873,6 @@ out: · 31 unmodified lines
886 netfs_put_request(rreq, false, netfs_rreq_trace_put_hold);873 netfs_put_request(rreq, false, netfs_rreq_trace_put_hold);
887 return ret;874 return ret;
888alloc_error:875alloc_error:
889 if (netfs_priv)
890 ops->cleanup(folio_file_mapping(folio), netfs_priv);
891 folio_unlock(folio);876 folio_unlock(folio);
892 return ret;877 return ret;
893}878}
@@ -898,6 +883,7 @@ EXPORT_SYMBOL(netfs_readpage); · 4 unmodified lines
898 * @folio: The folio being prepared883 * @folio: The folio being prepared
899 * @pos: starting position for the write884 * @pos: starting position for the write
900 * @len: length of write885 * @len: length of write
886 * @always_fill: T if the folio should always be completely filled/cleared
901 *887 *
902 * In some cases, write_begin doesn't need to read at all:888 * In some cases, write_begin doesn't need to read at all:
903 * - full folio write889 * - full folio write
@@ -907,17 +893,27 @@ EXPORT_SYMBOL(netfs_readpage); · 3 unmodified lines
907 * If any of these criteria are met, then zero out the unwritten parts893 * If any of these criteria are met, then zero out the unwritten parts
908 * of the folio and return true. Otherwise, return false.894 * of the folio and return true. Otherwise, return false.
909 */895 */
910static bool netfs_skip_folio_read(struct folio *folio, loff_t pos, size_t len)896static bool netfs_skip_folio_read(struct folio *folio, loff_t pos, size_t len,
897 bool always_fill)
911{898{
912 struct inode *inode = folio_inode(folio);899 struct inode *inode = folio_inode(folio);
913 loff_t i_size = i_size_read(inode);900 loff_t i_size = i_size_read(inode);
914 size_t offset = offset_in_folio(folio, pos);901 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 }
915 911
916 /* Full folio write */912 /* Full folio write */
917 if (offset == 0 && len >= folio_size(folio))913 if (offset == 0 && len >= plen)
918 return true;914 return true;
919 915
920 /* pos beyond last folio in the file */916 /* Page entirely beyond the end of the file */
921 if (pos - offset >= i_size)917 if (pos - offset >= i_size)
922 goto zero_out;918 goto zero_out;
923 919
@@ -927,7 +923,7 @@ static bool netfs_skip_folio_read(struct folio *folio, loff_t pos, size_t len) · 3 unmodified lines
927 923
928 return false;924 return false;
929zero_out:925zero_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);
931 return true;927 return true;
932}928}
933 929
@@ -940,8 +936,6 @@ zero_out: · 6 unmodified lines
940 * @aop_flags: AOP_* flags936 * @aop_flags: AOP_* flags
941 * @_folio: Where to put the resultant folio937 * @_folio: Where to put the resultant folio
942 * @_fsdata: Place for the netfs to store a cookie938 * @_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
945 *939 *
946 * Pre-read data for a write-begin request by drawing data from the cache if940 * Pre-read data for a write-begin request by drawing data from the cache if
947 * possible, or the netfs if not. Space beyond the EOF is zero-filled.941 * possible, or the netfs if not. Space beyond the EOF is zero-filled.
@@ -960,17 +954,18 @@ zero_out: · 12 unmodified lines
960 * should go ahead; unlock the folio and return -EAGAIN to cause the folio to954 * should go ahead; unlock the folio and return -EAGAIN to cause the folio to
961 * be regot; or return an error.955 * be regot; or return an error.
962 *956 *
957 * The calling netfs must initialise a netfs context contiguous to the vfs
958 * inode before calling this.
959 *
963 * This is usable whether or not caching is enabled.960 * This is usable whether or not caching is enabled.
964 */961 */
965int netfs_write_begin(struct file *file, struct address_space *mapping,962int netfs_write_begin(struct file *file, struct address_space *mapping,
966 loff_t pos, unsigned int len, unsigned int aop_flags,963 loff_t pos, unsigned int len, unsigned int aop_flags,
967 struct folio **_folio, void **_fsdata,964 struct folio **_folio, void **_fsdata)
968 const struct netfs_request_ops *ops,
969 void *netfs_priv)
970{965{
971 struct netfs_io_request *rreq;966 struct netfs_io_request *rreq;
967 struct netfs_i_context *ctx = netfs_i_context(file_inode(file ));
972 struct folio *folio;968 struct folio *folio;
973 struct inode *inode = file_inode(file);
974 unsigned int debug_index = 0, fgp_flags;969 unsigned int debug_index = 0, fgp_flags;
975 pgoff_t index = pos >> PAGE_SHIFT;970 pgoff_t index = pos >> PAGE_SHIFT;
976 int ret;971 int ret;
@@ -986,9 +981,9 @@ retry: · 9 unmodified lines
986 if (!folio)981 if (!folio)
987 return -ENOMEM;982 return -ENOMEM;
988 983
989 if (ops->check_write_begin) {984 if (ctx->ops->check_write_begin) {
990 /* Allow the netfs (eg. ceph) to flush conflicts. */985 /* 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);
992 if (ret < 0) {987 if (ret < 0) {
993 trace_netfs_failure(NULL, NULL, ret, netfs_fail_check_write_begin);988 trace_netfs_failure(NULL, NULL, ret, netfs_fail_check_write_begin);
994 if (ret == -EAGAIN)989 if (ret == -EAGAIN)
@@ -1004,13 +999,13 @@ retry: · 9 unmodified lines
1004 * within the cache granule containing the EOF, in which case we need999 * within the cache granule containing the EOF, in which case we need
1005 * to preload the granule.1000 * to preload the granule.
1006 */1001 */
1007 if (!ops->is_cache_enabled(inode) &&1002 if (!netfs_is_cache_enabled(ctx) &&
1008 netfs_skip_folio_read(folio, pos, len)) {1003 netfs_skip_folio_read(folio, pos, len, false)) {
1009 netfs_stat(&netfs_n_rh_write_zskip);1004 netfs_stat(&netfs_n_rh_write_zskip);
1010 goto have_folio_no_wait;1005 goto have_folio_no_wait;
1011 }1006 }
1012 1007
1013 rreq = netfs_alloc_request(mapping, file, ops, netfs_priv,1008 rreq = netfs_alloc_request(mapping, file,
1014 folio_file_pos(folio), folio_size(folio),1009 folio_file_pos(folio), folio_size(folio),
1015 NETFS_READ_FOR_WRITE);1010 NETFS_READ_FOR_WRITE);
1016 if (IS_ERR(rreq)) {1011 if (IS_ERR(rreq)) {
@@ -1019,10 +1014,9 @@ retry: · 2 unmodified lines
1019 }1014 }
1020 rreq->no_unlock_folio = folio_index(folio);1015 rreq->no_unlock_folio = folio_index(folio);
1021 __set_bit(NETFS_RREQ_NO_UNLOCK_FOLIO, &rreq->flags);1016 __set_bit(NETFS_RREQ_NO_UNLOCK_FOLIO, &rreq->flags);
1022 netfs_priv = NULL;
1023 1017
1024 if (ops->begin_cache_operation) {1018 if (ctx->ops->begin_cache_operation) {
1025 ret = ops->begin_cache_operation(rreq);1019 ret = ctx->ops->begin_cache_operation(rreq);
1026 if (ret == -ENOMEM || ret == -EINTR || ret == -ERESTARTSYS)1020 if (ret == -ENOMEM || ret == -EINTR || ret == -ERESTARTSYS)
1027 goto error_put;1021 goto error_put;
1028 }1022 }
@@ -1076,8 +1070,6 @@ have_folio: · 47 unmodified lines
1076 if (ret < 0)1070 if (ret < 0)
1077 goto error;1071 goto error;
1078have_folio_no_wait:1072have_folio_no_wait:
1079 if (netfs_priv)
1080 ops->cleanup(mapping, netfs_priv);
1081 *_folio = folio;1073 *_folio = folio;
1082 _leave(" = 0");1074 _leave(" = 0");
1083 return 0;1075 return 0;
@@ -1087,8 +1079,6 @@ error_put: · 3 unmodified lines
1087error:1079error:
1088 folio_unlock(folio);1080 folio_unlock(folio);
1089 folio_put(folio);1081 folio_put(folio);
1090 if (netfs_priv)
1091 ops->cleanup(mapping, netfs_priv);
1092 _leave(" = %d", ret);1082 _leave(" = %d", ret);
1093 return ret;1083 return ret;
1094}1084}
fs/netfs/stats.c+0−1
@@ -7,7 +7,6 @@ · 6 unmodified lines
7 7
8#include <linux/export.h>8#include <linux/export.h>
9#include <linux/seq_file.h>9#include <linux/seq_file.h>
10#include <linux/netfs.h>
11#include "internal.h"10#include "internal.h"
12 11
13atomic_t netfs_n_rh_readahead;12atomic_t netfs_n_rh_readahead;
include/linux/netfs.h+70−11
@@ -118,6 +118,16 @@ enum netfs_io_source { · 117 unmodified lines
118typedef void (*netfs_io_terminated_t)(void *priv, ssize_t transferred_or_error,118typedef void (*netfs_io_terminated_t)(void *priv, ssize_t transferred_or_error,
119 bool was_async);119 bool was_async);
120 120
121/*
122 * Per-inode description. This must be directly after the inode struct.
123 */
124struct 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
121/*131/*
122 * Resources required to do operations on a cache.132 * Resources required to do operations on a cache.
123 */133 */
@@ -192,7 +202,6 @@ struct netfs_io_request { · 68 unmodified lines
192 * Operations the network filesystem can/must provide to the helpers.202 * Operations the network filesystem can/must provide to the helpers.
193 */203 */
194struct netfs_request_ops {204struct netfs_request_ops {
195 bool (*is_cache_enabled)(struct inode *inode);
196 int (*init_request)(struct netfs_io_request *rreq, struct file *file);205 int (*init_request)(struct netfs_io_request *rreq, struct file *file);
197 int (*begin_cache_operation)(struct netfs_io_request *rreq);206 int (*begin_cache_operation)(struct netfs_io_request *rreq);
198 void (*expand_readahead)(struct netfs_io_request *rreq);207 void (*expand_readahead)(struct netfs_io_request *rreq);
@@ -263,18 +272,11 @@ struct netfs_cache_ops { · 64 unmodified lines
263};272};
264 273
265struct readahead_control;274struct readahead_control;
266extern void netfs_readahead(struct readahead_control *,275extern void netfs_readahead(struct readahead_control *);
267 const struct netfs_request_ops *,276extern int netfs_readpage(struct file *, struct page *);
268 void *);
269extern int netfs_readpage(struct file *,
270 struct folio *,
271 const struct netfs_request_ops *,
272 void *);
273extern int netfs_write_begin(struct file *, struct address_space *,277extern int netfs_write_begin(struct file *, struct address_space *,
274 loff_t, unsigned int, unsigned int, struct folio **,278 loff_t, unsigned int, unsigned int, struct folio **,
275 void **,279 void **);
276 const struct netfs_request_ops *,
277 void *);
278 280
279extern void netfs_subreq_terminated(struct netfs_io_subrequest *, ssize_t, bool);281extern void netfs_subreq_terminated(struct netfs_io_subrequest *, ssize_t, bool);
280extern void netfs_get_subrequest(struct netfs_io_subrequest *subreq,282extern 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
283 bool was_async, enum netfs_sreq_ref_trace what);285 bool was_async, enum netfs_sreq_ref_trace what);
284extern void netfs_stats_show(struct seq_file *);286extern void netfs_stats_show(struct seq_file *);
285 287
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 */
295static 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 */
307static 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 */
320static 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 */
335static 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
286#endif /* _LINUX_NETFS_H */345#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