Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 38850
b: refs/heads/master
c: 2426443
h: refs/heads/master
v: v3
  • Loading branch information
Steven Whitehouse committed Sep 12, 2006
1 parent 6ba41cf commit 2d629f6
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 66 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: 94610610f10749c0e17b4d2840ff8a7cb636c413
refs/heads/master: 24264434603cc102d71fb2a1b3b7e282a781f449
95 changes: 31 additions & 64 deletions trunk/fs/gfs2/glock.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <linux/kref.h>
#include <linux/kallsyms.h>
#include <linux/gfs2_ondisk.h>
#include <linux/list.h>
#include <asm/uaccess.h>

#include "gfs2.h"
Expand All @@ -33,12 +34,6 @@
#include "super.h"
#include "util.h"

/* Must be kept in sync with the beginning of struct gfs2_glock */
struct glock_plug {
struct list_head gl_list;
unsigned long gl_flags;
};

struct greedy {
struct gfs2_holder gr_gh;
struct work_struct gr_work;
Expand All @@ -52,6 +47,7 @@ typedef void (*glock_examiner) (struct gfs2_glock * gl);

static int gfs2_dump_lockstate(struct gfs2_sbd *sdp);
static int dump_glock(struct gfs2_glock *gl);
static int dump_inode(struct gfs2_inode *ip);

#define GFS2_GL_HASH_SHIFT 13
#define GFS2_GL_HASH_SIZE (1 << GFS2_GL_HASH_SHIFT)
Expand Down Expand Up @@ -214,7 +210,7 @@ int gfs2_glock_put(struct gfs2_glock *gl)

write_lock(gl_lock_addr(gl->gl_hash));
if (kref_put(&gl->gl_ref, kill_glock)) {
list_del_init(&gl_hash_table[gl->gl_hash].hb_list);
list_del_init(&gl->gl_list);
write_unlock(gl_lock_addr(gl->gl_hash));
BUG_ON(spin_is_locked(&gl->gl_spin));
glock_free(gl);
Expand Down Expand Up @@ -265,8 +261,6 @@ static struct gfs2_glock *search_bucket(unsigned int hash,
struct gfs2_glock *gl;

list_for_each_entry(gl, &gl_hash_table[hash].hb_list, gl_list) {
if (test_bit(GLF_PLUG, &gl->gl_flags))
continue;
if (!lm_name_equal(&gl->gl_name, name))
continue;
if (gl->gl_sbd != sdp)
Expand Down Expand Up @@ -1899,51 +1893,33 @@ void gfs2_reclaim_glock(struct gfs2_sbd *sdp)
static int examine_bucket(glock_examiner examiner, struct gfs2_sbd *sdp,
unsigned int hash)
{
struct glock_plug plug;
struct list_head *tmp;
struct gfs2_glock *gl;
int entries;

/* Add "plug" to end of bucket list, work back up list from there */
memset(&plug.gl_flags, 0, sizeof(unsigned long));
set_bit(GLF_PLUG, &plug.gl_flags);

write_lock(gl_lock_addr(hash));
list_add(&plug.gl_list, &gl_hash_table[hash].hb_list);
write_unlock(gl_lock_addr(hash));

for (;;) {
write_lock(gl_lock_addr(hash));

for (;;) {
tmp = plug.gl_list.next;
struct gfs2_glock *gl, *prev = NULL;
int has_entries = 0;
struct list_head *head = &gl_hash_table[hash].hb_list;

if (tmp == &gl_hash_table[hash].hb_list) {
list_del(&plug.gl_list);
entries = !list_empty(&gl_hash_table[hash].hb_list);
write_unlock(gl_lock_addr(hash));
return entries;
}
gl = list_entry(tmp, struct gfs2_glock, gl_list);

/* Move plug up list */
list_move(&plug.gl_list, &gl->gl_list);

if (test_bit(GLF_PLUG, &gl->gl_flags))
continue;
if (gl->gl_sbd != sdp)
continue;

/* examiner() must glock_put() */
read_lock(gl_lock_addr(hash));
/* Can't use list_for_each_entry - don't want prefetch here */
if (list_empty(head))
goto out;
has_entries = 1;
gl = list_entry(head->next, struct gfs2_glock, gl_list);
while(&gl->gl_list != head) {
if (gl->gl_sbd == sdp) {
gfs2_glock_hold(gl);

break;
read_unlock(gl_lock_addr(hash));
if (prev)
gfs2_glock_put(prev);
prev = gl;
examiner(gl);
read_lock(gl_lock_addr(hash));
}

write_unlock(gl_lock_addr(hash));

examiner(gl);
gl = list_entry(gl->gl_list.next, struct gfs2_glock, gl_list);
}
out:
read_unlock(gl_lock_addr(hash));
if (prev)
gfs2_glock_put(prev);
return has_entries;
}

/**
Expand All @@ -1955,23 +1931,19 @@ static int examine_bucket(glock_examiner examiner, struct gfs2_sbd *sdp,
static void scan_glock(struct gfs2_glock *gl)
{
if (gl->gl_ops == &gfs2_inode_glops)
goto out;
return;

if (gfs2_glmutex_trylock(gl)) {
if (queue_empty(gl, &gl->gl_holders) &&
gl->gl_state != LM_ST_UNLOCKED &&
demote_ok(gl))
gl->gl_state != LM_ST_UNLOCKED && demote_ok(gl))
goto out_schedule;
gfs2_glmutex_unlock(gl);
}
out:
gfs2_glock_put(gl);
return;

out_schedule:
gfs2_glmutex_unlock(gl);
gfs2_glock_schedule_for_reclaim(gl);
gfs2_glock_put(gl);
}

/**
Expand Down Expand Up @@ -2014,11 +1986,8 @@ static void clear_glock(struct gfs2_glock *gl)
if (queue_empty(gl, &gl->gl_holders) &&
gl->gl_state != LM_ST_UNLOCKED)
handle_callback(gl, LM_ST_UNLOCKED);

gfs2_glmutex_unlock(gl);
}

gfs2_glock_put(gl);
}

/**
Expand All @@ -2040,10 +2009,10 @@ void gfs2_gl_hash_clear(struct gfs2_sbd *sdp, int wait)

for (;;) {
cont = 0;

for (x = 0; x < GFS2_GL_HASH_SIZE; x++)
if (examine_bucket(clear_glock, sdp, x))
for (x = 0; x < GFS2_GL_HASH_SIZE; x++) {
if (examine_bucket(clear_glock, sdp, x))
cont = 1;
}

if (!wait || !cont)
break;
Expand Down Expand Up @@ -2234,8 +2203,6 @@ static int gfs2_dump_lockstate(struct gfs2_sbd *sdp)
read_lock(gl_lock_addr(x));

list_for_each_entry(gl, &gl_hash_table[x].hb_list, gl_list) {
if (test_bit(GLF_PLUG, &gl->gl_flags))
continue;
if (gl->gl_sbd != sdp)
continue;

Expand Down
1 change: 0 additions & 1 deletion trunk/fs/gfs2/incore.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,6 @@ struct gfs2_holder {
};

enum {
GLF_PLUG = 0,
GLF_LOCK = 1,
GLF_STICKY = 2,
GLF_PREFETCH = 3,
Expand Down

0 comments on commit 2d629f6

Please sign in to comment.