Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 89534
b: refs/heads/master
c: 58e9fee
h: refs/heads/master
v: v3
  • Loading branch information
Benjamin Marzinski authored and Steven Whitehouse committed Mar 31, 2008
1 parent 52e585d commit a470bda
Show file tree
Hide file tree
Showing 7 changed files with 45 additions and 18 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: f5a8cd020173c455705fc0095b7d299da6f8f87b
refs/heads/master: 58e9fee13e579df44922172dbe3c9e3ba3edf7a3
35 changes: 21 additions & 14 deletions trunk/fs/gfs2/glock.c
Original file line number Diff line number Diff line change
Expand Up @@ -764,16 +764,22 @@ static void state_change(struct gfs2_glock *gl, unsigned int new_state)
static void drop_bh(struct gfs2_glock *gl, unsigned int ret)
{
struct gfs2_sbd *sdp = gl->gl_sbd;
const struct gfs2_glock_operations *glops = gl->gl_ops;
struct gfs2_holder *gh = gl->gl_req_gh;

gfs2_assert_warn(sdp, test_bit(GLF_LOCK, &gl->gl_flags));
gfs2_assert_warn(sdp, list_empty(&gl->gl_holders));
gfs2_assert_warn(sdp, !ret);

state_change(gl, LM_ST_UNLOCKED);

if (glops->go_inval)
glops->go_inval(gl, DIO_METADATA);
if (test_and_clear_bit(GLF_CONV_DEADLK, &gl->gl_flags)) {
spin_lock(&gl->gl_spin);
gh->gh_error = 0;
spin_unlock(&gl->gl_spin);
gfs2_glock_xmote_th(gl, gl->gl_req_gh);
gfs2_glock_put(gl);
return;
}

spin_lock(&gl->gl_spin);
gfs2_demote_wake(gl);
Expand All @@ -794,7 +800,6 @@ static void xmote_bh(struct gfs2_glock *gl, unsigned int ret)
struct gfs2_sbd *sdp = gl->gl_sbd;
const struct gfs2_glock_operations *glops = gl->gl_ops;
struct gfs2_holder *gh = gl->gl_req_gh;
int prev_state = gl->gl_state;
int op_done = 1;

if (!gh && (ret & LM_OUT_ST_MASK) == LM_ST_UNLOCKED) {
Expand All @@ -808,16 +813,6 @@ static void xmote_bh(struct gfs2_glock *gl, unsigned int ret)

state_change(gl, ret & LM_OUT_ST_MASK);

if (prev_state != LM_ST_UNLOCKED && !(ret & LM_OUT_CACHEABLE)) {
if (glops->go_inval)
glops->go_inval(gl, DIO_METADATA);
} else if (gl->gl_state == LM_ST_DEFERRED) {
/* We might not want to do this here.
Look at moving to the inode glops. */
if (glops->go_inval)
glops->go_inval(gl, 0);
}

/* Deal with each possible exit condition */

if (!gh) {
Expand All @@ -837,6 +832,14 @@ static void xmote_bh(struct gfs2_glock *gl, unsigned int ret)
}
} else {
spin_lock(&gl->gl_spin);
if (ret & LM_OUT_CONV_DEADLK) {
gh->gh_error = 0;
set_bit(GLF_CONV_DEADLK, &gl->gl_flags);
spin_unlock(&gl->gl_spin);
gfs2_glock_drop_th(gl);
gfs2_glock_put(gl);
return;
}
list_del_init(&gh->gh_list);
gh->gh_error = -EIO;
if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags)))
Expand Down Expand Up @@ -910,6 +913,8 @@ static void gfs2_glock_xmote_th(struct gfs2_glock *gl, struct gfs2_holder *gh)

if (glops->go_xmote_th)
glops->go_xmote_th(gl);
if (state == LM_ST_DEFERRED && glops->go_inval)
glops->go_inval(gl, DIO_METADATA);

gfs2_assert_warn(sdp, test_bit(GLF_LOCK, &gl->gl_flags));
gfs2_assert_warn(sdp, list_empty(&gl->gl_holders));
Expand Down Expand Up @@ -952,6 +957,8 @@ static void gfs2_glock_drop_th(struct gfs2_glock *gl)

