xref: /openbmc/linux/fs/nfs/fscache.h (revision 6e31ded6)
1b4d0d230SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */
28ec442aeSDavid Howells /* NFS filesystem cache interface definitions
38ec442aeSDavid Howells  *
48ec442aeSDavid Howells  * Copyright (C) 2008 Red Hat, Inc. All Rights Reserved.
58ec442aeSDavid Howells  * Written by David Howells (dhowells@redhat.com)
68ec442aeSDavid Howells  */
78ec442aeSDavid Howells 
88ec442aeSDavid Howells #ifndef _NFS_FSCACHE_H
98ec442aeSDavid Howells #define _NFS_FSCACHE_H
108ec442aeSDavid Howells 
118ec442aeSDavid Howells #include <linux/nfs_fs.h>
128ec442aeSDavid Howells #include <linux/nfs_mount.h>
138ec442aeSDavid Howells #include <linux/nfs4_mount.h>
148ec442aeSDavid Howells #include <linux/fscache.h>
158ec442aeSDavid Howells 
168ec442aeSDavid Howells #ifdef CONFIG_NFS_FSCACHE
178ec442aeSDavid Howells 
188ec442aeSDavid Howells /*
1908734048SDavid Howells  * set of NFS FS-Cache objects that form a superblock key
2008734048SDavid Howells  */
2108734048SDavid Howells struct nfs_fscache_key {
2208734048SDavid Howells 	struct rb_node		node;
2308734048SDavid Howells 	struct nfs_client	*nfs_client;	/* the server */
2408734048SDavid Howells 
2508734048SDavid Howells 	/* the elements of the unique key - as used by nfs_compare_super() and
2608734048SDavid Howells 	 * nfs_compare_mount_options() to distinguish superblocks */
2708734048SDavid Howells 	struct {
2808734048SDavid Howells 		struct {
2908734048SDavid Howells 			unsigned long	s_flags;	/* various flags
3008734048SDavid Howells 							 * (& NFS_MS_MASK) */
3108734048SDavid Howells 		} super;
3208734048SDavid Howells 
3308734048SDavid Howells 		struct {
3408734048SDavid Howells 			struct nfs_fsid fsid;
3508734048SDavid Howells 			int		flags;
3608734048SDavid Howells 			unsigned int	rsize;		/* read size */
3708734048SDavid Howells 			unsigned int	wsize;		/* write size */
3808734048SDavid Howells 			unsigned int	acregmin;	/* attr cache timeouts */
3908734048SDavid Howells 			unsigned int	acregmax;
4008734048SDavid Howells 			unsigned int	acdirmin;
4108734048SDavid Howells 			unsigned int	acdirmax;
4208734048SDavid Howells 		} nfs_server;
4308734048SDavid Howells 
4408734048SDavid Howells 		struct {
4508734048SDavid Howells 			rpc_authflavor_t au_flavor;
4608734048SDavid Howells 		} rpc_auth;
4708734048SDavid Howells 
4808734048SDavid Howells 		/* uniquifier - can be used if nfs_server.flags includes
4908734048SDavid Howells 		 * NFS_MOUNT_UNSHARED  */
5008734048SDavid Howells 		u8 uniq_len;
5108734048SDavid Howells 		char uniquifier[0];
5208734048SDavid Howells 	} key;
5308734048SDavid Howells };
5408734048SDavid Howells 
5508734048SDavid Howells /*
56402cb8ddSDavid Howells  * Definition of the auxiliary data attached to NFS inode storage objects
57402cb8ddSDavid Howells  * within the cache.
58402cb8ddSDavid Howells  *
59402cb8ddSDavid Howells  * The contents of this struct are recorded in the on-disk local cache in the
60402cb8ddSDavid Howells  * auxiliary data attached to the data storage object backing an inode.  This
61402cb8ddSDavid Howells  * permits coherency to be managed when a new inode binds to an already extant
62402cb8ddSDavid Howells  * cache object.
63402cb8ddSDavid Howells  */
64402cb8ddSDavid Howells struct nfs_fscache_inode_auxdata {
656e31ded6SArnd Bergmann 	s64	mtime_sec;
666e31ded6SArnd Bergmann 	s64	mtime_nsec;
676e31ded6SArnd Bergmann 	s64	ctime_sec;
686e31ded6SArnd Bergmann 	s64	ctime_nsec;
69402cb8ddSDavid Howells 	u64	change_attr;
70402cb8ddSDavid Howells };
71402cb8ddSDavid Howells 
72402cb8ddSDavid Howells /*
738ec442aeSDavid Howells  * fscache-index.c
748ec442aeSDavid Howells  */
758ec442aeSDavid Howells extern struct fscache_netfs nfs_fscache_netfs;
7614727281SDavid Howells extern const struct fscache_cookie_def nfs_fscache_server_index_def;
7708734048SDavid Howells extern const struct fscache_cookie_def nfs_fscache_super_index_def;
7810329a5dSDavid Howells extern const struct fscache_cookie_def nfs_fscache_inode_object_def;
798ec442aeSDavid Howells 
808ec442aeSDavid Howells extern int nfs_fscache_register(void);
818ec442aeSDavid Howells extern void nfs_fscache_unregister(void);
828ec442aeSDavid Howells 
8314727281SDavid Howells /*
8414727281SDavid Howells  * fscache.c
8514727281SDavid Howells  */
8614727281SDavid Howells extern void nfs_fscache_get_client_cookie(struct nfs_client *);
8714727281SDavid Howells extern void nfs_fscache_release_client_cookie(struct nfs_client *);
8814727281SDavid Howells 
892311b943SBryan Schumaker extern void nfs_fscache_get_super_cookie(struct super_block *, const char *, int);
9008734048SDavid Howells extern void nfs_fscache_release_super_cookie(struct super_block *);
9108734048SDavid Howells 
92f1fe29b4SDavid Howells extern void nfs_fscache_init_inode(struct inode *);
93f1fe29b4SDavid Howells extern void nfs_fscache_clear_inode(struct inode *);
94f1fe29b4SDavid Howells extern void nfs_fscache_open_file(struct inode *, struct file *);
95ef79c097SDavid Howells 
96545db45fSDavid Howells extern void __nfs_fscache_invalidate_page(struct page *, struct inode *);
97545db45fSDavid Howells extern int nfs_fscache_release_page(struct page *, gfp_t);
98545db45fSDavid Howells 
999a9fc1c0SDavid Howells extern int __nfs_readpage_from_fscache(struct nfs_open_context *,
1009a9fc1c0SDavid Howells 				       struct inode *, struct page *);
1019a9fc1c0SDavid Howells extern int __nfs_readpages_from_fscache(struct nfs_open_context *,
1029a9fc1c0SDavid Howells 					struct inode *, struct address_space *,
1039a9fc1c0SDavid Howells 					struct list_head *, unsigned *);
1047f8e05f6SDavid Howells extern void __nfs_readpage_to_fscache(struct inode *, struct page *, int);
1059a9fc1c0SDavid Howells 
106545db45fSDavid Howells /*
107545db45fSDavid Howells  * wait for a page to complete writing to the cache
108545db45fSDavid Howells  */
109545db45fSDavid Howells static inline void nfs_fscache_wait_on_page_write(struct nfs_inode *nfsi,
110545db45fSDavid Howells 						  struct page *page)
111545db45fSDavid Howells {
112545db45fSDavid Howells 	if (PageFsCache(page))
113545db45fSDavid Howells 		fscache_wait_on_page_write(nfsi->fscache, page);
114545db45fSDavid Howells }
115545db45fSDavid Howells 
116545db45fSDavid Howells /*
117545db45fSDavid Howells  * release the caching state associated with a page if undergoing complete page
118545db45fSDavid Howells  * invalidation
119545db45fSDavid Howells  */
120545db45fSDavid Howells static inline void nfs_fscache_invalidate_page(struct page *page,
121545db45fSDavid Howells 					       struct inode *inode)
122545db45fSDavid Howells {
123545db45fSDavid Howells 	if (PageFsCache(page))
124545db45fSDavid Howells 		__nfs_fscache_invalidate_page(page, inode);
125545db45fSDavid Howells }
126545db45fSDavid Howells 
1279a9fc1c0SDavid Howells /*
1289a9fc1c0SDavid Howells  * Retrieve a page from an inode data storage object.
1299a9fc1c0SDavid Howells  */
1309a9fc1c0SDavid Howells static inline int nfs_readpage_from_fscache(struct nfs_open_context *ctx,
1319a9fc1c0SDavid Howells 					    struct inode *inode,
1329a9fc1c0SDavid Howells 					    struct page *page)
1339a9fc1c0SDavid Howells {
1349a9fc1c0SDavid Howells 	if (NFS_I(inode)->fscache)
1359a9fc1c0SDavid Howells 		return __nfs_readpage_from_fscache(ctx, inode, page);
1369a9fc1c0SDavid Howells 	return -ENOBUFS;
1379a9fc1c0SDavid Howells }
1389a9fc1c0SDavid Howells 
1399a9fc1c0SDavid Howells /*
1409a9fc1c0SDavid Howells  * Retrieve a set of pages from an inode data storage object.
1419a9fc1c0SDavid Howells  */
1429a9fc1c0SDavid Howells static inline int nfs_readpages_from_fscache(struct nfs_open_context *ctx,
1439a9fc1c0SDavid Howells 					     struct inode *inode,
1449a9fc1c0SDavid Howells 					     struct address_space *mapping,
1459a9fc1c0SDavid Howells 					     struct list_head *pages,
1469a9fc1c0SDavid Howells 					     unsigned *nr_pages)
1479a9fc1c0SDavid Howells {
1489a9fc1c0SDavid Howells 	if (NFS_I(inode)->fscache)
1499a9fc1c0SDavid Howells 		return __nfs_readpages_from_fscache(ctx, inode, mapping, pages,
1509a9fc1c0SDavid Howells 						    nr_pages);
1519a9fc1c0SDavid Howells 	return -ENOBUFS;
1529a9fc1c0SDavid Howells }
153545db45fSDavid Howells 
1547f8e05f6SDavid Howells /*
1557f8e05f6SDavid Howells  * Store a page newly fetched from the server in an inode data storage object
1567f8e05f6SDavid Howells  * in the cache.
1577f8e05f6SDavid Howells  */
1587f8e05f6SDavid Howells static inline void nfs_readpage_to_fscache(struct inode *inode,
1597f8e05f6SDavid Howells 					   struct page *page,
1607f8e05f6SDavid Howells 					   int sync)
1617f8e05f6SDavid Howells {
1627f8e05f6SDavid Howells 	if (PageFsCache(page))
1637f8e05f6SDavid Howells 		__nfs_readpage_to_fscache(inode, page, sync);
1647f8e05f6SDavid Howells }
1657f8e05f6SDavid Howells 
1665d1acff1SDavid Howells /*
167de242c0bSDavid Howells  * Invalidate the contents of fscache for this inode.  This will not sleep.
168de242c0bSDavid Howells  */
169de242c0bSDavid Howells static inline void nfs_fscache_invalidate(struct inode *inode)
170de242c0bSDavid Howells {
171de242c0bSDavid Howells 	fscache_invalidate(NFS_I(inode)->fscache);
172de242c0bSDavid Howells }
173de242c0bSDavid Howells 
174de242c0bSDavid Howells /*
175de242c0bSDavid Howells  * Wait for an object to finish being invalidated.
176de242c0bSDavid Howells  */
177de242c0bSDavid Howells static inline void nfs_fscache_wait_on_invalidate(struct inode *inode)
178de242c0bSDavid Howells {
179de242c0bSDavid Howells 	fscache_wait_on_invalidate(NFS_I(inode)->fscache);
180de242c0bSDavid Howells }
181de242c0bSDavid Howells 
182de242c0bSDavid Howells /*
1835d1acff1SDavid Howells  * indicate the client caching state as readable text
1845d1acff1SDavid Howells  */
1855d1acff1SDavid Howells static inline const char *nfs_server_fscache_state(struct nfs_server *server)
1865d1acff1SDavid Howells {
187dea1bb35STrond Myklebust 	if (server->fscache)
1885d1acff1SDavid Howells 		return "yes";
1895d1acff1SDavid Howells 	return "no ";
1905d1acff1SDavid Howells }
1915d1acff1SDavid Howells 
1928ec442aeSDavid Howells #else /* CONFIG_NFS_FSCACHE */
1938ec442aeSDavid Howells static inline int nfs_fscache_register(void) { return 0; }
1948ec442aeSDavid Howells static inline void nfs_fscache_unregister(void) {}
1958ec442aeSDavid Howells 
19614727281SDavid Howells static inline void nfs_fscache_get_client_cookie(struct nfs_client *clp) {}
19714727281SDavid Howells static inline void nfs_fscache_release_client_cookie(struct nfs_client *clp) {}
19814727281SDavid Howells 
19908734048SDavid Howells static inline void nfs_fscache_release_super_cookie(struct super_block *sb) {}
20008734048SDavid Howells 
201f1fe29b4SDavid Howells static inline void nfs_fscache_init_inode(struct inode *inode) {}
202f1fe29b4SDavid Howells static inline void nfs_fscache_clear_inode(struct inode *inode) {}
203f1fe29b4SDavid Howells static inline void nfs_fscache_open_file(struct inode *inode,
204ef79c097SDavid Howells 					 struct file *filp) {}
205ef79c097SDavid Howells 
206545db45fSDavid Howells static inline int nfs_fscache_release_page(struct page *page, gfp_t gfp)
207545db45fSDavid Howells {
208545db45fSDavid Howells 	return 1; /* True: may release page */
209545db45fSDavid Howells }
210545db45fSDavid Howells static inline void nfs_fscache_invalidate_page(struct page *page,
211545db45fSDavid Howells 					       struct inode *inode) {}
212545db45fSDavid Howells static inline void nfs_fscache_wait_on_page_write(struct nfs_inode *nfsi,
213545db45fSDavid Howells 						  struct page *page) {}
214545db45fSDavid Howells 
2159a9fc1c0SDavid Howells static inline int nfs_readpage_from_fscache(struct nfs_open_context *ctx,
2169a9fc1c0SDavid Howells 					    struct inode *inode,
2179a9fc1c0SDavid Howells 					    struct page *page)
2189a9fc1c0SDavid Howells {
2199a9fc1c0SDavid Howells 	return -ENOBUFS;
2209a9fc1c0SDavid Howells }
2219a9fc1c0SDavid Howells static inline int nfs_readpages_from_fscache(struct nfs_open_context *ctx,
2229a9fc1c0SDavid Howells 					     struct inode *inode,
2239a9fc1c0SDavid Howells 					     struct address_space *mapping,
2249a9fc1c0SDavid Howells 					     struct list_head *pages,
2259a9fc1c0SDavid Howells 					     unsigned *nr_pages)
2269a9fc1c0SDavid Howells {
2279a9fc1c0SDavid Howells 	return -ENOBUFS;
2289a9fc1c0SDavid Howells }
2297f8e05f6SDavid Howells static inline void nfs_readpage_to_fscache(struct inode *inode,
2307f8e05f6SDavid Howells 					   struct page *page, int sync) {}
2319a9fc1c0SDavid Howells 
232de242c0bSDavid Howells 
233de242c0bSDavid Howells static inline void nfs_fscache_invalidate(struct inode *inode) {}
234c129c293SDavid Howells static inline void nfs_fscache_wait_on_invalidate(struct inode *inode) {}
235de242c0bSDavid Howells 
2365d1acff1SDavid Howells static inline const char *nfs_server_fscache_state(struct nfs_server *server)
2375d1acff1SDavid Howells {
2385d1acff1SDavid Howells 	return "no ";
2395d1acff1SDavid Howells }
2405d1acff1SDavid Howells 
2418ec442aeSDavid Howells #endif /* CONFIG_NFS_FSCACHE */
2428ec442aeSDavid Howells #endif /* _NFS_FSCACHE_H */
243