Commit c397852c authored by Peter Staubach's avatar Peter Staubach Committed by Linus Torvalds

[PATCH] knfsd: Don't mess with the 'mode' when storing a exclusive-create cookie

NFS V3 (and V4) support exclusive create by passing a 'cookie' which can get
stored with the file.  If the file exists but has exactly the right cookie
stored, then we assume this is a retransmit and the exclusive create was
successful.

The cookie is 64bits and is traditionally stored in the mtime and atime
fields.  This causes a problem with Solaris7 as negative mtime or atime
confuse it.  So we moved two bits into the mode word instead.

But inherited ACLs sometimes overwrite the mode word on create, so this is a
problem.

So we give up and just store 62 of the 64 bits and assume that is close
enough.
Signed-off-by: default avatarNeil Brown <neilb@suse.de>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent e2df0c86
...@@ -1245,7 +1245,6 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp, ...@@ -1245,7 +1245,6 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
__be32 err; __be32 err;
int host_err; int host_err;
__u32 v_mtime=0, v_atime=0; __u32 v_mtime=0, v_atime=0;
int v_mode=0;
err = nfserr_perm; err = nfserr_perm;
if (!flen) if (!flen)
...@@ -1282,16 +1281,11 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp, ...@@ -1282,16 +1281,11 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
goto out; goto out;
if (createmode == NFS3_CREATE_EXCLUSIVE) { if (createmode == NFS3_CREATE_EXCLUSIVE) {
/* while the verifier would fit in mtime+atime, /* solaris7 gets confused (bugid 4218508) if these have
* solaris7 gets confused (bugid 4218508) if these have * the high bit set, so just clear the high bits.
* the high bit set, so we use the mode as well
*/ */
v_mtime = verifier[0]&0x7fffffff; v_mtime = verifier[0]&0x7fffffff;
v_atime = verifier[1]&0x7fffffff; v_atime = verifier[1]&0x7fffffff;
v_mode = S_IFREG
| ((verifier[0]&0x80000000) >> (32-7)) /* u+x */
| ((verifier[1]&0x80000000) >> (32-9)) /* u+r */
;
} }
if (dchild->d_inode) { if (dchild->d_inode) {
...@@ -1319,7 +1313,6 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp, ...@@ -1319,7 +1313,6 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
case NFS3_CREATE_EXCLUSIVE: case NFS3_CREATE_EXCLUSIVE:
if ( dchild->d_inode->i_mtime.tv_sec == v_mtime if ( dchild->d_inode->i_mtime.tv_sec == v_mtime
&& dchild->d_inode->i_atime.tv_sec == v_atime && dchild->d_inode->i_atime.tv_sec == v_atime
&& dchild->d_inode->i_mode == v_mode
&& dchild->d_inode->i_size == 0 ) && dchild->d_inode->i_size == 0 )
break; break;
/* fallthru */ /* fallthru */
...@@ -1341,26 +1334,22 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp, ...@@ -1341,26 +1334,22 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
} }
if (createmode == NFS3_CREATE_EXCLUSIVE) { if (createmode == NFS3_CREATE_EXCLUSIVE) {
/* Cram the verifier into atime/mtime/mode */ /* Cram the verifier into atime/mtime */
iap->ia_valid = ATTR_MTIME|ATTR_ATIME iap->ia_valid = ATTR_MTIME|ATTR_ATIME
| ATTR_MTIME_SET|ATTR_ATIME_SET | ATTR_MTIME_SET|ATTR_ATIME_SET;
| ATTR_MODE;
/* XXX someone who knows this better please fix it for nsec */ /* XXX someone who knows this better please fix it for nsec */
iap->ia_mtime.tv_sec = v_mtime; iap->ia_mtime.tv_sec = v_mtime;
iap->ia_atime.tv_sec = v_atime; iap->ia_atime.tv_sec = v_atime;
iap->ia_mtime.tv_nsec = 0; iap->ia_mtime.tv_nsec = 0;
iap->ia_atime.tv_nsec = 0; iap->ia_atime.tv_nsec = 0;
iap->ia_mode = v_mode;
} }
/* Set file attributes. /* Set file attributes.
* Mode has already been set but we might need to reset it
* for CREATE_EXCLUSIVE
* Irix appears to send along the gid when it tries to * Irix appears to send along the gid when it tries to
* implement setgid directories via NFS. Clear out all that cruft. * implement setgid directories via NFS. Clear out all that cruft.
*/ */
set_attr: set_attr:
if ((iap->ia_valid &= ~(ATTR_UID|ATTR_GID)) != 0) { if ((iap->ia_valid &= ~(ATTR_UID|ATTR_GID|ATTR_MODE)) != 0) {
__be32 err2 = nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0); __be32 err2 = nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0);
if (err2) if (err2)
err = err2; err = err2;
......
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