aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4proc.c
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2007-06-05 14:49:03 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2007-07-10 23:40:25 -0400
commitaa53ed541a1fec78a78d02afc8b042d040cc080d (patch)
tree04d4c66b643e4ec9ec1277f3ad642b18f3f94990 /fs/nfs/nfs4proc.c
parentfc6ae3cf482c385a6fe87ba119d399bb85aa670b (diff)
NFS4: on a O_EXCL OPEN make sure SETATTR sets the fields holding the verifier
The Linux NFS4 client simply skips over the bitmask in an O_EXCL open call and so it doesn't bother to reset any fields that may be holding the verifier. This patch has us save the first two words of the bitmask (which is all the current client has #defines for). The client then later checks this bitmask and turns on the appropriate flags in the sattr->ia_verify field for the following SETATTR call. This patch only currently checks to see if the server used the atime and mtime slots for the verifier (which is what the Linux server uses for this). I'm not sure of what other fields the server could reasonably use, but adding checks for others should be trivial. Signed-off-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r--fs/nfs/nfs4proc.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 3cc75445a68d..fee2d14b158b 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -943,6 +943,22 @@ static struct nfs4_state *nfs4_open_delegated(struct inode *inode, int flags, st
943} 943}
944 944
945/* 945/*
946 * on an EXCLUSIVE create, the server should send back a bitmask with FATTR4-*
947 * fields corresponding to attributes that were used to store the verifier.
948 * Make sure we clobber those fields in the later setattr call
949 */
950static inline void nfs4_exclusive_attrset(struct nfs4_opendata *opendata, struct iattr *sattr)
951{
952 if ((opendata->o_res.attrset[1] & FATTR4_WORD1_TIME_ACCESS) &&
953 !(sattr->ia_valid & ATTR_ATIME_SET))
954 sattr->ia_valid |= ATTR_ATIME;
955
956 if ((opendata->o_res.attrset[1] & FATTR4_WORD1_TIME_MODIFY) &&
957 !(sattr->ia_valid & ATTR_MTIME_SET))
958 sattr->ia_valid |= ATTR_MTIME;
959}
960
961/*
946 * Returns a referenced nfs4_state 962 * Returns a referenced nfs4_state
947 */ 963 */
948static int _nfs4_do_open(struct inode *dir, struct path *path, int flags, struct iattr *sattr, struct rpc_cred *cred, struct nfs4_state **res) 964static int _nfs4_do_open(struct inode *dir, struct path *path, int flags, struct iattr *sattr, struct rpc_cred *cred, struct nfs4_state **res)
@@ -973,6 +989,9 @@ static int _nfs4_do_open(struct inode *dir, struct path *path, int flags, struct
973 if (status != 0) 989 if (status != 0)
974 goto err_opendata_free; 990 goto err_opendata_free;
975 991
992 if (opendata->o_arg.open_flags & O_EXCL)
993 nfs4_exclusive_attrset(opendata, sattr);
994
976 status = -ENOMEM; 995 status = -ENOMEM;
977 state = nfs4_opendata_to_nfs4_state(opendata); 996 state = nfs4_opendata_to_nfs4_state(opendata);
978 if (state == NULL) 997 if (state == NULL)
@@ -1784,6 +1803,7 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
1784 status = nfs4_do_setattr(state->inode, &fattr, sattr, state); 1803 status = nfs4_do_setattr(state->inode, &fattr, sattr, state);
1785 if (status == 0) 1804 if (status == 0)
1786 nfs_setattr_update_inode(state->inode, sattr); 1805 nfs_setattr_update_inode(state->inode, sattr);
1806 nfs_post_op_update_inode(state->inode, &fattr);
1787 } 1807 }
1788 if (status == 0 && (nd->flags & LOOKUP_OPEN) != 0) 1808 if (status == 0 && (nd->flags & LOOKUP_OPEN) != 0)
1789 status = nfs4_intent_set_file(nd, &path, state); 1809 status = nfs4_intent_set_file(nd, &path, state);