Skip to content

Commit fd70ab7

Browse files
author
Andreas Gruenbacher
committed
gfs2: Further sanitize lock_dlm.c
The gl_req field and GLF_BLOCKING flag are only relevant to gdlm_lock(), its callback gdlm_ast(), and their helpers, so set and clear them inside lock_dlm.c. Also, the LM_FLAG_ANY flag is relevant to gdlm_lock(), but do_xmote() doesn't pass that flag down to gdlm_lock() as it should. Fix that by passing down all the flags. In addition, document the effect of the LM_FLAG_ANY flag on locks held in EX mode locally. Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> Reviewed-by: Andrew Price <anprice@redhat.com>
1 parent cd71804 commit fd70ab7

3 files changed

Lines changed: 22 additions & 14 deletions

File tree

fs/gfs2/glock.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -717,12 +717,6 @@ __acquires(&gl->gl_lockref.lock)
717717
return;
718718
do_error(gl, 0); /* Fail queued try locks */
719719
}
720-
gl->gl_req = target;
721-
set_bit(GLF_BLOCKING, &gl->gl_flags);
722-
if ((gl->gl_req == LM_ST_UNLOCKED) ||
723-
(gl->gl_state == LM_ST_EXCLUSIVE) ||
724-
(lck_flags & (LM_FLAG_TRY|LM_FLAG_TRY_1CB)))
725-
clear_bit(GLF_BLOCKING, &gl->gl_flags);
726720
if (!glops->go_inval && !glops->go_sync)
727721
goto skip_inval;
728722

fs/gfs2/glock.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,10 @@ enum {
6868
* also be granted in SHARED. The preferred state is whichever is compatible
6969
* with other granted locks, or the specified state if no other locks exist.
7070
*
71+
* In addition, when a lock is already held in EX mode locally, a SHARED or
72+
* DEFERRED mode request with the LM_FLAG_ANY flag set will be granted.
73+
* (The LM_FLAG_ANY flag is only use for SHARED mode requests currently.)
74+
*
7175
* LM_FLAG_NODE_SCOPE
7276
* This holder agrees to share the lock within this node. In other words,
7377
* the glock is held in EX mode according to DLM, but local holders on the

fs/gfs2/lock_dlm.c

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ static inline void gfs2_update_stats(struct gfs2_lkstats *s, unsigned index,
5858
/**
5959
* gfs2_update_reply_times - Update locking statistics
6060
* @gl: The glock to update
61+
* @blocking: The operation may have been blocking
6162
*
6263
* This assumes that gl->gl_dstamp has been set earlier.
6364
*
@@ -72,12 +73,12 @@ static inline void gfs2_update_stats(struct gfs2_lkstats *s, unsigned index,
7273
* TRY_1CB flags are set are classified as non-blocking. All
7374
* other DLM requests are counted as (potentially) blocking.
7475
*/
75-
static inline void gfs2_update_reply_times(struct gfs2_glock *gl)
76+
static inline void gfs2_update_reply_times(struct gfs2_glock *gl,
77+
bool blocking)
7678
{
7779
struct gfs2_pcpu_lkstats *lks;
7880
const unsigned gltype = gl->gl_name.ln_type;
79-
unsigned index = test_bit(GLF_BLOCKING, &gl->gl_flags) ?
80-
GFS2_LKS_SRTTB : GFS2_LKS_SRTT;
81+
unsigned index = blocking ? GFS2_LKS_SRTTB : GFS2_LKS_SRTT;
8182
s64 rtt;
8283

8384
preempt_disable();
@@ -119,14 +120,18 @@ static inline void gfs2_update_request_times(struct gfs2_glock *gl)
119120
static void gdlm_ast(void *arg)
120121
{
121122
struct gfs2_glock *gl = arg;
123+
bool blocking;
122124
unsigned ret;
123125

126+
blocking = test_bit(GLF_BLOCKING, &gl->gl_flags);
127+
gfs2_update_reply_times(gl, blocking);
128+
clear_bit(GLF_BLOCKING, &gl->gl_flags);
129+
124130
/* If the glock is dead, we only react to a dlm_unlock() reply. */
125131
if (__lockref_is_dead(&gl->gl_lockref) &&
126132
gl->gl_lksb.sb_status != -DLM_EUNLOCK)
127133
return;
128134

129-
gfs2_update_reply_times(gl);
130135
BUG_ON(gl->gl_lksb.sb_flags & DLM_SBF_DEMOTED);
131136

132137
if ((gl->gl_lksb.sb_flags & DLM_SBF_VALNOTVALID) && gl->gl_lksb.sb_lvbptr)
@@ -241,7 +246,7 @@ static bool down_conversion(int cur, int req)
241246
}
242247

243248
static u32 make_flags(struct gfs2_glock *gl, const unsigned int gfs_flags,
244-
const int cur, const int req)
249+
const int req, bool blocking)
245250
{
246251
u32 lkf = 0;
247252

@@ -274,7 +279,7 @@ static u32 make_flags(struct gfs2_glock *gl, const unsigned int gfs_flags,
274279
* "upward" lock conversions or else DLM will reject the
275280
* request as invalid.
276281
*/
277-
if (!down_conversion(cur, req))
282+
if (blocking)
278283
lkf |= DLM_LKF_QUECVT;
279284
}
280285

@@ -294,14 +299,20 @@ static int gdlm_lock(struct gfs2_glock *gl, unsigned int req_state,
294299
unsigned int flags)
295300
{
296301
struct lm_lockstruct *ls = &gl->gl_name.ln_sbd->sd_lockstruct;
302+
bool blocking;
297303
int cur, req;
298304
u32 lkf;
299305
char strname[GDLM_STRNAME_BYTES] = "";
300306
int error;
301307

308+
gl->gl_req = req_state;
302309
cur = make_mode(gl->gl_name.ln_sbd, gl->gl_state);
303310
req = make_mode(gl->gl_name.ln_sbd, req_state);
304-
lkf = make_flags(gl, flags, cur, req);
311+
blocking = !down_conversion(cur, req) &&
312+
!(flags & (LM_FLAG_TRY|LM_FLAG_TRY_1CB));
313+
lkf = make_flags(gl, flags, req, blocking);
314+
if (blocking)
315+
set_bit(GLF_BLOCKING, &gl->gl_flags);
305316
gfs2_glstats_inc(gl, GFS2_LKS_DCOUNT);
306317
gfs2_sbstats_inc(gl, GFS2_LKS_DCOUNT);
307318
if (test_bit(GLF_INITIAL, &gl->gl_flags)) {
@@ -341,7 +352,6 @@ static void gdlm_put_lock(struct gfs2_glock *gl)
341352
return;
342353
}
343354

344-
clear_bit(GLF_BLOCKING, &gl->gl_flags);
345355
gfs2_glstats_inc(gl, GFS2_LKS_DCOUNT);
346356
gfs2_sbstats_inc(gl, GFS2_LKS_DCOUNT);
347357
gfs2_update_request_times(gl);

0 commit comments

Comments
 (0)