aboutsummaryrefslogtreecommitdiffstats
path: root/fs/dlm/ast.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/dlm/ast.c')
-rw-r--r--fs/dlm/ast.c56
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
36void dlm_add_ast(struct dlm_lkb *lkb, int type) 36void 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 (;;) { 66repeat:
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
108static inline int no_asts(void) 100static inline int no_asts(void)