if (glops->go_xmote_th)
glops->go_xmote_th(gl);
if (glops->go_inval)
glops->go_inval(gl, DIO_METADATA);

gfs2_assert_warn(sdp, test_bit(GLF_LOCK, &gl->gl_flags));
gfs2_assert_warn(sdp, list_empty(&gl->gl_holders));
Expand Down
1 change: 1 addition & 0 deletions trunk/fs/gfs2/incore.h
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ enum {
GLF_DEMOTE_IN_PROGRESS = 6,
GLF_LFLUSH = 7,
GLF_WAITERS2 = 8,
GLF_CONV_DEADLK = 9,
};

struct gfs2_glock {
Expand Down
3 changes: 2 additions & 1 deletion trunk/fs/gfs2/locking/dlm/lock.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,8 @@ static inline unsigned int make_flags(struct gdlm_lock *lp,

/* Conversion deadlock avoidance by DLM */

if (!test_bit(LFL_FORCE_PROMOTE, &lp->flags) &&
if (!(lp->ls->fsflags & LM_MFLAG_CONV_NODROP) &&
!test_bit(LFL_FORCE_PROMOTE, &lp->flags) &&
!(lkf & DLM_LKF_NOQUEUE) &&
cur > DLM_LOCK_NL && req > DLM_LOCK_NL && cur != req)
lkf |= DLM_LKF_CONVDEADLK;
Expand Down
10 changes: 9 additions & 1 deletion trunk/fs/gfs2/locking/dlm/thread.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,15 @@ static void process_complete(struct gdlm_lock *lp)
lp->lksb.sb_status, lp->lockname.ln_type,
(unsigned long long)lp->lockname.ln_number,
lp->flags);
return;
if (lp->lksb.sb_status == -EDEADLOCK &&
lp->ls->fsflags & LM_MFLAG_CONV_NODROP) {
lp->req = lp->cur;
acb.lc_ret |= LM_OUT_CONV_DEADLK;
if (lp->cur == DLM_LOCK_IV)
lp->lksb.sb_lkid = 0;
goto out;
} else
return;
}

/*
Expand Down
2 changes: 1 addition & 1 deletion trunk/fs/gfs2/ops_fstype.c
Original file line number Diff line number Diff line change
Expand Up @@ -723,7 +723,7 @@ static int gfs2_lm_mount(struct gfs2_sbd *sdp, int silent)
{
char *proto = sdp->sd_proto_name;
char *table = sdp->sd_table_name;
int flags = 0;
int flags = LM_MFLAG_CONV_NODROP;
int error;

if (sdp->sd_args.ar_spectator)
Expand Down
10 changes: 10 additions & 0 deletions trunk/include/linux/lm_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,15 @@ typedef void (*lm_callback_t) (void *ptr, unsigned int type, void *data);
* modify the filesystem. The lock module shouldn't assign a journal to the FS
* mount. It shouldn't send recovery callbacks to the FS mount. If the node
* dies or withdraws, all locks can be wiped immediately.
*
* LM_MFLAG_CONV_NODROP
* Do not allow the dlm to internally resolve conversion deadlocks by demoting
* the lock to unlocked and then reacquiring it in the requested mode. Instead,
* it should cancel the request and return LM_OUT_CONV_DEADLK.
*/

#define LM_MFLAG_SPECTATOR 0x00000001
#define LM_MFLAG_CONV_NODROP 0x00000002

/*
* lm_lockstruct flags
Expand Down Expand Up @@ -110,13 +116,17 @@ typedef void (*lm_callback_t) (void *ptr, unsigned int type, void *data);
*
* LM_OUT_ASYNC
* The result of the request will be returned in an LM_CB_ASYNC callback.
*
* LM_OUT_CONV_DEADLK
* The lock request was canceled do to a conversion deadlock.
*/

#define LM_OUT_ST_MASK 0x00000003
#define LM_OUT_CACHEABLE 0x00000004
#define LM_OUT_CANCELED 0x00000008
#define LM_OUT_ASYNC 0x00000080
#define LM_OUT_ERROR 0x00000100
#define LM_OUT_CONV_DEADLK 0x00000200

/*
* lm_callback_t types
Expand Down

0 comments on commit a470bda

Please sign in to comment.