diff options
Diffstat (limited to 'fs/dlm/ast.c')
| -rw-r--r-- | fs/dlm/ast.c | 56 |
1 files changed, 24 insertions, 32 deletions
diff --git a/fs/dlm/ast.c b/fs/dlm/ast.c index 8bf31e3fbf01..dc2ad6008b2d 100644 --- a/fs/dlm/ast.c +++ b/fs/dlm/ast.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | ******************************************************************************* | 2 | ******************************************************************************* |
| 3 | ** | 3 | ** |
| 4 | ** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. | 4 | ** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. |
| 5 | ** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. | 5 | ** Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved. |
| 6 | ** | 6 | ** |
| 7 | ** This copyrighted material is made available to anyone wishing to use, | 7 | ** This copyrighted material is made available to anyone wishing to use, |
| 8 | ** modify, copy, or redistribute it subject to the terms and conditions | 8 | ** modify, copy, or redistribute it subject to the terms and conditions |
| @@ -33,10 +33,10 @@ void dlm_del_ast(struct dlm_lkb *lkb) | |||
| 33 | spin_unlock(&ast_queue_lock); | 33 | spin_unlock(&ast_queue_lock); |
| 34 | } | 34 | } |
| 35 | 35 | ||
| 36 | void dlm_add_ast(struct dlm_lkb *lkb, int type) | 36 | void dlm_add_ast(struct dlm_lkb *lkb, int type, int bastmode) |
| 37 | { | 37 | { |
| 38 | if (lkb->lkb_flags & DLM_IFL_USER) { | 38 | if (lkb->lkb_flags & DLM_IFL_USER) { |
| 39 | dlm_user_add_ast(lkb, type); | 39 | dlm_user_add_ast(lkb, type, bastmode); |
| 40 | return; | 40 | return; |
| 41 | } | 41 | } |
| 42 | 42 | ||
| @@ -46,6 +46,8 @@ void dlm_add_ast(struct dlm_lkb *lkb, int type) | |||
| 46 | list_add_tail(&lkb->lkb_astqueue, &ast_queue); | 46 | list_add_tail(&lkb->lkb_astqueue, &ast_queue); |
| 47 | } | 47 | } |
| 48 | lkb->lkb_ast_type |= type; | 48 | lkb->lkb_ast_type |= type; |
| 49 | if (bastmode) | ||
| 50 | lkb->lkb_bastmode = bastmode; | ||
| 49 | spin_unlock(&ast_queue_lock); | 51 | spin_unlock(&ast_queue_lock); |
| 50 | 52 | ||
| 51 | set_bit(WAKE_ASTS, &astd_wakeflags); | 53 | set_bit(WAKE_ASTS, &astd_wakeflags); |
| @@ -59,50 +61,40 @@ static void process_asts(void) | |||
| 59 | struct dlm_lkb *lkb; | 61 | struct dlm_lkb *lkb; |
| 60 | void (*cast) (void *astparam); | 62 | void (*cast) (void *astparam); |
| 61 | void (*bast) (void *astparam, int mode); | 63 | void (*bast) (void *astparam, int mode); |
| 62 | int type = 0, found, bmode; | 64 | int type = 0, bastmode; |
| 63 | 65 | ||
| 64 | for (;;) { | 66 | repeat: |
| 65 | found = 0; | 67 | spin_lock(&ast_queue_lock); |
| 66 | spin_lock(&ast_queue_lock); | 68 | list_for_each_entry(lkb, &ast_queue, lkb_astqueue) { |
| 67 | list_for_each_entry(lkb, &ast_queue, lkb_astqueue) { | 69 | r = lkb->lkb_resource; |
| 68 | r = lkb->lkb_resource; | 70 | ls = r->res_ls; |
| 69 | ls = r->res_ls; | 71 | |
| 70 | 72 | if (dlm_locking_stopped(ls)) | |
| 71 | if (dlm_locking_stopped(ls)) | 73 | continue; |
| 72 | continue; | ||
| 73 | |||
| 74 | list_del(&lkb->lkb_astqueue); | ||
| 75 | type = lkb->lkb_ast_type; | ||
| 76 | lkb->lkb_ast_type = 0; | ||
| 77 | found = 1; | ||
| 78 | break; | ||
| 79 | } | ||
| 80 | spin_unlock(&ast_queue_lock); | ||
| 81 | 74 | ||
| 82 | if (!found) | 75 | list_del(&lkb->lkb_astqueue); |
| 83 | break; | 76 | type = lkb->lkb_ast_type; |
| 77 | lkb->lkb_ast_type = 0; | ||
| 78 | bastmode = lkb->lkb_bastmode; | ||
| 84 | 79 | ||
| 80 | spin_unlock(&ast_queue_lock); | ||
| 85 | cast = lkb->lkb_astfn; | 81 | cast = lkb->lkb_astfn; |
| 86 | bast = lkb->lkb_bastfn; | 82 | bast = lkb->lkb_bastfn; |
| 87 | bmode = lkb->lkb_bastmode; | ||
| 88 | 83 | ||
| 89 | if ((type & AST_COMP) && cast) | 84 | if ((type & AST_COMP) && cast) |
| 90 | cast(lkb->lkb_astparam); | 85 | cast(lkb->lkb_astparam); |
| 91 | 86 | ||
| 92 | /* FIXME: Is it safe to look at lkb_grmode here | ||
| 93 | without doing a lock_rsb() ? | ||
| 94 | Look at other checks in v1 to avoid basts. */ | ||
| 95 | |||
| 96 | if ((type & AST_BAST) && bast) | 87 | if ((type & AST_BAST) && bast) |
| 97 | if (!dlm_modes_compat(lkb->lkb_grmode, bmode)) | 88 | bast(lkb->lkb_astparam, bastmode); |
| 98 | bast(lkb->lkb_astparam, bmode); | ||
| 99 | 89 | ||
| 100 | /* this removes the reference added by dlm_add_ast | 90 | /* this removes the reference added by dlm_add_ast |
| 101 | and may result in the lkb being freed */ | 91 | and may result in the lkb being freed */ |
| 102 | dlm_put_lkb(lkb); | 92 | dlm_put_lkb(lkb); |
| 103 | 93 | ||
| 104 | schedule(); | 94 | cond_resched(); |
| 95 | goto repeat; | ||
| 105 | } | 96 | } |
| 97 | spin_unlock(&ast_queue_lock); | ||
| 106 | } | 98 | } |
| 107 | 99 | ||
| 108 | static inline int no_asts(void) | 100 | static inline int no_asts(void) |
