18ec442aeSDavid Howells /* NFS filesystem cache interface definitions 28ec442aeSDavid Howells * 38ec442aeSDavid Howells * Copyright (C) 2008 Red Hat, Inc. All Rights Reserved. 48ec442aeSDavid Howells * Written by David Howells (dhowells@redhat.com) 58ec442aeSDavid Howells * 68ec442aeSDavid Howells * This program is free software; you can redistribute it and/or 78ec442aeSDavid Howells * modify it under the terms of the GNU General Public Licence 88ec442aeSDavid Howells * as published by the Free Software Foundation; either version 98ec442aeSDavid Howells * 2 of the Licence, or (at your option) any later version. 108ec442aeSDavid Howells */ 118ec442aeSDavid Howells 128ec442aeSDavid Howells #ifndef _NFS_FSCACHE_H 138ec442aeSDavid Howells #define _NFS_FSCACHE_H 148ec442aeSDavid Howells 158ec442aeSDavid Howells #include <linux/nfs_fs.h> 168ec442aeSDavid Howells #include <linux/nfs_mount.h> 178ec442aeSDavid Howells #include <linux/nfs4_mount.h> 188ec442aeSDavid Howells #include <linux/fscache.h> 198ec442aeSDavid Howells 208ec442aeSDavid Howells #ifdef CONFIG_NFS_FSCACHE 218ec442aeSDavid Howells 228ec442aeSDavid Howells /* 2308734048SDavid Howells * set of NFS FS-Cache objects that form a superblock key 2408734048SDavid Howells */ 2508734048SDavid Howells struct nfs_fscache_key { 2608734048SDavid Howells struct rb_node node; 2708734048SDavid Howells struct nfs_client *nfs_client; /* the server */ 2808734048SDavid Howells 2908734048SDavid Howells /* the elements of the unique key - as used by nfs_compare_super() and 3008734048SDavid Howells * nfs_compare_mount_options() to distinguish superblocks */ 3108734048SDavid Howells struct { 3208734048SDavid Howells struct { 3308734048SDavid Howells unsigned long s_flags; /* various flags 3408734048SDavid Howells * (& NFS_MS_MASK) */ 3508734048SDavid Howells } super; 3608734048SDavid Howells 3708734048SDavid Howells struct { 3808734048SDavid Howells struct nfs_fsid fsid; 3908734048SDavid Howells int flags; 4008734048SDavid Howells unsigned int rsize; /* read size */ 4108734048SDavid Howells unsigned int wsize; /* write size */ 4208734048SDavid Howells unsigned int acregmin; /* attr cache timeouts */ 4308734048SDavid Howells unsigned int acregmax; 4408734048SDavid Howells unsigned int acdirmin; 4508734048SDavid Howells unsigned int acdirmax; 4608734048SDavid Howells } nfs_server; 4708734048SDavid Howells 4808734048SDavid Howells struct { 4908734048SDavid Howells rpc_authflavor_t au_flavor; 5008734048SDavid Howells } rpc_auth; 5108734048SDavid Howells 5208734048SDavid Howells /* uniquifier - can be used if nfs_server.flags includes 5308734048SDavid Howells * NFS_MOUNT_UNSHARED */ 5408734048SDavid Howells u8 uniq_len; 5508734048SDavid Howells char uniquifier[0]; 5608734048SDavid Howells } key; 5708734048SDavid Howells }; 5808734048SDavid Howells 5908734048SDavid Howells /* 608ec442aeSDavid Howells * fscache-index.c 618ec442aeSDavid Howells */ 628ec442aeSDavid Howells extern struct fscache_netfs nfs_fscache_netfs; 6314727281SDavid Howells extern const struct fscache_cookie_def nfs_fscache_server_index_def; 6408734048SDavid Howells extern const struct fscache_cookie_def nfs_fscache_super_index_def; 6510329a5dSDavid Howells extern const struct fscache_cookie_def nfs_fscache_inode_object_def; 668ec442aeSDavid Howells 678ec442aeSDavid Howells extern int nfs_fscache_register(void); 688ec442aeSDavid Howells extern void nfs_fscache_unregister(void); 698ec442aeSDavid Howells 7014727281SDavid Howells /* 7114727281SDavid Howells * fscache.c 7214727281SDavid Howells */ 7314727281SDavid Howells extern void nfs_fscache_get_client_cookie(struct nfs_client *); 7414727281SDavid Howells extern void nfs_fscache_release_client_cookie(struct nfs_client *); 7514727281SDavid Howells 762311b943SBryan Schumaker extern void nfs_fscache_get_super_cookie(struct super_block *, const char *, int); 7708734048SDavid Howells extern void nfs_fscache_release_super_cookie(struct super_block *); 7808734048SDavid Howells 79f1fe29b4SDavid Howells extern void nfs_fscache_init_inode(struct inode *); 80f1fe29b4SDavid Howells extern void nfs_fscache_clear_inode(struct inode *); 81f1fe29b4SDavid Howells extern void nfs_fscache_open_file(struct inode *, struct file *); 82ef79c097SDavid Howells 83545db45fSDavid Howells extern void __nfs_fscache_invalidate_page(struct page *, struct inode *); 84545db45fSDavid Howells extern int nfs_fscache_release_page(struct page *, gfp_t); 85545db45fSDavid Howells 869a9fc1c0SDavid Howells extern int __nfs_readpage_from_fscache(struct nfs_open_context *, 879a9fc1c0SDavid Howells struct inode *, struct page *); 889a9fc1c0SDavid Howells extern int __nfs_readpages_from_fscache(struct nfs_open_context *, 899a9fc1c0SDavid Howells struct inode *, struct address_space *, 909a9fc1c0SDavid Howells struct list_head *, unsigned *); 917f8e05f6SDavid Howells extern void __nfs_readpage_to_fscache(struct inode *, struct page *, int); 929a9fc1c0SDavid Howells 93545db45fSDavid Howells /* 94545db45fSDavid Howells * wait for a page to complete writing to the cache 95545db45fSDavid Howells */ 96545db45fSDavid Howells static inline void nfs_fscache_wait_on_page_write(struct nfs_inode *nfsi, 97545db45fSDavid Howells struct page *page) 98545db45fSDavid Howells { 99545db45fSDavid Howells if (PageFsCache(page)) 100545db45fSDavid Howells fscache_wait_on_page_write(nfsi->fscache, page); 101545db45fSDavid Howells } 102545db45fSDavid Howells 103545db45fSDavid Howells /* 104545db45fSDavid Howells * release the caching state associated with a page if undergoing complete page 105545db45fSDavid Howells * invalidation 106545db45fSDavid Howells */ 107545db45fSDavid Howells static inline void nfs_fscache_invalidate_page(struct page *page, 108545db45fSDavid Howells struct inode *inode) 109545db45fSDavid Howells { 110545db45fSDavid Howells if (PageFsCache(page)) 111545db45fSDavid Howells __nfs_fscache_invalidate_page(page, inode); 112545db45fSDavid Howells } 113545db45fSDavid Howells 1149a9fc1c0SDavid Howells /* 1159a9fc1c0SDavid Howells * Retrieve a page from an inode data storage object. 1169a9fc1c0SDavid Howells */ 1179a9fc1c0SDavid Howells static inline int nfs_readpage_from_fscache(struct nfs_open_context *ctx, 1189a9fc1c0SDavid Howells struct inode *inode, 1199a9fc1c0SDavid Howells struct page *page) 1209a9fc1c0SDavid Howells { 1219a9fc1c0SDavid Howells if (NFS_I(inode)->fscache) 1229a9fc1c0SDavid Howells return __nfs_readpage_from_fscache(ctx, inode, page); 1239a9fc1c0SDavid Howells return -ENOBUFS; 1249a9fc1c0SDavid Howells } 1259a9fc1c0SDavid Howells 1269a9fc1c0SDavid Howells /* 1279a9fc1c0SDavid Howells * Retrieve a set of pages from an inode data storage object. 1289a9fc1c0SDavid Howells */ 1299a9fc1c0SDavid Howells static inline int nfs_readpages_from_fscache(struct nfs_open_context *ctx, 1309a9fc1c0SDavid Howells struct inode *inode, 1319a9fc1c0SDavid Howells struct address_space *mapping, 1329a9fc1c0SDavid Howells struct list_head *pages, 1339a9fc1c0SDavid Howells unsigned *nr_pages) 1349a9fc1c0SDavid Howells { 1359a9fc1c0SDavid Howells if (NFS_I(inode)->fscache) 1369a9fc1c0SDavid Howells return __nfs_readpages_from_fscache(ctx, inode, mapping, pages, 1379a9fc1c0SDavid Howells nr_pages); 1389a9fc1c0SDavid Howells return -ENOBUFS; 1399a9fc1c0SDavid Howells } 140545db45fSDavid Howells 1417f8e05f6SDavid Howells /* 1427f8e05f6SDavid Howells * Store a page newly fetched from the server in an inode data storage object 1437f8e05f6SDavid Howells * in the cache. 1447f8e05f6SDavid Howells */ 1457f8e05f6SDavid Howells static inline void nfs_readpage_to_fscache(struct inode *inode, 1467f8e05f6SDavid Howells struct page *page, 1477f8e05f6SDavid Howells int sync) 1487f8e05f6SDavid Howells { 1497f8e05f6SDavid Howells if (PageFsCache(page)) 1507f8e05f6SDavid Howells __nfs_readpage_to_fscache(inode, page, sync); 1517f8e05f6SDavid Howells } 1527f8e05f6SDavid Howells 1535d1acff1SDavid Howells /* 154de242c0bSDavid Howells * Invalidate the contents of fscache for this inode. This will not sleep. 155de242c0bSDavid Howells */ 156de242c0bSDavid Howells static inline void nfs_fscache_invalidate(struct inode *inode) 157de242c0bSDavid Howells { 158de242c0bSDavid Howells fscache_invalidate(NFS_I(inode)->fscache); 159de242c0bSDavid Howells } 160de242c0bSDavid Howells 161de242c0bSDavid Howells /* 162de242c0bSDavid Howells * Wait for an object to finish being invalidated. 163de242c0bSDavid Howells */ 164de242c0bSDavid Howells static inline void nfs_fscache_wait_on_invalidate(struct inode *inode) 165de242c0bSDavid Howells { 166de242c0bSDavid Howells fscache_wait_on_invalidate(NFS_I(inode)->fscache); 167de242c0bSDavid Howells } 168de242c0bSDavid Howells 169de242c0bSDavid Howells /* 1705d1acff1SDavid Howells * indicate the client caching state as readable text 1715d1acff1SDavid Howells */ 1725d1acff1SDavid Howells static inline const char *nfs_server_fscache_state(struct nfs_server *server) 1735d1acff1SDavid Howells { 1745d1acff1SDavid Howells if (server->fscache && (server->options & NFS_OPTION_FSCACHE)) 1755d1acff1SDavid Howells return "yes"; 1765d1acff1SDavid Howells return "no "; 1775d1acff1SDavid Howells } 1785d1acff1SDavid Howells 1798ec442aeSDavid Howells #else /* CONFIG_NFS_FSCACHE */ 1808ec442aeSDavid Howells static inline int nfs_fscache_register(void) { return 0; } 1818ec442aeSDavid Howells static inline void nfs_fscache_unregister(void) {} 1828ec442aeSDavid Howells 18314727281SDavid Howells static inline void nfs_fscache_get_client_cookie(struct nfs_client *clp) {} 18414727281SDavid Howells static inline void nfs_fscache_release_client_cookie(struct nfs_client *clp) {} 18514727281SDavid Howells 18608734048SDavid Howells static inline void nfs_fscache_release_super_cookie(struct super_block *sb) {} 18708734048SDavid Howells 188f1fe29b4SDavid Howells static inline void nfs_fscache_init_inode(struct inode *inode) {} 189f1fe29b4SDavid Howells static inline void nfs_fscache_clear_inode(struct inode *inode) {} 190f1fe29b4SDavid Howells static inline void nfs_fscache_open_file(struct inode *inode, 191ef79c097SDavid Howells struct file *filp) {} 192ef79c097SDavid Howells 193545db45fSDavid Howells static inline int nfs_fscache_release_page(struct page *page, gfp_t gfp) 194545db45fSDavid Howells { 195545db45fSDavid Howells return 1; /* True: may release page */ 196545db45fSDavid Howells } 197545db45fSDavid Howells static inline void nfs_fscache_invalidate_page(struct page *page, 198545db45fSDavid Howells struct inode *inode) {} 199545db45fSDavid Howells static inline void nfs_fscache_wait_on_page_write(struct nfs_inode *nfsi, 200545db45fSDavid Howells struct page *page) {} 201545db45fSDavid Howells 2029a9fc1c0SDavid Howells static inline int nfs_readpage_from_fscache(struct nfs_open_context *ctx, 2039a9fc1c0SDavid Howells struct inode *inode, 2049a9fc1c0SDavid Howells struct page *page) 2059a9fc1c0SDavid Howells { 2069a9fc1c0SDavid Howells return -ENOBUFS; 2079a9fc1c0SDavid Howells } 2089a9fc1c0SDavid Howells static inline int nfs_readpages_from_fscache(struct nfs_open_context *ctx, 2099a9fc1c0SDavid Howells struct inode *inode, 2109a9fc1c0SDavid Howells struct address_space *mapping, 2119a9fc1c0SDavid Howells struct list_head *pages, 2129a9fc1c0SDavid Howells unsigned *nr_pages) 2139a9fc1c0SDavid Howells { 2149a9fc1c0SDavid Howells return -ENOBUFS; 2159a9fc1c0SDavid Howells } 2167f8e05f6SDavid Howells static inline void nfs_readpage_to_fscache(struct inode *inode, 2177f8e05f6SDavid Howells struct page *page, int sync) {} 2189a9fc1c0SDavid Howells 219de242c0bSDavid Howells 220de242c0bSDavid Howells static inline void nfs_fscache_invalidate(struct inode *inode) {} 221c129c293SDavid Howells static inline void nfs_fscache_wait_on_invalidate(struct inode *inode) {} 222de242c0bSDavid Howells 2235d1acff1SDavid Howells static inline const char *nfs_server_fscache_state(struct nfs_server *server) 2245d1acff1SDavid Howells { 2255d1acff1SDavid Howells return "no "; 2265d1acff1SDavid Howells } 2275d1acff1SDavid Howells 2288ec442aeSDavid Howells #endif /* CONFIG_NFS_FSCACHE */ 2298ec442aeSDavid Howells #endif /* _NFS_FSCACHE_H */ 230