Skip to content

Commit 6144464

Browse files
author
Andreas Gruenbacher
committed
gfs2: Clean up function may_grant
Pass the first current glock holder into function may_grant and deobfuscate the logic there. While at it, switch from BUG_ON to GLOCK_BUG_ON in may_grant. To make that build cleanly, de-constify the may_grant arguments. We're now using function find_first_holder in do_promote, so move the function's definition above do_promote. Signed-off-by: Andreas Gruenbacher <[email protected]>
1 parent 2eb7509 commit 6144464

File tree

1 file changed

+69
-50
lines changed

1 file changed

+69
-50
lines changed

fs/gfs2/glock.c

Lines changed: 69 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -301,46 +301,59 @@ void gfs2_glock_put(struct gfs2_glock *gl)
301301
}
302302

303303
/**
304-
* may_grant - check if its ok to grant a new lock
304+
* may_grant - check if it's ok to grant a new lock
305305
* @gl: The glock
306+
* @current_gh: One of the current holders of @gl
306307
* @gh: The lock request which we wish to grant
307308
*
308-
* Returns: true if its ok to grant the lock
309+
* With our current compatibility rules, if a glock has one or more active
310+
* holders (HIF_HOLDER flag set), any of those holders can be passed in as
311+
* @current_gh; they are all the same as far as compatibility with the new @gh
312+
* goes.
313+
*
314+
* Returns true if it's ok to grant the lock.
309315
*/
310316

311-
static inline int may_grant(const struct gfs2_glock *gl, const struct gfs2_holder *gh)
312-
{
313-
const struct gfs2_holder *gh_head = list_first_entry(&gl->gl_holders, const struct gfs2_holder, gh_list);
317+
static inline bool may_grant(struct gfs2_glock *gl,
318+
struct gfs2_holder *current_gh,
319+
struct gfs2_holder *gh)
320+
{
321+
if (current_gh) {
322+
GLOCK_BUG_ON(gl, !test_bit(HIF_HOLDER, &current_gh->gh_iflags));
323+
324+
switch(current_gh->gh_state) {
325+
case LM_ST_EXCLUSIVE:
326+
/*
327+
* Here we make a special exception to grant holders
328+
* who agree to share the EX lock with other holders
329+
* who also have the bit set. If the original holder
330+
* has the LM_FLAG_NODE_SCOPE bit set, we grant more
331+
* holders with the bit set.
332+
*/
333+
return gh->gh_state == LM_ST_EXCLUSIVE &&
334+
(current_gh->gh_flags & LM_FLAG_NODE_SCOPE) &&
335+
(gh->gh_flags & LM_FLAG_NODE_SCOPE);
314336

315-
if (gh != gh_head) {
316-
/**
317-
* Here we make a special exception to grant holders who agree
318-
* to share the EX lock with other holders who also have the
319-
* bit set. If the original holder has the LM_FLAG_NODE_SCOPE bit
320-
* is set, we grant more holders with the bit set.
321-
*/
322-
if (gh_head->gh_state == LM_ST_EXCLUSIVE &&
323-
(gh_head->gh_flags & LM_FLAG_NODE_SCOPE) &&
324-
gh->gh_state == LM_ST_EXCLUSIVE &&
325-
(gh->gh_flags & LM_FLAG_NODE_SCOPE))
326-
return 1;
327-
if ((gh->gh_state == LM_ST_EXCLUSIVE ||
328-
gh_head->gh_state == LM_ST_EXCLUSIVE))
329-
return 0;
337+
case LM_ST_SHARED:
338+
case LM_ST_DEFERRED:
339+
return gh->gh_state == current_gh->gh_state;
340+
341+
default:
342+
return false;
343+
}
330344
}
345+
331346
if (gl->gl_state == gh->gh_state)
332-
return 1;
347+
return true;
333348
if (gh->gh_flags & GL_EXACT)
334-
return 0;
349+
return false;
335350
if (gl->gl_state == LM_ST_EXCLUSIVE) {
336-
if (gh->gh_state == LM_ST_SHARED && gh_head->gh_state == LM_ST_SHARED)
337-
return 1;
338-
if (gh->gh_state == LM_ST_DEFERRED && gh_head->gh_state == LM_ST_DEFERRED)
339-
return 1;
351+
return gh->gh_state == LM_ST_SHARED ||
352+
gh->gh_state == LM_ST_DEFERRED;
340353
}
341-
if (gl->gl_state != LM_ST_UNLOCKED && (gh->gh_flags & LM_FLAG_ANY))
342-
return 1;
343-
return 0;
354+
if (gh->gh_flags & LM_FLAG_ANY)
355+
return gl->gl_state != LM_ST_UNLOCKED;
356+
return false;
344357
}
345358

346359
static void gfs2_holder_wake(struct gfs2_holder *gh)
@@ -380,6 +393,24 @@ static void do_error(struct gfs2_glock *gl, const int ret)
380393
}
381394
}
382395

