aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2015-01-22 06:09:50 -0500
committerJ. Bruce Fields <bfields@redhat.com>2015-01-23 10:29:13 -0500
commit4c94e13e9caed09103419c087f436d79f9d2faba (patch)
tree4d2703e464e1f165b42ae3957eeab418f7ed474a
parent3c5199143bc4b35f472c5c2534026d74821e2044 (diff)
nfsd: factor out a helper to decode nfstime4 values
Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
-rw-r--r--fs/nfsd/nfs4xdr.c43
1 files changed, 26 insertions, 17 deletions
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 91f7a3644ffb..974533e5a427 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -234,6 +234,26 @@ static char *savemem(struct nfsd4_compoundargs *argp, __be32 *p, int nbytes)
234 return ret; 234 return ret;
235} 235}
236 236
237/*
238 * We require the high 32 bits of 'seconds' to be 0, and
239 * we ignore all 32 bits of 'nseconds'.
240 */
241static __be32
242nfsd4_decode_time(struct nfsd4_compoundargs *argp, struct timespec *tv)
243{
244 DECODE_HEAD;
245 u64 sec;
246
247 READ_BUF(12);
248 p = xdr_decode_hyper(p, &sec);
249 tv->tv_sec = sec;
250 tv->tv_nsec = be32_to_cpup(p++);
251 if (tv->tv_nsec >= (u32)1000000000)
252 return nfserr_inval;
253
254 DECODE_TAIL;
255}
256
237static __be32 257static __be32
238nfsd4_decode_bitmap(struct nfsd4_compoundargs *argp, u32 *bmval) 258nfsd4_decode_bitmap(struct nfsd4_compoundargs *argp, u32 *bmval)
239{ 259{
@@ -267,7 +287,6 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
267{ 287{
268 int expected_len, len = 0; 288 int expected_len, len = 0;
269 u32 dummy32; 289 u32 dummy32;
270 u64 sec;
271 char *buf; 290 char *buf;
272 291
273 DECODE_HEAD; 292 DECODE_HEAD;
@@ -358,15 +377,10 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
358 dummy32 = be32_to_cpup(p++); 377 dummy32 = be32_to_cpup(p++);
359 switch (dummy32) { 378 switch (dummy32) {
360 case NFS4_SET_TO_CLIENT_TIME: 379 case NFS4_SET_TO_CLIENT_TIME:
361 /* We require the high 32 bits of 'seconds' to be 0, and we ignore
362 all 32 bits of 'nseconds'. */
363 READ_BUF(12);
364 len += 12; 380 len += 12;
365 p = xdr_decode_hyper(p, &sec); 381 status = nfsd4_decode_time(argp, &iattr->ia_atime);
366 iattr->ia_atime.tv_sec = (time_t)sec; 382 if (status)
367 iattr->ia_atime.tv_nsec = be32_to_cpup(p++); 383 return status;
368 if (iattr->ia_atime.tv_nsec >= (u32)1000000000)
369 return nfserr_inval;
370 iattr->ia_valid |= (ATTR_ATIME | ATTR_ATIME_SET); 384 iattr->ia_valid |= (ATTR_ATIME | ATTR_ATIME_SET);
371 break; 385 break;
372 case NFS4_SET_TO_SERVER_TIME: 386 case NFS4_SET_TO_SERVER_TIME:
@@ -382,15 +396,10 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
382 dummy32 = be32_to_cpup(p++); 396 dummy32 = be32_to_cpup(p++);
383 switch (dummy32) { 397 switch (dummy32) {
384 case NFS4_SET_TO_CLIENT_TIME: 398 case NFS4_SET_TO_CLIENT_TIME:
385 /* We require the high 32 bits of 'seconds' to be 0, and we ignore
386 all 32 bits of 'nseconds'. */
387 READ_BUF(12);
388 len += 12; 399 len += 12;
389 p = xdr_decode_hyper(p, &sec); 400 status = nfsd4_decode_time(argp, &iattr->ia_mtime);
390 iattr->ia_mtime.tv_sec = sec; 401 if (status)
391 iattr->ia_mtime.tv_nsec = be32_to_cpup(p++); 402 return status;
392 if (iattr->ia_mtime.tv_nsec >= (u32)1000000000)
393 return nfserr_inval;
394 iattr->ia_valid |= (ATTR_MTIME | ATTR_MTIME_SET); 403 iattr->ia_valid |= (ATTR_MTIME | ATTR_MTIME_SET);
395 break; 404 break;
396 case NFS4_SET_TO_SERVER_TIME: 405 case NFS4_SET_TO_SERVER_TIME: