summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
1837368)
If the LFSCK engine is notifying the remote LFSCK engine about some
LFSCK event, such as LE_PHASE1_DONE, but if the remote server (MDT
or OST) is offline, then such notification RPC will be blocked until
the remote server is online. At that time, if someone wants to stop
the LFSCK, he/she has to wait.
To avoid such trouble, we will make the LFSCK notification RPC to
be interruptable. Then even if some remote server is offline, the
running LFSCK still can be stopped.
Signed-off-by: Fan Yong <fan.yong@intel.com>
Change-Id: Ie9220bc578eb9fe1b1b804a6732fe8ecfba4affb
Reviewed-on: http://review.whamcloud.com/18082
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Lai Siyao <lai.siyao@intel.com>
Reviewed-by: Liang Zhen <liang.zhen@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
llsaa->llsaa_com = lfsck_component_get(com);
llsaa->llsaa_llst = llst;
req->rq_interpret_reply = lfsck_layout_slave_async_interpret;
llsaa->llsaa_com = lfsck_component_get(com);
llsaa->llsaa_llst = llst;
req->rq_interpret_reply = lfsck_layout_slave_async_interpret;
+ req->rq_allow_intr = 1;
ptlrpc_set_add_req(set, req);
RETURN(0);
ptlrpc_set_add_req(set, req);
RETURN(0);
tmp = req_capsule_client_get(&req->rq_pill, &RMF_LFSCK_REQUEST);
*tmp = *lr;
ptlrpc_request_set_replen(req);
tmp = req_capsule_client_get(&req->rq_pill, &RMF_LFSCK_REQUEST);
*tmp = *lr;
ptlrpc_request_set_replen(req);
+ req->rq_allow_intr = 1;
ptlrpc_set_add_req(set, req);
RETURN(0);
ptlrpc_set_add_req(set, req);
RETURN(0);
if (laia->laia_com != NULL)
lfsck_component_get(laia->laia_com);
req->rq_interpret_reply = interpreter;
if (laia->laia_com != NULL)
lfsck_component_get(laia->laia_com);
req->rq_interpret_reply = interpreter;
+ req->rq_allow_intr = 1;
ptlrpc_set_add_req(set, req);
return 0;
ptlrpc_set_add_req(set, req);
return 0;
{
LASSERT(list_empty(&req->rq_set_chain));
{
LASSERT(list_empty(&req->rq_set_chain));
+ if (req->rq_allow_intr)
+ set->set_allow_intr = 1;
+
/* The set takes over the caller's request reference */
list_add_tail(&req->rq_set_chain, &set->set_requests);
req->rq_set = set;
/* The set takes over the caller's request reference */
list_add_tail(&req->rq_set_chain, &set->set_requests);
req->rq_set = set;
rq_set_chain);
struct obd_import *imp = req->rq_import;
int unregistered = 0;
rq_set_chain);
struct obd_import *imp = req->rq_import;
int unregistered = 0;
+ if (req->rq_phase == RQ_PHASE_COMPLETE) {
+ list_move_tail(&req->rq_set_chain, &comp_reqs);
+ continue;
+ }
+
/* This schedule point is mainly for the ptlrpcd caller of this
* function. Most ptlrpc sets are not long-lived and unbounded
* in length, but at the least the set used by the ptlrpcd is.
/* This schedule point is mainly for the ptlrpcd caller of this
* function. Most ptlrpc sets are not long-lived and unbounded
* in length, but at the least the set used by the ptlrpcd is.
req->rq_status = -EINTR;
ptlrpc_rqphase_move(req, RQ_PHASE_INTERPRET);
req->rq_status = -EINTR;
ptlrpc_rqphase_move(req, RQ_PHASE_INTERPRET);
+ /* Since it is interpreted and we have to wait for
+ * the reply to be unlinked, then use sync mode. */
+ async = 0;
+
GOTO(interpret, req->rq_status);
}
GOTO(interpret, req->rq_status);
}
- if (req->rq_phase == RQ_PHASE_NEW &&
- ptlrpc_send_new_req(req)) {
- force_timer_recalc = 1;
- }
+ if (req->rq_phase == RQ_PHASE_NEW && ptlrpc_send_new_req(req))
+ force_timer_recalc = 1;
- /* delayed send - skip */
- if (req->rq_phase == RQ_PHASE_NEW && req->rq_sent)
+ /* delayed send - skip */
+ if (req->rq_phase == RQ_PHASE_NEW && req->rq_sent)
continue;
/* delayed resend - skip */
continue;
/* delayed resend - skip */
req->rq_sent > cfs_time_current_sec())
continue;
req->rq_sent > cfs_time_current_sec())
continue;
- if (!(req->rq_phase == RQ_PHASE_RPC ||
- req->rq_phase == RQ_PHASE_BULK ||
- req->rq_phase == RQ_PHASE_INTERPRET ||
- req->rq_phase == RQ_PHASE_UNREGISTERING ||
- req->rq_phase == RQ_PHASE_COMPLETE)) {
+ if (!(req->rq_phase == RQ_PHASE_RPC ||
+ req->rq_phase == RQ_PHASE_BULK ||
+ req->rq_phase == RQ_PHASE_INTERPRET ||
+ req->rq_phase == RQ_PHASE_UNREGISTERING)) {
DEBUG_REQ(D_ERROR, req, "bad phase %x", req->rq_phase);
LBUG();
}
DEBUG_REQ(D_ERROR, req, "bad phase %x", req->rq_phase);
LBUG();
}
ptlrpc_rqphase_move(req, req->rq_next_phase);
}
ptlrpc_rqphase_move(req, req->rq_next_phase);
}
- if (req->rq_phase == RQ_PHASE_COMPLETE) {
- list_move_tail(&req->rq_set_chain, &comp_reqs);
- continue;
- }
-
if (req->rq_phase == RQ_PHASE_INTERPRET)
GOTO(interpret, req->rq_status);
if (req->rq_phase == RQ_PHASE_INTERPRET)
GOTO(interpret, req->rq_status);
- ptlrpc_rqphase_move(req, RQ_PHASE_INTERPRET);
+ ptlrpc_rqphase_move(req, RQ_PHASE_INTERPRET);
- interpret:
- LASSERT(req->rq_phase == RQ_PHASE_INTERPRET);
+ interpret:
+ LASSERT(req->rq_phase == RQ_PHASE_INTERPRET);
- /* This moves to "unregistering" phase we need to wait for
- * reply unlink. */
- if (!unregistered && !ptlrpc_unregister_reply(req, 1)) {
- /* start async bulk unlink too */
- ptlrpc_unregister_bulk(req, 1);
- continue;
- }
+ /* This moves to "unregistering" phase we need to wait for
+ * reply unlink. */
+ if (!unregistered && !ptlrpc_unregister_reply(req, async)) {
+ /* start async bulk unlink too */
+ ptlrpc_unregister_bulk(req, 1);
+ continue;
+ }
- if (!ptlrpc_unregister_bulk(req, 1))
- continue;
+ if (!ptlrpc_unregister_bulk(req, async))
+ continue;
- /* When calling interpret receiving already should be
- * finished. */
- LASSERT(!req->rq_receiving_reply);
+ /* When calling interpret receiving already should be
+ * finished. */
+ LASSERT(!req->rq_receiving_reply);
- ptlrpc_req_interpret(env, req, req->rq_status);
+ ptlrpc_req_interpret(env, req, req->rq_status);
if (ptlrpcd_check_work(req)) {
atomic_dec(&set->set_remaining);
if (ptlrpcd_check_work(req)) {
atomic_dec(&set->set_remaining);
struct ptlrpc_request *req =
list_entry(tmp, struct ptlrpc_request, rq_set_chain);
struct ptlrpc_request *req =
list_entry(tmp, struct ptlrpc_request, rq_set_chain);
+ if (req->rq_intr)
+ continue;
+
if (req->rq_phase != RQ_PHASE_RPC &&
req->rq_phase != RQ_PHASE_UNREGISTERING &&
!req->rq_allow_intr)
if (req->rq_phase != RQ_PHASE_RPC &&
req->rq_phase != RQ_PHASE_UNREGISTERING &&
!req->rq_allow_intr)
CDEBUG(D_RPCTRACE, "set %p going to sleep for %d seconds\n",
set, timeout);
CDEBUG(D_RPCTRACE, "set %p going to sleep for %d seconds\n",
set, timeout);
- if (timeout == 0 && !signal_pending(current))
- /*
- * No requests are in-flight (ether timed out
- * or delayed), so we can allow interrupts.
- * We still want to block for a limited time,
- * so we allow interrupts during the timeout.
- */
- lwi = LWI_TIMEOUT_INTR_ALL(cfs_time_seconds(1),
- ptlrpc_expired_set,
- ptlrpc_interrupted_set, set);
- else if (set->set_allow_intr)
+ if ((timeout == 0 && !signal_pending(current)) ||
+ set->set_allow_intr)
+ /* No requests are in-flight (ether timed out
+ * or delayed), so we can allow interrupts.
+ * We still want to block for a limited time,
+ * so we allow interrupts during the timeout. */
lwi = LWI_TIMEOUT_INTR_ALL(
cfs_time_seconds(timeout ? timeout : 1),
ptlrpc_expired_set,
lwi = LWI_TIMEOUT_INTR_ALL(
cfs_time_seconds(timeout ? timeout : 1),
ptlrpc_expired_set,
- if (req->rq_allow_intr)
- set->set_allow_intr = 1;
-
/* for distributed debugging */
lustre_msg_set_status(req->rq_reqmsg, current_pid());
/* for distributed debugging */
lustre_msg_set_status(req->rq_reqmsg, current_pid());