396+
/**
397+
* find_first_holder - find the first "holder" gh
398+
* @gl: the glock
399+
*/
400+
401+
static inline struct gfs2_holder *find_first_holder(const struct gfs2_glock *gl)
402+
{
403+
struct gfs2_holder *gh;
404+
405+
if (!list_empty(&gl->gl_holders)) {
406+
gh = list_first_entry(&gl->gl_holders, struct gfs2_holder,
407+
gh_list);
408+
if (test_bit(HIF_HOLDER, &gh->gh_iflags))
409+
return gh;
410+
}
411+
return NULL;
412+
}
413+
383414
/**
384415
* do_promote - promote as many requests as possible on the current queue
385416
* @gl: The glock
@@ -393,14 +424,15 @@ __releases(&gl->gl_lockref.lock)
393424
__acquires(&gl->gl_lockref.lock)
394425
{
395426
const struct gfs2_glock_operations *glops = gl->gl_ops;
396-
struct gfs2_holder *gh, *tmp;
427+
struct gfs2_holder *gh, *tmp, *first_gh;
397428
int ret;
398429

399430
restart:
431+
first_gh = find_first_holder(gl);
400432
list_for_each_entry_safe(gh, tmp, &gl->gl_holders, gh_list) {
401433
if (test_bit(HIF_HOLDER, &gh->gh_iflags))
402434
continue;
403-
if (may_grant(gl, gh)) {
435+
if (may_grant(gl, first_gh, gh)) {
404436
if (gh->gh_list.prev == &gl->gl_holders &&
405437
glops->go_lock) {
406438
spin_unlock(&gl->gl_lockref.lock);
@@ -722,23 +754,6 @@ __acquires(&gl->gl_lockref.lock)
722754
spin_lock(&gl->gl_lockref.lock);
723755
}
724756

725-
/**
726-
* find_first_holder - find the first "holder" gh
727-
* @gl: the glock
728-
*/
729-
730-
static inline struct gfs2_holder *find_first_holder(const struct gfs2_glock *gl)
731-
{
732-
struct gfs2_holder *gh;
733-
734-
if (!list_empty(&gl->gl_holders)) {
735-
gh = list_first_entry(&gl->gl_holders, struct gfs2_holder, gh_list);
736-
if (test_bit(HIF_HOLDER, &gh->gh_iflags))
737-
return gh;
738-
}
739-
return NULL;
740-
}
741-
742757
/**
743758
* run_queue - do all outstanding tasks related to a glock
744759
* @gl: The glock in question
@@ -1354,8 +1369,12 @@ __acquires(&gl->gl_lockref.lock)
13541369
GLOCK_BUG_ON(gl, true);
13551370

13561371
if (gh->gh_flags & (LM_FLAG_TRY | LM_FLAG_TRY_1CB)) {
1357-
if (test_bit(GLF_LOCK, &gl->gl_flags))
1358-
try_futile = !may_grant(gl, gh);
1372+
if (test_bit(GLF_LOCK, &gl->gl_flags)) {
1373+
struct gfs2_holder *first_gh;
1374+
1375+
first_gh = find_first_holder(gl);
1376+
try_futile = !may_grant(gl, first_gh, gh);
1377+
}
13591378
if (test_bit(GLF_INVALIDATE_IN_PROGRESS, &gl->gl_flags))
13601379
goto fail;
13611380
}

0 commit comments

Comments
 (0)