The export nid hash would be removed in class_disconnect, But
still a race window exists in target_handle_connect to add it back.
Then the process of cleanup will wait infinity.
Signed-off-by: Yang Sheng <ys@whamcloud.com>
Change-Id: I9ad3edbd040b81e2aef7ae22494302d9a478d65b
Reviewed-on: https://review.whamcloud.com/41687
Tested-by: jenkins <devops@whamcloud.com>
Reviewed-by: Neil Brown <neilb@suse.de>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Mike Pershin <mpershin@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
struct obd_connect_data *data, *tmpdata;
int size, tmpsize;
lnet_nid_t *client_nid = NULL;
struct obd_connect_data *data, *tmpdata;
int size, tmpsize;
lnet_nid_t *client_nid = NULL;
+ struct ptlrpc_connection *pcon = NULL;
*/
ptlrpc_request_change_export(req, export);
*/
ptlrpc_request_change_export(req, export);
+ pcon = ptlrpc_connection_get(req->rq_peer, req->rq_self, &cluuid);
+ if (pcon == NULL)
+ GOTO(out, rc = -ENOTCONN);
+
spin_lock(&export->exp_lock);
spin_lock(&export->exp_lock);
+
+ if (export->exp_disconnected) {
+ spin_unlock(&export->exp_lock);
+ GOTO(out, rc = -ENODEV);
+ }
if (export->exp_conn_cnt >= lustre_msg_get_conn_cnt(req->rq_reqmsg)) {
spin_unlock(&export->exp_lock);
CDEBUG(D_RPCTRACE,
if (export->exp_conn_cnt >= lustre_msg_get_conn_cnt(req->rq_reqmsg)) {
spin_unlock(&export->exp_lock);
CDEBUG(D_RPCTRACE,
}
LASSERT(lustre_msg_get_conn_cnt(req->rq_reqmsg) > 0);
export->exp_conn_cnt = lustre_msg_get_conn_cnt(req->rq_reqmsg);
}
LASSERT(lustre_msg_get_conn_cnt(req->rq_reqmsg) > 0);
export->exp_conn_cnt = lustre_msg_get_conn_cnt(req->rq_reqmsg);
- spin_unlock(&export->exp_lock);
-
- if (export->exp_connection != NULL) {
- /* Check to see if connection came from another NID. */
- if (export->exp_connection->c_peer.nid != req->rq_peer.nid)
- obd_nid_del(export->exp_obd, export);
+ /* Check to see if connection came from another NID. */
+ if (export->exp_connection != NULL &&
+ export->exp_connection->c_peer.nid != req->rq_peer.nid) {
+ obd_nid_del(export->exp_obd, export);
ptlrpc_connection_put(export->exp_connection);
ptlrpc_connection_put(export->exp_connection);
+ export->exp_connection = NULL;
- export->exp_connection = ptlrpc_connection_get(req->rq_peer,
- req->rq_self,
- &cluuid);
- if (!export->exp_connection)
- GOTO(out, rc = -ENOTCONN);
-
+ if (export->exp_connection == NULL) {
+ export->exp_connection = pcon;
+ pcon = NULL;
+ }
obd_nid_add(export->exp_obd, export);
obd_nid_add(export->exp_obd, export);
+ spin_unlock(&export->exp_lock);
+
lustre_msg_set_handle(req->rq_repmsg, &conn);
rc = rev_import_reconnect(export, req);
lustre_msg_set_handle(req->rq_repmsg, &conn);
rc = rev_import_reconnect(export, req);
spin_unlock(&target->obd_dev_lock);
class_decref(target, "find", current);
}
spin_unlock(&target->obd_dev_lock);
class_decref(target, "find", current);
}
+ if (pcon)
+ ptlrpc_connection_put(pcon);
req->rq_status = rc;
RETURN(rc);
}
req->rq_status = rc;
RETURN(rc);
}