xref: /openbmc/linux/fs/nfs/fscache.h (revision 3577da4a)
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 
11d7bdba1cSDavid Howells #include <linux/swap.h>
128ec442aeSDavid Howells #include <linux/nfs_fs.h>
138ec442aeSDavid Howells #include <linux/nfs_mount.h>
148ec442aeSDavid Howells #include <linux/nfs4_mount.h>
158ec442aeSDavid Howells #include <linux/fscache.h>
16a6b5a28eSDave Wysochanski #include <linux/iversion.h>
178ec442aeSDavid Howells 
188ec442aeSDavid Howells #ifdef CONFIG_NFS_FSCACHE
198ec442aeSDavid Howells 
208ec442aeSDavid Howells /*
21402cb8ddSDavid Howells  * Definition of the auxiliary data attached to NFS inode storage objects
22402cb8ddSDavid Howells  * within the cache.
23402cb8ddSDavid Howells  *
24402cb8ddSDavid Howells  * The contents of this struct are recorded in the on-disk local cache in the
25402cb8ddSDavid Howells  * auxiliary data attached to the data storage object backing an inode.  This
26402cb8ddSDavid Howells  * permits coherency to be managed when a new inode binds to an already extant
27402cb8ddSDavid Howells  * cache object.
28402cb8ddSDavid Howells  */
29402cb8ddSDavid Howells struct nfs_fscache_inode_auxdata {
306e31ded6SArnd Bergmann 	s64	mtime_sec;
316e31ded6SArnd Bergmann 	s64	mtime_nsec;
326e31ded6SArnd Bergmann 	s64	ctime_sec;
336e31ded6SArnd Bergmann 	s64	ctime_nsec;
34402cb8ddSDavid Howells 	u64	change_attr;
35402cb8ddSDavid Howells };
36402cb8ddSDavid Howells 
37402cb8ddSDavid Howells /*
3814727281SDavid Howells  * fscache.c
3914727281SDavid Howells  */
40a6b5a28eSDave Wysochanski extern int nfs_fscache_get_super_cookie(struct super_block *, const char *, int);
4108734048SDavid Howells extern void nfs_fscache_release_super_cookie(struct super_block *);
4208734048SDavid Howells 
43f1fe29b4SDavid Howells extern void nfs_fscache_init_inode(struct inode *);
44f1fe29b4SDavid Howells extern void nfs_fscache_clear_inode(struct inode *);
45f1fe29b4SDavid Howells extern void nfs_fscache_open_file(struct inode *, struct file *);
46a6b5a28eSDave Wysochanski extern void nfs_fscache_release_file(struct inode *, struct file *);
47ef79c097SDavid Howells 
48fc1c5abfSDave Wysochanski extern int __nfs_fscache_read_page(struct inode *, struct page *);
49fc1c5abfSDave Wysochanski extern void __nfs_fscache_write_page(struct inode *, struct page *);
509a9fc1c0SDavid Howells 
51*3577da4aSMatthew Wilcox (Oracle) static inline bool nfs_fscache_release_folio(struct folio *folio, gfp_t gfp)
52545db45fSDavid Howells {
53*3577da4aSMatthew Wilcox (Oracle) 	if (folio_test_fscache(folio)) {
54d7bdba1cSDavid Howells 		if (current_is_kswapd() || !(gfp & __GFP_FS))
55a6b5a28eSDave Wysochanski 			return false;
56*3577da4aSMatthew Wilcox (Oracle) 		folio_wait_fscache(folio);
57*3577da4aSMatthew Wilcox (Oracle) 		fscache_note_page_release(nfs_i_fscache(folio->mapping->host));
58*3577da4aSMatthew Wilcox (Oracle) 		nfs_inc_fscache_stats(folio->mapping->host,
59a6b5a28eSDave Wysochanski 				      NFSIOS_FSCACHE_PAGES_UNCACHED);
60545db45fSDavid Howells 	}
61a6b5a28eSDave Wysochanski 	return true;
62545db45fSDavid Howells }
63545db45fSDavid Howells 
649a9fc1c0SDavid Howells /*
659a9fc1c0SDavid Howells  * Retrieve a page from an inode data storage object.
669a9fc1c0SDavid Howells  */
67fc1c5abfSDave Wysochanski static inline int nfs_fscache_read_page(struct inode *inode, struct page *page)
689a9fc1c0SDavid Howells {
69fc1c5abfSDave Wysochanski 	if (nfs_i_fscache(inode))
70fc1c5abfSDave Wysochanski 		return __nfs_fscache_read_page(inode, page);
719a9fc1c0SDavid Howells 	return -ENOBUFS;
729a9fc1c0SDavid Howells }
73545db45fSDavid Howells 
747f8e05f6SDavid Howells /*
757f8e05f6SDavid Howells  * Store a page newly fetched from the server in an inode data storage object
767f8e05f6SDavid Howells  * in the cache.
777f8e05f6SDavid Howells  */
78fc1c5abfSDave Wysochanski static inline void nfs_fscache_write_page(struct inode *inode,
7916f2f4e6SDavid Howells 					   struct page *page)
807f8e05f6SDavid Howells {
81fc1c5abfSDave Wysochanski 	if (nfs_i_fscache(inode))
82fc1c5abfSDave Wysochanski 		__nfs_fscache_write_page(inode, page);
837f8e05f6SDavid Howells }
847f8e05f6SDavid Howells 
85a6b5a28eSDave Wysochanski static inline void nfs_fscache_update_auxdata(struct nfs_fscache_inode_auxdata *auxdata,
8645f3a70bSDave Wysochanski 					      struct inode *inode)
87de242c0bSDavid Howells {
88a6b5a28eSDave Wysochanski 	memset(auxdata, 0, sizeof(*auxdata));
8945f3a70bSDave Wysochanski 	auxdata->mtime_sec  = inode->i_mtime.tv_sec;
9045f3a70bSDave Wysochanski 	auxdata->mtime_nsec = inode->i_mtime.tv_nsec;
9145f3a70bSDave Wysochanski 	auxdata->ctime_sec  = inode->i_ctime.tv_sec;
9245f3a70bSDave Wysochanski 	auxdata->ctime_nsec = inode->i_ctime.tv_nsec;
93a6b5a28eSDave Wysochanski 
9445f3a70bSDave Wysochanski 	if (NFS_SERVER(inode)->nfs_client->rpc_ops->version == 4)
9545f3a70bSDave Wysochanski 		auxdata->change_attr = inode_peek_iversion_raw(inode);
96de242c0bSDavid Howells }
97de242c0bSDavid Howells 
98de242c0bSDavid Howells /*
99a6b5a28eSDave Wysochanski  * Invalidate the contents of fscache for this inode.  This will not sleep.
100de242c0bSDavid Howells  */
101a6b5a28eSDave Wysochanski static inline void nfs_fscache_invalidate(struct inode *inode, int flags)
102de242c0bSDavid Howells {
103a6b5a28eSDave Wysochanski 	struct nfs_fscache_inode_auxdata auxdata;
104a6b5a28eSDave Wysochanski 	struct nfs_inode *nfsi = NFS_I(inode);
105a6b5a28eSDave Wysochanski 
106a6b5a28eSDave Wysochanski 	if (nfsi->fscache) {
10745f3a70bSDave Wysochanski 		nfs_fscache_update_auxdata(&auxdata, inode);
108a6b5a28eSDave Wysochanski 		fscache_invalidate(nfsi->fscache, &auxdata,
10945f3a70bSDave Wysochanski 				   i_size_read(inode), flags);
110a6b5a28eSDave Wysochanski 	}
111de242c0bSDavid Howells }
112de242c0bSDavid Howells 
113de242c0bSDavid Howells /*
1145d1acff1SDavid Howells  * indicate the client caching state as readable text
1155d1acff1SDavid Howells  */
1165d1acff1SDavid Howells static inline const char *nfs_server_fscache_state(struct nfs_server *server)
1175d1acff1SDavid Howells {
118dea1bb35STrond Myklebust 	if (server->fscache)
1195d1acff1SDavid Howells 		return "yes";
1205d1acff1SDavid Howells 	return "no ";
1215d1acff1SDavid Howells }
1225d1acff1SDavid Howells 
1238ec442aeSDavid Howells #else /* CONFIG_NFS_FSCACHE */
12408734048SDavid Howells static inline void nfs_fscache_release_super_cookie(struct super_block *sb) {}
12508734048SDavid Howells 
126f1fe29b4SDavid Howells static inline void nfs_fscache_init_inode(struct inode *inode) {}
127f1fe29b4SDavid Howells static inline void nfs_fscache_clear_inode(struct inode *inode) {}
128f1fe29b4SDavid Howells static inline void nfs_fscache_open_file(struct inode *inode,
129ef79c097SDavid Howells 					 struct file *filp) {}
130a6b5a28eSDave Wysochanski static inline void nfs_fscache_release_file(struct inode *inode, struct file *file) {}
131ef79c097SDavid Howells 
132*3577da4aSMatthew Wilcox (Oracle) static inline bool nfs_fscache_release_folio(struct folio *folio, gfp_t gfp)
133545db45fSDavid Howells {
134*3577da4aSMatthew Wilcox (Oracle) 	return true; /* may release folio */
135545db45fSDavid Howells }
136fc1c5abfSDave Wysochanski static inline int nfs_fscache_read_page(struct inode *inode, struct page *page)
1379a9fc1c0SDavid Howells {
1389a9fc1c0SDavid Howells 	return -ENOBUFS;
1399a9fc1c0SDavid Howells }
140fc1c5abfSDave Wysochanski static inline void nfs_fscache_write_page(struct inode *inode, struct page *page) {}
141a6b5a28eSDave Wysochanski static inline void nfs_fscache_invalidate(struct inode *inode, int flags) {}
142de242c0bSDavid Howells 
1435d1acff1SDavid Howells static inline const char *nfs_server_fscache_state(struct nfs_server *server)
1445d1acff1SDavid Howells {
1455d1acff1SDavid Howells 	return "no ";
1465d1acff1SDavid Howells }
1475d1acff1SDavid Howells 
1488ec442aeSDavid Howells #endif /* CONFIG_NFS_FSCACHE */
1498ec442aeSDavid Howells #endif /* _NFS_FSCACHE_H */
150