diff options
Diffstat (limited to 'fs/nfsd/nfsxdr.c')
-rw-r--r-- | fs/nfsd/nfsxdr.c | 39 |
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 | |||
231 | nfssvc_decode_sattrargs(struct svc_rqst *rqstp, __be32 *p, | 231 | nfssvc_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 | |||
346 | nfssvc_decode_createargs(struct svc_rqst *rqstp, __be32 *p, | 335 | nfssvc_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 | |||
393 | nfssvc_decode_symlinkargs(struct svc_rqst *rqstp, __be32 *p, | 382 | nfssvc_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 | } |