mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-19 10:14:23 +08:00
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+
This commit is contained in:
parent
5bc2afc2b5
commit
52b26a3e1b
@ -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_pnfs_ds *ds = dsaddr->ds_list[ds_idx];
|
||||
struct nfs4_deviceid_node *devid = FILELAYOUT_DEVID_NODE(lseg);
|
||||
|
||||
if (filelayout_test_devid_unavailable(devid))
|
||||
return NULL;
|
||||
struct nfs4_pnfs_ds *ret = ds;
|
||||
|
||||
if (ds == NULL) {
|
||||
printk(KERN_ERR "NFS: %s: No data server for offset index %d\n",
|
||||
__func__, ds_idx);
|
||||
filelayout_mark_devid_invalid(devid);
|
||||
return NULL;
|
||||
goto out;
|
||||
}
|
||||
if (ds->ds_clp)
|
||||
return ds;
|
||||
goto out_test_devid;
|
||||
|
||||
if (test_and_set_bit(NFS4DS_CONNECTING, &ds->ds_state) == 0) {
|
||||
struct nfs_server *s = NFS_SERVER(lseg->pls_layout->plh_inode);
|
||||
int err;
|
||||
|
||||
err = nfs4_ds_connect(s, ds);
|
||||
if (err) {
|
||||
if (err)
|
||||
nfs4_mark_deviceid_unavailable(devid);
|
||||
ds = NULL;
|
||||
}
|
||||
nfs4_clear_ds_conn_bit(ds);
|
||||
} else {
|
||||
/* Either ds is connected, or ds is NULL */
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user