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
Showing the changes to include (1 of 25 files). Show all
Unified · Split
| @@ -118,6 +118,16 @@ enum netfs_io_source { · 117 unmodified lines | ||
| 118 | 118 | typedef void (*netfs_io_terminated_t)(void *priv, ssize_t transferred_or_error, |
| 119 | 119 | bool was_async); |
| 120 | 120 | |
| 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 | + | |
| 121 | 131 | /* |
| 122 | 132 | * Resources required to do operations on a cache. |
| 123 | 133 | */ |
| @@ -192,7 +202,6 @@ struct netfs_io_request { · 68 unmodified lines | ||
| 192 | 202 | * Operations the network filesystem can/must provide to the helpers. |
| 193 | 203 | */ |
| 194 | 204 | struct netfs_request_ops { |
| 195 | − bool (*is_cache_enabled)(struct inode *inode); | |
| 196 | 205 | int (*init_request)(struct netfs_io_request *rreq, struct file *file); |
| 197 | 206 | int (*begin_cache_operation)(struct netfs_io_request *rreq); |
| 198 | 207 | void (*expand_readahead)(struct netfs_io_request *rreq); |
| @@ -263,18 +272,11 @@ struct netfs_cache_ops { · 64 unmodified lines | ||
| 263 | 272 | }; |
| 264 | 273 | |
| 265 | 274 | 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 *); | |
| 273 | 277 | extern int netfs_write_begin(struct file *, struct address_space *, |
| 274 | 278 | loff_t, unsigned int, unsigned int, struct folio **, |
| 275 | − void **, | |
| 276 | − const struct netfs_request_ops *, | |
| 277 | − void *); | |
| 279 | + void **); | |
| 278 | 280 | |
| 279 | 281 | extern void netfs_subreq_terminated(struct netfs_io_subrequest *, ssize_t, bool); |
| 280 | 282 | 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 | ||
| 283 | 285 | bool was_async, enum netfs_sreq_ref_trace what); |
| 284 | 286 | extern 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 | + */ | |
| 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 | + | |
| 286 | 345 | #endif /* _LINUX_NETFS_H */ |