diff options
Diffstat (limited to 'fs/nfs/filelayout/filelayoutdev.c')
-rw-r--r-- | fs/nfs/filelayout/filelayoutdev.c | 108 |
1 files changed, 5 insertions, 103 deletions
diff --git a/fs/nfs/filelayout/filelayoutdev.c b/fs/nfs/filelayout/filelayoutdev.c index 8540516f4d71..9bb806a76d99 100644 --- a/fs/nfs/filelayout/filelayoutdev.c +++ b/fs/nfs/filelayout/filelayoutdev.c | |||
@@ -484,8 +484,9 @@ out_err: | |||
484 | } | 484 | } |
485 | 485 | ||
486 | /* Decode opaque device data and return the result */ | 486 | /* Decode opaque device data and return the result */ |
487 | static struct nfs4_file_layout_dsaddr* | 487 | struct nfs4_file_layout_dsaddr * |
488 | decode_device(struct inode *ino, struct pnfs_device *pdev, gfp_t gfp_flags) | 488 | nfs4_fl_alloc_deviceid_node(struct nfs_server *server, struct pnfs_device *pdev, |
489 | gfp_t gfp_flags) | ||
489 | { | 490 | { |
490 | int i; | 491 | int i; |
491 | u32 cnt, num; | 492 | u32 cnt, num; |
@@ -570,10 +571,7 @@ decode_device(struct inode *ino, struct pnfs_device *pdev, gfp_t gfp_flags) | |||
570 | dsaddr->stripe_indices = stripe_indices; | 571 | dsaddr->stripe_indices = stripe_indices; |
571 | stripe_indices = NULL; | 572 | stripe_indices = NULL; |
572 | dsaddr->ds_num = num; | 573 | dsaddr->ds_num = num; |
573 | nfs4_init_deviceid_node(&dsaddr->id_node, | 574 | nfs4_init_deviceid_node(&dsaddr->id_node, server, &pdev->dev_id); |
574 | NFS_SERVER(ino)->pnfs_curr_ld, | ||
575 | NFS_SERVER(ino)->nfs_client, | ||
576 | &pdev->dev_id); | ||
577 | 575 | ||
578 | INIT_LIST_HEAD(&dsaddrs); | 576 | INIT_LIST_HEAD(&dsaddrs); |
579 | 577 | ||
@@ -587,7 +585,7 @@ decode_device(struct inode *ino, struct pnfs_device *pdev, gfp_t gfp_flags) | |||
587 | 585 | ||
588 | mp_count = be32_to_cpup(p); /* multipath count */ | 586 | mp_count = be32_to_cpup(p); /* multipath count */ |
589 | for (j = 0; j < mp_count; j++) { | 587 | for (j = 0; j < mp_count; j++) { |
590 | da = decode_ds_addr(NFS_SERVER(ino)->nfs_client->cl_net, | 588 | da = decode_ds_addr(server->nfs_client->cl_net, |
591 | &stream, gfp_flags); | 589 | &stream, gfp_flags); |
592 | if (da) | 590 | if (da) |
593 | list_add_tail(&da->da_node, &dsaddrs); | 591 | list_add_tail(&da->da_node, &dsaddrs); |
@@ -637,102 +635,6 @@ out_err: | |||
637 | return NULL; | 635 | return NULL; |
638 | } | 636 | } |
639 | 637 | ||
640 | /* | ||
641 | * Decode the opaque device specified in 'dev' and add it to the cache of | ||
642 | * available devices. | ||
643 | */ | ||
644 | static struct nfs4_file_layout_dsaddr * | ||
645 | decode_and_add_device(struct inode *inode, struct pnfs_device *dev, gfp_t gfp_flags) | ||
646 | { | ||
647 | struct nfs4_deviceid_node *d; | ||
648 | struct nfs4_file_layout_dsaddr *n, *new; | ||
649 | |||
650 | new = decode_device(inode, dev, gfp_flags); | ||
651 | if (!new) { | ||
652 | printk(KERN_WARNING "NFS: %s: Could not decode or add device\n", | ||
653 | __func__); | ||
654 | return NULL; | ||
655 | } | ||
656 | |||
657 | d = nfs4_insert_deviceid_node(&new->id_node); | ||
658 | n = container_of(d, struct nfs4_file_layout_dsaddr, id_node); | ||
659 | if (n != new) { | ||
660 | nfs4_fl_free_deviceid(new); | ||
661 | return n; | ||
662 | } | ||
663 | |||
664 | return new; | ||
665 | } | ||
666 | |||
667 | /* | ||
668 | * Retrieve the information for dev_id, add it to the list | ||
669 | * of available devices, and return it. | ||
670 | */ | ||
671 | struct nfs4_file_layout_dsaddr * | ||
672 | filelayout_get_device_info(struct inode *inode, | ||
673 | struct nfs4_deviceid *dev_id, | ||
674 | struct rpc_cred *cred, | ||
675 | gfp_t gfp_flags) | ||
676 | { | ||
677 | struct pnfs_device *pdev = NULL; | ||
678 | u32 max_resp_sz; | ||
679 | int max_pages; | ||
680 | struct page **pages = NULL; | ||
681 | struct nfs4_file_layout_dsaddr *dsaddr = NULL; | ||
682 | int rc, i; | ||
683 | struct nfs_server *server = NFS_SERVER(inode); | ||
684 | |||
685 | /* | ||
686 | * Use the session max response size as the basis for setting | ||
687 | * GETDEVICEINFO's maxcount | ||
688 | */ | ||
689 | max_resp_sz = server->nfs_client->cl_session->fc_attrs.max_resp_sz; | ||
690 | max_pages = nfs_page_array_len(0, max_resp_sz); | ||
691 | dprintk("%s inode %p max_resp_sz %u max_pages %d\n", | ||
692 | __func__, inode, max_resp_sz, max_pages); | ||
693 | |||
694 | pdev = kzalloc(sizeof(struct pnfs_device), gfp_flags); | ||
695 | if (pdev == NULL) | ||
696 | return NULL; | ||
697 | |||
698 | pages = kcalloc(max_pages, sizeof(struct page *), gfp_flags); | ||
699 | if (pages == NULL) { | ||
700 | kfree(pdev); | ||
701 | return NULL; | ||
702 | } | ||
703 | for (i = 0; i < max_pages; i++) { | ||
704 | pages[i] = alloc_page(gfp_flags); | ||
705 | if (!pages[i]) | ||
706 | goto out_free; | ||
707 | } | ||
708 | |||
709 | memcpy(&pdev->dev_id, dev_id, sizeof(*dev_id)); | ||
710 | pdev->layout_type = LAYOUT_NFSV4_1_FILES; | ||
711 | pdev->pages = pages; | ||
712 | pdev->pgbase = 0; | ||
713 | pdev->pglen = max_resp_sz; | ||
714 | pdev->mincount = 0; | ||
715 | pdev->maxcount = max_resp_sz - nfs41_maxgetdevinfo_overhead; | ||
716 | |||
717 | rc = nfs4_proc_getdeviceinfo(server, pdev, cred); | ||
718 | dprintk("%s getdevice info returns %d\n", __func__, rc); | ||
719 | if (rc) | ||
720 | goto out_free; | ||
721 | |||
722 | /* | ||
723 | * Found new device, need to decode it and then add it to the | ||
724 | * list of known devices for this mountpoint. | ||
725 | */ | ||
726 | dsaddr = decode_and_add_device(inode, pdev, gfp_flags); | ||
727 | out_free: | ||
728 | for (i = 0; i < max_pages; i++) | ||
729 | __free_page(pages[i]); | ||
730 | kfree(pages); | ||
731 | kfree(pdev); | ||
732 | dprintk("<-- %s dsaddr %p\n", __func__, dsaddr); | ||
733 | return dsaddr; | ||
734 | } | ||
735 | |||
736 | void | 638 | void |
737 | nfs4_fl_put_deviceid(struct nfs4_file_layout_dsaddr *dsaddr) | 639 | nfs4_fl_put_deviceid(struct nfs4_file_layout_dsaddr *dsaddr) |
738 | { | 640 | { |