aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2006-01-03 03:55:37 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2006-01-06 14:58:51 -0500
commitbeb2a5ec386e5ce6891ebd1c06b913da04354b40 (patch)
tree370e0065936e5739de638389af6c85ee960a6b28 /fs/nfs
parent969b7f2522c90dfed5d0d2553a91522bda2c3bf3 (diff)
NFSv4: Ensure change attribute returned by GETATTR callback conforms to spec
According to RFC3530 we're supposed to cache the change attribute at the time the client receives a write delegation. If the inode is clean, a CB_GETATTR callback by the server to the client is supposed to return the cached change attribute. If, OTOH, the inode is dirty, the client should bump the cached change attribute by 1. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/callback_proc.c4
-rw-r--r--fs/nfs/delegation.c1
-rw-r--r--fs/nfs/delegation.h1
3 files changed, 5 insertions, 1 deletions
diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c
index 65f1e19e4d19..462cfceb50c5 100644
--- a/fs/nfs/callback_proc.c
+++ b/fs/nfs/callback_proc.c
@@ -35,7 +35,9 @@ unsigned nfs4_callback_getattr(struct cb_getattrargs *args, struct cb_getattrres
35 if (delegation == NULL || (delegation->type & FMODE_WRITE) == 0) 35 if (delegation == NULL || (delegation->type & FMODE_WRITE) == 0)
36 goto out_iput; 36 goto out_iput;
37 res->size = i_size_read(inode); 37 res->size = i_size_read(inode);
38 res->change_attr = NFS_CHANGE_ATTR(inode); 38 res->change_attr = delegation->change_attr;
39 if (nfsi->npages != 0)
40 res->change_attr++;
39 res->ctime = inode->i_ctime; 41 res->ctime = inode->i_ctime;
40 res->mtime = inode->i_mtime; 42 res->mtime = inode->i_mtime;
41 res->bitmap[0] = (FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE) & 43 res->bitmap[0] = (FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE) &
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
index 75dfb1c717a0..d2ee09b38cee 100644
--- a/fs/nfs/delegation.c
+++ b/fs/nfs/delegation.c
@@ -131,6 +131,7 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct
131 sizeof(delegation->stateid.data)); 131 sizeof(delegation->stateid.data));
132 delegation->type = res->delegation_type; 132 delegation->type = res->delegation_type;
133 delegation->maxsize = res->maxsize; 133 delegation->maxsize = res->maxsize;
134 delegation->change_attr = nfsi->change_attr;
134 delegation->cred = get_rpccred(cred); 135 delegation->cred = get_rpccred(cred);
135 delegation->inode = inode; 136 delegation->inode = inode;
136 137
diff --git a/fs/nfs/delegation.h b/fs/nfs/delegation.h
index fbc50ec271c5..7a0b2bfce771 100644
--- a/fs/nfs/delegation.h
+++ b/fs/nfs/delegation.h
@@ -21,6 +21,7 @@ struct nfs_delegation {
21#define NFS_DELEGATION_NEED_RECLAIM 1 21#define NFS_DELEGATION_NEED_RECLAIM 1
22 long flags; 22 long flags;
23 loff_t maxsize; 23 loff_t maxsize;
24 __u64 change_attr;
24}; 25};
25 26
26int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res); 27int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res);