1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 /* NFS filesystem cache interface definitions 3 * 4 * Copyright (C) 2008 Red Hat, Inc. All Rights Reserved. 5 * Written by David Howells (dhowells@redhat.com) 6 */ 7 8 #ifndef _NFS_FSCACHE_H 9 #define _NFS_FSCACHE_H 10 11 #include <linux/nfs_fs.h> 12 #include <linux/nfs_mount.h> 13 #include <linux/nfs4_mount.h> 14 #include <linux/fscache.h> 15 #include <linux/iversion.h> 16 17 #ifdef CONFIG_NFS_FSCACHE 18 19 /* 20 * Definition of the auxiliary data attached to NFS inode storage objects 21 * within the cache. 22 * 23 * The contents of this struct are recorded in the on-disk local cache in the 24 * auxiliary data attached to the data storage object backing an inode. This 25 * permits coherency to be managed when a new inode binds to an already extant 26 * cache object. 27 */ 28 struct nfs_fscache_inode_auxdata { 29 s64 mtime_sec; 30 s64 mtime_nsec; 31 s64 ctime_sec; 32 s64 ctime_nsec; 33 u64 change_attr; 34 }; 35 36 /* 37 * fscache.c 38 */ 39 extern int nfs_fscache_get_super_cookie(struct super_block *, const char *, int); 40 extern void nfs_fscache_release_super_cookie(struct super_block *); 41 42 extern void nfs_fscache_init_inode(struct inode *); 43 extern void nfs_fscache_clear_inode(struct inode *); 44 extern void nfs_fscache_open_file(struct inode *, struct file *); 45 extern void nfs_fscache_release_file(struct inode *, struct file *); 46 47 extern int __nfs_readpage_from_fscache(struct inode *, struct page *); 48 extern void __nfs_read_completion_to_fscache(struct nfs_pgio_header *hdr, 49 unsigned long bytes); 50 extern void __nfs_readpage_to_fscache(struct inode *, struct page *); 51 52 static inline int nfs_fscache_release_page(struct page *page, gfp_t gfp) 53 { 54 if (PageFsCache(page)) { 55 if (!gfpflags_allow_blocking(gfp) || !(gfp & __GFP_FS)) 56 return false; 57 wait_on_page_fscache(page); 58 fscache_note_page_release(nfs_i_fscache(page->mapping->host)); 59 nfs_inc_fscache_stats(page->mapping->host, 60 NFSIOS_FSCACHE_PAGES_UNCACHED); 61 } 62 return true; 63 } 64 65 /* 66 * Retrieve a page from an inode data storage object. 67 */ 68 static inline int nfs_readpage_from_fscache(struct inode *inode, 69 struct page *page) 70 { 71 if (NFS_I(inode)->fscache) 72 return __nfs_readpage_from_fscache(inode, page); 73 return -ENOBUFS; 74 } 75 76 /* 77 * Store a page newly fetched from the server in an inode data storage object 78 * in the cache. 79 */ 80 static inline void nfs_readpage_to_fscache(struct inode *inode, 81 struct page *page) 82 { 83 if (NFS_I(inode)->fscache) 84 __nfs_readpage_to_fscache(inode, page); 85 } 86 87 static inline void nfs_fscache_update_auxdata(struct nfs_fscache_inode_auxdata *auxdata, 88 struct nfs_inode *nfsi) 89 { 90 memset(auxdata, 0, sizeof(*auxdata)); 91 auxdata->mtime_sec = nfsi->vfs_inode.i_mtime.tv_sec; 92 auxdata->mtime_nsec = nfsi->vfs_inode.i_mtime.tv_nsec; 93 auxdata->ctime_sec = nfsi->vfs_inode.i_ctime.tv_sec; 94 auxdata->ctime_nsec = nfsi->vfs_inode.i_ctime.tv_nsec; 95 96 if (NFS_SERVER(&nfsi->vfs_inode)->nfs_client->rpc_ops->version == 4) 97 auxdata->change_attr = inode_peek_iversion_raw(&nfsi->vfs_inode); 98 } 99 100 /* 101 * Invalidate the contents of fscache for this inode. This will not sleep. 102 */ 103 static inline void nfs_fscache_invalidate(struct inode *inode, int flags) 104 { 105 struct nfs_fscache_inode_auxdata auxdata; 106 struct nfs_inode *nfsi = NFS_I(inode); 107 108 if (nfsi->fscache) { 109 nfs_fscache_update_auxdata(&auxdata, nfsi); 110 fscache_invalidate(nfsi->fscache, &auxdata, 111 i_size_read(&nfsi->vfs_inode), flags); 112 } 113 } 114 115 /* 116 * indicate the client caching state as readable text 117 */ 118 static inline const char *nfs_server_fscache_state(struct nfs_server *server) 119 { 120 if (server->fscache) 121 return "yes"; 122 return "no "; 123 } 124 125 #else /* CONFIG_NFS_FSCACHE */ 126 static inline void nfs_fscache_release_super_cookie(struct super_block *sb) {} 127 128 static inline void nfs_fscache_init_inode(struct inode *inode) {} 129 static inline void nfs_fscache_clear_inode(struct inode *inode) {} 130 static inline void nfs_fscache_open_file(struct inode *inode, 131 struct file *filp) {} 132 static inline void nfs_fscache_release_file(struct inode *inode, struct file *file) {} 133 134 static inline int nfs_fscache_release_page(struct page *page, gfp_t gfp) 135 { 136 return 1; /* True: may release page */ 137 } 138 static inline int nfs_readpage_from_fscache(struct inode *inode, 139 struct page *page) 140 { 141 return -ENOBUFS; 142 } 143 static inline void nfs_readpage_to_fscache(struct inode *inode, 144 struct page *page) {} 145 146 147 static inline void nfs_fscache_invalidate(struct inode *inode, int flags) {} 148 149 static inline const char *nfs_server_fscache_state(struct nfs_server *server) 150 { 151 return "no "; 152 } 153 154 #endif /* CONFIG_NFS_FSCACHE */ 155 #endif /* _NFS_FSCACHE_H */ 156