aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfsxdr.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfsd/nfsxdr.c')
-rw-r--r--fs/nfsd/nfsxdr.c39
1 files changed, 14 insertions, 25 deletions
diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c
index 6035e03655c6..cb3e7fadb772 100644
--- a/fs/nfsd/nfsxdr.c
+++ b/fs/nfsd/nfsxdr.c
@@ -231,9 +231,10 @@ int
231nfssvc_decode_sattrargs(struct svc_rqst *rqstp, __be32 *p, 231nfssvc_decode_sattrargs(struct svc_rqst *rqstp, __be32 *p,
232 struct nfsd_sattrargs *args) 232 struct nfsd_sattrargs *args)
233{ 233{
234 if (!(p = decode_fh(p, &args->fh)) 234 p = decode_fh(p, &args->fh);
235 || !(p = decode_sattr(p, &args->attrs))) 235 if (!p)
236 return 0; 236 return 0;
237 p = decode_sattr(p, &args->attrs);
237 238
238 return xdr_argsize_check(rqstp, p); 239 return xdr_argsize_check(rqstp, p);
239} 240}
@@ -303,29 +304,17 @@ nfssvc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p,
303 /* 304 /*
304 * Check to make sure that we got the right number of 305 * Check to make sure that we got the right number of
305 * bytes. 306 * bytes.
306 *
307 * If more than one page was used, then compute the length
308 * of the data in the request as the total size of the
309 * request minus the transport protocol headers minus the
310 * RPC protocol headers minus the NFS protocol fields
311 * already consumed. If the request fits into a single
312 * page, then compete the length of the data as the size
313 * of the NFS portion of the request minus the NFS
314 * protocol fields already consumed.
315 */ 307 */
316 hdr = (void*)p - rqstp->rq_arg.head[0].iov_base; 308 hdr = (void*)p - rqstp->rq_arg.head[0].iov_base;
317 if (rqstp->rq_respages != rqstp->rq_pages + 1) { 309 dlen = rqstp->rq_arg.head[0].iov_len + rqstp->rq_arg.page_len
318 dlen = rqstp->rq_arg.len - 310 - hdr;
319 (PAGE_SIZE - rqstp->rq_arg.head[0].iov_len) - hdr; 311
320 } else {
321 dlen = rqstp->rq_arg.head[0].iov_len - hdr;
322 }
323 /* 312 /*
324 * Round the length of the data which was specified up to 313 * Round the length of the data which was specified up to
325 * the next multiple of XDR units and then compare that 314 * the next multiple of XDR units and then compare that
326 * against the length which was actually received. 315 * against the length which was actually received.
327 */ 316 */
328 if (dlen != ((len + 3) & ~0x3)) 317 if (dlen != XDR_QUADLEN(len)*4)
329 return 0; 318 return 0;
330 319
331 rqstp->rq_vec[0].iov_base = (void*)p; 320 rqstp->rq_vec[0].iov_base = (void*)p;
@@ -346,10 +335,10 @@ int
346nfssvc_decode_createargs(struct svc_rqst *rqstp, __be32 *p, 335nfssvc_decode_createargs(struct svc_rqst *rqstp, __be32 *p,
347 struct nfsd_createargs *args) 336 struct nfsd_createargs *args)
348{ 337{
349 if (!(p = decode_fh(p, &args->fh)) 338 if ( !(p = decode_fh(p, &args->fh))
350 || !(p = decode_filename(p, &args->name, &args->len)) 339 || !(p = decode_filename(p, &args->name, &args->len)))
351 || !(p = decode_sattr(p, &args->attrs)))
352 return 0; 340 return 0;
341 p = decode_sattr(p, &args->attrs);
353 342
354 return xdr_argsize_check(rqstp, p); 343 return xdr_argsize_check(rqstp, p);
355} 344}
@@ -393,11 +382,11 @@ int
393nfssvc_decode_symlinkargs(struct svc_rqst *rqstp, __be32 *p, 382nfssvc_decode_symlinkargs(struct svc_rqst *rqstp, __be32 *p,
394 struct nfsd_symlinkargs *args) 383 struct nfsd_symlinkargs *args)
395{ 384{
396 if (!(p = decode_fh(p, &args->ffh)) 385 if ( !(p = decode_fh(p, &args->ffh))
397 || !(p = decode_filename(p, &args->fname, &args->flen)) 386 || !(p = decode_filename(p, &args->fname, &args->flen))
398 || !(p = decode_pathname(p, &args->tname, &args->tlen)) 387 || !(p = decode_pathname(p, &args->tname, &args->tlen)))
399 || !(p = decode_sattr(p, &args->attrs)))
400 return 0; 388 return 0;
389 p = decode_sattr(p, &args->attrs);
401 390
402 return xdr_argsize_check(rqstp, p); 391 return xdr_argsize_check(rqstp, p);
403} 392}