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