diff options
Diffstat (limited to 'fs/dlm')
-rw-r--r-- | fs/dlm/ast.c | 74 | ||||
-rw-r--r-- | fs/dlm/ast.h | 4 | ||||
-rw-r--r-- | fs/dlm/dlm_internal.h | 10 | ||||
-rw-r--r-- | fs/dlm/lock.c | 4 | ||||
-rw-r--r-- | fs/dlm/user.c | 10 | ||||
-rw-r--r-- | fs/dlm/user.h | 4 |
6 files changed, 78 insertions, 28 deletions
diff --git a/fs/dlm/ast.c b/fs/dlm/ast.c index dc2ad6008b2d..4314f0d48d85 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-2008 Red Hat, Inc. All rights reserved. | 5 | ** Copyright (C) 2004-2010 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, int bastmode) | 36 | void dlm_add_ast(struct dlm_lkb *lkb, int type, int mode) |
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, bastmode); | 39 | dlm_user_add_ast(lkb, type, mode); |
40 | return; | 40 | return; |
41 | } | 41 | } |
42 | 42 | ||
@@ -44,10 +44,21 @@ void dlm_add_ast(struct dlm_lkb *lkb, int type, int bastmode) | |||
44 | if (!(lkb->lkb_ast_type & (AST_COMP | AST_BAST))) { | 44 | if (!(lkb->lkb_ast_type & (AST_COMP | AST_BAST))) { |
45 | kref_get(&lkb->lkb_ref); | 45 | kref_get(&lkb->lkb_ref); |
46 | list_add_tail(&lkb->lkb_astqueue, &ast_queue); | 46 | list_add_tail(&lkb->lkb_astqueue, &ast_queue); |
47 | lkb->lkb_ast_first = type; | ||
47 | } | 48 | } |
49 | |||
50 | /* sanity check, this should not happen */ | ||
51 | |||
52 | if ((type == AST_COMP) && (lkb->lkb_ast_type & AST_COMP)) | ||
53 | log_print("repeat cast %d castmode %d lock %x %s", | ||
54 | mode, lkb->lkb_castmode, | ||
55 | lkb->lkb_id, lkb->lkb_resource->res_name); | ||
56 | |||
48 | lkb->lkb_ast_type |= type; | 57 | lkb->lkb_ast_type |= type; |
49 | if (bastmode) | 58 | if (type == AST_BAST) |
50 | lkb->lkb_bastmode = bastmode; | 59 | lkb->lkb_bastmode = mode; |
60 | else | ||
61 | lkb->lkb_castmode = mode; | ||
51 | spin_unlock(&ast_queue_lock); | 62 | spin_unlock(&ast_queue_lock); |
52 | 63 | ||
53 | set_bit(WAKE_ASTS, &astd_wakeflags); | 64 | set_bit(WAKE_ASTS, &astd_wakeflags); |
@@ -59,9 +70,9 @@ static void process_asts(void) | |||
59 | struct dlm_ls *ls = NULL; | 70 | struct dlm_ls *ls = NULL; |
60 | struct dlm_rsb *r = NULL; | 71 | struct dlm_rsb *r = NULL; |
61 | struct dlm_lkb *lkb; | 72 | struct dlm_lkb *lkb; |
62 | void (*cast) (void *astparam); | 73 | void (*castfn) (void *astparam); |
63 | void (*bast) (void *astparam, int mode); | 74 | void (*bastfn) (void *astparam, int mode); |
64 | int type = 0, bastmode; | 75 | int type, first, bastmode, castmode, do_bast, do_cast, last_castmode; |
65 | 76 | ||
66 | repeat: | 77 | repeat: |
67 | spin_lock(&ast_queue_lock); | 78 | spin_lock(&ast_queue_lock); |
@@ -75,17 +86,48 @@ repeat: | |||
75 | list_del(&lkb->lkb_astqueue); | 86 | list_del(&lkb->lkb_astqueue); |
76 | type = lkb->lkb_ast_type; | 87 | type = lkb->lkb_ast_type; |
77 | lkb->lkb_ast_type = 0; | 88 | lkb->lkb_ast_type = 0; |
89 | first = lkb->lkb_ast_first; | ||
90 | lkb->lkb_ast_first = 0; | ||
78 | bastmode = lkb->lkb_bastmode; | 91 | bastmode = lkb->lkb_bastmode; |
79 | 92 | castmode = lkb->lkb_castmode; | |
93 | castfn = lkb->lkb_astfn; | ||
94 | bastfn = lkb->lkb_bastfn; | ||
80 | spin_unlock(&ast_queue_lock); | 95 | spin_unlock(&ast_queue_lock); |
81 | cast = lkb->lkb_astfn; | ||
82 | bast = lkb->lkb_bastfn; | ||
83 | |||
84 | if ((type & AST_COMP) && cast) | ||
85 | cast(lkb->lkb_astparam); | ||
86 | 96 | ||
87 | if ((type & AST_BAST) && bast) | 97 | do_cast = (type & AST_COMP) && castfn; |
88 | bast(lkb->lkb_astparam, bastmode); | 98 | do_bast = (type & AST_BAST) && bastfn; |
99 | |||
100 | /* Skip a bast if its blocking mode is compatible with the | ||
101 | granted mode of the preceding cast. */ | ||
102 | |||
103 | if (do_bast) { | ||
104 | if (first == AST_COMP) | ||
105 | last_castmode = castmode; | ||
106 | else | ||
107 | last_castmode = lkb->lkb_castmode_done; | ||
108 | if (dlm_modes_compat(bastmode, last_castmode)) | ||
109 | do_bast = 0; | ||
110 | } | ||
111 | |||
112 | if (first == AST_COMP) { | ||
113 | if (do_cast) | ||
114 | castfn(lkb->lkb_astparam); | ||
115 | if (do_bast) | ||
116 | bastfn(lkb->lkb_astparam, bastmode); | ||
117 | } else if (first == AST_BAST) { | ||
118 | if (do_bast) | ||
119 | bastfn(lkb->lkb_astparam, bastmode); | ||
120 | if (do_cast) | ||
121 | castfn(lkb->lkb_astparam); | ||
122 | } else { | ||
123 | log_error(ls, "bad ast_first %d ast_type %d", | ||
124 | first, type); | ||
125 | } | ||
126 | |||
127 | if (do_cast) | ||
128 | lkb->lkb_castmode_done = castmode; | ||
129 | if (do_bast) | ||
130 | lkb->lkb_bastmode_done = bastmode; | ||
89 | 131 | ||
90 | /* this removes the reference added by dlm_add_ast | 132 | /* this removes the reference added by dlm_add_ast |
91 | and may result in the lkb being freed */ | 133 | and may result in the lkb being freed */ |
diff --git a/fs/dlm/ast.h b/fs/dlm/ast.h index 1b5fc5f428fd..bcb1aaba519d 100644 --- a/fs/dlm/ast.h +++ b/fs/dlm/ast.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | ******************************************************************************* | 2 | ******************************************************************************* |
3 | ** | 3 | ** |
4 | ** Copyright (C) 2005-2008 Red Hat, Inc. All rights reserved. | 4 | ** Copyright (C) 2005-2010 Red Hat, Inc. All rights reserved. |
5 | ** | 5 | ** |
6 | ** This copyrighted material is made available to anyone wishing to use, | 6 | ** This copyrighted material is made available to anyone wishing to use, |
7 | ** modify, copy, or redistribute it subject to the terms and conditions | 7 | ** modify, copy, or redistribute it subject to the terms and conditions |
@@ -13,7 +13,7 @@ | |||
13 | #ifndef __ASTD_DOT_H__ | 13 | #ifndef __ASTD_DOT_H__ |
14 | #define __ASTD_DOT_H__ | 14 | #define __ASTD_DOT_H__ |
15 | 15 | ||
16 | void dlm_add_ast(struct dlm_lkb *lkb, int type, int bastmode); | 16 | void dlm_add_ast(struct dlm_lkb *lkb, int type, int mode); |
17 | void dlm_del_ast(struct dlm_lkb *lkb); | 17 | void dlm_del_ast(struct dlm_lkb *lkb); |
18 | 18 | ||
19 | void dlm_astd_wake(void); | 19 | void dlm_astd_wake(void); |
diff --git a/fs/dlm/dlm_internal.h b/fs/dlm/dlm_internal.h index 826d3dc6e0ab..f632b58cd222 100644 --- a/fs/dlm/dlm_internal.h +++ b/fs/dlm/dlm_internal.h | |||
@@ -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-2008 Red Hat, Inc. All rights reserved. | 5 | ** Copyright (C) 2004-2010 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 |
@@ -232,11 +232,17 @@ struct dlm_lkb { | |||
232 | int8_t lkb_status; /* granted, waiting, convert */ | 232 | int8_t lkb_status; /* granted, waiting, convert */ |
233 | int8_t lkb_rqmode; /* requested lock mode */ | 233 | int8_t lkb_rqmode; /* requested lock mode */ |
234 | int8_t lkb_grmode; /* granted lock mode */ | 234 | int8_t lkb_grmode; /* granted lock mode */ |
235 | int8_t lkb_bastmode; /* requested mode */ | ||
236 | int8_t lkb_highbast; /* highest mode bast sent for */ | 235 | int8_t lkb_highbast; /* highest mode bast sent for */ |
236 | |||
237 | int8_t lkb_wait_type; /* type of reply waiting for */ | 237 | int8_t lkb_wait_type; /* type of reply waiting for */ |
238 | int8_t lkb_wait_count; | 238 | int8_t lkb_wait_count; |
239 | int8_t lkb_ast_type; /* type of ast queued for */ | 239 | int8_t lkb_ast_type; /* type of ast queued for */ |
240 | int8_t lkb_ast_first; /* type of first ast queued */ | ||
241 | |||
242 | int8_t lkb_bastmode; /* req mode of queued bast */ | ||
243 | int8_t lkb_castmode; /* gr mode of queued cast */ | ||
244 | int8_t lkb_bastmode_done; /* last delivered bastmode */ | ||
245 | int8_t lkb_castmode_done; /* last delivered castmode */ | ||
240 | 246 | ||
241 | struct list_head lkb_idtbl_list; /* lockspace lkbtbl */ | 247 | struct list_head lkb_idtbl_list; /* lockspace lkbtbl */ |
242 | struct list_head lkb_statequeue; /* rsb g/c/w list */ | 248 | struct list_head lkb_statequeue; /* rsb g/c/w list */ |
diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c index 9c0c1db1e105..e08ea93432bc 100644 --- a/fs/dlm/lock.c +++ b/fs/dlm/lock.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | ******************************************************************************* | 2 | ******************************************************************************* |
3 | ** | 3 | ** |
4 | ** Copyright (C) 2005-2008 Red Hat, Inc. All rights reserved. | 4 | ** Copyright (C) 2005-2010 Red Hat, Inc. All rights reserved. |
5 | ** | 5 | ** |
6 | ** This copyrighted material is made available to anyone wishing to use, | 6 | ** This copyrighted material is made available to anyone wishing to use, |
7 | ** modify, copy, or redistribute it subject to the terms and conditions | 7 | ** modify, copy, or redistribute it subject to the terms and conditions |
@@ -307,7 +307,7 @@ static void queue_cast(struct dlm_rsb *r, struct dlm_lkb *lkb, int rv) | |||
307 | lkb->lkb_lksb->sb_status = rv; | 307 | lkb->lkb_lksb->sb_status = rv; |
308 | lkb->lkb_lksb->sb_flags = lkb->lkb_sbflags; | 308 | lkb->lkb_lksb->sb_flags = lkb->lkb_sbflags; |
309 | 309 | ||
310 | dlm_add_ast(lkb, AST_COMP, 0); | 310 | dlm_add_ast(lkb, AST_COMP, lkb->lkb_grmode); |
311 | } | 311 | } |
312 | 312 | ||
313 | static inline void queue_cast_overlap(struct dlm_rsb *r, struct dlm_lkb *lkb) | 313 | static inline void queue_cast_overlap(struct dlm_rsb *r, struct dlm_lkb *lkb) |
diff --git a/fs/dlm/user.c b/fs/dlm/user.c index e73a4bb572aa..a4bfd31ac45b 100644 --- a/fs/dlm/user.c +++ b/fs/dlm/user.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2006-2009 Red Hat, Inc. All rights reserved. | 2 | * Copyright (C) 2006-2010 Red Hat, Inc. All rights reserved. |
3 | * | 3 | * |
4 | * This copyrighted material is made available to anyone wishing to use, | 4 | * This copyrighted material is made available to anyone wishing to use, |
5 | * modify, copy, or redistribute it subject to the terms and conditions | 5 | * modify, copy, or redistribute it subject to the terms and conditions |
@@ -173,7 +173,7 @@ static int lkb_is_endoflife(struct dlm_lkb *lkb, int sb_status, int type) | |||
173 | /* we could possibly check if the cancel of an orphan has resulted in the lkb | 173 | /* we could possibly check if the cancel of an orphan has resulted in the lkb |
174 | being removed and then remove that lkb from the orphans list and free it */ | 174 | being removed and then remove that lkb from the orphans list and free it */ |
175 | 175 | ||
176 | void dlm_user_add_ast(struct dlm_lkb *lkb, int type, int bastmode) | 176 | void dlm_user_add_ast(struct dlm_lkb *lkb, int type, int mode) |
177 | { | 177 | { |
178 | struct dlm_ls *ls; | 178 | struct dlm_ls *ls; |
179 | struct dlm_user_args *ua; | 179 | struct dlm_user_args *ua; |
@@ -206,8 +206,10 @@ void dlm_user_add_ast(struct dlm_lkb *lkb, int type, int bastmode) | |||
206 | 206 | ||
207 | ast_type = lkb->lkb_ast_type; | 207 | ast_type = lkb->lkb_ast_type; |
208 | lkb->lkb_ast_type |= type; | 208 | lkb->lkb_ast_type |= type; |
209 | if (bastmode) | 209 | if (type == AST_BAST) |
210 | lkb->lkb_bastmode = bastmode; | 210 | lkb->lkb_bastmode = mode; |
211 | else | ||
212 | lkb->lkb_castmode = mode; | ||
211 | 213 | ||
212 | if (!ast_type) { | 214 | if (!ast_type) { |
213 | kref_get(&lkb->lkb_ref); | 215 | kref_get(&lkb->lkb_ref); |
diff --git a/fs/dlm/user.h b/fs/dlm/user.h index 1c9686492286..f196091dd7ff 100644 --- a/fs/dlm/user.h +++ b/fs/dlm/user.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2006-2008 Red Hat, Inc. All rights reserved. | 2 | * Copyright (C) 2006-2010 Red Hat, Inc. All rights reserved. |
3 | * | 3 | * |
4 | * This copyrighted material is made available to anyone wishing to use, | 4 | * This copyrighted material is made available to anyone wishing to use, |
5 | * modify, copy, or redistribute it subject to the terms and conditions | 5 | * modify, copy, or redistribute it subject to the terms and conditions |
@@ -9,7 +9,7 @@ | |||
9 | #ifndef __USER_DOT_H__ | 9 | #ifndef __USER_DOT_H__ |
10 | #define __USER_DOT_H__ | 10 | #define __USER_DOT_H__ |
11 | 11 | ||
12 | void dlm_user_add_ast(struct dlm_lkb *lkb, int type, int bastmode); | 12 | void dlm_user_add_ast(struct dlm_lkb *lkb, int type, int mode); |
13 | int dlm_user_init(void); | 13 | int dlm_user_init(void); |
14 | void dlm_user_exit(void); | 14 | void dlm_user_exit(void); |
15 | int dlm_device_deregister(struct dlm_ls *ls); | 15 | int dlm_device_deregister(struct dlm_ls *ls); |