diff options
-rw-r--r-- | fs/gfs2/locking/dlm/lock.c | 11 | ||||
-rw-r--r-- | fs/gfs2/locking/dlm/lock_dlm.h | 2 | ||||
-rw-r--r-- | fs/gfs2/locking/dlm/thread.c | 11 |
3 files changed, 18 insertions, 6 deletions
diff --git a/fs/gfs2/locking/dlm/lock.c b/fs/gfs2/locking/dlm/lock.c index c305255bfe8a..542a797ac89a 100644 --- a/fs/gfs2/locking/dlm/lock.c +++ b/fs/gfs2/locking/dlm/lock.c | |||
@@ -174,7 +174,6 @@ static int gdlm_create_lp(struct gdlm_ls *ls, struct lm_lockname *name, | |||
174 | lp->cur = DLM_LOCK_IV; | 174 | lp->cur = DLM_LOCK_IV; |
175 | lp->lvb = NULL; | 175 | lp->lvb = NULL; |
176 | lp->hold_null = NULL; | 176 | lp->hold_null = NULL; |
177 | init_completion(&lp->ast_wait); | ||
178 | INIT_LIST_HEAD(&lp->clist); | 177 | INIT_LIST_HEAD(&lp->clist); |
179 | INIT_LIST_HEAD(&lp->blist); | 178 | INIT_LIST_HEAD(&lp->blist); |
180 | INIT_LIST_HEAD(&lp->delay_list); | 179 | INIT_LIST_HEAD(&lp->delay_list); |
@@ -399,6 +398,12 @@ static void gdlm_del_lvb(struct gdlm_lock *lp) | |||
399 | lp->lksb.sb_lvbptr = NULL; | 398 | lp->lksb.sb_lvbptr = NULL; |
400 | } | 399 | } |
401 | 400 | ||
401 | static int gdlm_ast_wait(void *word) | ||
402 | { | ||
403 | schedule(); | ||
404 | return 0; | ||
405 | } | ||
406 | |||
402 | /* This can do a synchronous dlm request (requiring a lock_dlm thread to get | 407 | /* This can do a synchronous dlm request (requiring a lock_dlm thread to get |
403 | the completion) because gfs won't call hold_lvb() during a callback (from | 408 | the completion) because gfs won't call hold_lvb() during a callback (from |
404 | the context of a lock_dlm thread). */ | 409 | the context of a lock_dlm thread). */ |
@@ -424,10 +429,10 @@ static int hold_null_lock(struct gdlm_lock *lp) | |||
424 | lpn->lkf = DLM_LKF_VALBLK | DLM_LKF_EXPEDITE; | 429 | lpn->lkf = DLM_LKF_VALBLK | DLM_LKF_EXPEDITE; |
425 | set_bit(LFL_NOBAST, &lpn->flags); | 430 | set_bit(LFL_NOBAST, &lpn->flags); |
426 | set_bit(LFL_INLOCK, &lpn->flags); | 431 | set_bit(LFL_INLOCK, &lpn->flags); |
432 | set_bit(LFL_AST_WAIT, &lpn->flags); | ||
427 | 433 | ||
428 | init_completion(&lpn->ast_wait); | ||
429 | gdlm_do_lock(lpn); | 434 | gdlm_do_lock(lpn); |
430 | wait_for_completion(&lpn->ast_wait); | 435 | wait_on_bit(&lpn->flags, LFL_AST_WAIT, gdlm_ast_wait, TASK_UNINTERRUPTIBLE); |
431 | error = lpn->lksb.sb_status; | 436 | error = lpn->lksb.sb_status; |
432 | if (error) { | 437 | if (error) { |
433 | printk(KERN_INFO "lock_dlm: hold_null_lock dlm error %d\n", | 438 | printk(KERN_INFO "lock_dlm: hold_null_lock dlm error %d\n", |
diff --git a/fs/gfs2/locking/dlm/lock_dlm.h b/fs/gfs2/locking/dlm/lock_dlm.h index d074c6e6f9bf..24d70f73b651 100644 --- a/fs/gfs2/locking/dlm/lock_dlm.h +++ b/fs/gfs2/locking/dlm/lock_dlm.h | |||
@@ -101,6 +101,7 @@ enum { | |||
101 | LFL_NOBAST = 10, | 101 | LFL_NOBAST = 10, |
102 | LFL_HEADQUE = 11, | 102 | LFL_HEADQUE = 11, |
103 | LFL_UNLOCK_DELETE = 12, | 103 | LFL_UNLOCK_DELETE = 12, |
104 | LFL_AST_WAIT = 13, | ||
104 | }; | 105 | }; |
105 | 106 | ||
106 | struct gdlm_lock { | 107 | struct gdlm_lock { |
@@ -117,7 +118,6 @@ struct gdlm_lock { | |||
117 | unsigned long flags; /* lock_dlm flags LFL_ */ | 118 | unsigned long flags; /* lock_dlm flags LFL_ */ |
118 | 119 | ||
119 | int bast_mode; /* protected by async_lock */ | 120 | int bast_mode; /* protected by async_lock */ |
120 | struct completion ast_wait; | ||
121 | 121 | ||
122 | struct list_head clist; /* complete */ | 122 | struct list_head clist; /* complete */ |
123 | struct list_head blist; /* blocking */ | 123 | struct list_head blist; /* blocking */ |
diff --git a/fs/gfs2/locking/dlm/thread.c b/fs/gfs2/locking/dlm/thread.c index 9cf1f168eaf8..1aca51e45092 100644 --- a/fs/gfs2/locking/dlm/thread.c +++ b/fs/gfs2/locking/dlm/thread.c | |||
@@ -44,6 +44,13 @@ static void process_blocking(struct gdlm_lock *lp, int bast_mode) | |||
44 | ls->fscb(ls->sdp, cb, &lp->lockname); | 44 | ls->fscb(ls->sdp, cb, &lp->lockname); |
45 | } | 45 | } |
46 | 46 | ||
47 | static void wake_up_ast(struct gdlm_lock *lp) | ||
48 | { | ||
49 | clear_bit(LFL_AST_WAIT, &lp->flags); | ||
50 | smp_mb__after_clear_bit(); | ||
51 | wake_up_bit(&lp->flags, LFL_AST_WAIT); | ||
52 | } | ||
53 | |||
47 | static void process_complete(struct gdlm_lock *lp) | 54 | static void process_complete(struct gdlm_lock *lp) |
48 | { | 55 | { |
49 | struct gdlm_ls *ls = lp->ls; | 56 | struct gdlm_ls *ls = lp->ls; |
@@ -136,7 +143,7 @@ static void process_complete(struct gdlm_lock *lp) | |||
136 | */ | 143 | */ |
137 | 144 | ||
138 | if (test_and_clear_bit(LFL_SYNC_LVB, &lp->flags)) { | 145 | if (test_and_clear_bit(LFL_SYNC_LVB, &lp->flags)) { |
139 | complete(&lp->ast_wait); | 146 | wake_up_ast(lp); |
140 | return; | 147 | return; |
141 | } | 148 | } |
142 | 149 | ||
@@ -214,7 +221,7 @@ out: | |||
214 | if (test_bit(LFL_INLOCK, &lp->flags)) { | 221 | if (test_bit(LFL_INLOCK, &lp->flags)) { |
215 | clear_bit(LFL_NOBLOCK, &lp->flags); | 222 | clear_bit(LFL_NOBLOCK, &lp->flags); |
216 | lp->cur = lp->req; | 223 | lp->cur = lp->req; |
217 | complete(&lp->ast_wait); | 224 | wake_up_ast(lp); |
218 | return; | 225 | return; |
219 | } | 226 | } |
220 | 227 | ||