@@ -234,6 +234,26 @@ static char *savemem(struct nfsd4_compoundargs *argp, __be32 *p, int nbytes)
234234 return ret ;
235235}
236236
237+ /*
238+ * We require the high 32 bits of 'seconds' to be 0, and
239+ * we ignore all 32 bits of 'nseconds'.
240+ */
241+ static __be32
242+ nfsd4_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+
237257static __be32
238258nfsd4_decode_bitmap (struct nfsd4_compoundargs * argp , u32 * bmval )
239259{
@@ -267,7 +287,6 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
267287{
268288 int expected_len , len = 0 ;
269289 u32 dummy32 ;
270- u64 sec ;
271290 char * buf ;
272291
273292 DECODE_HEAD ;
@@ -358,15 +377,10 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
358377 dummy32 = be32_to_cpup (p ++ );
359378 switch (dummy32 ) {
360379 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 );
364380 len += 12 ;
365- p = xdr_decode_hyper (p , & sec );
366- iattr -> ia_atime .tv_sec = (time_t )sec ;
367- iattr -> ia_atime .tv_nsec = be32_to_cpup (p ++ );
368- if (iattr -> ia_atime .tv_nsec >= (u32 )1000000000 )
369- return nfserr_inval ;
381+ status = nfsd4_decode_time (argp , & iattr -> ia_atime );
382+ if (status )
383+ return status ;
370384 iattr -> ia_valid |= (ATTR_ATIME | ATTR_ATIME_SET );
371385 break ;
372386 case NFS4_SET_TO_SERVER_TIME :
@@ -382,15 +396,10 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
382396 dummy32 = be32_to_cpup (p ++ );
383397 switch (dummy32 ) {
384398 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 );
388399 len += 12 ;
389- p = xdr_decode_hyper (p , & sec );
390- iattr -> ia_mtime .tv_sec = sec ;
391- iattr -> ia_mtime .tv_nsec = be32_to_cpup (p ++ );
392- if (iattr -> ia_mtime .tv_nsec >= (u32 )1000000000 )
393- return nfserr_inval ;
400+ status = nfsd4_decode_time (argp , & iattr -> ia_mtime );
401+ if (status )
402+ return status ;
394403 iattr -> ia_valid |= (ATTR_MTIME | ATTR_MTIME_SET );
395404 break ;
396405 case NFS4_SET_TO_SERVER_TIME :
0 commit comments