aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeng Tao <tao.peng@primarydata.com>2015-12-03 13:57:48 -0500
committerTrond Myklebust <trond.myklebust@primarydata.com>2015-12-28 14:32:36 -0500
commitd600ad1f2bdbf97c4818dcc85b174f72c90c21bd (patch)
treedaec357d0f24c241834d7c37e3adc723925e369f
parentd0379a5d066a998b0210a81dc52e266ce4daaa36 (diff)
NFS41: pop some layoutget errors to application
For ERESTARTSYS/EIO/EROFS/ENOSPC/E2BIG in layoutget, we should just bail out instead of hiding the error and retrying inband IO. Change all the call sites to pop the error all the way up. Signed-off-by: Peng Tao <tao.peng@primarydata.com> Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
-rw-r--r--fs/nfs/direct.c15
-rw-r--r--fs/nfs/filelayout/filelayout.c17
-rw-r--r--fs/nfs/flexfilelayout/flexfilelayout.c25
-rw-r--r--fs/nfs/pagelist.c9
-rw-r--r--fs/nfs/pnfs.c24
-rw-r--r--fs/nfs/read.c2
6 files changed, 78 insertions, 14 deletions
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index 4b1d08f56aba..2e7142bcb4c8 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -670,6 +670,10 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq)
670 670
671 req = nfs_list_entry(reqs.next); 671 req = nfs_list_entry(reqs.next);
672 nfs_direct_setup_mirroring(dreq, &desc, req); 672 nfs_direct_setup_mirroring(dreq, &desc, req);
673 if (desc.pg_error < 0) {
674 list_splice_init(&reqs, &failed);
675 goto out_failed;
676 }
673 677
674 list_for_each_entry_safe(req, tmp, &reqs, wb_list) { 678 list_for_each_entry_safe(req, tmp, &reqs, wb_list) {
675 if (!nfs_pageio_add_request(&desc, req)) { 679 if (!nfs_pageio_add_request(&desc, req)) {
@@ -677,13 +681,17 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq)
677 nfs_list_add_request(req, &failed); 681 nfs_list_add_request(req, &failed);
678 spin_lock(cinfo.lock); 682 spin_lock(cinfo.lock);
679 dreq->flags = 0; 683 dreq->flags = 0;
680 dreq->error = -EIO; 684 if (desc.pg_error < 0)
685 dreq->error = desc.pg_error;
686 else
687 dreq->error = -EIO;
681 spin_unlock(cinfo.lock); 688 spin_unlock(cinfo.lock);
682 } 689 }
683 nfs_release_request(req); 690 nfs_release_request(req);
684 } 691 }
685 nfs_pageio_complete(&desc); 692 nfs_pageio_complete(&desc);
686 693
694out_failed:
687 while (!list_empty(&failed)) { 695 while (!list_empty(&failed)) {
688 req = nfs_list_entry(failed.next); 696 req = nfs_list_entry(failed.next);
689 nfs_list_remove_request(req); 697 nfs_list_remove_request(req);
@@ -900,6 +908,11 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq,
900 } 908 }
901 909
902 nfs_direct_setup_mirroring(dreq, &desc, req); 910 nfs_direct_setup_mirroring(dreq, &desc, req);
911 if (desc.pg_error < 0) {
912 nfs_free_request(req);
913 result = desc.pg_error;
914 break;
915 }
903 916
904 nfs_lock_request(req); 917 nfs_lock_request(req);
905 req->wb_index = pos >> PAGE_SHIFT; 918 req->wb_index = pos >> PAGE_SHIFT;
diff --git a/fs/nfs/filelayout/filelayout.c b/fs/nfs/filelayout/filelayout.c
index 02ec07973bc4..ae07b0f56659 100644
--- a/fs/nfs/filelayout/filelayout.c
+++ b/fs/nfs/filelayout/filelayout.c
@@ -883,13 +883,19 @@ static void
883filelayout_pg_init_read(struct nfs_pageio_descriptor *pgio, 883filelayout_pg_init_read(struct nfs_pageio_descriptor *pgio,
884 struct nfs_page *req) 884 struct nfs_page *req)
885{ 885{
886 if (!pgio->pg_lseg) 886 if (!pgio->pg_lseg) {
887 pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode, 887 pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode,
888 req->wb_context, 888 req->wb_context,
889 0, 889 0,
890 NFS4_MAX_UINT64, 890 NFS4_MAX_UINT64,
891 IOMODE_READ, 891 IOMODE_READ,
892 GFP_KERNEL); 892 GFP_KERNEL);
893 if (IS_ERR(pgio->pg_lseg)) {
894 pgio->pg_error = PTR_ERR(pgio->pg_lseg);
895 pgio->pg_lseg = NULL;
896 return;
897 }
898 }
893 /* If no lseg, fall back to read through mds */ 899 /* If no lseg, fall back to read through mds */
894 if (pgio->pg_lseg == NULL) 900 if (pgio->pg_lseg == NULL)
895 nfs_pageio_reset_read_mds(pgio); 901 nfs_pageio_reset_read_mds(pgio);
@@ -902,13 +908,20 @@ filelayout_pg_init_write(struct nfs_pageio_descriptor *pgio,
902 struct nfs_commit_info cinfo; 908 struct nfs_commit_info cinfo;
903 int status; 909 int status;
904 910
905 if (!pgio->pg_lseg) 911 if (!pgio->pg_lseg) {
906 pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode, 912 pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode,
907 req->wb_context, 913 req->wb_context,
908 0, 914 0,
909 NFS4_MAX_UINT64, 915 NFS4_MAX_UINT64,
910 IOMODE_RW, 916 IOMODE_RW,
911 GFP_NOFS); 917 GFP_NOFS);
918 if (IS_ERR(pgio->pg_lseg)) {
919 pgio->pg_error = PTR_ERR(pgio->pg_lseg);
920 pgio->pg_lseg = NULL;
921 return;
922 }
923 }
924
912 /* If no lseg, fall back to write through mds */ 925 /* If no lseg, fall back to write through mds */
913 if (pgio->pg_lseg == NULL) 926 if (pgio->pg_lseg == NULL)
914 goto out_mds; 927 goto out_mds;
diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c
index 616817a46410..57e4010e3cde 100644
--- a/fs/nfs/flexfilelayout/flexfilelayout.c
+++ b/fs/nfs/flexfilelayout/flexfilelayout.c
@@ -795,13 +795,19 @@ ff_layout_pg_init_read(struct nfs_pageio_descriptor *pgio,
795 int ds_idx; 795 int ds_idx;
796 796
797 /* Use full layout for now */ 797 /* Use full layout for now */
798 if (!pgio->pg_lseg) 798 if (!pgio->pg_lseg) {
799 pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode, 799 pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode,
800 req->wb_context, 800 req->wb_context,
801 0, 801 0,
802 NFS4_MAX_UINT64, 802 NFS4_MAX_UINT64,
803 IOMODE_READ, 803 IOMODE_READ,
804 GFP_KERNEL); 804 GFP_KERNEL);
805 if (IS_ERR(pgio->pg_lseg)) {
806 pgio->pg_error = PTR_ERR(pgio->pg_lseg);
807 pgio->pg_lseg = NULL;
808 return;
809 }
810 }
805 /* If no lseg, fall back to read through mds */ 811 /* If no lseg, fall back to read through mds */
806 if (pgio->pg_lseg == NULL) 812 if (pgio->pg_lseg == NULL)
807 goto out_mds; 813 goto out_mds;
@@ -835,13 +841,19 @@ ff_layout_pg_init_write(struct nfs_pageio_descriptor *pgio,
835 int i; 841 int i;
836 int status; 842 int status;
837 843
838 if (!pgio->pg_lseg) 844 if (!pgio->pg_lseg) {
839 pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode, 845 pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode,
840 req->wb_context, 846 req->wb_context,
841 0, 847 0,
842 NFS4_MAX_UINT64, 848 NFS4_MAX_UINT64,
843 IOMODE_RW, 849 IOMODE_RW,
844 GFP_NOFS); 850 GFP_NOFS);
851 if (IS_ERR(pgio->pg_lseg)) {
852 pgio->pg_error = PTR_ERR(pgio->pg_lseg);
853 pgio->pg_lseg = NULL;
854 return;
855 }
856 }
845 /* If no lseg, fall back to write through mds */ 857 /* If no lseg, fall back to write through mds */
846 if (pgio->pg_lseg == NULL) 858 if (pgio->pg_lseg == NULL)
847 goto out_mds; 859 goto out_mds;
@@ -877,18 +889,25 @@ static unsigned int
877ff_layout_pg_get_mirror_count_write(struct nfs_pageio_descriptor *pgio, 889ff_layout_pg_get_mirror_count_write(struct nfs_pageio_descriptor *pgio,
878 struct nfs_page *req) 890 struct nfs_page *req)
879{ 891{
880 if (!pgio->pg_lseg) 892 if (!pgio->pg_lseg) {
881 pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode, 893 pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode,
882 req->wb_context, 894 req->wb_context,
883 0, 895 0,
884 NFS4_MAX_UINT64, 896 NFS4_MAX_UINT64,
885 IOMODE_RW, 897 IOMODE_RW,
886 GFP_NOFS); 898 GFP_NOFS);
899 if (IS_ERR(pgio->pg_lseg)) {
900 pgio->pg_error = PTR_ERR(pgio->pg_lseg);
901 pgio->pg_lseg = NULL;
902 goto out;
903 }
904 }
887 if (pgio->pg_lseg) 905 if (pgio->pg_lseg)
888 return FF_LAYOUT_MIRROR_COUNT(pgio->pg_lseg); 906 return FF_LAYOUT_MIRROR_COUNT(pgio->pg_lseg);
889 907
890 /* no lseg means that pnfs is not in use, so no mirroring here */ 908 /* no lseg means that pnfs is not in use, so no mirroring here */
891 nfs_pageio_reset_write_mds(pgio); 909 nfs_pageio_reset_write_mds(pgio);
910out:
892 return 1; 911 return 1;
893} 912}
894 913
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c
index 452a011ba0d8..728f65884cea 100644
--- a/fs/nfs/pagelist.c
+++ b/fs/nfs/pagelist.c
@@ -874,6 +874,9 @@ static int nfs_pageio_setup_mirroring(struct nfs_pageio_descriptor *pgio,
874 874
875 mirror_count = pgio->pg_ops->pg_get_mirror_count(pgio, req); 875 mirror_count = pgio->pg_ops->pg_get_mirror_count(pgio, req);
876 876
877 if (pgio->pg_error < 0)
878 return pgio->pg_error;
879
877 if (!mirror_count || mirror_count > NFS_PAGEIO_DESCRIPTOR_MIRROR_MAX) 880 if (!mirror_count || mirror_count > NFS_PAGEIO_DESCRIPTOR_MIRROR_MAX)
878 return -EINVAL; 881 return -EINVAL;
879 882
@@ -982,6 +985,8 @@ static int nfs_pageio_do_add_request(struct nfs_pageio_descriptor *desc,
982 } else { 985 } else {
983 if (desc->pg_ops->pg_init) 986 if (desc->pg_ops->pg_init)
984 desc->pg_ops->pg_init(desc, req); 987 desc->pg_ops->pg_init(desc, req);
988 if (desc->pg_error < 0)
989 return 0;
985 mirror->pg_base = req->wb_pgbase; 990 mirror->pg_base = req->wb_pgbase;
986 } 991 }
987 if (!nfs_can_coalesce_requests(prev, req, desc)) 992 if (!nfs_can_coalesce_requests(prev, req, desc))
@@ -1147,6 +1152,8 @@ int nfs_pageio_add_request(struct nfs_pageio_descriptor *desc,
1147 bytes = req->wb_bytes; 1152 bytes = req->wb_bytes;
1148 1153
1149 nfs_pageio_setup_mirroring(desc, req); 1154 nfs_pageio_setup_mirroring(desc, req);
1155 if (desc->pg_error < 0)
1156 return 0;
1150 1157
1151 for (midx = 0; midx < desc->pg_mirror_count; midx++) { 1158 for (midx = 0; midx < desc->pg_mirror_count; midx++) {
1152 if (midx) { 1159 if (midx) {
@@ -1232,7 +1239,7 @@ int nfs_pageio_resend(struct nfs_pageio_descriptor *desc,
1232 nfs_pageio_complete(desc); 1239 nfs_pageio_complete(desc);
1233 if (!list_empty(&failed)) { 1240 if (!list_empty(&failed)) {
1234 list_move(&failed, &hdr->pages); 1241 list_move(&failed, &hdr->pages);
1235 return -EIO; 1242 return desc->pg_error < 0 ? desc->pg_error : -EIO;
1236 } 1243 }
1237 return 0; 1244 return 0;
1238} 1245}
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index 6095a8d42766..b1acc4135c3c 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -906,14 +906,15 @@ send_layoutget(struct pnfs_layout_hdr *lo,
906 906
907 if (IS_ERR(lseg)) { 907 if (IS_ERR(lseg)) {
908 switch (PTR_ERR(lseg)) { 908 switch (PTR_ERR(lseg)) {
909 case -ENOMEM:
910 case -ERESTARTSYS: 909 case -ERESTARTSYS:
910 case -EIO:
911 case -ENOSPC:
912 case -EROFS:
913 case -E2BIG:
911 break; 914 break;
912 default: 915 default:
913 /* remember that LAYOUTGET failed and suspend trying */ 916 return NULL;
914 pnfs_layout_io_set_failed(lo, range->iomode);
915 } 917 }
916 return NULL;
917 } else 918 } else
918 pnfs_layout_clear_fail_bit(lo, 919 pnfs_layout_clear_fail_bit(lo,
919 pnfs_iomode_to_fail_bit(range->iomode)); 920 pnfs_iomode_to_fail_bit(range->iomode));
@@ -1649,7 +1650,7 @@ out:
1649 "(%s, offset: %llu, length: %llu)\n", 1650 "(%s, offset: %llu, length: %llu)\n",
1650 __func__, ino->i_sb->s_id, 1651 __func__, ino->i_sb->s_id,
1651 (unsigned long long)NFS_FILEID(ino), 1652 (unsigned long long)NFS_FILEID(ino),
1652 lseg == NULL ? "not found" : "found", 1653 IS_ERR_OR_NULL(lseg) ? "not found" : "found",
1653 iomode==IOMODE_RW ? "read/write" : "read-only", 1654 iomode==IOMODE_RW ? "read/write" : "read-only",
1654 (unsigned long long)pos, 1655 (unsigned long long)pos,
1655 (unsigned long long)count); 1656 (unsigned long long)count);
@@ -1828,6 +1829,11 @@ pnfs_generic_pg_init_read(struct nfs_pageio_descriptor *pgio, struct nfs_page *r
1828 rd_size, 1829 rd_size,
1829 IOMODE_READ, 1830 IOMODE_READ,
1830 GFP_KERNEL); 1831 GFP_KERNEL);
1832 if (IS_ERR(pgio->pg_lseg)) {
1833 pgio->pg_error = PTR_ERR(pgio->pg_lseg);
1834 pgio->pg_lseg = NULL;
1835 return;
1836 }
1831 } 1837 }
1832 /* If no lseg, fall back to read through mds */ 1838 /* If no lseg, fall back to read through mds */
1833 if (pgio->pg_lseg == NULL) 1839 if (pgio->pg_lseg == NULL)
@@ -1840,13 +1846,19 @@ void
1840pnfs_generic_pg_init_write(struct nfs_pageio_descriptor *pgio, 1846pnfs_generic_pg_init_write(struct nfs_pageio_descriptor *pgio,
1841 struct nfs_page *req, u64 wb_size) 1847 struct nfs_page *req, u64 wb_size)
1842{ 1848{
1843 if (pgio->pg_lseg == NULL) 1849 if (pgio->pg_lseg == NULL) {
1844 pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode, 1850 pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode,
1845 req->wb_context, 1851 req->wb_context,
1846 req_offset(req), 1852 req_offset(req),
1847 wb_size, 1853 wb_size,
1848 IOMODE_RW, 1854 IOMODE_RW,
1849 GFP_NOFS); 1855 GFP_NOFS);
1856 if (IS_ERR(pgio->pg_lseg)) {
1857 pgio->pg_error = PTR_ERR(pgio->pg_lseg);
1858 pgio->pg_lseg = NULL;
1859 return;
1860 }
1861 }
1850 /* If no lseg, fall back to write through mds */ 1862 /* If no lseg, fall back to write through mds */
1851 if (pgio->pg_lseg == NULL) 1863 if (pgio->pg_lseg == NULL)
1852 nfs_pageio_reset_write_mds(pgio); 1864 nfs_pageio_reset_write_mds(pgio);
diff --git a/fs/nfs/read.c b/fs/nfs/read.c
index 0a5e33f33b5c..0bb580174cb3 100644
--- a/fs/nfs/read.c
+++ b/fs/nfs/read.c
@@ -115,7 +115,7 @@ int nfs_readpage_async(struct nfs_open_context *ctx, struct inode *inode,
115 pgm = &pgio.pg_mirrors[0]; 115 pgm = &pgio.pg_mirrors[0];
116 NFS_I(inode)->read_io += pgm->pg_bytes_written; 116 NFS_I(inode)->read_io += pgm->pg_bytes_written;
117 117
118 return 0; 118 return pgio.pg_error < 0 ? pgio.pg_error : 0;
119} 119}
120 120
121static void nfs_readpage_release(struct nfs_page *req) 121static void nfs_readpage_release(struct nfs_page *req)