aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4filelayout.c
diff options
context:
space:
mode:
authorWeston Andros Adamson <dros@netapp.com>2011-03-24 16:48:21 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2011-03-24 17:01:41 -0400
commit35124a0994fc02545b14b9fa3aad000b3331f1c0 (patch)
tree5149267f387199fd9ca2718c74d86b6779013501 /fs/nfs/nfs4filelayout.c
parentef31153786bc1e4304e6b9422cc8b9efef455611 (diff)
Cleanup XDR parsing for LAYOUTGET, GETDEVICEINFO
changes LAYOUTGET and GETDEVICEINFO XDR parsing to: - not use vmap, which doesn't work on incoherent archs - use xdr_stream parsing for all xdr Signed-off-by: Weston Andros Adamson <dros@netapp.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/nfs4filelayout.c')
-rw-r--r--fs/nfs/nfs4filelayout.c53
1 files changed, 44 insertions, 9 deletions
diff --git a/fs/nfs/nfs4filelayout.c b/fs/nfs/nfs4filelayout.c
index ffb54a082f3a..6f8192f4cfc7 100644
--- a/fs/nfs/nfs4filelayout.c
+++ b/fs/nfs/nfs4filelayout.c
@@ -502,12 +502,33 @@ filelayout_decode_layout(struct pnfs_layout_hdr *flo,
502 struct nfs4_layoutget_res *lgr, 502 struct nfs4_layoutget_res *lgr,
503 struct nfs4_deviceid *id) 503 struct nfs4_deviceid *id)
504{ 504{
505 uint32_t *p = (uint32_t *)lgr->layout.buf; 505 struct xdr_stream stream;
506 struct xdr_buf buf = {
507 .pages = lgr->layoutp->pages,
508 .page_len = lgr->layoutp->len,
509 .buflen = lgr->layoutp->len,
510 .len = lgr->layoutp->len,
511 };
512 struct page *scratch;
513 __be32 *p;
506 uint32_t nfl_util; 514 uint32_t nfl_util;
507 int i; 515 int i;
508 516
509 dprintk("%s: set_layout_map Begin\n", __func__); 517 dprintk("%s: set_layout_map Begin\n", __func__);
510 518
519 scratch = alloc_page(GFP_KERNEL);
520 if (!scratch)
521 return -ENOMEM;
522
523 xdr_init_decode(&stream, &buf, NULL);
524 xdr_set_scratch_buffer(&stream, page_address(scratch), PAGE_SIZE);
525
526 /* 20 = ufl_util (4), first_stripe_index (4), pattern_offset (8),
527 * num_fh (4) */
528 p = xdr_inline_decode(&stream, NFS4_DEVICEID4_SIZE + 20);
529 if (unlikely(!p))
530 goto out_err;
531
511 memcpy(id, p, sizeof(*id)); 532 memcpy(id, p, sizeof(*id));
512 p += XDR_QUADLEN(NFS4_DEVICEID4_SIZE); 533 p += XDR_QUADLEN(NFS4_DEVICEID4_SIZE);
513 print_deviceid(id); 534 print_deviceid(id);
@@ -529,32 +550,46 @@ filelayout_decode_layout(struct pnfs_layout_hdr *flo,
529 __func__, nfl_util, fl->num_fh, fl->first_stripe_index, 550 __func__, nfl_util, fl->num_fh, fl->first_stripe_index,
530 fl->pattern_offset); 551 fl->pattern_offset);
531 552
553 if (!fl->num_fh)
554 goto out_err;
555
532 fl->fh_array = kzalloc(fl->num_fh * sizeof(struct nfs_fh *), 556 fl->fh_array = kzalloc(fl->num_fh * sizeof(struct nfs_fh *),
533 GFP_KERNEL); 557 GFP_KERNEL);
534 if (!fl->fh_array) 558 if (!fl->fh_array)
535 return -ENOMEM; 559 goto out_err;
536 560
537 for (i = 0; i < fl->num_fh; i++) { 561 for (i = 0; i < fl->num_fh; i++) {
538 /* Do we want to use a mempool here? */ 562 /* Do we want to use a mempool here? */
539 fl->fh_array[i] = kmalloc(sizeof(struct nfs_fh), GFP_KERNEL); 563 fl->fh_array[i] = kmalloc(sizeof(struct nfs_fh), GFP_KERNEL);
540 if (!fl->fh_array[i]) { 564 if (!fl->fh_array[i])
541 filelayout_free_fh_array(fl); 565 goto out_err_free;
542 return -ENOMEM; 566
543 } 567 p = xdr_inline_decode(&stream, 4);
568 if (unlikely(!p))
569 goto out_err_free;
544 fl->fh_array[i]->size = be32_to_cpup(p++); 570 fl->fh_array[i]->size = be32_to_cpup(p++);
545 if (sizeof(struct nfs_fh) < fl->fh_array[i]->size) { 571 if (sizeof(struct nfs_fh) < fl->fh_array[i]->size) {
546 printk(KERN_ERR "Too big fh %d received %d\n", 572 printk(KERN_ERR "Too big fh %d received %d\n",
547 i, fl->fh_array[i]->size); 573 i, fl->fh_array[i]->size);
548 filelayout_free_fh_array(fl); 574 goto out_err_free;
549 return -EIO;
550 } 575 }
576
577 p = xdr_inline_decode(&stream, fl->fh_array[i]->size);
578 if (unlikely(!p))
579 goto out_err_free;
551 memcpy(fl->fh_array[i]->data, p, fl->fh_array[i]->size); 580 memcpy(fl->fh_array[i]->data, p, fl->fh_array[i]->size);
552 p += XDR_QUADLEN(fl->fh_array[i]->size);
553 dprintk("DEBUG: %s: fh len %d\n", __func__, 581 dprintk("DEBUG: %s: fh len %d\n", __func__,
554 fl->fh_array[i]->size); 582 fl->fh_array[i]->size);
555 } 583 }
556 584
585 __free_page(scratch);
557 return 0; 586 return 0;
587
588out_err_free:
589 filelayout_free_fh_array(fl);
590out_err:
591 __free_page(scratch);
592 return -EIO;
558} 593}
559 594
560static void 595static void