Commit 52b26a3e authored by Trond Myklebust's avatar Trond Myklebust

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: default avatarAndy Adamson <andros@netapp.com>
Reported-by: default avatarJeff Layton <jlayton@redhat.com>
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
Cc: <stable@vger.kernel.org> # v3.10+
parent 5bc2afc2
...@@ -801,34 +801,34 @@ nfs4_fl_prepare_ds(struct pnfs_layout_segment *lseg, u32 ds_idx) ...@@ -801,34 +801,34 @@ nfs4_fl_prepare_ds(struct pnfs_layout_segment *lseg, u32 ds_idx)
struct nfs4_file_layout_dsaddr *dsaddr = FILELAYOUT_LSEG(lseg)->dsaddr; struct nfs4_file_layout_dsaddr *dsaddr = FILELAYOUT_LSEG(lseg)->dsaddr;
struct nfs4_pnfs_ds *ds = dsaddr->ds_list[ds_idx]; struct nfs4_pnfs_ds *ds = dsaddr->ds_list[ds_idx];
struct nfs4_deviceid_node *devid = FILELAYOUT_DEVID_NODE(lseg); struct nfs4_deviceid_node *devid = FILELAYOUT_DEVID_NODE(lseg);
struct nfs4_pnfs_ds *ret = ds;
if (filelayout_test_devid_unavailable(devid))
return NULL;
if (ds == NULL) { if (ds == NULL) {
printk(KERN_ERR "NFS: %s: No data server for offset index %d\n", printk(KERN_ERR "NFS: %s: No data server for offset index %d\n",
__func__, ds_idx); __func__, ds_idx);
filelayout_mark_devid_invalid(devid); filelayout_mark_devid_invalid(devid);
return NULL; goto out;
} }
if (ds->ds_clp) if (ds->ds_clp)
return ds; goto out_test_devid;
if (test_and_set_bit(NFS4DS_CONNECTING, &ds->ds_state) == 0) { if (test_and_set_bit(NFS4DS_CONNECTING, &ds->ds_state) == 0) {
struct nfs_server *s = NFS_SERVER(lseg->pls_layout->plh_inode); struct nfs_server *s = NFS_SERVER(lseg->pls_layout->plh_inode);
int err; int err;
err = nfs4_ds_connect(s, ds); err = nfs4_ds_connect(s, ds);
if (err) { if (err)
nfs4_mark_deviceid_unavailable(devid); nfs4_mark_deviceid_unavailable(devid);
ds = NULL;
}
nfs4_clear_ds_conn_bit(ds); nfs4_clear_ds_conn_bit(ds);
} else { } else {
/* Either ds is connected, or ds is NULL */ /* Either ds is connected, or ds is NULL */
nfs4_wait_ds_connect(ds); nfs4_wait_ds_connect(ds);
} }
return ds; out_test_devid:
if (filelayout_test_devid_unavailable(devid))
ret = NULL;
out:
return ret;
} }
module_param(dataserver_retrans, uint, 0644); module_param(dataserver_retrans, uint, 0644);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment