aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4filelayout.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/nfs4filelayout.c')
-rw-r--r--fs/nfs/nfs4filelayout.c38
1 files changed, 23 insertions, 15 deletions
diff --git a/fs/nfs/nfs4filelayout.c b/fs/nfs/nfs4filelayout.c
index be79dc9f386d..426908809c97 100644
--- a/fs/nfs/nfs4filelayout.c
+++ b/fs/nfs/nfs4filelayout.c
@@ -421,6 +421,7 @@ filelayout_check_layout(struct pnfs_layout_hdr *lo,
421 struct nfs4_deviceid *id, 421 struct nfs4_deviceid *id,
422 gfp_t gfp_flags) 422 gfp_t gfp_flags)
423{ 423{
424 struct nfs4_deviceid_node *d;
424 struct nfs4_file_layout_dsaddr *dsaddr; 425 struct nfs4_file_layout_dsaddr *dsaddr;
425 int status = -EINVAL; 426 int status = -EINVAL;
426 struct nfs_server *nfss = NFS_SERVER(lo->plh_inode); 427 struct nfs_server *nfss = NFS_SERVER(lo->plh_inode);
@@ -428,7 +429,7 @@ filelayout_check_layout(struct pnfs_layout_hdr *lo,
428 dprintk("--> %s\n", __func__); 429 dprintk("--> %s\n", __func__);
429 430
430 if (fl->pattern_offset > lgr->range.offset) { 431 if (fl->pattern_offset > lgr->range.offset) {
431 dprintk("%s pattern_offset %lld to large\n", 432 dprintk("%s pattern_offset %lld too large\n",
432 __func__, fl->pattern_offset); 433 __func__, fl->pattern_offset);
433 goto out; 434 goto out;
434 } 435 }
@@ -440,12 +441,14 @@ filelayout_check_layout(struct pnfs_layout_hdr *lo,
440 } 441 }
441 442
442 /* find and reference the deviceid */ 443 /* find and reference the deviceid */
443 dsaddr = nfs4_fl_find_get_deviceid(id); 444 d = nfs4_find_get_deviceid(NFS_SERVER(lo->plh_inode)->pnfs_curr_ld,
444 if (dsaddr == NULL) { 445 NFS_SERVER(lo->plh_inode)->nfs_client, id);
446 if (d == NULL) {
445 dsaddr = get_device_info(lo->plh_inode, id, gfp_flags); 447 dsaddr = get_device_info(lo->plh_inode, id, gfp_flags);
446 if (dsaddr == NULL) 448 if (dsaddr == NULL)
447 goto out; 449 goto out;
448 } 450 } else
451 dsaddr = container_of(d, struct nfs4_file_layout_dsaddr, id_node);
449 fl->dsaddr = dsaddr; 452 fl->dsaddr = dsaddr;
450 453
451 if (fl->first_stripe_index < 0 || 454 if (fl->first_stripe_index < 0 ||
@@ -507,12 +510,7 @@ filelayout_decode_layout(struct pnfs_layout_hdr *flo,
507 gfp_t gfp_flags) 510 gfp_t gfp_flags)
508{ 511{
509 struct xdr_stream stream; 512 struct xdr_stream stream;
510 struct xdr_buf buf = { 513 struct xdr_buf buf;
511 .pages = lgr->layoutp->pages,
512 .page_len = lgr->layoutp->len,
513 .buflen = lgr->layoutp->len,
514 .len = lgr->layoutp->len,
515 };
516 struct page *scratch; 514 struct page *scratch;
517 __be32 *p; 515 __be32 *p;
518 uint32_t nfl_util; 516 uint32_t nfl_util;
@@ -524,7 +522,7 @@ filelayout_decode_layout(struct pnfs_layout_hdr *flo,
524 if (!scratch) 522 if (!scratch)
525 return -ENOMEM; 523 return -ENOMEM;
526 524
527 xdr_init_decode(&stream, &buf, NULL); 525 xdr_init_decode_pages(&stream, &buf, lgr->layoutp->pages, lgr->layoutp->len);
528 xdr_set_scratch_buffer(&stream, page_address(scratch), PAGE_SIZE); 526 xdr_set_scratch_buffer(&stream, page_address(scratch), PAGE_SIZE);
529 527
530 /* 20 = ufl_util (4), first_stripe_index (4), pattern_offset (8), 528 /* 20 = ufl_util (4), first_stripe_index (4), pattern_offset (8),
@@ -535,7 +533,7 @@ filelayout_decode_layout(struct pnfs_layout_hdr *flo,
535 533
536 memcpy(id, p, sizeof(*id)); 534 memcpy(id, p, sizeof(*id));
537 p += XDR_QUADLEN(NFS4_DEVICEID4_SIZE); 535 p += XDR_QUADLEN(NFS4_DEVICEID4_SIZE);
538 print_deviceid(id); 536 nfs4_print_deviceid(id);
539 537
540 nfl_util = be32_to_cpup(p++); 538 nfl_util = be32_to_cpup(p++);
541 if (nfl_util & NFL4_UFLG_COMMIT_THRU_MDS) 539 if (nfl_util & NFL4_UFLG_COMMIT_THRU_MDS)
@@ -653,16 +651,19 @@ filelayout_alloc_lseg(struct pnfs_layout_hdr *layoutid,
653/* 651/*
654 * filelayout_pg_test(). Called by nfs_can_coalesce_requests() 652 * filelayout_pg_test(). Called by nfs_can_coalesce_requests()
655 * 653 *
656 * return 1 : coalesce page 654 * return true : coalesce page
657 * return 0 : don't coalesce page 655 * return false : don't coalesce page
658 */ 656 */
659int 657bool
660filelayout_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev, 658filelayout_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev,
661 struct nfs_page *req) 659 struct nfs_page *req)
662{ 660{
663 u64 p_stripe, r_stripe; 661 u64 p_stripe, r_stripe;
664 u32 stripe_unit; 662 u32 stripe_unit;
665 663
664 if (!pnfs_generic_pg_test(pgio, prev, req))
665 return 0;
666
666 if (!pgio->pg_lseg) 667 if (!pgio->pg_lseg)
667 return 1; 668 return 1;
668 p_stripe = (u64)prev->wb_index << PAGE_CACHE_SHIFT; 669 p_stripe = (u64)prev->wb_index << PAGE_CACHE_SHIFT;
@@ -860,6 +861,12 @@ filelayout_commit_pagelist(struct inode *inode, struct list_head *mds_pages,
860 return -ENOMEM; 861 return -ENOMEM;
861} 862}
862 863
864static void
865filelayout_free_deveiceid_node(struct nfs4_deviceid_node *d)
866{
867 nfs4_fl_free_deviceid(container_of(d, struct nfs4_file_layout_dsaddr, id_node));
868}
869
863static struct pnfs_layoutdriver_type filelayout_type = { 870static struct pnfs_layoutdriver_type filelayout_type = {
864 .id = LAYOUT_NFSV4_1_FILES, 871 .id = LAYOUT_NFSV4_1_FILES,
865 .name = "LAYOUT_NFSV4_1_FILES", 872 .name = "LAYOUT_NFSV4_1_FILES",
@@ -872,6 +879,7 @@ static struct pnfs_layoutdriver_type filelayout_type = {
872 .commit_pagelist = filelayout_commit_pagelist, 879 .commit_pagelist = filelayout_commit_pagelist,
873 .read_pagelist = filelayout_read_pagelist, 880 .read_pagelist = filelayout_read_pagelist,
874 .write_pagelist = filelayout_write_pagelist, 881 .write_pagelist = filelayout_write_pagelist,
882 .free_deviceid_node = filelayout_free_deveiceid_node,
875}; 883};
876 884
877static int __init nfs4filelayout_init(void) 885static int __init nfs4filelayout_init(void)