diff options
-rw-r--r-- | fs/dlm/dlm_internal.h | 1 | ||||
-rw-r--r-- | fs/dlm/lock.c | 30 | ||||
-rw-r--r-- | fs/dlm/user.c | 9 |
3 files changed, 28 insertions, 12 deletions
diff --git a/fs/dlm/dlm_internal.h b/fs/dlm/dlm_internal.h index ee993c5c2307..61d93201e1b2 100644 --- a/fs/dlm/dlm_internal.h +++ b/fs/dlm/dlm_internal.h | |||
@@ -526,6 +526,7 @@ struct dlm_user_proc { | |||
526 | spinlock_t asts_spin; | 526 | spinlock_t asts_spin; |
527 | struct list_head locks; | 527 | struct list_head locks; |
528 | spinlock_t locks_spin; | 528 | spinlock_t locks_spin; |
529 | struct list_head unlocking; | ||
529 | wait_queue_head_t wait; | 530 | wait_queue_head_t wait; |
530 | }; | 531 | }; |
531 | 532 | ||
diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c index 5bac9827ded3..6ad2b8eb96a5 100644 --- a/fs/dlm/lock.c +++ b/fs/dlm/lock.c | |||
@@ -3772,12 +3772,10 @@ int dlm_user_unlock(struct dlm_ls *ls, struct dlm_user_args *ua_tmp, | |||
3772 | goto out_put; | 3772 | goto out_put; |
3773 | 3773 | ||
3774 | spin_lock(&ua->proc->locks_spin); | 3774 | spin_lock(&ua->proc->locks_spin); |
3775 | list_del_init(&lkb->lkb_ownqueue); | 3775 | /* dlm_user_add_ast() may have already taken lkb off the proc list */ |
3776 | if (!list_empty(&lkb->lkb_ownqueue)) | ||
3777 | list_move(&lkb->lkb_ownqueue, &ua->proc->unlocking); | ||
3776 | spin_unlock(&ua->proc->locks_spin); | 3778 | spin_unlock(&ua->proc->locks_spin); |
3777 | |||
3778 | /* this removes the reference for the proc->locks list added by | ||
3779 | dlm_user_request */ | ||
3780 | unhold_lkb(lkb); | ||
3781 | out_put: | 3779 | out_put: |
3782 | dlm_put_lkb(lkb); | 3780 | dlm_put_lkb(lkb); |
3783 | out: | 3781 | out: |
@@ -3817,9 +3815,8 @@ int dlm_user_cancel(struct dlm_ls *ls, struct dlm_user_args *ua_tmp, | |||
3817 | /* this lkb was removed from the WAITING queue */ | 3815 | /* this lkb was removed from the WAITING queue */ |
3818 | if (lkb->lkb_grmode == DLM_LOCK_IV) { | 3816 | if (lkb->lkb_grmode == DLM_LOCK_IV) { |
3819 | spin_lock(&ua->proc->locks_spin); | 3817 | spin_lock(&ua->proc->locks_spin); |
3820 | list_del_init(&lkb->lkb_ownqueue); | 3818 | list_move(&lkb->lkb_ownqueue, &ua->proc->unlocking); |
3821 | spin_unlock(&ua->proc->locks_spin); | 3819 | spin_unlock(&ua->proc->locks_spin); |
3822 | unhold_lkb(lkb); | ||
3823 | } | 3820 | } |
3824 | out_put: | 3821 | out_put: |
3825 | dlm_put_lkb(lkb); | 3822 | dlm_put_lkb(lkb); |
@@ -3880,11 +3877,6 @@ void dlm_clear_proc_locks(struct dlm_ls *ls, struct dlm_user_proc *proc) | |||
3880 | mutex_lock(&ls->ls_clear_proc_locks); | 3877 | mutex_lock(&ls->ls_clear_proc_locks); |
3881 | 3878 | ||
3882 | list_for_each_entry_safe(lkb, safe, &proc->locks, lkb_ownqueue) { | 3879 | list_for_each_entry_safe(lkb, safe, &proc->locks, lkb_ownqueue) { |
3883 | if (lkb->lkb_ast_type) { | ||
3884 | list_del(&lkb->lkb_astqueue); | ||
3885 | unhold_lkb(lkb); | ||
3886 | } | ||
3887 | |||
3888 | list_del_init(&lkb->lkb_ownqueue); | 3880 | list_del_init(&lkb->lkb_ownqueue); |
3889 | 3881 | ||
3890 | if (lkb->lkb_exflags & DLM_LKF_PERSISTENT) { | 3882 | if (lkb->lkb_exflags & DLM_LKF_PERSISTENT) { |
@@ -3901,6 +3893,20 @@ void dlm_clear_proc_locks(struct dlm_ls *ls, struct dlm_user_proc *proc) | |||
3901 | 3893 | ||
3902 | dlm_put_lkb(lkb); | 3894 | dlm_put_lkb(lkb); |
3903 | } | 3895 | } |
3896 | |||
3897 | /* in-progress unlocks */ | ||
3898 | list_for_each_entry_safe(lkb, safe, &proc->unlocking, lkb_ownqueue) { | ||
3899 | list_del_init(&lkb->lkb_ownqueue); | ||
3900 | lkb->lkb_flags |= DLM_IFL_DEAD; | ||
3901 | dlm_put_lkb(lkb); | ||
3902 | } | ||
3903 | |||
3904 | list_for_each_entry_safe(lkb, safe, &proc->asts, lkb_astqueue) { | ||
3905 | list_del(&lkb->lkb_astqueue); | ||
3906 | dlm_put_lkb(lkb); | ||
3907 | } | ||
3908 | |||
3904 | mutex_unlock(&ls->ls_clear_proc_locks); | 3909 | mutex_unlock(&ls->ls_clear_proc_locks); |
3905 | unlock_recovery(ls); | 3910 | unlock_recovery(ls); |
3906 | } | 3911 | } |
3912 | |||
diff --git a/fs/dlm/user.c b/fs/dlm/user.c index c37e93e4f2df..d378b7fe2a1e 100644 --- a/fs/dlm/user.c +++ b/fs/dlm/user.c | |||
@@ -180,6 +180,14 @@ void dlm_user_add_ast(struct dlm_lkb *lkb, int type) | |||
180 | ua->lksb.sb_status == -EAGAIN && !list_empty(&lkb->lkb_ownqueue)) | 180 | ua->lksb.sb_status == -EAGAIN && !list_empty(&lkb->lkb_ownqueue)) |
181 | remove_ownqueue = 1; | 181 | remove_ownqueue = 1; |
182 | 182 | ||
183 | /* unlocks or cancels of waiting requests need to be removed from the | ||
184 | proc's unlocking list, again there must be a better way... */ | ||
185 | |||
186 | if (ua->lksb.sb_status == -DLM_EUNLOCK || | ||
187 | (ua->lksb.sb_status == -DLM_ECANCEL && | ||
188 | lkb->lkb_grmode == DLM_LOCK_IV)) | ||
189 | remove_ownqueue = 1; | ||
190 | |||
183 | /* We want to copy the lvb to userspace when the completion | 191 | /* We want to copy the lvb to userspace when the completion |
184 | ast is read if the status is 0, the lock has an lvb and | 192 | ast is read if the status is 0, the lock has an lvb and |
185 | lvb_ops says we should. We could probably have set_lvb_lock() | 193 | lvb_ops says we should. We could probably have set_lvb_lock() |
@@ -523,6 +531,7 @@ static int device_open(struct inode *inode, struct file *file) | |||
523 | proc->lockspace = ls->ls_local_handle; | 531 | proc->lockspace = ls->ls_local_handle; |
524 | INIT_LIST_HEAD(&proc->asts); | 532 | INIT_LIST_HEAD(&proc->asts); |
525 | INIT_LIST_HEAD(&proc->locks); | 533 | INIT_LIST_HEAD(&proc->locks); |
534 | INIT_LIST_HEAD(&proc->unlocking); | ||
526 | spin_lock_init(&proc->asts_spin); | 535 | spin_lock_init(&proc->asts_spin); |
527 | spin_lock_init(&proc->locks_spin); | 536 | spin_lock_init(&proc->locks_spin); |
528 | init_waitqueue_head(&proc->wait); | 537 | init_waitqueue_head(&proc->wait); |