1f7b422b1SDavid Howells /* 2f7b422b1SDavid Howells * NFS internal definitions 3f7b422b1SDavid Howells */ 4f7b422b1SDavid Howells 5f7b422b1SDavid Howells #include <linux/mount.h> 6f7b422b1SDavid Howells 754ceac45SDavid Howells struct nfs_string; 854ceac45SDavid Howells 954ceac45SDavid Howells /* Maximum number of readahead requests 1054ceac45SDavid Howells * FIXME: this should really be a sysctl so that users may tune it to suit 1154ceac45SDavid Howells * their needs. People that do NFS over a slow network, might for 1254ceac45SDavid Howells * instance want to reduce it to something closer to 1 for improved 1354ceac45SDavid Howells * interactive response. 1454ceac45SDavid Howells */ 1554ceac45SDavid Howells #define NFS_MAX_READAHEAD (RPC_DEF_SLOT_TABLE - 1) 1654ceac45SDavid Howells 17f7b422b1SDavid Howells struct nfs_clone_mount { 18f7b422b1SDavid Howells const struct super_block *sb; 19f7b422b1SDavid Howells const struct dentry *dentry; 20f7b422b1SDavid Howells struct nfs_fh *fh; 21f7b422b1SDavid Howells struct nfs_fattr *fattr; 22f7b422b1SDavid Howells char *hostname; 23f7b422b1SDavid Howells char *mnt_path; 246677d095SChuck Lever struct sockaddr *addr; 256677d095SChuck Lever size_t addrlen; 26f7b422b1SDavid Howells rpc_authflavor_t authflavor; 27f7b422b1SDavid Howells }; 28f7b422b1SDavid Howells 296b18eaa0S\"Talpey, Thomas\ /* 306b18eaa0S\"Talpey, Thomas\ * In-kernel mount arguments 316b18eaa0S\"Talpey, Thomas\ */ 326b18eaa0S\"Talpey, Thomas\ struct nfs_parsed_mount_data { 336b18eaa0S\"Talpey, Thomas\ int flags; 346b18eaa0S\"Talpey, Thomas\ int rsize, wsize; 356b18eaa0S\"Talpey, Thomas\ int timeo, retrans; 366b18eaa0S\"Talpey, Thomas\ int acregmin, acregmax, 376b18eaa0S\"Talpey, Thomas\ acdirmin, acdirmax; 386b18eaa0S\"Talpey, Thomas\ int namlen; 396b18eaa0S\"Talpey, Thomas\ unsigned int bsize; 406b18eaa0S\"Talpey, Thomas\ unsigned int auth_flavor_len; 416b18eaa0S\"Talpey, Thomas\ rpc_authflavor_t auth_flavors[1]; 426b18eaa0S\"Talpey, Thomas\ char *client_address; 436b18eaa0S\"Talpey, Thomas\ 446b18eaa0S\"Talpey, Thomas\ struct { 456b18eaa0S\"Talpey, Thomas\ struct sockaddr_in address; 466b18eaa0S\"Talpey, Thomas\ char *hostname; 476b18eaa0S\"Talpey, Thomas\ unsigned int version; 486b18eaa0S\"Talpey, Thomas\ unsigned short port; 496b18eaa0S\"Talpey, Thomas\ int protocol; 506b18eaa0S\"Talpey, Thomas\ } mount_server; 516b18eaa0S\"Talpey, Thomas\ 526b18eaa0S\"Talpey, Thomas\ struct { 536b18eaa0S\"Talpey, Thomas\ struct sockaddr_in address; 546b18eaa0S\"Talpey, Thomas\ char *hostname; 556b18eaa0S\"Talpey, Thomas\ char *export_path; 566b18eaa0S\"Talpey, Thomas\ int protocol; 576b18eaa0S\"Talpey, Thomas\ } nfs_server; 586b18eaa0S\"Talpey, Thomas\ }; 596b18eaa0S\"Talpey, Thomas\ 6024c8dbbbSDavid Howells /* client.c */ 6154ceac45SDavid Howells extern struct rpc_program nfs_program; 6254ceac45SDavid Howells 6324c8dbbbSDavid Howells extern void nfs_put_client(struct nfs_client *); 64ff052645SChuck Lever extern struct nfs_client *nfs_find_client(const struct sockaddr *, u32); 652283f8d6S\"Talpey, Thomas\ extern struct nfs_server *nfs_create_server( 662283f8d6S\"Talpey, Thomas\ const struct nfs_parsed_mount_data *, 6754ceac45SDavid Howells struct nfs_fh *); 6891ea40b9S\"Talpey, Thomas\ extern struct nfs_server *nfs4_create_server( 6991ea40b9S\"Talpey, Thomas\ const struct nfs_parsed_mount_data *, 7054ceac45SDavid Howells struct nfs_fh *); 7154ceac45SDavid Howells extern struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *, 7254ceac45SDavid Howells struct nfs_fh *); 7354ceac45SDavid Howells extern void nfs_free_server(struct nfs_server *server); 7454ceac45SDavid Howells extern struct nfs_server *nfs_clone_server(struct nfs_server *, 7554ceac45SDavid Howells struct nfs_fh *, 7654ceac45SDavid Howells struct nfs_fattr *); 776aaca566SDavid Howells #ifdef CONFIG_PROC_FS 786aaca566SDavid Howells extern int __init nfs_fs_proc_init(void); 796aaca566SDavid Howells extern void nfs_fs_proc_exit(void); 806aaca566SDavid Howells #else 816aaca566SDavid Howells static inline int nfs_fs_proc_init(void) 826aaca566SDavid Howells { 836aaca566SDavid Howells return 0; 846aaca566SDavid Howells } 856aaca566SDavid Howells static inline void nfs_fs_proc_exit(void) 866aaca566SDavid Howells { 876aaca566SDavid Howells } 886aaca566SDavid Howells #endif 8924c8dbbbSDavid Howells 907d4e2747SDavid Howells /* nfs4namespace.c */ 91f7b422b1SDavid Howells #ifdef CONFIG_NFS_V4 92f7b422b1SDavid Howells extern struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent, struct dentry *dentry); 93f7b422b1SDavid Howells #else 94f7b422b1SDavid Howells static inline 95f7b422b1SDavid Howells struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent, struct dentry *dentry) 96f7b422b1SDavid Howells { 97f7b422b1SDavid Howells return ERR_PTR(-ENOENT); 98f7b422b1SDavid Howells } 99f7b422b1SDavid Howells #endif 100f7b422b1SDavid Howells 101f7b422b1SDavid Howells /* callback_xdr.c */ 102f7b422b1SDavid Howells extern struct svc_version nfs4_callback_version1; 103f7b422b1SDavid Howells 104f7b422b1SDavid Howells /* pagelist.c */ 105f7b422b1SDavid Howells extern int __init nfs_init_nfspagecache(void); 106266bee88SDavid Brownell extern void nfs_destroy_nfspagecache(void); 107f7b422b1SDavid Howells extern int __init nfs_init_readpagecache(void); 108266bee88SDavid Brownell extern void nfs_destroy_readpagecache(void); 109f7b422b1SDavid Howells extern int __init nfs_init_writepagecache(void); 110266bee88SDavid Brownell extern void nfs_destroy_writepagecache(void); 111f7b422b1SDavid Howells 112f7b422b1SDavid Howells #ifdef CONFIG_NFS_DIRECTIO 113f7b422b1SDavid Howells extern int __init nfs_init_directcache(void); 114266bee88SDavid Brownell extern void nfs_destroy_directcache(void); 115f7b422b1SDavid Howells #else 116f7b422b1SDavid Howells #define nfs_init_directcache() (0) 117f7b422b1SDavid Howells #define nfs_destroy_directcache() do {} while(0) 118f7b422b1SDavid Howells #endif 119f7b422b1SDavid Howells 120f7b422b1SDavid Howells /* nfs2xdr.c */ 1217d4e2747SDavid Howells extern int nfs_stat_to_errno(int); 122f7b422b1SDavid Howells extern struct rpc_procinfo nfs_procedures[]; 1230dbb4c67SAl Viro extern __be32 * nfs_decode_dirent(__be32 *, struct nfs_entry *, int); 124f7b422b1SDavid Howells 125f7b422b1SDavid Howells /* nfs3xdr.c */ 126f7b422b1SDavid Howells extern struct rpc_procinfo nfs3_procedures[]; 1270dbb4c67SAl Viro extern __be32 *nfs3_decode_dirent(__be32 *, struct nfs_entry *, int); 128f7b422b1SDavid Howells 129f7b422b1SDavid Howells /* nfs4xdr.c */ 1307d4e2747SDavid Howells #ifdef CONFIG_NFS_V4 1310dbb4c67SAl Viro extern __be32 *nfs4_decode_dirent(__be32 *p, struct nfs_entry *entry, int plus); 1327d4e2747SDavid Howells #endif 133f7b422b1SDavid Howells 134f7b422b1SDavid Howells /* nfs4proc.c */ 135d75d5414SAndrew Morton #ifdef CONFIG_NFS_V4 136f7b422b1SDavid Howells extern struct rpc_procinfo nfs4_procedures[]; 137d75d5414SAndrew Morton #endif 138f7b422b1SDavid Howells 139979df72eSTrond Myklebust /* dir.c */ 140979df72eSTrond Myklebust extern int nfs_access_cache_shrinker(int nr_to_scan, gfp_t gfp_mask); 141979df72eSTrond Myklebust 142f7b422b1SDavid Howells /* inode.c */ 143f7b422b1SDavid Howells extern struct inode *nfs_alloc_inode(struct super_block *sb); 144f7b422b1SDavid Howells extern void nfs_destroy_inode(struct inode *); 145f7b422b1SDavid Howells extern int nfs_write_inode(struct inode *,int); 146f7b422b1SDavid Howells extern void nfs_clear_inode(struct inode *); 147f7b422b1SDavid Howells #ifdef CONFIG_NFS_V4 148f7b422b1SDavid Howells extern void nfs4_clear_inode(struct inode *); 149f7b422b1SDavid Howells #endif 150f7b422b1SDavid Howells 151f7b422b1SDavid Howells /* super.c */ 15254ceac45SDavid Howells extern struct file_system_type nfs_xdev_fs_type; 153f7b422b1SDavid Howells #ifdef CONFIG_NFS_V4 15454ceac45SDavid Howells extern struct file_system_type nfs4_xdev_fs_type; 15554ceac45SDavid Howells extern struct file_system_type nfs4_referral_fs_type; 156f7b422b1SDavid Howells #endif 1574ebd9ab3SDominik Hackl 158f7b422b1SDavid Howells extern struct rpc_stat nfs_rpcstat; 1594ebd9ab3SDominik Hackl 160f7b422b1SDavid Howells extern int __init register_nfs_fs(void); 161f7b422b1SDavid Howells extern void __exit unregister_nfs_fs(void); 162ef818a28SSteve Dickson extern void nfs_sb_active(struct nfs_server *server); 163ef818a28SSteve Dickson extern void nfs_sb_deactive(struct nfs_server *server); 164f7b422b1SDavid Howells 165f7b422b1SDavid Howells /* namespace.c */ 16654ceac45SDavid Howells extern char *nfs_path(const char *base, 16754ceac45SDavid Howells const struct dentry *droot, 16854ceac45SDavid Howells const struct dentry *dentry, 169f7b422b1SDavid Howells char *buffer, ssize_t buflen); 170f7b422b1SDavid Howells 17154ceac45SDavid Howells /* getroot.c */ 17254ceac45SDavid Howells extern struct dentry *nfs_get_root(struct super_block *, struct nfs_fh *); 1737d4e2747SDavid Howells #ifdef CONFIG_NFS_V4 17454ceac45SDavid Howells extern struct dentry *nfs4_get_root(struct super_block *, struct nfs_fh *); 17554ceac45SDavid Howells 17654ceac45SDavid Howells extern int nfs4_path_walk(struct nfs_server *server, 17754ceac45SDavid Howells struct nfs_fh *mntfh, 17854ceac45SDavid Howells const char *path); 1797d4e2747SDavid Howells #endif 180f7b422b1SDavid Howells 181f7b422b1SDavid Howells /* 182f7b422b1SDavid Howells * Determine the device name as a string 183f7b422b1SDavid Howells */ 184f7b422b1SDavid Howells static inline char *nfs_devname(const struct vfsmount *mnt_parent, 185f7b422b1SDavid Howells const struct dentry *dentry, 186f7b422b1SDavid Howells char *buffer, ssize_t buflen) 187f7b422b1SDavid Howells { 18854ceac45SDavid Howells return nfs_path(mnt_parent->mnt_devname, mnt_parent->mnt_root, 18954ceac45SDavid Howells dentry, buffer, buflen); 190f7b422b1SDavid Howells } 191f7b422b1SDavid Howells 192f7b422b1SDavid Howells /* 193f7b422b1SDavid Howells * Determine the actual block size (and log2 thereof) 194f7b422b1SDavid Howells */ 195f7b422b1SDavid Howells static inline 196f7b422b1SDavid Howells unsigned long nfs_block_bits(unsigned long bsize, unsigned char *nrbitsp) 197f7b422b1SDavid Howells { 198f7b422b1SDavid Howells /* make sure blocksize is a power of two */ 199f7b422b1SDavid Howells if ((bsize & (bsize - 1)) || nrbitsp) { 200f7b422b1SDavid Howells unsigned char nrbits; 201f7b422b1SDavid Howells 202f7b422b1SDavid Howells for (nrbits = 31; nrbits && !(bsize & (1 << nrbits)); nrbits--) 203f7b422b1SDavid Howells ; 204f7b422b1SDavid Howells bsize = 1 << nrbits; 205f7b422b1SDavid Howells if (nrbitsp) 206f7b422b1SDavid Howells *nrbitsp = nrbits; 207f7b422b1SDavid Howells } 208f7b422b1SDavid Howells 209f7b422b1SDavid Howells return bsize; 210f7b422b1SDavid Howells } 211f7b422b1SDavid Howells 212f7b422b1SDavid Howells /* 213f7b422b1SDavid Howells * Calculate the number of 512byte blocks used. 214f7b422b1SDavid Howells */ 2159eaa67c6SChuck Lever static inline blkcnt_t nfs_calc_block_size(u64 tsize) 216f7b422b1SDavid Howells { 2179eaa67c6SChuck Lever blkcnt_t used = (tsize + 511) >> 9; 218f7b422b1SDavid Howells return (used > ULONG_MAX) ? ULONG_MAX : used; 219f7b422b1SDavid Howells } 220f7b422b1SDavid Howells 221f7b422b1SDavid Howells /* 222f7b422b1SDavid Howells * Compute and set NFS server blocksize 223f7b422b1SDavid Howells */ 224f7b422b1SDavid Howells static inline 225f7b422b1SDavid Howells unsigned long nfs_block_size(unsigned long bsize, unsigned char *nrbitsp) 226f7b422b1SDavid Howells { 227f7b422b1SDavid Howells if (bsize < NFS_MIN_FILE_IO_SIZE) 228f7b422b1SDavid Howells bsize = NFS_DEF_FILE_IO_SIZE; 229f7b422b1SDavid Howells else if (bsize >= NFS_MAX_FILE_IO_SIZE) 230f7b422b1SDavid Howells bsize = NFS_MAX_FILE_IO_SIZE; 231f7b422b1SDavid Howells 232f7b422b1SDavid Howells return nfs_block_bits(bsize, nrbitsp); 233f7b422b1SDavid Howells } 234f7b422b1SDavid Howells 235f7b422b1SDavid Howells /* 236f7b422b1SDavid Howells * Determine the maximum file size for a superblock 237f7b422b1SDavid Howells */ 238f7b422b1SDavid Howells static inline 239f7b422b1SDavid Howells void nfs_super_set_maxbytes(struct super_block *sb, __u64 maxfilesize) 240f7b422b1SDavid Howells { 241f7b422b1SDavid Howells sb->s_maxbytes = (loff_t)maxfilesize; 242f7b422b1SDavid Howells if (sb->s_maxbytes > MAX_LFS_FILESIZE || sb->s_maxbytes <= 0) 243f7b422b1SDavid Howells sb->s_maxbytes = MAX_LFS_FILESIZE; 244f7b422b1SDavid Howells } 24549a70f27STrond Myklebust 24649a70f27STrond Myklebust /* 24749a70f27STrond Myklebust * Determine the number of bytes of data the page contains 24849a70f27STrond Myklebust */ 24949a70f27STrond Myklebust static inline 25049a70f27STrond Myklebust unsigned int nfs_page_length(struct page *page) 25149a70f27STrond Myklebust { 25249a70f27STrond Myklebust loff_t i_size = i_size_read(page->mapping->host); 25349a70f27STrond Myklebust 25449a70f27STrond Myklebust if (i_size > 0) { 25549a70f27STrond Myklebust pgoff_t end_index = (i_size - 1) >> PAGE_CACHE_SHIFT; 25649a70f27STrond Myklebust if (page->index < end_index) 25749a70f27STrond Myklebust return PAGE_CACHE_SIZE; 25849a70f27STrond Myklebust if (page->index == end_index) 25949a70f27STrond Myklebust return ((i_size - 1) & ~PAGE_CACHE_MASK) + 1; 26049a70f27STrond Myklebust } 26149a70f27STrond Myklebust return 0; 26249a70f27STrond Myklebust } 2638d5658c9STrond Myklebust 2648d5658c9STrond Myklebust /* 2658d5658c9STrond Myklebust * Determine the number of pages in an array of length 'len' and 2668d5658c9STrond Myklebust * with a base offset of 'base' 2678d5658c9STrond Myklebust */ 2688d5658c9STrond Myklebust static inline 2698d5658c9STrond Myklebust unsigned int nfs_page_array_len(unsigned int base, size_t len) 2708d5658c9STrond Myklebust { 2718d5658c9STrond Myklebust return ((unsigned long)len + (unsigned long)base + 2728d5658c9STrond Myklebust PAGE_SIZE - 1) >> PAGE_SHIFT; 2738d5658c9STrond Myklebust } 2748d5658c9STrond Myklebust 275