aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4filelayoutdev.c
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2013-09-26 14:08:36 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2013-09-29 15:56:35 -0400
commit52b26a3e1bb3e065c32b3febdac1e1f117d88e15 (patch)
treebcad0ee4bfb02acd387c4ef7f10ffdb1b69d52fc /fs/nfs/nfs4filelayoutdev.c
parent5bc2afc2b53fc73f154e6344cd898585628e6d27 (diff)
NFSv4.1: nfs4_fl_prepare_ds - fix bugs when the connect attempt fails
- Fix an Oops when nfs4_ds_connect() returns an error. - Always check the device status after waiting for a connect to complete. Reported-by: Andy Adamson <andros@netapp.com> Reported-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> Cc: <stable@vger.kernel.org> # v3.10+
Diffstat (limited to 'fs/nfs/nfs4filelayoutdev.c')
-rw-r--r--fs/nfs/nfs4filelayoutdev.c18
1 files changed, 9 insertions, 9 deletions
diff --git a/fs/nfs/nfs4filelayoutdev.c b/fs/nfs/nfs4filelayoutdev.c
index 95604f64cab8..cd3aef571c34 100644
--- a/fs/nfs/nfs4filelayoutdev.c
+++ b/fs/nfs/nfs4filelayoutdev.c
@@ -801,34 +801,34 @@ nfs4_fl_prepare_ds(struct pnfs_layout_segment *lseg, u32 ds_idx)
801 struct nfs4_file_layout_dsaddr *dsaddr = FILELAYOUT_LSEG(lseg)->dsaddr; 801 struct nfs4_file_layout_dsaddr *dsaddr = FILELAYOUT_LSEG(lseg)->dsaddr;
802 struct nfs4_pnfs_ds *ds = dsaddr->ds_list[ds_idx]; 802 struct nfs4_pnfs_ds *ds = dsaddr->ds_list[ds_idx];
803 struct nfs4_deviceid_node *devid = FILELAYOUT_DEVID_NODE(lseg); 803 struct nfs4_deviceid_node *devid = FILELAYOUT_DEVID_NODE(lseg);
804 804 struct nfs4_pnfs_ds *ret = ds;
805 if (filelayout_test_devid_unavailable(devid))
806 return NULL;
807 805
808 if (ds == NULL) { 806 if (ds == NULL) {
809 printk(KERN_ERR "NFS: %s: No data server for offset index %d\n", 807 printk(KERN_ERR "NFS: %s: No data server for offset index %d\n",
810 __func__, ds_idx); 808 __func__, ds_idx);
811 filelayout_mark_devid_invalid(devid); 809 filelayout_mark_devid_invalid(devid);
812 return NULL; 810 goto out;
813 } 811 }
814 if (ds->ds_clp) 812 if (ds->ds_clp)
815 return ds; 813 goto out_test_devid;
816 814
817 if (test_and_set_bit(NFS4DS_CONNECTING, &ds->ds_state) == 0) { 815 if (test_and_set_bit(NFS4DS_CONNECTING, &ds->ds_state) == 0) {
818 struct nfs_server *s = NFS_SERVER(lseg->pls_layout->plh_inode); 816 struct nfs_server *s = NFS_SERVER(lseg->pls_layout->plh_inode);
819 int err; 817 int err;
820 818
821 err = nfs4_ds_connect(s, ds); 819 err = nfs4_ds_connect(s, ds);
822 if (err) { 820 if (err)
823 nfs4_mark_deviceid_unavailable(devid); 821 nfs4_mark_deviceid_unavailable(devid);
824 ds = NULL;
825 }
826 nfs4_clear_ds_conn_bit(ds); 822 nfs4_clear_ds_conn_bit(ds);
827 } else { 823 } else {
828 /* Either ds is connected, or ds is NULL */ 824 /* Either ds is connected, or ds is NULL */
829 nfs4_wait_ds_connect(ds); 825 nfs4_wait_ds_connect(ds);
830 } 826 }
831 return ds; 827out_test_devid:
828 if (filelayout_test_devid_unavailable(devid))
829 ret = NULL;
830out:
831 return ret;
832} 832}
833 833
834module_param(dataserver_retrans, uint, 0644); 834module_param(dataserver_retrans, uint, 0644);