Commit da066f3f authored by Weston Andros Adamson's avatar Weston Andros Adamson Committed by Anna Schumaker

pNFS/flexfiles: never nfs4_mark_deviceid_unavailable

The flexfiles layout should never mark a device unavailable.

Move nfs4_mark_deviceid_unavailable out of nfs4_pnfs_ds_connect and call
directly from files layout where it's still needed.

The flexfiles driver still handles marked devices in error paths, but will
now print a rate limited warning.
Signed-off-by: default avatarWeston Andros Adamson <dros@primarydata.com>
Signed-off-by: default avatarAnna Schumaker <Anna.Schumaker@Netapp.com>
parent a33e4b03
...@@ -282,6 +282,7 @@ nfs4_fl_prepare_ds(struct pnfs_layout_segment *lseg, u32 ds_idx) ...@@ -282,6 +282,7 @@ nfs4_fl_prepare_ds(struct pnfs_layout_segment *lseg, u32 ds_idx)
dataserver_retrans, 4, dataserver_retrans, 4,
s->nfs_client->cl_minorversion); s->nfs_client->cl_minorversion);
if (status) { if (status) {
nfs4_mark_deviceid_unavailable(devid);
ret = NULL; ret = NULL;
goto out; goto out;
} }
......
...@@ -175,7 +175,19 @@ ff_layout_no_read_on_rw(struct pnfs_layout_segment *lseg) ...@@ -175,7 +175,19 @@ ff_layout_no_read_on_rw(struct pnfs_layout_segment *lseg)
static inline bool static inline bool
ff_layout_test_devid_unavailable(struct nfs4_deviceid_node *node) ff_layout_test_devid_unavailable(struct nfs4_deviceid_node *node)
{ {
return nfs4_test_deviceid_unavailable(node); /*
* Flexfiles should never mark a DS unavailable, but if it does
* print a (ratelimited) warning as this can affect performance.
*/
if (nfs4_test_deviceid_unavailable(node)) {
u32 *p = (u32 *)node->deviceid.data;
pr_warn_ratelimited("NFS: flexfiles layout referencing an "
"unavailable device [%x%x%x%x]\n",
p[0], p[1], p[2], p[3]);
return true;
}
return false;
} }
static inline int static inline int
......
...@@ -421,11 +421,11 @@ nfs4_ff_layout_prepare_ds(struct pnfs_layout_segment *lseg, u32 ds_idx, ...@@ -421,11 +421,11 @@ nfs4_ff_layout_prepare_ds(struct pnfs_layout_segment *lseg, u32 ds_idx,
mirror->mirror_ds->ds_versions[0].wsize = max_payload; mirror->mirror_ds->ds_versions[0].wsize = max_payload;
goto out; goto out;
} }
out_fail:
ff_layout_track_ds_error(FF_LAYOUT_FROM_HDR(lseg->pls_layout), ff_layout_track_ds_error(FF_LAYOUT_FROM_HDR(lseg->pls_layout),
mirror, lseg->pls_range.offset, mirror, lseg->pls_range.offset,
lseg->pls_range.length, NFS4ERR_NXIO, lseg->pls_range.length, NFS4ERR_NXIO,
OP_ILLEGAL, GFP_NOIO); OP_ILLEGAL, GFP_NOIO);
out_fail:
if (fail_return || !ff_layout_has_available_ds(lseg)) if (fail_return || !ff_layout_has_available_ds(lseg))
pnfs_error_mark_layout_for_return(ino, lseg); pnfs_error_mark_layout_for_return(ino, lseg);
ds = NULL; ds = NULL;
......
...@@ -751,9 +751,11 @@ int nfs4_pnfs_ds_connect(struct nfs_server *mds_srv, struct nfs4_pnfs_ds *ds, ...@@ -751,9 +751,11 @@ int nfs4_pnfs_ds_connect(struct nfs_server *mds_srv, struct nfs4_pnfs_ds *ds,
struct nfs4_deviceid_node *devid, unsigned int timeo, struct nfs4_deviceid_node *devid, unsigned int timeo,
unsigned int retrans, u32 version, u32 minor_version) unsigned int retrans, u32 version, u32 minor_version)
{ {
if (test_and_set_bit(NFS4DS_CONNECTING, &ds->ds_state) == 0) { int err;
int err = 0;
again:
err = 0;
if (test_and_set_bit(NFS4DS_CONNECTING, &ds->ds_state) == 0) {
if (version == 3) { if (version == 3) {
err = _nfs4_pnfs_v3_ds_connect(mds_srv, ds, timeo, err = _nfs4_pnfs_v3_ds_connect(mds_srv, ds, timeo,
retrans); retrans);
...@@ -766,23 +768,29 @@ int nfs4_pnfs_ds_connect(struct nfs_server *mds_srv, struct nfs4_pnfs_ds *ds, ...@@ -766,23 +768,29 @@ int nfs4_pnfs_ds_connect(struct nfs_server *mds_srv, struct nfs4_pnfs_ds *ds,
err = -EPROTONOSUPPORT; err = -EPROTONOSUPPORT;
} }
if (err)
nfs4_mark_deviceid_unavailable(devid);
nfs4_clear_ds_conn_bit(ds); nfs4_clear_ds_conn_bit(ds);
} else { } else {
nfs4_wait_ds_connect(ds); nfs4_wait_ds_connect(ds);
/* what was waited on didn't connect AND didn't mark unavail */
if (!ds->ds_clp && !nfs4_test_deviceid_unavailable(devid))
goto again;
} }
/* /*
* At this point the ds->ds_clp should be ready, but it might have * At this point the ds->ds_clp should be ready, but it might have
* hit an error. * hit an error.
*/ */
if (!ds->ds_clp || !nfs_client_init_is_complete(ds->ds_clp)) { if (!err) {
WARN_ON_ONCE(1); if (!ds->ds_clp || !nfs_client_init_is_complete(ds->ds_clp)) {
return -EINVAL; WARN_ON_ONCE(ds->ds_clp ||
!nfs4_test_deviceid_unavailable(devid));
return -EINVAL;
}
err = nfs_client_init_status(ds->ds_clp);
} }
return nfs_client_init_status(ds->ds_clp); return err;
} }
EXPORT_SYMBOL_GPL(nfs4_pnfs_ds_connect); EXPORT_SYMBOL_GPL(nfs4_pnfs_ds_connect);
......
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