aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Teigland <teigland@redhat.com>2008-12-09 12:55:46 -0500
committerDavid Teigland <teigland@redhat.com>2008-12-23 11:16:46 -0500
commitfd22a51bcc0b7b76fc729b02316214fd979f9fe1 (patch)
treee23326bb9df7cf0ee76b3b6b61c82364ff0aed78
parent03339696314fffb95dafb349b84243358e945ce6 (diff)
dlm: improve how bast mode handling
The lkb bastmode value is set in the context of processing the lock, and read by the dlm_astd thread. Because it's accessed in these two separate contexts, the writing/reading ought to be done under a lock. This is simple to do by setting it and reading it when the lkb is added to and removed from dlm_astd's callback list which is properly locked. Signed-off-by: David Teigland <teigland@redhat.com>
-rw-r--r--fs/dlm/ast.c14
-rw-r--r--fs/dlm/ast.h4
-rw-r--r--fs/dlm/lock.c8
-rw-r--r--fs/dlm/user.c4
-rw-r--r--fs/dlm/user.h2
5 files changed, 17 insertions, 15 deletions
diff --git a/fs/dlm/ast.c b/fs/dlm/ast.c
index 09b167df790e..fbe840d09493 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,7 +61,7 @@ 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, found, bastmode;
63 65
64 for (;;) { 66 for (;;) {
65 found = 0; 67 found = 0;
@@ -74,6 +76,7 @@ static void process_asts(void)
74 list_del(&lkb->lkb_astqueue); 76 list_del(&lkb->lkb_astqueue);
75 type = lkb->lkb_ast_type; 77 type = lkb->lkb_ast_type;
76 lkb->lkb_ast_type = 0; 78 lkb->lkb_ast_type = 0;
79 bastmode = lkb->lkb_bastmode;
77 found = 1; 80 found = 1;
78 break; 81 break;
79 } 82 }
@@ -84,13 +87,12 @@ static void process_asts(void)
84 87
85 cast = lkb->lkb_astfn; 88 cast = lkb->lkb_astfn;
86 bast = lkb->lkb_bastfn; 89 bast = lkb->lkb_bastfn;
87 bmode = lkb->lkb_bastmode;
88 90
89 if ((type & AST_COMP) && cast) 91 if ((type & AST_COMP) && cast)
90 cast(lkb->lkb_astparam); 92 cast(lkb->lkb_astparam);
91 93
92 if ((type & AST_BAST) && bast) 94 if ((type & AST_BAST) && bast)
93 bast(lkb->lkb_astparam, bmode); 95 bast(lkb->lkb_astparam, bastmode);
94 96
95 /* this removes the reference added by dlm_add_ast 97 /* this removes the reference added by dlm_add_ast
96 and may result in the lkb being freed */ 98 and may result in the lkb being freed */
diff --git a/fs/dlm/ast.h b/fs/dlm/ast.h
index 6ee276c74c52..1b5fc5f428fd 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 Red Hat, Inc. All rights reserved. 4** Copyright (C) 2005-2008 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
16void dlm_add_ast(struct dlm_lkb *lkb, int type); 16void dlm_add_ast(struct dlm_lkb *lkb, int type, int bastmode);
17void dlm_del_ast(struct dlm_lkb *lkb); 17void dlm_del_ast(struct dlm_lkb *lkb);
18 18
19void dlm_astd_wake(void); 19void dlm_astd_wake(void);
diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c
index 724ddac91538..7b758dadbdd6 100644
--- a/fs/dlm/lock.c
+++ b/fs/dlm/lock.c
@@ -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); 310 dlm_add_ast(lkb, AST_COMP, 0);
311} 311}
312 312
313static inline void queue_cast_overlap(struct dlm_rsb *r, struct dlm_lkb *lkb) 313static inline void queue_cast_overlap(struct dlm_rsb *r, struct dlm_lkb *lkb)
@@ -320,10 +320,8 @@ static void queue_bast(struct dlm_rsb *r, struct dlm_lkb *lkb, int rqmode)
320{ 320{
321 if (is_master_copy(lkb)) 321 if (is_master_copy(lkb))
322 send_bast(r, lkb, rqmode); 322 send_bast(r, lkb, rqmode);
323 else { 323 else
324 lkb->lkb_bastmode = rqmode; 324 dlm_add_ast(lkb, AST_BAST, rqmode);
325 dlm_add_ast(lkb, AST_BAST);
326 }
327} 325}
328 326
329/* 327/*
diff --git a/fs/dlm/user.c b/fs/dlm/user.c
index b3832c67194a..065149e84f42 100644
--- a/fs/dlm/user.c
+++ b/fs/dlm/user.c
@@ -175,7 +175,7 @@ static int lkb_is_endoflife(struct dlm_lkb *lkb, int sb_status, int type)
175/* we could possibly check if the cancel of an orphan has resulted in the lkb 175/* we could possibly check if the cancel of an orphan has resulted in the lkb
176 being removed and then remove that lkb from the orphans list and free it */ 176 being removed and then remove that lkb from the orphans list and free it */
177 177
178void dlm_user_add_ast(struct dlm_lkb *lkb, int type) 178void dlm_user_add_ast(struct dlm_lkb *lkb, int type, int bastmode)
179{ 179{
180 struct dlm_ls *ls; 180 struct dlm_ls *ls;
181 struct dlm_user_args *ua; 181 struct dlm_user_args *ua;
@@ -208,6 +208,8 @@ void dlm_user_add_ast(struct dlm_lkb *lkb, int type)
208 208
209 ast_type = lkb->lkb_ast_type; 209 ast_type = lkb->lkb_ast_type;
210 lkb->lkb_ast_type |= type; 210 lkb->lkb_ast_type |= type;
211 if (bastmode)
212 lkb->lkb_bastmode = bastmode;
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 35eb6a13d616..1c9686492286 100644
--- a/fs/dlm/user.h
+++ b/fs/dlm/user.h
@@ -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
12void dlm_user_add_ast(struct dlm_lkb *lkb, int type); 12void dlm_user_add_ast(struct dlm_lkb *lkb, int type, int bastmode);
13int dlm_user_init(void); 13int dlm_user_init(void);
14void dlm_user_exit(void); 14void dlm_user_exit(void);
15int dlm_device_deregister(struct dlm_ls *ls); 15int dlm_device_deregister(struct dlm_ls *ls);