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 | typedef void (*netfs_io_terminated_t)(void *priv, ssize_t transferred_or_error, | 118 | typedef 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 | */ | ||
| 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 | * 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 | */ |
| 194 | struct netfs_request_ops { | 204 | struct 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 | ||
| 265 | struct readahead_control; | 274 | struct readahead_control; |
| 266 | extern void netfs_readahead(struct readahead_control *, | 275 | extern void netfs_readahead(struct readahead_control *); |
| 267 | const struct netfs_request_ops *, | 276 | extern int netfs_readpage(struct file *, struct page *); |
| 268 | void *); | ||
| 269 | extern int netfs_readpage(struct file *, | ||
| 270 | struct folio *, | ||
| 271 | const struct netfs_request_ops *, | ||
| 272 | void *); | ||
| 273 | extern int netfs_write_begin(struct file *, struct address_space *, | 277 | extern 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 | ||
| 279 | extern void netfs_subreq_terminated(struct netfs_io_subrequest *, ssize_t, bool); | 281 | extern void netfs_subreq_terminated(struct netfs_io_subrequest *, ssize_t, bool); |
| 280 | extern void netfs_get_subrequest(struct netfs_io_subrequest *subreq, | 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 | bool was_async, enum netfs_sreq_ref_trace what); | 285 | bool was_async, enum netfs_sreq_ref_trace what); |
| 284 | extern void netfs_stats_show(struct seq_file *); | 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 | #endif /* _LINUX_NETFS_H */ | 345 | #endif /* _LINUX_NETFS_H */ |