User: | Jiri Slaby |
Error type: | Double Unlock |
Error type description: | Some lock is unlocked twice unintentionally in a sequence |
File location: | fs/ocfs2/dlm/dlmmaster.c |
Line in file: | 3388 |
Project: | Linux Kernel |
Project version: | 2.6.28 |
Tools: |
Stanse
(1.2)
|
Entered: | 2012-04-30 10:52:00 UTC |
3358{ 3359 assert_spin_locked(&res->spinlock); 3360 if (res->state & DLM_LOCK_RES_MIGRATING) { 3361 __dlm_print_one_lock_resource(res); 3362 } 3363 BUG_ON(res->state & DLM_LOCK_RES_MIGRATING); 3364 3365 atomic_inc(&res->asts_reserved); 3366} 3367 3368/* 3369 * used to drop the reserved ast, either because it went unused, 3370 * or because the ast/bast was actually called. 3371 * 3372 * also, if there is a pending migration on this lockres, 3373 * and this was the last pending ast on the lockres, 3374 * atomically set the MIGRATING flag before we drop the lock. 3375 * this is how we ensure that migration can proceed with no 3376 * asts in progress. note that it is ok if the state of the 3377 * queues is such that a lock should be granted in the future 3378 * or that a bast should be fired, because the new master will 3379 * shuffle the lists on this lockres as soon as it is migrated. 3380 */ 3381void dlm_lockres_release_ast(struct dlm_ctxt *dlm, 3382 struct dlm_lock_resource *res) 3383{ 3384 if (!atomic_dec_and_lock(&res->asts_reserved, &res->spinlock)) 3385 return; 3386 3387 if (!res->migration_pending) { 3388 spin_unlock(&res->spinlock); 3389 return; 3390 } 3391 3392 BUG_ON(res->state & DLM_LOCK_RES_MIGRATING); 3393 res->migration_pending = 0; 3394 res->state |= DLM_LOCK_RES_MIGRATING; 3395 spin_unlock(&res->spinlock); 3396 wake_up(&res->wq); 3397 wake_up(&dlm->migration_wq); 3398}