diff options
Diffstat (limited to 'fs/ocfs2/dlm/dlmlock.c')
-rw-r--r-- | fs/ocfs2/dlm/dlmlock.c | 71 |
1 files changed, 53 insertions, 18 deletions
diff --git a/fs/ocfs2/dlm/dlmlock.c b/fs/ocfs2/dlm/dlmlock.c index 6fea28318d6d..d6f89577e25f 100644 --- a/fs/ocfs2/dlm/dlmlock.c +++ b/fs/ocfs2/dlm/dlmlock.c | |||
@@ -201,6 +201,7 @@ static enum dlm_status dlmlock_remote(struct dlm_ctxt *dlm, | |||
201 | struct dlm_lock *lock, int flags) | 201 | struct dlm_lock *lock, int flags) |
202 | { | 202 | { |
203 | enum dlm_status status = DLM_DENIED; | 203 | enum dlm_status status = DLM_DENIED; |
204 | int lockres_changed = 1; | ||
204 | 205 | ||
205 | mlog_entry("type=%d\n", lock->ml.type); | 206 | mlog_entry("type=%d\n", lock->ml.type); |
206 | mlog(0, "lockres %.*s, flags = 0x%x\n", res->lockname.len, | 207 | mlog(0, "lockres %.*s, flags = 0x%x\n", res->lockname.len, |
@@ -226,8 +227,25 @@ static enum dlm_status dlmlock_remote(struct dlm_ctxt *dlm, | |||
226 | res->state &= ~DLM_LOCK_RES_IN_PROGRESS; | 227 | res->state &= ~DLM_LOCK_RES_IN_PROGRESS; |
227 | lock->lock_pending = 0; | 228 | lock->lock_pending = 0; |
228 | if (status != DLM_NORMAL) { | 229 | if (status != DLM_NORMAL) { |
229 | if (status != DLM_NOTQUEUED) | 230 | if (status == DLM_RECOVERING && |
231 | dlm_is_recovery_lock(res->lockname.name, | ||
232 | res->lockname.len)) { | ||
233 | /* recovery lock was mastered by dead node. | ||
234 | * we need to have calc_usage shoot down this | ||
235 | * lockres and completely remaster it. */ | ||
236 | mlog(0, "%s: recovery lock was owned by " | ||
237 | "dead node %u, remaster it now.\n", | ||
238 | dlm->name, res->owner); | ||
239 | } else if (status != DLM_NOTQUEUED) { | ||
240 | /* | ||
241 | * DO NOT call calc_usage, as this would unhash | ||
242 | * the remote lockres before we ever get to use | ||
243 | * it. treat as if we never made any change to | ||
244 | * the lockres. | ||
245 | */ | ||
246 | lockres_changed = 0; | ||
230 | dlm_error(status); | 247 | dlm_error(status); |
248 | } | ||
231 | dlm_revert_pending_lock(res, lock); | 249 | dlm_revert_pending_lock(res, lock); |
232 | dlm_lock_put(lock); | 250 | dlm_lock_put(lock); |
233 | } else if (dlm_is_recovery_lock(res->lockname.name, | 251 | } else if (dlm_is_recovery_lock(res->lockname.name, |
@@ -239,12 +257,12 @@ static enum dlm_status dlmlock_remote(struct dlm_ctxt *dlm, | |||
239 | mlog(0, "%s: $RECOVERY lock for this node (%u) is " | 257 | mlog(0, "%s: $RECOVERY lock for this node (%u) is " |
240 | "mastered by %u; got lock, manually granting (no ast)\n", | 258 | "mastered by %u; got lock, manually granting (no ast)\n", |
241 | dlm->name, dlm->node_num, res->owner); | 259 | dlm->name, dlm->node_num, res->owner); |
242 | list_del_init(&lock->list); | 260 | list_move_tail(&lock->list, &res->granted); |
243 | list_add_tail(&lock->list, &res->granted); | ||
244 | } | 261 | } |
245 | spin_unlock(&res->spinlock); | 262 | spin_unlock(&res->spinlock); |
246 | 263 | ||
247 | dlm_lockres_calc_usage(dlm, res); | 264 | if (lockres_changed) |
265 | dlm_lockres_calc_usage(dlm, res); | ||
248 | 266 | ||
249 | wake_up(&res->wq); | 267 | wake_up(&res->wq); |
250 | return status; | 268 | return status; |
@@ -281,6 +299,14 @@ static enum dlm_status dlm_send_remote_lock_request(struct dlm_ctxt *dlm, | |||
281 | if (tmpret >= 0) { | 299 | if (tmpret >= 0) { |
282 | // successfully sent and received | 300 | // successfully sent and received |
283 | ret = status; // this is already a dlm_status | 301 | ret = status; // this is already a dlm_status |
302 | if (ret == DLM_REJECTED) { | ||
303 | mlog(ML_ERROR, "%s:%.*s: BUG. this is a stale lockres " | ||
304 | "no longer owned by %u. that node is coming back " | ||
305 | "up currently.\n", dlm->name, create.namelen, | ||
306 | create.name, res->owner); | ||
307 | dlm_print_one_lock_resource(res); | ||
308 | BUG(); | ||
309 | } | ||
284 | } else { | 310 | } else { |
285 | mlog_errno(tmpret); | 311 | mlog_errno(tmpret); |
286 | if (dlm_is_host_down(tmpret)) { | 312 | if (dlm_is_host_down(tmpret)) { |
@@ -382,13 +408,13 @@ struct dlm_lock * dlm_new_lock(int type, u8 node, u64 cookie, | |||
382 | struct dlm_lock *lock; | 408 | struct dlm_lock *lock; |
383 | int kernel_allocated = 0; | 409 | int kernel_allocated = 0; |
384 | 410 | ||
385 | lock = kcalloc(1, sizeof(*lock), GFP_KERNEL); | 411 | lock = kcalloc(1, sizeof(*lock), GFP_NOFS); |
386 | if (!lock) | 412 | if (!lock) |
387 | return NULL; | 413 | return NULL; |
388 | 414 | ||
389 | if (!lksb) { | 415 | if (!lksb) { |
390 | /* zero memory only if kernel-allocated */ | 416 | /* zero memory only if kernel-allocated */ |
391 | lksb = kcalloc(1, sizeof(*lksb), GFP_KERNEL); | 417 | lksb = kcalloc(1, sizeof(*lksb), GFP_NOFS); |
392 | if (!lksb) { | 418 | if (!lksb) { |
393 | kfree(lock); | 419 | kfree(lock); |
394 | return NULL; | 420 | return NULL; |
@@ -429,11 +455,16 @@ int dlm_create_lock_handler(struct o2net_msg *msg, u32 len, void *data) | |||
429 | if (!dlm_grab(dlm)) | 455 | if (!dlm_grab(dlm)) |
430 | return DLM_REJECTED; | 456 | return DLM_REJECTED; |
431 | 457 | ||
432 | mlog_bug_on_msg(!dlm_domain_fully_joined(dlm), | ||
433 | "Domain %s not fully joined!\n", dlm->name); | ||
434 | |||
435 | name = create->name; | 458 | name = create->name; |
436 | namelen = create->namelen; | 459 | namelen = create->namelen; |
460 | status = DLM_REJECTED; | ||
461 | if (!dlm_domain_fully_joined(dlm)) { | ||
462 | mlog(ML_ERROR, "Domain %s not fully joined, but node %u is " | ||
463 | "sending a create_lock message for lock %.*s!\n", | ||
464 | dlm->name, create->node_idx, namelen, name); | ||
465 | dlm_error(status); | ||
466 | goto leave; | ||
467 | } | ||
437 | 468 | ||
438 | status = DLM_IVBUFLEN; | 469 | status = DLM_IVBUFLEN; |
439 | if (namelen > DLM_LOCKID_NAME_MAX) { | 470 | if (namelen > DLM_LOCKID_NAME_MAX) { |
@@ -669,18 +700,22 @@ retry_lock: | |||
669 | msleep(100); | 700 | msleep(100); |
670 | /* no waiting for dlm_reco_thread */ | 701 | /* no waiting for dlm_reco_thread */ |
671 | if (recovery) { | 702 | if (recovery) { |
672 | if (status == DLM_RECOVERING) { | 703 | if (status != DLM_RECOVERING) |
673 | mlog(0, "%s: got RECOVERING " | 704 | goto retry_lock; |
674 | "for $REOCVERY lock, master " | 705 | |
675 | "was %u\n", dlm->name, | 706 | mlog(0, "%s: got RECOVERING " |
676 | res->owner); | 707 | "for $RECOVERY lock, master " |
677 | dlm_wait_for_node_death(dlm, res->owner, | 708 | "was %u\n", dlm->name, |
678 | DLM_NODE_DEATH_WAIT_MAX); | 709 | res->owner); |
679 | } | 710 | /* wait to see the node go down, then |
711 | * drop down and allow the lockres to | ||
712 | * get cleaned up. need to remaster. */ | ||
713 | dlm_wait_for_node_death(dlm, res->owner, | ||
714 | DLM_NODE_DEATH_WAIT_MAX); | ||
680 | } else { | 715 | } else { |
681 | dlm_wait_for_recovery(dlm); | 716 | dlm_wait_for_recovery(dlm); |
717 | goto retry_lock; | ||
682 | } | 718 | } |
683 | goto retry_lock; | ||
684 | } | 719 | } |
685 | 720 | ||
686 | if (status != DLM_NORMAL) { | 721 | if (status != DLM_NORMAL) { |