aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/pnfs.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/pnfs.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/pnfs.c')
-rw-r--r--fs/nfs/pnfs.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index 22c2ddbef420..d9ab97269ce6 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -472,6 +472,9 @@ send_layoutget(struct pnfs_layout_hdr *lo,
472 struct nfs_server *server = NFS_SERVER(ino); 472 struct nfs_server *server = NFS_SERVER(ino);
473 struct nfs4_layoutget *lgp; 473 struct nfs4_layoutget *lgp;
474 struct pnfs_layout_segment *lseg = NULL; 474 struct pnfs_layout_segment *lseg = NULL;
475 struct page **pages = NULL;
476 int i;
477 u32 max_resp_sz, max_pages;
475 478
476 dprintk("--> %s\n", __func__); 479 dprintk("--> %s\n", __func__);
477 480
@@ -479,6 +482,21 @@ send_layoutget(struct pnfs_layout_hdr *lo,
479 lgp = kzalloc(sizeof(*lgp), GFP_KERNEL); 482 lgp = kzalloc(sizeof(*lgp), GFP_KERNEL);
480 if (lgp == NULL) 483 if (lgp == NULL)
481 return NULL; 484 return NULL;
485
486 /* allocate pages for xdr post processing */
487 max_resp_sz = server->nfs_client->cl_session->fc_attrs.max_resp_sz;
488 max_pages = max_resp_sz >> PAGE_SHIFT;
489
490 pages = kzalloc(max_pages * sizeof(struct page *), GFP_KERNEL);
491 if (!pages)
492 goto out_err_free;
493
494 for (i = 0; i < max_pages; i++) {
495 pages[i] = alloc_page(GFP_KERNEL);
496 if (!pages[i])
497 goto out_err_free;
498 }
499
482 lgp->args.minlength = NFS4_MAX_UINT64; 500 lgp->args.minlength = NFS4_MAX_UINT64;
483 lgp->args.maxcount = PNFS_LAYOUT_MAXSIZE; 501 lgp->args.maxcount = PNFS_LAYOUT_MAXSIZE;
484 lgp->args.range.iomode = iomode; 502 lgp->args.range.iomode = iomode;
@@ -487,6 +505,8 @@ send_layoutget(struct pnfs_layout_hdr *lo,
487 lgp->args.type = server->pnfs_curr_ld->id; 505 lgp->args.type = server->pnfs_curr_ld->id;
488 lgp->args.inode = ino; 506 lgp->args.inode = ino;
489 lgp->args.ctx = get_nfs_open_context(ctx); 507 lgp->args.ctx = get_nfs_open_context(ctx);
508 lgp->args.layout.pages = pages;
509 lgp->args.layout.pglen = max_pages * PAGE_SIZE;
490 lgp->lsegpp = &lseg; 510 lgp->lsegpp = &lseg;
491 511
492 /* Synchronously retrieve layout information from server and 512 /* Synchronously retrieve layout information from server and
@@ -497,7 +517,26 @@ send_layoutget(struct pnfs_layout_hdr *lo,
497 /* remember that LAYOUTGET failed and suspend trying */ 517 /* remember that LAYOUTGET failed and suspend trying */
498 set_bit(lo_fail_bit(iomode), &lo->plh_flags); 518 set_bit(lo_fail_bit(iomode), &lo->plh_flags);
499 } 519 }
520
521 /* free xdr pages */
522 for (i = 0; i < max_pages; i++)
523 __free_page(pages[i]);
524 kfree(pages);
525
500 return lseg; 526 return lseg;
527
528out_err_free:
529 /* free any allocated xdr pages, lgp as it's not used */
530 if (pages) {
531 for (i = 0; i < max_pages; i++) {
532 if (!pages[i])
533 break;
534 __free_page(pages[i]);
535 }
536 kfree(pages);
537 }
538 kfree(lgp);
539 return NULL;
501} 540}
502 541
503bool pnfs_roc(struct inode *ino) 542bool pnfs_roc(struct inode *ino)