Skip to content

Commit 7fe2b31

Browse files
committed
dlm: fix ordering of bast and cast
When both blocking and completion callbacks are queued for lock, the dlm would always deliver the completion callback (cast) first. In some cases the blocking callback (bast) is queued before the cast, though, and should be delivered first. This patch keeps track of the order in which they were queued and delivers them in that order. This patch also keeps track of the granted mode in the last cast and eliminates the following bast if the bast mode is compatible with the preceding cast mode. This happens when a remotely mastered lock is demoted, e.g. EX->NL, in which case the local node queues a cast immediately after sending the demote message. In this way a cast can be queued for a mode, e.g. NL, that makes an in-transit bast extraneous. Signed-off-by: David Teigland <[email protected]>
1 parent b0483e7 commit 7fe2b31

File tree

6 files changed

+78
-28
lines changed

6 files changed

+78
-28
lines changed

fs/dlm/ast.c

Lines changed: 58 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
*******************************************************************************
33
**
44
** 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.
66
**
77
** This copyrighted material is made available to anyone wishing to use,
88
** modify, copy, or redistribute it subject to the terms and conditions
@@ -33,21 +33,32 @@ void dlm_del_ast(struct dlm_lkb *lkb)
3333
spin_unlock(&ast_queue_lock);
3434
}
3535

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)
3737
{
3838
if (lkb->lkb_flags & DLM_IFL_USER) {
39-
dlm_user_add_ast(lkb, type, bastmode);
39+
dlm_user_add_ast(lkb, type, mode);
4040
return;
4141
}
4242

4343
spin_lock(&ast_queue_lock);
4444
if (!(lkb->lkb_ast_type & (AST_COMP | AST_BAST))) {
4545
kref_get(&lkb->lkb_ref);
4646
list_add_tail(&lkb->lkb_astqueue, &ast_queue);
47+
lkb->lkb_ast_first = type;
4748
}
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+
4857
lkb->lkb_ast_type |= type;
49-
if (bastmode)
50-
lkb->lkb_bastmode = bastmode;
58+
if (type == AST_BAST)
59+
lkb->lkb_bastmode = mode;
60+
else
61+
lkb->lkb_castmode = mode;
5162
spin_unlock(&ast_queue_lock);
5263

5364
set_bit(WAKE_ASTS, &astd_wakeflags);
@@ -59,9 +70,9 @@ static void process_asts(void)
5970
struct dlm_ls *ls = NULL;
6071
struct dlm_rsb *r = NULL;
6172
struct dlm_lkb *lkb;
62-
void (*cast) (void *astparam);
63-
void (*bast) (void *astparam, int mode);
64-
int type = 0, bastmode;
73+
void (*castfn) (void *astparam);
74+
void (*bastfn) (void *astparam, int mode);
75+
int type, first, bastmode, castmode, do_bast, do_cast, last_castmode;
6576

6677
repeat:
6778
spin_lock(&ast_queue_lock);
@@ -75,17 +86,48 @@ static void process_asts(void)
7586
list_del(&lkb->lkb_astqueue);
7687
type = lkb->lkb_ast_type;
7788
lkb->lkb_ast_type = 0;
89+
first = lkb->lkb_ast_first;
90+
lkb->lkb_ast_first = 0;
7891
bastmode = lkb->lkb_bastmode;
79-
92+
castmode = lkb->lkb_castmode;
93+
castfn = lkb->lkb_astfn;
94+
bastfn = lkb->lkb_bastfn;
8095
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);
8696

87-
if ((type & AST_BAST) && bast)
88-
bast(lkb->lkb_astparam, bastmode);
97+
do_cast = (type & AST_COMP) && castfn;
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;
89131

90132
/* this removes the reference added by dlm_add_ast
91133
and may result in the lkb being freed */

