* [Cluster-devel] [PATCH] [GFS2] bz253768 (bz248480 try 2) delay glock demote for a minimum hold time
@ 2007-08-23 18:19 Benjamin Marzinski
2007-08-24 7:29 ` Steven Whitehouse
0 siblings, 1 reply; 2+ messages in thread
From: Benjamin Marzinski @ 2007-08-23 18:19 UTC (permalink / raw)
To: cluster-devel.redhat.com
When a lot of IO, with some distributed mmap IO, is run on a GFS2 filesystem in
a cluster, it will deadlock. The reason is that do_no_page() will repeatedly
call gfs2_sharewrite_nopage(), because each node keeps giving up the glock
too early, and is forced to call unmap_mapping_range(). This bumps the
mapping->truncate_count sequence count, forcing do_no_page() to retry. This
patch institutes a minimum glock hold time a tenth a second. This insures
that even in heavy contention cases, the node has enough time to get some
useful work done before it gives up the glock.
A second issue is that when gfs2_glock_dq() is called from within a page fault
to demote a lock, and the associated page needs to be written out, it will
try to acqire a lock on it, but it has already been locked at a higher level.
This patch puts makes gfs2_glock_dq() use the work queue as well, to avoid this
issue. This is the same patch as Steve Whitehouse originally proposed to fix
this issue, execpt that gfs2_glock_dq() now grabs a reference to the glock
before it queues up the work on it.
This still doesn't allow the tests to complete. However the remaining bug is a
known one that will be fixed once Nick Piggin's VFS interface changes have gone
in.
Signed-off-by: Benjamin E. Marzinski <bmarzins@redhat.com>
-------------- next part --------------
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 3d94918..021237d 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -27,6 +27,8 @@
#include <linux/debugfs.h>
#include <linux/kthread.h>
#include <linux/freezer.h>
+#include <linux/workqueue.h>
+#include <linux/jiffies.h>
#include "gfs2.h"
#include "incore.h"
@@ -58,10 +60,13 @@
static int dump_glock(struct glock_iter *gi, struct gfs2_glock *gl);
static void gfs2_glock_xmote_th(struct gfs2_glock *gl, struct gfs2_holder *gh);
static void gfs2_glock_drop_th(struct gfs2_glock *gl);
+static void run_queue(struct gfs2_glock *gl);
+
static DECLARE_RWSEM(gfs2_umount_flush_sem);
static struct dentry *gfs2_root;
static struct task_struct *scand_process;
static unsigned int scand_secs = 5;
+static struct workqueue_struct *glock_workqueue;
#define GFS2_GL_HASH_SHIFT 15
#define GFS2_GL_HASH_SIZE (1 << GFS2_GL_HASH_SHIFT)
@@ -277,6 +282,18 @@
return gl;
}
+static void glock_work_func(struct work_struct *work)
+{
+ struct gfs2_glock *gl = container_of(work, struct gfs2_glock, gl_work.work);
+
+ spin_lock(&gl->gl_spin);
+ if (test_and_clear_bit(GLF_PENDING_DEMOTE, &gl->gl_flags))
+ set_bit(GLF_DEMOTE, &gl->gl_flags);
+ run_queue(gl);
+ spin_unlock(&gl->gl_spin);
+ gfs2_glock_put(gl);
+}
+
/**
* gfs2_glock_get() - Get a glock, or create one if one doesn't exist
* @sdp: The GFS2 superblock
@@ -316,6 +333,7 @@
gl->gl_name = name;
atomic_set(&gl->gl_ref, 1);
gl->gl_state = LM_ST_UNLOCKED;
+ gl->gl_demote_state = LM_ST_EXCLUSIVE;
gl->gl_hash = hash;
gl->gl_owner_pid = 0;
gl->gl_ip = 0;
@@ -324,10 +342,12 @@
gl->gl_req_bh = NULL;
gl->gl_vn = 0;
gl->gl_stamp = jiffies;
+ gl->gl_tchange = jiffies;
gl->gl_object = NULL;
gl->gl_sbd = sdp;
gl->gl_aspace = NULL;
lops_init_le(&gl->gl_le, &gfs2_glock_lops);
+ INIT_DELAYED_WORK(&gl->gl_work, glock_work_func);
/* If this glock protects actual on-disk data or metadata blocks,
create a VFS inode to manage the pages/buffers holding them. */
@@ -441,6 +461,8 @@
static void gfs2_demote_wake(struct gfs2_glock *gl)
{
+ BUG_ON(!spin_is_locked(&gl->gl_spin));
+ gl->gl_demote_state = LM_ST_EXCLUSIVE;
clear_bit(GLF_DEMOTE, &gl->gl_flags);
smp_mb__after_clear_bit();
wake_up_bit(&gl->gl_flags, GLF_DEMOTE);
@@ -682,10 +704,14 @@
* practise: LM_ST_SHARED and LM_ST_UNLOCKED
*/
-static void handle_callback(struct gfs2_glock *gl, unsigned int state, int remote)
+static void handle_callback(struct gfs2_glock *gl, unsigned int state,
+ int remote, unsigned long delay)
{
+ int bit = delay ? GLF_PENDING_DEMOTE : GLF_DEMOTE;
+
spin_lock(&gl->gl_spin);
- if (test_and_set_bit(GLF_DEMOTE, &gl->gl_flags) == 0) {
+ set_bit(bit, &gl->gl_flags);
+ if (gl->gl_demote_state == LM_ST_EXCLUSIVE) {
gl->gl_demote_state = state;
gl->gl_demote_time = jiffies;
if (remote && gl->gl_ops->go_type == LM_TYPE_IOPEN &&
@@ -727,6 +753,7 @@
}
gl->gl_state = new_state;
+ gl->gl_tchange = jiffies;
}
/**
@@ -813,7 +840,6 @@
gl->gl_req_gh = NULL;
gl->gl_req_bh = NULL;
clear_bit(GLF_LOCK, &gl->gl_flags);
- run_queue(gl);
spin_unlock(&gl->gl_spin);
}
@@ -885,7 +911,6 @@
gfs2_assert_warn(sdp, !ret);
state_change(gl, LM_ST_UNLOCKED);
- gfs2_demote_wake(gl);
if (glops->go_inval)
glops->go_inval(gl, DIO_METADATA);
@@ -898,10 +923,10 @@
}
spin_lock(&gl->gl_spin);
+ gfs2_demote_wake(gl);
gl->gl_req_gh = NULL;
gl->gl_req_bh = NULL;
clear_bit(GLF_LOCK, &gl->gl_flags);
- run_queue(gl);
spin_unlock(&gl->gl_spin);
gfs2_glock_put(gl);
@@ -1209,9 +1234,10 @@
{
struct gfs2_glock *gl = gh->gh_gl;
const struct gfs2_glock_operations *glops = gl->gl_ops;
+ unsigned delay = 0;
if (gh->gh_flags & GL_NOCACHE)
- handle_callback(gl, LM_ST_UNLOCKED, 0);
+ handle_callback(gl, LM_ST_UNLOCKED, 0, 0);
gfs2_glmutex_lock(gl);
@@ -1229,8 +1255,14 @@
}
clear_bit(GLF_LOCK, &gl->gl_flags);
- run_queue(gl);
spin_unlock(&gl->gl_spin);
+
+ gfs2_glock_hold(gl);
+ if (test_bit(GLF_PENDING_DEMOTE, &gl->gl_flags) &&
+ !test_bit(GLF_DEMOTE, &gl->gl_flags))
+ delay = gl->gl_ops->go_min_hold_time;
+ if (queue_delayed_work(glock_workqueue, &gl->gl_work, delay) == 0)
+ gfs2_glock_put(gl);
}
void gfs2_glock_dq_wait(struct gfs2_holder *gh)
@@ -1457,18 +1489,21 @@
unsigned int state)
{
struct gfs2_glock *gl;
+ unsigned long delay = 0;
+ unsigned long holdtime;
+ unsigned long now = jiffies;
gl = gfs2_glock_find(sdp, name);
if (!gl)
return;
- handle_callback(gl, state, 1);
-
- spin_lock(&gl->gl_spin);
- run_queue(gl);
- spin_unlock(&gl->gl_spin);
+ holdtime = gl->gl_tchange + gl->gl_ops->go_min_hold_time;
+ if (time_before(now, holdtime))
+ delay = holdtime - now;
- gfs2_glock_put(gl);
+ handle_callback(gl, state, 1, delay);
+ if (queue_delayed_work(glock_workqueue, &gl->gl_work, delay) == 0)
+ gfs2_glock_put(gl);
}
/**
@@ -1509,7 +1544,8 @@
return;
if (!gfs2_assert_warn(sdp, gl->gl_req_bh))
gl->gl_req_bh(gl, async->lc_ret);
- gfs2_glock_put(gl);
+ if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0)
+ gfs2_glock_put(gl);
up_read(&gfs2_umount_flush_sem);
return;
}
@@ -1602,7 +1638,7 @@
if (gfs2_glmutex_trylock(gl)) {
if (list_empty(&gl->gl_holders) &&
gl->gl_state != LM_ST_UNLOCKED && demote_ok(gl))
- handle_callback(gl, LM_ST_UNLOCKED, 0);
+ handle_callback(gl, LM_ST_UNLOCKED, 0, 0);
gfs2_glmutex_unlock(gl);
}
@@ -1702,7 +1738,7 @@
if (gfs2_glmutex_trylock(gl)) {
if (list_empty(&gl->gl_holders) &&
gl->gl_state != LM_ST_UNLOCKED)
- handle_callback(gl, LM_ST_UNLOCKED, 0);
+ handle_callback(gl, LM_ST_UNLOCKED, 0, 0);
gfs2_glmutex_unlock(gl);
}
}
@@ -2009,11 +2045,18 @@
if (IS_ERR(scand_process))
return PTR_ERR(scand_process);
+ glock_workqueue = create_workqueue("glock_workqueue");
+ if (IS_ERR(glock_workqueue)) {
+ kthread_stop(scand_process);
+ return PTR_ERR(glock_workqueue);
+ }
+
return 0;
}
void gfs2_glock_exit(void)
{
+ destroy_workqueue(glock_workqueue);
kthread_stop(scand_process);
}
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c
--- a/fs/gfs2/glops.c
+++ b/fs/gfs2/glops.c
@@ -454,6 +454,7 @@
.go_lock = inode_go_lock,
.go_unlock = inode_go_unlock,
.go_type = LM_TYPE_INODE,
+ .go_min_hold_time = HZ / 10,
};
const struct gfs2_glock_operations gfs2_rgrp_glops = {
@@ -464,6 +465,7 @@
.go_lock = rgrp_go_lock,
.go_unlock = rgrp_go_unlock,
.go_type = LM_TYPE_RGRP,
+ .go_min_hold_time = HZ / 10,
};
const struct gfs2_glock_operations gfs2_trans_glops = {
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
@@ -11,6 +11,7 @@
#define __INCORE_DOT_H__
#include <linux/fs.h>
+#include <linux/workqueue.h>
#define DIO_WAIT 0x00000010
#define DIO_METADATA 0x00000020
@@ -130,6 +131,7 @@
int (*go_lock) (struct gfs2_holder *gh);
void (*go_unlock) (struct gfs2_holder *gh);
const int go_type;
+ const unsigned long go_min_hold_time;
};
enum {
@@ -161,6 +163,7 @@
GLF_LOCK = 1,
GLF_STICKY = 2,
GLF_DEMOTE = 3,
+ GLF_PENDING_DEMOTE = 4,
GLF_DIRTY = 5,
};
@@ -193,6 +196,7 @@
u64 gl_vn;
unsigned long gl_stamp;
+ unsigned long gl_tchange;
void *gl_object;
struct list_head gl_reclaim;
@@ -203,6 +207,7 @@
struct gfs2_log_element gl_le;
struct list_head gl_ail_list;
atomic_t gl_ail_count;
+ struct delayed_work gl_work;
};
struct gfs2_alloc {
^ permalink raw reply related [flat|nested] 2+ messages in thread
* [Cluster-devel] [PATCH] [GFS2] bz253768 (bz248480 try 2) delay glock demote for a minimum hold time
2007-08-23 18:19 [Cluster-devel] [PATCH] [GFS2] bz253768 (bz248480 try 2) delay glock demote for a minimum hold time Benjamin Marzinski
@ 2007-08-24 7:29 ` Steven Whitehouse
0 siblings, 0 replies; 2+ messages in thread
From: Steven Whitehouse @ 2007-08-24 7:29 UTC (permalink / raw)
To: cluster-devel.redhat.com
Hi,
Now in the -nmw git tree. Thanks,
Steve.
On Thu, 2007-08-23 at 13:19 -0500, Benjamin Marzinski wrote:
> When a lot of IO, with some distributed mmap IO, is run on a GFS2 filesystem in
> a cluster, it will deadlock. The reason is that do_no_page() will repeatedly
> call gfs2_sharewrite_nopage(), because each node keeps giving up the glock
> too early, and is forced to call unmap_mapping_range(). This bumps the
> mapping->truncate_count sequence count, forcing do_no_page() to retry. This
> patch institutes a minimum glock hold time a tenth a second. This insures
> that even in heavy contention cases, the node has enough time to get some
> useful work done before it gives up the glock.
>
> A second issue is that when gfs2_glock_dq() is called from within a page fault
> to demote a lock, and the associated page needs to be written out, it will
> try to acqire a lock on it, but it has already been locked at a higher level.
> This patch puts makes gfs2_glock_dq() use the work queue as well, to avoid this
> issue. This is the same patch as Steve Whitehouse originally proposed to fix
> this issue, execpt that gfs2_glock_dq() now grabs a reference to the glock
> before it queues up the work on it.
>
> This still doesn't allow the tests to complete. However the remaining bug is a
> known one that will be fixed once Nick Piggin's VFS interface changes have gone
> in.
>
> Signed-off-by: Benjamin E. Marzinski <bmarzins@redhat.com>
>
> plain text document attachment (add-glock-workqueue.patch)
> diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
> index 3d94918..021237d 100644
> --- a/fs/gfs2/glock.c
> +++ b/fs/gfs2/glock.c
> @@ -27,6 +27,8 @@
> #include <linux/debugfs.h>
> #include <linux/kthread.h>
> #include <linux/freezer.h>
> +#include <linux/workqueue.h>
> +#include <linux/jiffies.h>
>
> #include "gfs2.h"
> #include "incore.h"
> @@ -58,10 +60,13 @@
> static int dump_glock(struct glock_iter *gi, struct gfs2_glock *gl);
> static void gfs2_glock_xmote_th(struct gfs2_glock *gl, struct gfs2_holder *gh);
> static void gfs2_glock_drop_th(struct gfs2_glock *gl);
> +static void run_queue(struct gfs2_glock *gl);
> +
> static DECLARE_RWSEM(gfs2_umount_flush_sem);
> static struct dentry *gfs2_root;
> static struct task_struct *scand_process;
> static unsigned int scand_secs = 5;
> +static struct workqueue_struct *glock_workqueue;
>
> #define GFS2_GL_HASH_SHIFT 15
> #define GFS2_GL_HASH_SIZE (1 << GFS2_GL_HASH_SHIFT)
> @@ -277,6 +282,18 @@
> return gl;
> }
>
> +static void glock_work_func(struct work_struct *work)
> +{
> + struct gfs2_glock *gl = container_of(work, struct gfs2_glock, gl_work.work);
> +
> + spin_lock(&gl->gl_spin);
> + if (test_and_clear_bit(GLF_PENDING_DEMOTE, &gl->gl_flags))
> + set_bit(GLF_DEMOTE, &gl->gl_flags);
> + run_queue(gl);
> + spin_unlock(&gl->gl_spin);
> + gfs2_glock_put(gl);
> +}
> +
> /**
> * gfs2_glock_get() - Get a glock, or create one if one doesn't exist
> * @sdp: The GFS2 superblock
> @@ -316,6 +333,7 @@
> gl->gl_name = name;
> atomic_set(&gl->gl_ref, 1);
> gl->gl_state = LM_ST_UNLOCKED;
> + gl->gl_demote_state = LM_ST_EXCLUSIVE;
> gl->gl_hash = hash;
> gl->gl_owner_pid = 0;
> gl->gl_ip = 0;
> @@ -324,10 +342,12 @@
> gl->gl_req_bh = NULL;
> gl->gl_vn = 0;
> gl->gl_stamp = jiffies;
> + gl->gl_tchange = jiffies;
> gl->gl_object = NULL;
> gl->gl_sbd = sdp;
> gl->gl_aspace = NULL;
> lops_init_le(&gl->gl_le, &gfs2_glock_lops);
> + INIT_DELAYED_WORK(&gl->gl_work, glock_work_func);
>
> /* If this glock protects actual on-disk data or metadata blocks,
> create a VFS inode to manage the pages/buffers holding them. */
> @@ -441,6 +461,8 @@
>
> static void gfs2_demote_wake(struct gfs2_glock *gl)
> {
> + BUG_ON(!spin_is_locked(&gl->gl_spin));
> + gl->gl_demote_state = LM_ST_EXCLUSIVE;
> clear_bit(GLF_DEMOTE, &gl->gl_flags);
> smp_mb__after_clear_bit();
> wake_up_bit(&gl->gl_flags, GLF_DEMOTE);
> @@ -682,10 +704,14 @@
> * practise: LM_ST_SHARED and LM_ST_UNLOCKED
> */
>
> -static void handle_callback(struct gfs2_glock *gl, unsigned int state, int remote)
> +static void handle_callback(struct gfs2_glock *gl, unsigned int state,
> + int remote, unsigned long delay)
> {
> + int bit = delay ? GLF_PENDING_DEMOTE : GLF_DEMOTE;
> +
> spin_lock(&gl->gl_spin);
> - if (test_and_set_bit(GLF_DEMOTE, &gl->gl_flags) == 0) {
> + set_bit(bit, &gl->gl_flags);
> + if (gl->gl_demote_state == LM_ST_EXCLUSIVE) {
> gl->gl_demote_state = state;
> gl->gl_demote_time = jiffies;
> if (remote && gl->gl_ops->go_type == LM_TYPE_IOPEN &&
> @@ -727,6 +753,7 @@
> }
>
> gl->gl_state = new_state;
> + gl->gl_tchange = jiffies;
> }
>
> /**
> @@ -813,7 +840,6 @@
> gl->gl_req_gh = NULL;
> gl->gl_req_bh = NULL;
> clear_bit(GLF_LOCK, &gl->gl_flags);
> - run_queue(gl);
> spin_unlock(&gl->gl_spin);
> }
>
> @@ -885,7 +911,6 @@
> gfs2_assert_warn(sdp, !ret);
>
> state_change(gl, LM_ST_UNLOCKED);
> - gfs2_demote_wake(gl);
>
> if (glops->go_inval)
> glops->go_inval(gl, DIO_METADATA);
> @@ -898,10 +923,10 @@
> }
>
> spin_lock(&gl->gl_spin);
> + gfs2_demote_wake(gl);
> gl->gl_req_gh = NULL;
> gl->gl_req_bh = NULL;
> clear_bit(GLF_LOCK, &gl->gl_flags);
> - run_queue(gl);
> spin_unlock(&gl->gl_spin);
>
> gfs2_glock_put(gl);
> @@ -1209,9 +1234,10 @@
> {
> struct gfs2_glock *gl = gh->gh_gl;
> const struct gfs2_glock_operations *glops = gl->gl_ops;
> + unsigned delay = 0;
>
> if (gh->gh_flags & GL_NOCACHE)
> - handle_callback(gl, LM_ST_UNLOCKED, 0);
> + handle_callback(gl, LM_ST_UNLOCKED, 0, 0);
>
> gfs2_glmutex_lock(gl);
>
> @@ -1229,8 +1255,14 @@
> }
>
> clear_bit(GLF_LOCK, &gl->gl_flags);
> - run_queue(gl);
> spin_unlock(&gl->gl_spin);
> +
> + gfs2_glock_hold(gl);
> + if (test_bit(GLF_PENDING_DEMOTE, &gl->gl_flags) &&
> + !test_bit(GLF_DEMOTE, &gl->gl_flags))
> + delay = gl->gl_ops->go_min_hold_time;
> + if (queue_delayed_work(glock_workqueue, &gl->gl_work, delay) == 0)
> + gfs2_glock_put(gl);
> }
>
> void gfs2_glock_dq_wait(struct gfs2_holder *gh)
> @@ -1457,18 +1489,21 @@
> unsigned int state)
> {
> struct gfs2_glock *gl;
> + unsigned long delay = 0;
> + unsigned long holdtime;
> + unsigned long now = jiffies;
>
> gl = gfs2_glock_find(sdp, name);
> if (!gl)
> return;
>
> - handle_callback(gl, state, 1);
> -
> - spin_lock(&gl->gl_spin);
> - run_queue(gl);
> - spin_unlock(&gl->gl_spin);
> + holdtime = gl->gl_tchange + gl->gl_ops->go_min_hold_time;
> + if (time_before(now, holdtime))
> + delay = holdtime - now;
>
> - gfs2_glock_put(gl);
> + handle_callback(gl, state, 1, delay);
> + if (queue_delayed_work(glock_workqueue, &gl->gl_work, delay) == 0)
> + gfs2_glock_put(gl);
> }
>
> /**
> @@ -1509,7 +1544,8 @@
> return;
> if (!gfs2_assert_warn(sdp, gl->gl_req_bh))
> gl->gl_req_bh(gl, async->lc_ret);
> - gfs2_glock_put(gl);
> + if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0)
> + gfs2_glock_put(gl);
> up_read(&gfs2_umount_flush_sem);
> return;
> }
> @@ -1602,7 +1638,7 @@
> if (gfs2_glmutex_trylock(gl)) {
> if (list_empty(&gl->gl_holders) &&
> gl->gl_state != LM_ST_UNLOCKED && demote_ok(gl))
> - handle_callback(gl, LM_ST_UNLOCKED, 0);
> + handle_callback(gl, LM_ST_UNLOCKED, 0, 0);
> gfs2_glmutex_unlock(gl);
> }
>
> @@ -1702,7 +1738,7 @@
> if (gfs2_glmutex_trylock(gl)) {
> if (list_empty(&gl->gl_holders) &&
> gl->gl_state != LM_ST_UNLOCKED)
> - handle_callback(gl, LM_ST_UNLOCKED, 0);
> + handle_callback(gl, LM_ST_UNLOCKED, 0, 0);
> gfs2_glmutex_unlock(gl);
> }
> }
> @@ -2009,11 +2045,18 @@
> if (IS_ERR(scand_process))
> return PTR_ERR(scand_process);
>
> + glock_workqueue = create_workqueue("glock_workqueue");
> + if (IS_ERR(glock_workqueue)) {
> + kthread_stop(scand_process);
> + return PTR_ERR(glock_workqueue);
> + }
> +
> return 0;
> }
>
> void gfs2_glock_exit(void)
> {
> + destroy_workqueue(glock_workqueue);
> kthread_stop(scand_process);
> }
>
> diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c
> --- a/fs/gfs2/glops.c
> +++ b/fs/gfs2/glops.c
> @@ -454,6 +454,7 @@
> .go_lock = inode_go_lock,
> .go_unlock = inode_go_unlock,
> .go_type = LM_TYPE_INODE,
> + .go_min_hold_time = HZ / 10,
> };
>
> const struct gfs2_glock_operations gfs2_rgrp_glops = {
> @@ -464,6 +465,7 @@
> .go_lock = rgrp_go_lock,
> .go_unlock = rgrp_go_unlock,
> .go_type = LM_TYPE_RGRP,
> + .go_min_hold_time = HZ / 10,
> };
>
> const struct gfs2_glock_operations gfs2_trans_glops = {
> diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
> --- a/fs/gfs2/incore.h
> +++ b/fs/gfs2/incore.h
> @@ -11,6 +11,7 @@
> #define __INCORE_DOT_H__
>
> #include <linux/fs.h>
> +#include <linux/workqueue.h>
>
> #define DIO_WAIT 0x00000010
> #define DIO_METADATA 0x00000020
> @@ -130,6 +131,7 @@
> int (*go_lock) (struct gfs2_holder *gh);
> void (*go_unlock) (struct gfs2_holder *gh);
> const int go_type;
> + const unsigned long go_min_hold_time;
> };
>
> enum {
> @@ -161,6 +163,7 @@
> GLF_LOCK = 1,
> GLF_STICKY = 2,
> GLF_DEMOTE = 3,
> + GLF_PENDING_DEMOTE = 4,
> GLF_DIRTY = 5,
> };
>
> @@ -193,6 +196,7 @@
>
> u64 gl_vn;
> unsigned long gl_stamp;
> + unsigned long gl_tchange;
> void *gl_object;
>
> struct list_head gl_reclaim;
> @@ -203,6 +207,7 @@
> struct gfs2_log_element gl_le;
> struct list_head gl_ail_list;
> atomic_t gl_ail_count;
> + struct delayed_work gl_work;
> };
>
> struct gfs2_alloc {
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2007-08-24 7:29 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-08-23 18:19 [Cluster-devel] [PATCH] [GFS2] bz253768 (bz248480 try 2) delay glock demote for a minimum hold time Benjamin Marzinski
2007-08-24 7:29 ` Steven Whitehouse
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).