aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/vfs.c
diff options
context:
space:
mode:
authorPeter Staubach <staubach@redhat.com>2007-01-26 03:57:00 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-01-26 16:50:59 -0500
commitc397852c3ddad582ead8c57fbc48bdeccd995a30 (patch)
tree32510f921ce2d901c26cc8b38734b7454b07d2df /fs/nfsd/vfs.c
parente2df0c8644db3d01e3c6fc5f7670fdd7b4c2b234 (diff)
[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: Neil Brown <neilb@suse.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/nfsd/vfs.c')
-rw-r--r--fs/nfsd/vfs.c21
1 files changed, 5 insertions, 16 deletions
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index ea855629a1c2..4dd49d6e90cd 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -1245,7 +1245,6 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
1245 __be32 err; 1245 __be32 err;
1246 int host_err; 1246 int host_err;
1247 __u32 v_mtime=0, v_atime=0; 1247 __u32 v_mtime=0, v_atime=0;
1248 int v_mode=0;
1249 1248
1250 err = nfserr_perm; 1249 err = nfserr_perm;
1251 if (!flen) 1250 if (!flen)
@@ -1282,16 +1281,11 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
1282 goto out; 1281 goto out;
1283 1282
1284 if (createmode == NFS3_CREATE_EXCLUSIVE) { 1283 if (createmode == NFS3_CREATE_EXCLUSIVE) {
1285 /* while the verifier would fit in mtime+atime, 1284 /* solaris7 gets confused (bugid 4218508) if these have
1286 * solaris7 gets confused (bugid 4218508) if these have 1285 * the high bit set, so just clear the high bits.
1287 * the high bit set, so we use the mode as well
1288 */ 1286 */
1289 v_mtime = verifier[0]&0x7fffffff; 1287 v_mtime = verifier[0]&0x7fffffff;
1290 v_atime = verifier[1]&0x7fffffff; 1288 v_atime = verifier[1]&0x7fffffff;
1291 v_mode = S_IFREG
1292 | ((verifier[0]&0x80000000) >> (32-7)) /* u+x */
1293 | ((verifier[1]&0x80000000) >> (32-9)) /* u+r */
1294 ;
1295 } 1289 }
1296 1290
1297 if (dchild->d_inode) { 1291 if (dchild->d_inode) {
@@ -1319,7 +1313,6 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
1319 case NFS3_CREATE_EXCLUSIVE: 1313 case NFS3_CREATE_EXCLUSIVE:
1320 if ( dchild->d_inode->i_mtime.tv_sec == v_mtime 1314 if ( dchild->d_inode->i_mtime.tv_sec == v_mtime
1321 && dchild->d_inode->i_atime.tv_sec == v_atime 1315 && dchild->d_inode->i_atime.tv_sec == v_atime
1322 && dchild->d_inode->i_mode == v_mode
1323 && dchild->d_inode->i_size == 0 ) 1316 && dchild->d_inode->i_size == 0 )
1324 break; 1317 break;
1325 /* fallthru */ 1318 /* fallthru */
@@ -1341,26 +1334,22 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
1341 } 1334 }
1342 1335
1343 if (createmode == NFS3_CREATE_EXCLUSIVE) { 1336 if (createmode == NFS3_CREATE_EXCLUSIVE) {
1344 /* Cram the verifier into atime/mtime/mode */ 1337 /* Cram the verifier into atime/mtime */
1345 iap->ia_valid = ATTR_MTIME|ATTR_ATIME 1338 iap->ia_valid = ATTR_MTIME|ATTR_ATIME
1346 | ATTR_MTIME_SET|ATTR_ATIME_SET 1339 | ATTR_MTIME_SET|ATTR_ATIME_SET;
1347 | ATTR_MODE;
1348 /* XXX someone who knows this better please fix it for nsec */ 1340 /* XXX someone who knows this better please fix it for nsec */
1349 iap->ia_mtime.tv_sec = v_mtime; 1341 iap->ia_mtime.tv_sec = v_mtime;
1350 iap->ia_atime.tv_sec = v_atime; 1342 iap->ia_atime.tv_sec = v_atime;
1351 iap->ia_mtime.tv_nsec = 0; 1343 iap->ia_mtime.tv_nsec = 0;
1352 iap->ia_atime.tv_nsec = 0; 1344 iap->ia_atime.tv_nsec = 0;
1353 iap->ia_mode = v_mode;
1354 } 1345 }
1355 1346
1356 /* Set file attributes. 1347 /* Set file attributes.
1357 * Mode has already been set but we might need to reset it
1358 * for CREATE_EXCLUSIVE
1359 * Irix appears to send along the gid when it tries to 1348 * Irix appears to send along the gid when it tries to
1360 * implement setgid directories via NFS. Clear out all that cruft. 1349 * implement setgid directories via NFS. Clear out all that cruft.
1361 */ 1350 */
1362 set_attr: 1351 set_attr:
1363 if ((iap->ia_valid &= ~(ATTR_UID|ATTR_GID)) != 0) { 1352 if ((iap->ia_valid &= ~(ATTR_UID|ATTR_GID|ATTR_MODE)) != 0) {
1364 __be32 err2 = nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0); 1353 __be32 err2 = nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0);
1365 if (err2) 1354 if (err2)
1366 err = err2; 1355 err = err2;