-/* SPECIAL CASE for the $RECOVERY lock used by the recovery thread.
- * We cannot wait for node recovery to complete to begin mastering this
- * lockres because this lockres is used to kick off recovery! ;-)
- * So, do a pre-check on all living nodes to see if any of those nodes
- * think that $RECOVERY is currently mastered by a dead node. If so,
- * we wait a short time to allow that node to get notified by its own
- * heartbeat stack, then check again. All $RECOVERY lock resources
- * mastered by dead nodes are purged when the hearbeat callback is
- * fired, so we can know for sure that it is safe to continue once
- * the node returns a live node or no node. */
-static int dlm_pre_master_reco_lockres(struct dlm_ctxt *dlm,
- struct dlm_lock_resource *res)
-{
- struct dlm_node_iter iter;
- int nodenum;
- int ret = 0;
- u8 master = DLM_LOCK_RES_OWNER_UNKNOWN;
-
- spin_lock(&dlm->spinlock);
- dlm_node_iter_init(dlm->domain_map, &iter);
- spin_unlock(&dlm->spinlock);
-
- while ((nodenum = dlm_node_iter_next(&iter)) >= 0) {
- /* do not send to self */
- if (nodenum == dlm->node_num)
- continue;
- ret = dlm_do_master_requery(dlm, res, nodenum, &master);
- if (ret < 0) {
- mlog_errno(ret);
- if (!dlm_is_host_down(ret))
- BUG();
- /* host is down, so answer for that node would be
- * DLM_LOCK_RES_OWNER_UNKNOWN. continue. */
- }
-
- if (master != DLM_LOCK_RES_OWNER_UNKNOWN) {
- /* check to see if this master is in the recovery map */
- spin_lock(&dlm->spinlock);
- if (test_bit(master, dlm->recovery_map)) {
- mlog(ML_NOTICE, "%s: node %u has not seen "
- "node %u go down yet, and thinks the "
- "dead node is mastering the recovery "
- "lock. must wait.\n", dlm->name,
- nodenum, master);
- ret = -EAGAIN;
- }
- spin_unlock(&dlm->spinlock);
- mlog(0, "%s: reco lock master is %u\n", dlm->name,
- master);
- break;
- }
- }
- return ret;
-}
-