X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=include%2Flinux%2Fnfs_fs.h;fp=include%2Flinux%2Fnfs_fs.h;h=b4dc6e2e10c980d75b92474291c18bf4d8dd57b0;hb=64ba3f394c830ec48a1c31b53dcae312c56f1604;hp=821c628d0ba7b75d617d372d657b9a325cf19132;hpb=be1e6109ac94a859551f8e1774eb9a8469fe055c;p=linux-2.6.git diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index 821c628d0..b4dc6e2e1 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h @@ -9,6 +9,27 @@ #ifndef _LINUX_NFS_FS_H #define _LINUX_NFS_FS_H +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + /* * Enable debugging support for nfs client. * Requires RPC_DEBUG. @@ -26,46 +47,25 @@ */ #define NFS_SUPER_MAGIC 0x6969 +/* + * These are the default flags for swap requests + */ +#define NFS_RPC_SWAPFLAGS (RPC_TASK_SWAPPER|RPC_TASK_ROOTCREDS) + /* * When flushing a cluster of dirty pages, there can be different * strategies: */ +#define FLUSH_AGING 0 /* only flush old buffers */ #define FLUSH_SYNC 1 /* file being synced, or contention */ +#define FLUSH_WAIT 2 /* wait for completion */ #define FLUSH_STABLE 4 /* commit to stable storage */ #define FLUSH_LOWPRI 8 /* low priority background flush */ #define FLUSH_HIGHPRI 16 /* high priority memory reclaim flush */ #define FLUSH_NOCOMMIT 32 /* Don't send the NFSv3/v4 COMMIT */ -#define FLUSH_INVALIDATE 64 /* Invalidate the page cache */ #ifdef __KERNEL__ -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -/* - * These are the default flags for swap requests - */ -#define NFS_RPC_SWAPFLAGS (RPC_TASK_SWAPPER|RPC_TASK_ROOTCREDS) - /* * NFSv3/v4 Access mode cache entry */ @@ -78,7 +78,6 @@ struct nfs_access_entry { struct nfs4_state; struct nfs_open_context { atomic_t count; - struct vfsmount *vfsmnt; struct dentry *dentry; struct rpc_cred *cred; struct nfs4_state *state; @@ -119,7 +118,8 @@ struct nfs_inode { unsigned long cache_validity; /* bit mask */ /* - * read_cache_jiffies is when we started read-caching this inode. + * read_cache_jiffies is when we started read-caching this inode, + * and read_cache_mtime is the mtime of the inode at that time. * attrtimeo is for how long the cached information is assumed * to be valid. A successful attribute revalidation doubles * attrtimeo (up to acregmax/acdirmax), a failure resets it to @@ -128,6 +128,11 @@ struct nfs_inode { * We need to revalidate the cached attrs for this inode if * * jiffies - read_cache_jiffies > attrtimeo + * + * and invalidate any cached data/flush out any dirty pages if + * we find that + * + * mtime != read_cache_mtime */ unsigned long read_cache_jiffies; unsigned long attrtimeo; @@ -181,9 +186,6 @@ struct nfs_inode { int delegation_state; struct rw_semaphore rwsem; #endif /* CONFIG_NFS_V4*/ -#ifdef CONFIG_NFS_FSCACHE - struct fscache_cookie *fscache; -#endif struct inode vfs_inode; }; @@ -213,7 +215,7 @@ static inline struct nfs_inode *NFS_I(struct inode *inode) #define NFS_FH(inode) (&NFS_I(inode)->fh) #define NFS_SERVER(inode) (NFS_SB(inode->i_sb)) #define NFS_CLIENT(inode) (NFS_SERVER(inode)->client) -#define NFS_PROTO(inode) (NFS_SERVER(inode)->nfs_client->rpc_ops) +#define NFS_PROTO(inode) (NFS_SERVER(inode)->rpc_ops) #define NFS_ADDR(inode) (RPC_PEERADDR(NFS_CLIENT(inode))) #define NFS_COOKIEVERF(inode) (NFS_I(inode)->cookieverf) #define NFS_READTIME(inode) (NFS_I(inode)->read_cache_jiffies) @@ -239,12 +241,8 @@ static inline int nfs_caches_unstable(struct inode *inode) static inline void nfs_mark_for_revalidate(struct inode *inode) { - struct nfs_inode *nfsi = NFS_I(inode); - spin_lock(&inode->i_lock); - nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS; - if (S_ISDIR(inode->i_mode)) - nfsi->cache_validity |= NFS_INO_REVAL_PAGECACHE|NFS_INO_INVALID_DATA; + NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS; spin_unlock(&inode->i_lock); } @@ -306,20 +304,19 @@ extern int nfs_release(struct inode *, struct file *); extern int nfs_attribute_timeout(struct inode *inode); extern int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode); extern int __nfs_revalidate_inode(struct nfs_server *, struct inode *); -extern int nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping); +extern void nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping); extern int nfs_setattr(struct dentry *, struct iattr *); extern void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr); extern void nfs_begin_attr_update(struct inode *); extern void nfs_end_attr_update(struct inode *); extern void nfs_begin_data_update(struct inode *); extern void nfs_end_data_update(struct inode *); +extern struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry, struct rpc_cred *cred); extern struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ctx); extern void put_nfs_open_context(struct nfs_open_context *ctx); +extern void nfs_file_set_open_context(struct file *filp, struct nfs_open_context *ctx); extern struct nfs_open_context *nfs_find_open_context(struct inode *inode, struct rpc_cred *cred, int mode); -extern struct vfsmount *nfs_do_submount(const struct vfsmount *mnt_parent, - const struct dentry *dentry, - struct nfs_fh *fh, - struct nfs_fattr *fattr); +extern void nfs_file_clear_open_context(struct file *filp); /* linux/net/ipv4/ipconfig.c: trims ip addr off front of name, too. */ extern u32 root_nfs_parse_addr(char *name); /*__init*/ @@ -337,8 +334,8 @@ extern struct inode_operations nfs_file_inode_operations; #ifdef CONFIG_NFS_V3 extern struct inode_operations nfs3_file_inode_operations; #endif /* CONFIG_NFS_V3 */ -extern const struct file_operations nfs_file_operations; -extern const struct address_space_operations nfs_file_aops; +extern struct file_operations nfs_file_operations; +extern struct address_space_operations nfs_file_aops; static inline struct rpc_cred *nfs_file_cred(struct file *file) { @@ -384,7 +381,7 @@ extern struct inode_operations nfs_dir_inode_operations; #ifdef CONFIG_NFS_V3 extern struct inode_operations nfs3_dir_inode_operations; #endif /* CONFIG_NFS_V3 */ -extern const struct file_operations nfs_dir_operations; +extern struct file_operations nfs_dir_operations; extern struct dentry_operations nfs_dentry_operations; extern int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fh, struct nfs_fattr *fattr); @@ -405,15 +402,6 @@ extern void nfs_unregister_sysctl(void); #define nfs_unregister_sysctl() do { } while(0) #endif -/* - * linux/fs/nfs/namespace.c - */ -extern struct list_head nfs_automount_list; -extern struct inode_operations nfs_mountpoint_inode_operations; -extern struct inode_operations nfs_referral_inode_operations; -extern int nfs_mountpoint_expiry_timeout; -extern void nfs_release_automount_timer(void); - /* * linux/fs/nfs/unlink.c */ @@ -427,22 +415,21 @@ extern int nfs_writepage(struct page *page, struct writeback_control *wbc); extern int nfs_writepages(struct address_space *, struct writeback_control *); extern int nfs_flush_incompatible(struct file *file, struct page *page); extern int nfs_updatepage(struct file *, struct page *, unsigned int, unsigned int); -extern int nfs_writeback_done(struct rpc_task *, struct nfs_write_data *); -extern void nfs_writedata_release(void *); +extern void nfs_writeback_done(struct rpc_task *task, void *data); +extern void nfs_writedata_release(void *data); #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) -struct nfs_write_data *nfs_commit_alloc(void); -void nfs_commit_free(struct nfs_write_data *p); +extern void nfs_commit_done(struct rpc_task *, void *data); +extern void nfs_commit_release(void *data); #endif /* * Try to write back everything synchronously (but check the * return value!) */ -extern int nfs_sync_inode_wait(struct inode *, unsigned long, unsigned int, int); +extern int nfs_sync_inode(struct inode *, unsigned long, unsigned int, int); #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) extern int nfs_commit_inode(struct inode *, int); -extern void nfs_commit_release(void *wdata); #else static inline int nfs_commit_inode(struct inode *inode, int how) @@ -460,7 +447,7 @@ nfs_have_writebacks(struct inode *inode) static inline int nfs_wb_all(struct inode *inode) { - int error = nfs_sync_inode_wait(inode, 0, 0, 0); + int error = nfs_sync_inode(inode, 0, 0, FLUSH_WAIT); return (error < 0) ? error : 0; } @@ -469,8 +456,8 @@ nfs_wb_all(struct inode *inode) */ static inline int nfs_wb_page_priority(struct inode *inode, struct page* page, int how) { - int error = nfs_sync_inode_wait(inode, page->index, 1, - how | FLUSH_STABLE); + int error = nfs_sync_inode(inode, page->index, 1, + how | FLUSH_WAIT | FLUSH_STABLE); return (error < 0) ? error : 0; } @@ -480,9 +467,39 @@ static inline int nfs_wb_page(struct inode *inode, struct page* page) } /* - * Allocate nfs_write_data structures + * Allocate and free nfs_write_data structures */ -extern struct nfs_write_data *nfs_writedata_alloc(size_t len); +extern mempool_t *nfs_wdata_mempool; + +static inline struct nfs_write_data *nfs_writedata_alloc(unsigned int pagecount) +{ + struct nfs_write_data *p = mempool_alloc(nfs_wdata_mempool, SLAB_NOFS); + + if (p) { + memset(p, 0, sizeof(*p)); + INIT_LIST_HEAD(&p->pages); + if (pagecount < NFS_PAGEVEC_SIZE) + p->pagevec = &p->page_array[0]; + else { + size_t size = ++pagecount * sizeof(struct page *); + p->pagevec = kmalloc(size, GFP_NOFS); + if (p->pagevec) { + memset(p->pagevec, 0, size); + } else { + mempool_free(p, nfs_wdata_mempool); + p = NULL; + } + } + } + return p; +} + +static inline void nfs_writedata_free(struct nfs_write_data *p) +{ + if (p && (p->pagevec != &p->page_array[0])) + kfree(p->pagevec); + mempool_free(p, nfs_wdata_mempool); +} /* * linux/fs/nfs/read.c @@ -490,13 +507,44 @@ extern struct nfs_write_data *nfs_writedata_alloc(size_t len); extern int nfs_readpage(struct file *, struct page *); extern int nfs_readpages(struct file *, struct address_space *, struct list_head *, unsigned); -extern int nfs_readpage_result(struct rpc_task *, struct nfs_read_data *); -extern void nfs_readdata_release(void *data); +extern void nfs_readpage_result(struct rpc_task *, void *); +extern void nfs_readdata_release(void *data); + /* - * Allocate nfs_read_data structures + * Allocate and free nfs_read_data structures */ -extern struct nfs_read_data *nfs_readdata_alloc(size_t len); +extern mempool_t *nfs_rdata_mempool; + +static inline struct nfs_read_data *nfs_readdata_alloc(unsigned int pagecount) +{ + struct nfs_read_data *p = mempool_alloc(nfs_rdata_mempool, SLAB_NOFS); + + if (p) { + memset(p, 0, sizeof(*p)); + INIT_LIST_HEAD(&p->pages); + if (pagecount < NFS_PAGEVEC_SIZE) + p->pagevec = &p->page_array[0]; + else { + size_t size = ++pagecount * sizeof(struct page *); + p->pagevec = kmalloc(size, GFP_NOFS); + if (p->pagevec) { + memset(p->pagevec, 0, size); + } else { + mempool_free(p, nfs_rdata_mempool); + p = NULL; + } + } + } + return p; +} + +static inline void nfs_readdata_free(struct nfs_read_data *p) +{ + if (p && (p->pagevec != &p->page_array[0])) + kfree(p->pagevec); + mempool_free(p, nfs_rdata_mempool); +} /* * linux/fs/nfs3proc.c @@ -541,6 +589,15 @@ nfs_size_to_loff_t(__u64 size) return (loff_t) size; } +static inline ino_t +nfs_fileid_to_ino_t(u64 fileid) +{ + ino_t ino = (ino_t) fileid; + if (sizeof(ino_t) < sizeof(u64)) + ino ^= fileid >> (sizeof(u64)-sizeof(ino_t)) * 8; + return ino; +} + /* NFS root */ extern void * nfs_root_data(void); @@ -574,8 +631,6 @@ extern void * nfs_root_data(void); #define NFSDBG_FILE 0x0040 #define NFSDBG_ROOT 0x0080 #define NFSDBG_CALLBACK 0x0100 -#define NFSDBG_CLIENT 0x0200 -#define NFSDBG_FSCACHE 0x0400 #define NFSDBG_ALL 0xFFFF #ifdef __KERNEL__