aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/filelayout/filelayout.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/filelayout/filelayout.c')
-rw-r--r--fs/nfs/filelayout/filelayout.c138
1 files changed, 91 insertions, 47 deletions
diff --git a/fs/nfs/filelayout/filelayout.c b/fs/nfs/filelayout/filelayout.c
index cad74c1c79ff..367f8eb19bfa 100644
--- a/fs/nfs/filelayout/filelayout.c
+++ b/fs/nfs/filelayout/filelayout.c
@@ -560,6 +560,50 @@ filelayout_write_pagelist(struct nfs_pgio_header *hdr, int sync)
560 return PNFS_ATTEMPTED; 560 return PNFS_ATTEMPTED;
561} 561}
562 562
563static int
564filelayout_check_deviceid(struct pnfs_layout_hdr *lo,
565 struct nfs4_filelayout_segment *fl,
566 gfp_t gfp_flags)
567{
568 struct nfs4_deviceid_node *d;
569 struct nfs4_file_layout_dsaddr *dsaddr;
570 int status = -EINVAL;
571
572 /* find and reference the deviceid */
573 d = nfs4_find_get_deviceid(NFS_SERVER(lo->plh_inode), &fl->deviceid,
574 lo->plh_lc_cred, gfp_flags);
575 if (d == NULL)
576 goto out;
577
578 dsaddr = container_of(d, struct nfs4_file_layout_dsaddr, id_node);
579 /* Found deviceid is unavailable */
580 if (filelayout_test_devid_unavailable(&dsaddr->id_node))
581 goto out_put;
582
583 fl->dsaddr = dsaddr;
584
585 if (fl->first_stripe_index >= dsaddr->stripe_count) {
586 dprintk("%s Bad first_stripe_index %u\n",
587 __func__, fl->first_stripe_index);
588 goto out_put;
589 }
590
591 if ((fl->stripe_type == STRIPE_SPARSE &&
592 fl->num_fh > 1 && fl->num_fh != dsaddr->ds_num) ||
593 (fl->stripe_type == STRIPE_DENSE &&
594 fl->num_fh != dsaddr->stripe_count)) {
595 dprintk("%s num_fh %u not valid for given packing\n",
596 __func__, fl->num_fh);
597 goto out_put;
598 }
599 status = 0;
600out:
601 return status;
602out_put:
603 nfs4_fl_put_deviceid(dsaddr);
604 goto out;
605}
606
563/* 607/*
564 * filelayout_check_layout() 608 * filelayout_check_layout()
565 * 609 *
@@ -574,8 +618,6 @@ filelayout_check_layout(struct pnfs_layout_hdr *lo,
574 struct nfs4_layoutget_res *lgr, 618 struct nfs4_layoutget_res *lgr,
575 gfp_t gfp_flags) 619 gfp_t gfp_flags)
576{ 620{
577 struct nfs4_deviceid_node *d;
578 struct nfs4_file_layout_dsaddr *dsaddr;
579 int status = -EINVAL; 621 int status = -EINVAL;
580 622
581 dprintk("--> %s\n", __func__); 623 dprintk("--> %s\n", __func__);
@@ -600,41 +642,10 @@ filelayout_check_layout(struct pnfs_layout_hdr *lo,
600 goto out; 642 goto out;
601 } 643 }
602 644
603 /* find and reference the deviceid */
604 d = nfs4_find_get_deviceid(NFS_SERVER(lo->plh_inode), &fl->deviceid,
605 lo->plh_lc_cred, gfp_flags);
606 if (d == NULL)
607 goto out;
608
609 dsaddr = container_of(d, struct nfs4_file_layout_dsaddr, id_node);
610 /* Found deviceid is unavailable */
611 if (filelayout_test_devid_unavailable(&dsaddr->id_node))
612 goto out_put;
613
614 fl->dsaddr = dsaddr;
615
616 if (fl->first_stripe_index >= dsaddr->stripe_count) {
617 dprintk("%s Bad first_stripe_index %u\n",
618 __func__, fl->first_stripe_index);
619 goto out_put;
620 }
621
622 if ((fl->stripe_type == STRIPE_SPARSE &&
623 fl->num_fh > 1 && fl->num_fh != dsaddr->ds_num) ||
624 (fl->stripe_type == STRIPE_DENSE &&
625 fl->num_fh != dsaddr->stripe_count)) {
626 dprintk("%s num_fh %u not valid for given packing\n",
627 __func__, fl->num_fh);
628 goto out_put;
629 }
630
631 status = 0; 645 status = 0;
632out: 646out:
633 dprintk("--> %s returns %d\n", __func__, status); 647 dprintk("--> %s returns %d\n", __func__, status);
634 return status; 648 return status;
635out_put:
636 nfs4_fl_put_deviceid(dsaddr);
637 goto out;
638} 649}
639 650
640static void _filelayout_free_lseg(struct nfs4_filelayout_segment *fl) 651static void _filelayout_free_lseg(struct nfs4_filelayout_segment *fl)
@@ -885,18 +896,51 @@ filelayout_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev,
885 return min(stripe_unit - (unsigned int)stripe_offset, size); 896 return min(stripe_unit - (unsigned int)stripe_offset, size);
886} 897}
887 898
899static struct pnfs_layout_segment *
900fl_pnfs_update_layout(struct inode *ino,
901 struct nfs_open_context *ctx,
902 loff_t pos,
903 u64 count,
904 enum pnfs_iomode iomode,
905 bool strict_iomode,
906 gfp_t gfp_flags)
907{
908 struct pnfs_layout_segment *lseg = NULL;
909 struct pnfs_layout_hdr *lo;
910 struct nfs4_filelayout_segment *fl;
911 int status;
912
913 lseg = pnfs_update_layout(ino, ctx, pos, count, iomode, strict_iomode,
914 gfp_flags);
915 if (!lseg)
916 lseg = ERR_PTR(-ENOMEM);
917 if (IS_ERR(lseg))
918 goto out;
919
920 lo = NFS_I(ino)->layout;
921 fl = FILELAYOUT_LSEG(lseg);
922
923 status = filelayout_check_deviceid(lo, fl, gfp_flags);
924 if (status)
925 lseg = ERR_PTR(status);
926out:
927 if (IS_ERR(lseg))
928 pnfs_put_lseg(lseg);
929 return lseg;
930}
931
888static void 932static void
889filelayout_pg_init_read(struct nfs_pageio_descriptor *pgio, 933filelayout_pg_init_read(struct nfs_pageio_descriptor *pgio,
890 struct nfs_page *req) 934 struct nfs_page *req)
891{ 935{
892 if (!pgio->pg_lseg) { 936 if (!pgio->pg_lseg) {
893 pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode, 937 pgio->pg_lseg = fl_pnfs_update_layout(pgio->pg_inode,
894 req->wb_context, 938 req->wb_context,
895 0, 939 0,
896 NFS4_MAX_UINT64, 940 NFS4_MAX_UINT64,
897 IOMODE_READ, 941 IOMODE_READ,
898 false, 942 false,
899 GFP_KERNEL); 943 GFP_KERNEL);
900 if (IS_ERR(pgio->pg_lseg)) { 944 if (IS_ERR(pgio->pg_lseg)) {
901 pgio->pg_error = PTR_ERR(pgio->pg_lseg); 945 pgio->pg_error = PTR_ERR(pgio->pg_lseg);
902 pgio->pg_lseg = NULL; 946 pgio->pg_lseg = NULL;
@@ -916,13 +960,13 @@ filelayout_pg_init_write(struct nfs_pageio_descriptor *pgio,
916 int status; 960 int status;
917 961
918 if (!pgio->pg_lseg) { 962 if (!pgio->pg_lseg) {
919 pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode, 963 pgio->pg_lseg = fl_pnfs_update_layout(pgio->pg_inode,
920 req->wb_context, 964 req->wb_context,
921 0, 965 0,
922 NFS4_MAX_UINT64, 966 NFS4_MAX_UINT64,
923 IOMODE_RW, 967 IOMODE_RW,
924 false, 968 false,
925 GFP_NOFS); 969 GFP_NOFS);
926 if (IS_ERR(pgio->pg_lseg)) { 970 if (IS_ERR(pgio->pg_lseg)) {
927 pgio->pg_error = PTR_ERR(pgio->pg_lseg); 971 pgio->pg_error = PTR_ERR(pgio->pg_lseg);
928 pgio->pg_lseg = NULL; 972 pgio->pg_lseg = NULL;