fs/dlm/ast.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/******************************************************************************
22
*******************************************************************************
33
**
4-
** Copyright (C) 2005-2008 Red Hat, Inc. All rights reserved.
4+
** Copyright (C) 2005-2010 Red Hat, Inc. All rights reserved.
55
**
66
** This copyrighted material is made available to anyone wishing to use,
77
** modify, copy, or redistribute it subject to the terms and conditions
@@ -13,7 +13,7 @@
1313
#ifndef __ASTD_DOT_H__
1414
#define __ASTD_DOT_H__
1515

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);
1717
void dlm_del_ast(struct dlm_lkb *lkb);
1818

1919
void dlm_astd_wake(void);

fs/dlm/dlm_internal.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
*******************************************************************************
33
**
44
** 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.
66
**
77
** This copyrighted material is made available to anyone wishing to use,
88
** modify, copy, or redistribute it subject to the terms and conditions
@@ -232,11 +232,17 @@ struct dlm_lkb {
232232
int8_t lkb_status; /* granted, waiting, convert */
233233
int8_t lkb_rqmode; /* requested lock mode */
234234
int8_t lkb_grmode; /* granted lock mode */
235-
int8_t lkb_bastmode; /* requested mode */
236235
int8_t lkb_highbast; /* highest mode bast sent for */
236+
237237
int8_t lkb_wait_type; /* type of reply waiting for */
238238
int8_t lkb_wait_count;
239239
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 */
240246

241247
struct list_head lkb_idtbl_list; /* lockspace lkbtbl */
242248
struct list_head lkb_statequeue; /* rsb g/c/w list */

fs/dlm/lock.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/******************************************************************************
22
*******************************************************************************
33
**
4-
** Copyright (C) 2005-2008 Red Hat, Inc. All rights reserved.
4+
** Copyright (C) 2005-2010 Red Hat, Inc. All rights reserved.
55
**
66
** This copyrighted material is made available to anyone wishing to use,
77
** 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)
307307
lkb->lkb_lksb->sb_status = rv;
308308
lkb->lkb_lksb->sb_flags = lkb->lkb_sbflags;
309309

310-
dlm_add_ast(lkb, AST_COMP, 0);
310+
dlm_add_ast(lkb, AST_COMP, lkb->lkb_grmode);
311311
}
312312

313313
static inline void queue_cast_overlap(struct dlm_rsb *r, struct dlm_lkb *lkb)

fs/dlm/user.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2006-2009 Red Hat, Inc. All rights reserved.
2+
* Copyright (C) 2006-2010 Red Hat, Inc. All rights reserved.
33
*
44
* This copyrighted material is made available to anyone wishing to use,
55
* 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)
173173
/* we could possibly check if the cancel of an orphan has resulted in the lkb
174174
being removed and then remove that lkb from the orphans list and free it */
175175

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)
177177
{
178178
struct dlm_ls *ls;
179179
struct dlm_user_args *ua;
@@ -206,8 +206,10 @@ void dlm_user_add_ast(struct dlm_lkb *lkb, int type, int bastmode)
206206

207207
ast_type = lkb->lkb_ast_type;
208208
lkb->lkb_ast_type |= type;
209-
if (bastmode)
210-
lkb->lkb_bastmode = bastmode;
209+
if (type == AST_BAST)
210+
lkb->lkb_bastmode = mode;
211+
else
212+
lkb->lkb_castmode = mode;
211213

212214
if (!ast_type) {
213215
kref_get(&lkb->lkb_ref);

fs/dlm/user.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2006-2008 Red Hat, Inc. All rights reserved.
2+
* Copyright (C) 2006-2010 Red Hat, Inc. All rights reserved.
33
*
44
* This copyrighted material is made available to anyone wishing to use,
55
* modify, copy, or redistribute it subject to the terms and conditions
@@ -9,7 +9,7 @@
99
#ifndef __USER_DOT_H__
1010
#define __USER_DOT_H__
1111

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);
1313
int dlm_user_init(void);
1414
void dlm_user_exit(void);
1515
int dlm_device_deregister(struct dlm_ls *ls);

0 commit comments

Comments
 (0)