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>
This commit is contained in:
14
fs/dlm/ast.c
14
fs/dlm/ast.c
@@ -2,7 +2,7 @@
|
|||||||
*******************************************************************************
|
*******************************************************************************
|
||||||
**
|
**
|
||||||
** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
|
** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
|
||||||
** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
|
** Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved.
|
||||||
**
|
**
|
||||||
** This copyrighted material is made available to anyone wishing to use,
|
** This copyrighted material is made available to anyone wishing to use,
|
||||||
** modify, copy, or redistribute it subject to the terms and conditions
|
** modify, copy, or redistribute it subject to the terms and conditions
|
||||||
@@ -33,10 +33,10 @@ void dlm_del_ast(struct dlm_lkb *lkb)
|
|||||||
spin_unlock(&ast_queue_lock);
|
spin_unlock(&ast_queue_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dlm_add_ast(struct dlm_lkb *lkb, int type)
|
void dlm_add_ast(struct dlm_lkb *lkb, int type, int bastmode)
|
||||||
{
|
{
|
||||||
if (lkb->lkb_flags & DLM_IFL_USER) {
|
if (lkb->lkb_flags & DLM_IFL_USER) {
|
||||||
dlm_user_add_ast(lkb, type);
|
dlm_user_add_ast(lkb, type, bastmode);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,6 +46,8 @@ void dlm_add_ast(struct dlm_lkb *lkb, int type)
|
|||||||
list_add_tail(&lkb->lkb_astqueue, &ast_queue);
|
list_add_tail(&lkb->lkb_astqueue, &ast_queue);
|
||||||
}
|
}
|
||||||
lkb->lkb_ast_type |= type;
|
lkb->lkb_ast_type |= type;
|
||||||
|
if (bastmode)
|
||||||
|
lkb->lkb_bastmode = bastmode;
|
||||||
spin_unlock(&ast_queue_lock);
|
spin_unlock(&ast_queue_lock);
|
||||||
|
|
||||||
set_bit(WAKE_ASTS, &astd_wakeflags);
|
set_bit(WAKE_ASTS, &astd_wakeflags);
|
||||||
@@ -59,7 +61,7 @@ static void process_asts(void)
|
|||||||
struct dlm_lkb *lkb;
|
struct dlm_lkb *lkb;
|
||||||
void (*cast) (void *astparam);
|
void (*cast) (void *astparam);
|
||||||
void (*bast) (void *astparam, int mode);
|
void (*bast) (void *astparam, int mode);
|
||||||
int type = 0, found, bmode;
|
int type = 0, found, bastmode;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
found = 0;
|
found = 0;
|
||||||
@@ -74,6 +76,7 @@ static void process_asts(void)
|
|||||||
list_del(&lkb->lkb_astqueue);
|
list_del(&lkb->lkb_astqueue);
|
||||||
type = lkb->lkb_ast_type;
|
type = lkb->lkb_ast_type;
|
||||||
lkb->lkb_ast_type = 0;
|
lkb->lkb_ast_type = 0;
|
||||||
|
bastmode = lkb->lkb_bastmode;
|
||||||
found = 1;
|
found = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -84,13 +87,12 @@ static void process_asts(void)
|
|||||||
|
|
||||||
cast = lkb->lkb_astfn;
|
cast = lkb->lkb_astfn;
|
||||||
bast = lkb->lkb_bastfn;
|
bast = lkb->lkb_bastfn;
|
||||||
bmode = lkb->lkb_bastmode;
|
|
||||||
|
|
||||||
if ((type & AST_COMP) && cast)
|
if ((type & AST_COMP) && cast)
|
||||||
cast(lkb->lkb_astparam);
|
cast(lkb->lkb_astparam);
|
||||||
|
|
||||||
if ((type & AST_BAST) && bast)
|
if ((type & AST_BAST) && bast)
|
||||||
bast(lkb->lkb_astparam, bmode);
|
bast(lkb->lkb_astparam, bastmode);
|
||||||
|
|
||||||
/* this removes the reference added by dlm_add_ast
|
/* this removes the reference added by dlm_add_ast
|
||||||
and may result in the lkb being freed */
|
and may result in the lkb being freed */
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
*******************************************************************************
|
*******************************************************************************
|
||||||
**
|
**
|
||||||
** Copyright (C) 2005 Red Hat, Inc. All rights reserved.
|
** Copyright (C) 2005-2008 Red Hat, Inc. All rights reserved.
|
||||||
**
|
**
|
||||||
** This copyrighted material is made available to anyone wishing to use,
|
** This copyrighted material is made available to anyone wishing to use,
|
||||||
** modify, copy, or redistribute it subject to the terms and conditions
|
** modify, copy, or redistribute it subject to the terms and conditions
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
#ifndef __ASTD_DOT_H__
|
#ifndef __ASTD_DOT_H__
|
||||||
#define __ASTD_DOT_H__
|
#define __ASTD_DOT_H__
|
||||||
|
|
||||||
void dlm_add_ast(struct dlm_lkb *lkb, int type);
|
void dlm_add_ast(struct dlm_lkb *lkb, int type, int bastmode);
|
||||||
void dlm_del_ast(struct dlm_lkb *lkb);
|
void dlm_del_ast(struct dlm_lkb *lkb);
|
||||||
|
|
||||||
void dlm_astd_wake(void);
|
void dlm_astd_wake(void);
|
||||||
|
@@ -307,7 +307,7 @@ static void queue_cast(struct dlm_rsb *r, struct dlm_lkb *lkb, int rv)
|
|||||||
lkb->lkb_lksb->sb_status = rv;
|
lkb->lkb_lksb->sb_status = rv;
|
||||||
lkb->lkb_lksb->sb_flags = lkb->lkb_sbflags;
|
lkb->lkb_lksb->sb_flags = lkb->lkb_sbflags;
|
||||||
|
|
||||||
dlm_add_ast(lkb, AST_COMP);
|
dlm_add_ast(lkb, AST_COMP, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void queue_cast_overlap(struct dlm_rsb *r, struct dlm_lkb *lkb)
|
static 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)
|
|||||||
{
|
{
|
||||||
if (is_master_copy(lkb))
|
if (is_master_copy(lkb))
|
||||||
send_bast(r, lkb, rqmode);
|
send_bast(r, lkb, rqmode);
|
||||||
else {
|
else
|
||||||
lkb->lkb_bastmode = rqmode;
|
dlm_add_ast(lkb, AST_BAST, rqmode);
|
||||||
dlm_add_ast(lkb, AST_BAST);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -175,7 +175,7 @@ static int lkb_is_endoflife(struct dlm_lkb *lkb, int sb_status, int type)
|
|||||||
/* we could possibly check if the cancel of an orphan has resulted in the lkb
|
/* we could possibly check if the cancel of an orphan has resulted in the lkb
|
||||||
being removed and then remove that lkb from the orphans list and free it */
|
being removed and then remove that lkb from the orphans list and free it */
|
||||||
|
|
||||||
void dlm_user_add_ast(struct dlm_lkb *lkb, int type)
|
void dlm_user_add_ast(struct dlm_lkb *lkb, int type, int bastmode)
|
||||||
{
|
{
|
||||||
struct dlm_ls *ls;
|
struct dlm_ls *ls;
|
||||||
struct dlm_user_args *ua;
|
struct dlm_user_args *ua;
|
||||||
@@ -208,6 +208,8 @@ void dlm_user_add_ast(struct dlm_lkb *lkb, int type)
|
|||||||
|
|
||||||
ast_type = lkb->lkb_ast_type;
|
ast_type = lkb->lkb_ast_type;
|
||||||
lkb->lkb_ast_type |= type;
|
lkb->lkb_ast_type |= type;
|
||||||
|
if (bastmode)
|
||||||
|
lkb->lkb_bastmode = bastmode;
|
||||||
|
|
||||||
if (!ast_type) {
|
if (!ast_type) {
|
||||||
kref_get(&lkb->lkb_ref);
|
kref_get(&lkb->lkb_ref);
|
||||||
|
@@ -9,7 +9,7 @@
|
|||||||
#ifndef __USER_DOT_H__
|
#ifndef __USER_DOT_H__
|
||||||
#define __USER_DOT_H__
|
#define __USER_DOT_H__
|
||||||
|
|
||||||
void dlm_user_add_ast(struct dlm_lkb *lkb, int type);
|
void dlm_user_add_ast(struct dlm_lkb *lkb, int type, int bastmode);
|
||||||
int dlm_user_init(void);
|
int dlm_user_init(void);
|
||||||
void dlm_user_exit(void);
|
void dlm_user_exit(void);
|
||||||
int dlm_device_deregister(struct dlm_ls *ls);
|
int dlm_device_deregister(struct dlm_ls *ls);
|
||||||
|
Reference in New Issue
Block a user