Commit beb2a5ec authored by Trond Myklebust's avatar Trond Myklebust

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: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 969b7f25
...@@ -35,7 +35,9 @@ unsigned nfs4_callback_getattr(struct cb_getattrargs *args, struct cb_getattrres ...@@ -35,7 +35,9 @@ unsigned nfs4_callback_getattr(struct cb_getattrargs *args, struct cb_getattrres
if (delegation == NULL || (delegation->type & FMODE_WRITE) == 0) if (delegation == NULL || (delegation->type & FMODE_WRITE) == 0)
goto out_iput; goto out_iput;
res->size = i_size_read(inode); res->size = i_size_read(inode);
res->change_attr = NFS_CHANGE_ATTR(inode); res->change_attr = delegation->change_attr;
if (nfsi->npages != 0)
res->change_attr++;
res->ctime = inode->i_ctime; res->ctime = inode->i_ctime;
res->mtime = inode->i_mtime; res->mtime = inode->i_mtime;
res->bitmap[0] = (FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE) & res->bitmap[0] = (FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE) &
......
...@@ -131,6 +131,7 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct ...@@ -131,6 +131,7 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct
sizeof(delegation->stateid.data)); sizeof(delegation->stateid.data));
delegation->type = res->delegation_type; delegation->type = res->delegation_type;
delegation->maxsize = res->maxsize; delegation->maxsize = res->maxsize;
delegation->change_attr = nfsi->change_attr;
delegation->cred = get_rpccred(cred); delegation->cred = get_rpccred(cred);
delegation->inode = inode; delegation->inode = inode;
......
...@@ -21,6 +21,7 @@ struct nfs_delegation { ...@@ -21,6 +21,7 @@ struct nfs_delegation {
#define NFS_DELEGATION_NEED_RECLAIM 1 #define NFS_DELEGATION_NEED_RECLAIM 1
long flags; long flags;
loff_t maxsize; loff_t maxsize;
__u64 change_attr;
}; };
int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res); int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment