void __dlm_queue_ast(struct dlm_ctxt *dlm, struct dlm_lock *lock) { struct dlm_lock_resource *res; BUG_ON(!dlm); BUG_ON(!lock); res = lock->lockres; assert_spin_locked(&dlm->ast_lock); if (!list_empty(&lock->ast_list)) { mlog(ML_ERROR, "%s: res %.*s, lock %u:%llu, " "AST list not empty, pending %d, newlevel %d\n", dlm->name, res->lockname.len, res->lockname.name, dlm_get_lock_cookie_node(be64_to_cpu(lock->ml.cookie)), dlm_get_lock_cookie_seq(be64_to_cpu(lock->ml.cookie)), lock->ast_pending, lock->ml.type); BUG(); } if (lock->ast_pending) mlog(0, "%s: res %.*s, lock %u:%llu, AST getting flushed\n", dlm->name, res->lockname.len, res->lockname.name, dlm_get_lock_cookie_node(be64_to_cpu(lock->ml.cookie)), dlm_get_lock_cookie_seq(be64_to_cpu(lock->ml.cookie))); /* putting lock on list, add a ref */ dlm_lock_get(lock); spin_lock(&lock->spinlock); /* check to see if this ast obsoletes the bast */ if (dlm_should_cancel_bast(dlm, lock)) { mlog(0, "%s: res %.*s, lock %u:%llu, Cancelling BAST\n", dlm->name, res->lockname.len, res->lockname.name, dlm_get_lock_cookie_node(be64_to_cpu(lock->ml.cookie)), dlm_get_lock_cookie_seq(be64_to_cpu(lock->ml.cookie))); lock->bast_pending = 0; list_del_init(&lock->bast_list); lock->ml.highest_blocked = LKM_IVMODE; /* removing lock from list, remove a ref. guaranteed * this won't be the last ref because of the get above, * so res->spinlock will not be taken here */ dlm_lock_put(lock); /* free up the reserved bast that we are cancelling. * guaranteed that this will not be the last reserved * ast because *both* an ast and a bast were reserved * to get to this point. the res->spinlock will not be * taken here */ dlm_lockres_release_ast(dlm, res); } list_add_tail(&lock->ast_list, &dlm->pending_asts); lock->ast_pending = 1; spin_unlock(&lock->spinlock); }
static void __dlm_queue_ast(struct dlm_ctxt *dlm, struct dlm_lock *lock) { mlog_entry_void(); BUG_ON(!dlm); BUG_ON(!lock); assert_spin_locked(&dlm->ast_lock); if (!list_empty(&lock->ast_list)) { mlog(ML_ERROR, "ast list not empty!! pending=%d, newlevel=%d\n", lock->ast_pending, lock->ml.type); BUG(); } BUG_ON(!list_empty(&lock->ast_list)); if (lock->ast_pending) mlog(0, "lock has an ast getting flushed right now\n"); /* putting lock on list, add a ref */ dlm_lock_get(lock); spin_lock(&lock->spinlock); /* check to see if this ast obsoletes the bast */ if (dlm_should_cancel_bast(dlm, lock)) { struct dlm_lock_resource *res = lock->lockres; mlog(0, "%s: cancelling bast for %.*s\n", dlm->name, res->lockname.len, res->lockname.name); lock->bast_pending = 0; list_del_init(&lock->bast_list); lock->ml.highest_blocked = LKM_IVMODE; /* removing lock from list, remove a ref. guaranteed * this won't be the last ref because of the get above, * so res->spinlock will not be taken here */ dlm_lock_put(lock); /* free up the reserved bast that we are cancelling. * guaranteed that this will not be the last reserved * ast because *both* an ast and a bast were reserved * to get to this point. the res->spinlock will not be * taken here */ dlm_lockres_release_ast(dlm, res); } list_add_tail(&lock->ast_list, &dlm->pending_asts); lock->ast_pending = 1; spin_unlock(&lock->spinlock); }