Skip to content

Commit

Permalink
GFS2: Fix locking bug in failed shared to exclusive conversion
Browse files Browse the repository at this point in the history
After calling out to the dlm, GFS2 sets the new state of a glock to
gl_target in gdlm_ast().  However, gl_target is not always the lock
state that was requested. If a conversion from shared to exclusive
fails, finish_xmote() will call do_xmote() with LM_ST_UNLOCKED, instead
of gl->gl_target, so that it can reacquire the lock in exlusive the next
time around.  In this case, setting the lock to gl_target in gdlm_ast()
will make GFS2 think that it has the glock in exclusive mode, when
really, it doesn't have the glock locked at all.  This patch adds a new
field to the gfs2_glock structure, gl_req, to track the mode that was
requested.

Signed-off-by: Benjamin Marzinski <[email protected]>
Signed-off-by: Steven Whitehouse <[email protected]>
  • Loading branch information
bmarzins authored and Steven Whitehouse committed Mar 24, 2009
1 parent 229615d commit 02ffad0
Show file tree
Hide file tree
Showing 2 changed files with 5 additions and 3 deletions.
1 change: 1 addition & 0 deletions fs/gfs2/incore.h
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ struct gfs2_glock {
unsigned int gl_target;
unsigned int gl_reply;
unsigned int gl_hash;
unsigned int gl_req;
unsigned int gl_demote_state; /* state requested by remote node */
unsigned long gl_demote_time; /* time of first demote request */
struct list_head gl_holders;
Expand Down
7 changes: 4 additions & 3 deletions fs/gfs2/lock_dlm.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,11 @@ static void gdlm_ast(void *arg)
BUG();
}

ret = gl->gl_target;
ret = gl->gl_req;
if (gl->gl_lksb.sb_flags & DLM_SBF_ALTMODE) {
if (gl->gl_target == LM_ST_SHARED)
if (gl->gl_req == LM_ST_SHARED)
ret = LM_ST_DEFERRED;
else if (gl->gl_target == LM_ST_DEFERRED)
else if (gl->gl_req == LM_ST_DEFERRED)
ret = LM_ST_SHARED;
else
BUG();
Expand Down Expand Up @@ -147,6 +147,7 @@ static unsigned int gdlm_lock(struct gfs2_glock *gl,
int req;
u32 lkf;

gl->gl_req = req_state;
req = make_mode(req_state);
lkf = make_flags(gl->gl_lksb.sb_lkid, flags, req);

Expand Down

0 comments on commit 02ffad0

Please sign in to comment.