aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorBryan Schumaker <bjschuma@netapp.com>2013-04-19 16:09:38 -0400
committerJ. Bruce Fields <bfields@redhat.com>2013-04-23 14:49:37 -0400
commitbf8d909705e9d9bac31d9b8eac6734d2b51332a7 (patch)
tree9ad53ba8e5d8b6cfd5dc85c86d243fb157a6b0e6 /fs
parentba138435d1f8b25aa2b787848ee939270a50e34f (diff)
nfsd: Decode and send 64bit time values
The seconds field of an nfstime4 structure is 64bit, but we are assuming that the first 32bits are zero-filled. So if the client tries to set atime to a value before the epoch (touch -t 196001010101), then the server will save the wrong value on disk. Signed-off-by: Bryan Schumaker <bjschuma@netapp.com> Cc: stable@kernel.org Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/nfsd/nfs4xdr.c19
1 files changed, 5 insertions, 14 deletions
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 1cf154511dae..888a600dad8c 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -344,10 +344,7 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
344 all 32 bits of 'nseconds'. */ 344 all 32 bits of 'nseconds'. */
345 READ_BUF(12); 345 READ_BUF(12);
346 len += 12; 346 len += 12;
347 READ32(dummy32); 347 READ64(iattr->ia_atime.tv_sec);
348 if (dummy32)
349 return nfserr_inval;
350 READ32(iattr->ia_atime.tv_sec);
351 READ32(iattr->ia_atime.tv_nsec); 348 READ32(iattr->ia_atime.tv_nsec);
352 if (iattr->ia_atime.tv_nsec >= (u32)1000000000) 349 if (iattr->ia_atime.tv_nsec >= (u32)1000000000)
353 return nfserr_inval; 350 return nfserr_inval;
@@ -370,10 +367,7 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
370 all 32 bits of 'nseconds'. */ 367 all 32 bits of 'nseconds'. */
371 READ_BUF(12); 368 READ_BUF(12);
372 len += 12; 369 len += 12;
373 READ32(dummy32); 370 READ64(iattr->ia_mtime.tv_sec);
374 if (dummy32)
375 return nfserr_inval;
376 READ32(iattr->ia_mtime.tv_sec);
377 READ32(iattr->ia_mtime.tv_nsec); 371 READ32(iattr->ia_mtime.tv_nsec);
378 if (iattr->ia_mtime.tv_nsec >= (u32)1000000000) 372 if (iattr->ia_mtime.tv_nsec >= (u32)1000000000)
379 return nfserr_inval; 373 return nfserr_inval;
@@ -2372,8 +2366,7 @@ out_acl:
2372 if (bmval1 & FATTR4_WORD1_TIME_ACCESS) { 2366 if (bmval1 & FATTR4_WORD1_TIME_ACCESS) {
2373 if ((buflen -= 12) < 0) 2367 if ((buflen -= 12) < 0)
2374 goto out_resource; 2368 goto out_resource;
2375 WRITE32(0); 2369 WRITE64((s64)stat.atime.tv_sec);
2376 WRITE32(stat.atime.tv_sec);
2377 WRITE32(stat.atime.tv_nsec); 2370 WRITE32(stat.atime.tv_nsec);
2378 } 2371 }
2379 if (bmval1 & FATTR4_WORD1_TIME_DELTA) { 2372 if (bmval1 & FATTR4_WORD1_TIME_DELTA) {
@@ -2386,15 +2379,13 @@ out_acl:
2386 if (bmval1 & FATTR4_WORD1_TIME_METADATA) { 2379 if (bmval1 & FATTR4_WORD1_TIME_METADATA) {
2387 if ((buflen -= 12) < 0) 2380 if ((buflen -= 12) < 0)
2388 goto out_resource; 2381 goto out_resource;
2389 WRITE32(0); 2382 WRITE64((s64)stat.ctime.tv_sec);
2390 WRITE32(stat.ctime.tv_sec);
2391 WRITE32(stat.ctime.tv_nsec); 2383 WRITE32(stat.ctime.tv_nsec);
2392 } 2384 }
2393 if (bmval1 & FATTR4_WORD1_TIME_MODIFY) { 2385 if (bmval1 & FATTR4_WORD1_TIME_MODIFY) {
2394 if ((buflen -= 12) < 0) 2386 if ((buflen -= 12) < 0)
2395 goto out_resource; 2387 goto out_resource;
2396 WRITE32(0); 2388 WRITE64((s64)stat.mtime.tv_sec);
2397 WRITE32(stat.mtime.tv_sec);
2398 WRITE32(stat.mtime.tv_nsec); 2389 WRITE32(stat.mtime.tv_nsec);
2399 } 2390 }
2400 if (bmval1 & FATTR4_WORD1_MOUNTED_ON_FILEID) { 2391 if (bmval1 & FATTR4_WORD1_MOUNTED_ON_FILEID) {