fs/nfs/delegation.h | 11 ++++++++++- fs/nfs/dir.c | 4 ++++ fs/nfs/file.c | 4 ++++ fs/nfs/inode.c | 47 +++++++++++++++++++++++++++++++++++++++-------- fs/nfs/write.c | 7 +++++-- include/linux/nfs_fs.h | 24 ++---------------------- 6 files changed, 64 insertions(+), 33 deletions(-) diff -u --recursive --new-file --show-c-function linux-2.6.7-14-delegation_open/fs/nfs/delegation.h linux-2.6.7-15-delegation_cache/fs/nfs/delegation.h --- linux-2.6.7-14-delegation_open/fs/nfs/delegation.h 2004-06-06 18:03:36.000000000 -0400 +++ linux-2.6.7-15-delegation_cache/fs/nfs/delegation.h 2004-06-06 21:53:59.000000000 -0400 @@ -8,6 +8,8 @@ #ifndef FS_NFS_DELEGATION_H #define FS_NFS_DELEGATION_H +#if defined(CONFIG_NFS_V4) + void nfs_inode_set_delegation(struct inode *inode, struct nfs_openres *res, long generation); void nfs_inode_clear_delegation(struct inode *inode); int nfs_inode_return_delegation(struct inode *inode); @@ -24,5 +26,12 @@ static inline int nfs_have_delegation(st return !list_empty(&delegation->list) && ((delegation->type & flags) == flags); } +#else + +static inline int nfs_have_delegation(struct inode *inode, int flags) +{ + return 0; +} -#endif +#endif /* defined(CONFIG_NFS_V4) */ +#endif /* !defined(FS_NFS_DELEGATION_H) */ diff -u --recursive --new-file --show-c-function linux-2.6.7-14-delegation_open/fs/nfs/dir.c linux-2.6.7-15-delegation_cache/fs/nfs/dir.c --- linux-2.6.7-14-delegation_open/fs/nfs/dir.c 2004-06-06 18:03:36.000000000 -0400 +++ linux-2.6.7-15-delegation_cache/fs/nfs/dir.c 2004-06-06 22:09:24.000000000 -0400 @@ -32,6 +32,8 @@ #include #include +#include "delegation.h" + #define NFS_PARANOIA 1 /* #define NFS_DEBUG_VERBOSE 1 */ @@ -887,6 +889,8 @@ out: return ret; no_open: dput(parent); + if (inode != NULL && nfs_have_delegation(inode, FMODE_READ)) + return 1; return nfs_lookup_revalidate(dentry, nd); } #endif /* CONFIG_NFSV4 */ diff -u --recursive --new-file --show-c-function linux-2.6.7-14-delegation_open/fs/nfs/file.c linux-2.6.7-15-delegation_cache/fs/nfs/file.c --- linux-2.6.7-14-delegation_open/fs/nfs/file.c 2004-06-06 18:02:39.000000000 -0400 +++ linux-2.6.7-15-delegation_cache/fs/nfs/file.c 2004-06-06 21:50:38.000000000 -0400 @@ -31,6 +31,8 @@ #include #include +#include "delegation.h" + #define NFSDBG_FACILITY NFSDBG_FILE static long nfs_file_fcntl(int fd, unsigned int cmd, @@ -135,6 +137,8 @@ nfs_file_flush(struct file *file) if ((file->f_mode & FMODE_WRITE) == 0) return 0; + if (nfs_have_delegation(inode, FMODE_WRITE)) + return 0; lock_kernel(); /* Ensure that data+attribute caches are up to date after close() */ status = nfs_wb_all(inode); diff -u --recursive --new-file --show-c-function linux-2.6.7-14-delegation_open/fs/nfs/inode.c linux-2.6.7-15-delegation_cache/fs/nfs/inode.c --- linux-2.6.7-14-delegation_open/fs/nfs/inode.c 2004-06-06 18:02:52.000000000 -0400 +++ linux-2.6.7-15-delegation_cache/fs/nfs/inode.c 2004-06-06 23:07:02.000000000 -0400 @@ -39,6 +39,8 @@ #include #include +#include "delegation.h" + #define NFSDBG_FACILITY NFSDBG_VFS #define NFS_PARANOIA 1 @@ -1064,6 +1066,30 @@ out: return status; } +int nfs_attribute_timeout(struct inode *inode) +{ + struct nfs_inode *nfsi = NFS_I(inode); + + if (nfs_have_delegation(inode, FMODE_READ)) + return 0; + return time_after(jiffies, nfsi->read_cache_jiffies+nfsi->attrtimeo); +} + +/** + * nfs_revalidate_inode - Revalidate the inode attributes + * @server - pointer to nfs_server struct + * @inode - pointer to inode struct + * + * Updates inode attribute information by retrieving the data from the server. + */ +int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) +{ + if (!(NFS_FLAGS(inode) & (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA)) + && !nfs_attribute_timeout(inode)) + return NFS_STALE(inode) ? -ESTALE : 0; + return __nfs_revalidate_inode(server, inode); +} + /** * nfs_begin_data_update * @inode - pointer to inode @@ -1085,11 +1111,13 @@ void nfs_end_data_update(struct inode *i { struct nfs_inode *nfsi = NFS_I(inode); - /* Mark the attribute cache for revalidation */ - nfsi->flags |= NFS_INO_INVALID_ATTR; - /* Directories and symlinks: invalidate page cache too */ - if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)) - nfsi->flags |= NFS_INO_INVALID_DATA; + if (!nfs_have_delegation(inode, FMODE_READ)) { + /* Mark the attribute cache for revalidation */ + nfsi->flags |= NFS_INO_INVALID_ATTR; + /* Directories and symlinks: invalidate page cache too */ + if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)) + nfsi->flags |= NFS_INO_INVALID_DATA; + } nfsi->cache_change_attribute ++; atomic_dec(&nfsi->data_updates); } @@ -1130,6 +1158,10 @@ int nfs_refresh_inode(struct inode *inod loff_t cur_size, new_isize; int data_unstable; + /* Do we hold a delegation? */ + if (nfs_have_delegation(inode, FMODE_READ)) + return 0; + /* Are we in the process of updating data on the server? */ data_unstable = nfs_caches_unstable(inode); @@ -1327,7 +1359,8 @@ static int nfs_update_inode(struct inode if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))) invalid &= ~NFS_INO_INVALID_DATA; - nfsi->flags |= invalid; + if (!nfs_have_delegation(inode, FMODE_READ)) + nfsi->flags |= invalid; return 0; out_changed: @@ -1462,8 +1495,6 @@ static struct file_system_type nfs_fs_ty #ifdef CONFIG_NFS_V4 -#include "delegation.h" - static void nfs4_clear_inode(struct inode *); static struct super_operations nfs4_sops = { diff -u --recursive --new-file --show-c-function linux-2.6.7-14-delegation_open/fs/nfs/write.c linux-2.6.7-15-delegation_cache/fs/nfs/write.c --- linux-2.6.7-14-delegation_open/fs/nfs/write.c 2004-06-06 18:02:47.000000000 -0400 +++ linux-2.6.7-15-delegation_cache/fs/nfs/write.c 2004-06-06 23:00:30.000000000 -0400 @@ -63,6 +63,8 @@ #include #include +#include "delegation.h" + #define NFSDBG_FACILITY NFSDBG_PAGECACHE #define MIN_POOL_WRITE (32) @@ -384,8 +386,7 @@ out: /* * Insert a write request into an inode */ -static inline int -nfs_inode_add_request(struct inode *inode, struct nfs_page *req) +static int nfs_inode_add_request(struct inode *inode, struct nfs_page *req) { struct nfs_inode *nfsi = NFS_I(inode); int error; @@ -397,6 +398,8 @@ nfs_inode_add_request(struct inode *inod if (!nfsi->npages) { igrab(inode); nfs_begin_data_update(inode); + if (nfs_have_delegation(inode, FMODE_WRITE)) + nfsi->change_attr++; } nfsi->npages++; req->wb_count++; diff -u --recursive --new-file --show-c-function linux-2.6.7-14-delegation_open/include/linux/nfs_fs.h linux-2.6.7-15-delegation_cache/include/linux/nfs_fs.h --- linux-2.6.7-14-delegation_open/include/linux/nfs_fs.h 2004-06-06 18:03:36.000000000 -0400 +++ linux-2.6.7-15-delegation_cache/include/linux/nfs_fs.h 2004-06-06 21:25:09.000000000 -0400 @@ -310,6 +310,8 @@ extern int nfs_permission(struct inode * extern int nfs_check_access(struct inode *, int, struct rpc_cred *); extern int nfs_open(struct inode *, struct file *); 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_setattr(struct dentry *, struct iattr *); extern void nfs_begin_attr_update(struct inode *); @@ -462,28 +464,6 @@ extern int nfsroot_mount(struct sockadd * inline functions */ -static inline int nfs_attribute_timeout(struct inode *inode) -{ - struct nfs_inode *nfsi = NFS_I(inode); - - return time_after(jiffies, nfsi->read_cache_jiffies+nfsi->attrtimeo); -} - -/** - * nfs_revalidate_inode - Revalidate the inode attributes - * @server - pointer to nfs_server struct - * @inode - pointer to inode struct - * - * Updates inode attribute information by retrieving the data from the server. - */ -static inline int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) -{ - if (!(NFS_FLAGS(inode) & (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA)) - && !nfs_attribute_timeout(inode)) - return NFS_STALE(inode) ? -ESTALE : 0; - return __nfs_revalidate_inode(server, inode); -} - static inline loff_t nfs_size_to_loff_t(__u64 size) {