···208208#define DLM_LOCK_RES_IN_PROGRESS 0x00000010209209#define DLM_LOCK_RES_MIGRATING 0x00000020210210211211+/* max milliseconds to wait to sync up a network failure with a node death */212212+#define DLM_NODE_DEATH_WAIT_MAX (5 * 1000)213213+211214#define DLM_PURGE_INTERVAL_MS (8 * 1000)212215213216struct dlm_lock_resource···661658void dlm_complete_recovery_thread(struct dlm_ctxt *dlm);662659void dlm_wait_for_recovery(struct dlm_ctxt *dlm);663660int dlm_is_node_dead(struct dlm_ctxt *dlm, u8 node);661661+int dlm_wait_for_node_death(struct dlm_ctxt *dlm, u8 node, int timeout);664662665663void dlm_put(struct dlm_ctxt *dlm);666664struct dlm_ctxt *dlm_grab(struct dlm_ctxt *dlm);
+9-3
fs/ocfs2/dlm/dlmconvert.c
···392392 } else {393393 mlog_errno(tmpret);394394 if (dlm_is_host_down(tmpret)) {395395+ /* instead of logging the same network error over396396+ * and over, sleep here and wait for the heartbeat397397+ * to notice the node is dead. times out after 5s. */398398+ dlm_wait_for_node_death(dlm, res->owner, 399399+ DLM_NODE_DEATH_WAIT_MAX);395400 ret = DLM_RECOVERING;396401 mlog(0, "node %u died so returning DLM_RECOVERING "397402 "from convert message!\n", res->owner);···426421 struct dlm_lockstatus *lksb;427422 enum dlm_status status = DLM_NORMAL;428423 u32 flags;429429- int call_ast = 0, kick_thread = 0;424424+ int call_ast = 0, kick_thread = 0, ast_reserved = 0;430425431426 if (!dlm_grab(dlm)) {432427 dlm_error(DLM_REJECTED);···495490 status = __dlm_lockres_state_to_status(res);496491 if (status == DLM_NORMAL) {497492 __dlm_lockres_reserve_ast(res);493493+ ast_reserved = 1;498494 res->state |= DLM_LOCK_RES_IN_PROGRESS;499495 status = __dlmconvert_master(dlm, res, lock, flags,500496 cnv->requested_type,···518512 else519513 dlm_lock_put(lock);520514521521- /* either queue the ast or release it */515515+ /* either queue the ast or release it, if reserved */522516 if (call_ast)523517 dlm_queue_ast(dlm, lock);524524- else518518+ else if (ast_reserved)525519 dlm_lockres_release_ast(dlm, res);526520527521 if (kick_thread)
+24-1
fs/ocfs2/dlm/dlmlock.c
···220220 dlm_error(status);221221 dlm_revert_pending_lock(res, lock);222222 dlm_lock_put(lock);223223+ } else if (dlm_is_recovery_lock(res->lockname.name, 224224+ res->lockname.len)) {225225+ /* special case for the $RECOVERY lock.226226+ * there will never be an AST delivered to put227227+ * this lock on the proper secondary queue228228+ * (granted), so do it manually. */229229+ mlog(0, "%s: $RECOVERY lock for this node (%u) is "230230+ "mastered by %u; got lock, manually granting (no ast)\n",231231+ dlm->name, dlm->node_num, res->owner);232232+ list_del_init(&lock->list);233233+ list_add_tail(&lock->list, &res->granted);223234 }224235 spin_unlock(&res->spinlock);225236···657646 mlog(0, "retrying lock with migration/"658647 "recovery/in progress\n");659648 msleep(100);660660- dlm_wait_for_recovery(dlm);649649+ /* no waiting for dlm_reco_thread */650650+ if (recovery) {651651+ if (status == DLM_RECOVERING) {652652+ mlog(0, "%s: got RECOVERING "653653+ "for $REOCVERY lock, master "654654+ "was %u\n", dlm->name, 655655+ res->owner);656656+ dlm_wait_for_node_death(dlm, res->owner, 657657+ DLM_NODE_DEATH_WAIT_MAX);658658+ }659659+ } else {660660+ dlm_wait_for_recovery(dlm);661661+ }661662 goto retry_lock;662663 }663664
+6-1
fs/ocfs2/dlm/dlmmaster.c
···24822482 atomic_set(&mle->woken, 1);24832483 spin_unlock(&mle->spinlock);24842484 wake_up(&mle->wq);24852485- /* final put will take care of list removal */24852485+ /* do not need events any longer, so detach 24862486+ * from heartbeat */24872487+ __dlm_mle_detach_hb_events(dlm, mle);24862488 __dlm_put_mle(mle);24872489 }24882490 continue;···25382536 dlm_move_lockres_to_recovery_list(dlm, res);25392537 spin_unlock(&res->spinlock);25402538 dlm_lockres_put(res);25392539+25402540+ /* about to get rid of mle, detach from heartbeat */25412541+ __dlm_mle_detach_hb_events(dlm, mle);2541254225422543 /* dump the mle */25432544 spin_lock(&dlm->master_lock);
+42
fs/ocfs2/dlm/dlmrecovery.c
···278278 return dead;279279}280280281281+int dlm_wait_for_node_death(struct dlm_ctxt *dlm, u8 node, int timeout)282282+{283283+ if (timeout) {284284+ mlog(ML_NOTICE, "%s: waiting %dms for notification of "285285+ "death of node %u\n", dlm->name, timeout, node);286286+ wait_event_timeout(dlm->dlm_reco_thread_wq,287287+ dlm_is_node_dead(dlm, node),288288+ msecs_to_jiffies(timeout));289289+ } else {290290+ mlog(ML_NOTICE, "%s: waiting indefinitely for notification "291291+ "of death of node %u\n", dlm->name, node);292292+ wait_event(dlm->dlm_reco_thread_wq,293293+ dlm_is_node_dead(dlm, node));294294+ }295295+ /* for now, return 0 */296296+ return 0;297297+}298298+281299/* callers of the top-level api calls (dlmlock/dlmunlock) should282300 * block on the dlm->reco.event when recovery is in progress.283301 * the dlm recovery thread will set this state when it begins···20502032 dlm->reco.new_master);20512033 status = -EEXIST;20522034 } else {20352035+ status = 0;20362036+20372037+ /* see if recovery was already finished elsewhere */20382038+ spin_lock(&dlm->spinlock);20392039+ if (dlm->reco.dead_node == O2NM_INVALID_NODE_NUM) {20402040+ status = -EINVAL; 20412041+ mlog(0, "%s: got reco EX lock, but "20422042+ "node got recovered already\n", dlm->name);20432043+ if (dlm->reco.new_master != O2NM_INVALID_NODE_NUM) {20442044+ mlog(ML_ERROR, "%s: new master is %u "20452045+ "but no dead node!\n", 20462046+ dlm->name, dlm->reco.new_master);20472047+ BUG();20482048+ }20492049+ }20502050+ spin_unlock(&dlm->spinlock);20512051+ }20522052+20532053+ /* if this node has actually become the recovery master,20542054+ * set the master and send the messages to begin recovery */20552055+ if (!status) {20562056+ mlog(0, "%s: dead=%u, this=%u, sending "20572057+ "begin_reco now\n", dlm->name, 20582058+ dlm->reco.dead_node, dlm->node_num);20532059 status = dlm_send_begin_reco_message(dlm,20542060 dlm->reco.dead_node);20552061 /* this always succeeds */
+3-4
fs/ocfs2/journal.c
···15841584 while (!(kthread_should_stop() &&15851585 atomic_read(&journal->j_num_trans) == 0)) {1586158615871587- wait_event_interruptible_timeout(osb->checkpoint_event,15881588- atomic_read(&journal->j_num_trans)15891589- || kthread_should_stop(),15901590- OCFS2_CHECKPOINT_INTERVAL);15871587+ wait_event_interruptible(osb->checkpoint_event,15881588+ atomic_read(&journal->j_num_trans)15891589+ || kthread_should_stop());1591159015921591 status = ocfs2_commit_cache(osb);15931592 if (status < 0)