<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 TRANSITIONAL//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; CHARSET=UTF-8">
<META NAME="GENERATOR" CONTENT="GtkHTML/3.12.0">
</HEAD>
<BODY>
What bugzilla does this address?<BR>
<BR>
Kevin<BR>
<BR>
On Tue, 2007-07-24 at 14:11 +0100, Steven Whitehouse wrote:
<BLOCKQUOTE TYPE=CITE>
<PRE>
<FONT COLOR="#000000">Hi,</FONT>
<FONT COLOR="#000000">This fixes an oops which was occurring during glock dumping due to the</FONT>
<FONT COLOR="#000000">seq file code not taking a reference to the glock. Also this fixes a</FONT>
<FONT COLOR="#000000">memory leak which occurred in certain cases, in turn preventing the</FONT>
<FONT COLOR="#000000">filesystem from unmounting.</FONT>
<FONT COLOR="#000000">Steve.</FONT>
<FONT COLOR="#000000">----------------------------------------------------------------------</FONT>
<FONT COLOR="#000000">diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c</FONT>
<FONT COLOR="#000000">index d403fd7..e4bc8ae 100644</FONT>
<FONT COLOR="#000000">--- a/fs/gfs2/glock.c</FONT>
<FONT COLOR="#000000">+++ b/fs/gfs2/glock.c</FONT>
<FONT COLOR="#000000">@@ -46,7 +46,6 @@ struct glock_iter {</FONT>
<FONT COLOR="#000000"> int hash; /* hash bucket index */</FONT>
<FONT COLOR="#000000"> struct gfs2_sbd *sdp; /* incore superblock */</FONT>
<FONT COLOR="#000000"> struct gfs2_glock *gl; /* current glock struct */</FONT>
<FONT COLOR="#000000">- struct hlist_head *hb_list; /* current hash bucket ptr */</FONT>
<FONT COLOR="#000000"> struct seq_file *seq; /* sequence file for debugfs */</FONT>
<FONT COLOR="#000000"> char string[512]; /* scratch space */</FONT>
<FONT COLOR="#000000"> };</FONT>
<FONT COLOR="#000000">@@ -1990,47 +1989,38 @@ int __init gfs2_glock_init(void)</FONT>
<FONT COLOR="#000000"> </FONT>
<FONT COLOR="#000000"> static int gfs2_glock_iter_next(struct glock_iter *gi)</FONT>
<FONT COLOR="#000000"> {</FONT>
<FONT COLOR="#000000">+ struct gfs2_glock *gl;</FONT>
<FONT COLOR="#000000">+</FONT>
<FONT COLOR="#000000"> read_lock(gl_lock_addr(gi->hash));</FONT>
<FONT COLOR="#000000">- while (1) {</FONT>
<FONT COLOR="#000000">- if (!gi->hb_list) { /* If we don't have a hash bucket yet */</FONT>
<FONT COLOR="#000000">- gi->hb_list = &gl_hash_table[gi->hash].hb_list;</FONT>
<FONT COLOR="#000000">- if (hlist_empty(gi->hb_list)) {</FONT>
<FONT COLOR="#000000">- read_unlock(gl_lock_addr(gi->hash));</FONT>
<FONT COLOR="#000000">- gi->hash++;</FONT>
<FONT COLOR="#000000">- read_lock(gl_lock_addr(gi->hash));</FONT>
<FONT COLOR="#000000">- gi->hb_list = NULL;</FONT>
<FONT COLOR="#000000">- if (gi->hash >= GFS2_GL_HASH_SIZE) {</FONT>
<FONT COLOR="#000000">- read_unlock(gl_lock_addr(gi->hash));</FONT>
<FONT COLOR="#000000">- return 1;</FONT>
<FONT COLOR="#000000">- }</FONT>
<FONT COLOR="#000000">- else</FONT>
<FONT COLOR="#000000">- continue;</FONT>
<FONT COLOR="#000000">- }</FONT>
<FONT COLOR="#000000">- if (!hlist_empty(gi->hb_list)) {</FONT>
<FONT COLOR="#000000">- gi->gl = list_entry(gi->hb_list->first,</FONT>
<FONT COLOR="#000000">- struct gfs2_glock,</FONT>
<FONT COLOR="#000000">- gl_list);</FONT>
<FONT COLOR="#000000">- }</FONT>
<FONT COLOR="#000000">- } else {</FONT>
<FONT COLOR="#000000">- if (gi->gl->gl_list.next == NULL) {</FONT>
<FONT COLOR="#000000">- read_unlock(gl_lock_addr(gi->hash));</FONT>
<FONT COLOR="#000000">- gi->hash++;</FONT>
<FONT COLOR="#000000">- read_lock(gl_lock_addr(gi->hash));</FONT>
<FONT COLOR="#000000">- gi->hb_list = NULL;</FONT>
<FONT COLOR="#000000">- continue;</FONT>
<FONT COLOR="#000000">- }</FONT>
<FONT COLOR="#000000">- gi->gl = list_entry(gi->gl->gl_list.next,</FONT>
<FONT COLOR="#000000">- struct gfs2_glock, gl_list);</FONT>
<FONT COLOR="#000000">- }</FONT>
<FONT COLOR="#000000">+ gl = gi->gl;</FONT>
<FONT COLOR="#000000">+ if (gl) {</FONT>
<FONT COLOR="#000000">+ gi->gl = hlist_entry(gl->gl_list.next, struct gfs2_glock,</FONT>
<FONT COLOR="#000000">+ gl_list);</FONT>
<FONT COLOR="#000000"> if (gi->gl)</FONT>
<FONT COLOR="#000000">- break;</FONT>
<FONT COLOR="#000000">+ gfs2_glock_hold(gi->gl);</FONT>
<FONT COLOR="#000000"> }</FONT>
<FONT COLOR="#000000"> read_unlock(gl_lock_addr(gi->hash));</FONT>
<FONT COLOR="#000000">+ if (gl)</FONT>
<FONT COLOR="#000000">+ gfs2_glock_put(gl);</FONT>
<FONT COLOR="#000000">+</FONT>
<FONT COLOR="#000000">+ while(gi->gl == NULL) {</FONT>
<FONT COLOR="#000000">+ gi->hash++;</FONT>
<FONT COLOR="#000000">+ if (gi->hash >= GFS2_GL_HASH_SIZE)</FONT>
<FONT COLOR="#000000">+ return 1;</FONT>
<FONT COLOR="#000000">+ read_lock(gl_lock_addr(gi->hash));</FONT>
<FONT COLOR="#000000">+ gi->gl = hlist_entry(gl_hash_table[gi->hash].hb_list.first,</FONT>
<FONT COLOR="#000000">+ struct gfs2_glock, gl_list);</FONT>
<FONT COLOR="#000000">+ if (gi->gl)</FONT>
<FONT COLOR="#000000">+ gfs2_glock_hold(gi->gl);</FONT>
<FONT COLOR="#000000">+ read_unlock(gl_lock_addr(gi->hash));</FONT>
<FONT COLOR="#000000">+ }</FONT>
<FONT COLOR="#000000"> return 0;</FONT>
<FONT COLOR="#000000"> }</FONT>
<FONT COLOR="#000000"> </FONT>
<FONT COLOR="#000000"> static void gfs2_glock_iter_free(struct glock_iter *gi)</FONT>
<FONT COLOR="#000000"> {</FONT>
<FONT COLOR="#000000">+ if (gi->gl)</FONT>
<FONT COLOR="#000000">+ gfs2_glock_put(gi->gl);</FONT>
<FONT COLOR="#000000"> kfree(gi);</FONT>
<FONT COLOR="#000000"> }</FONT>
<FONT COLOR="#000000"> </FONT>
<FONT COLOR="#000000">@@ -2044,12 +2034,17 @@ static struct glock_iter *gfs2_glock_iter_init(struct gfs2_sbd *sdp)</FONT>
<FONT COLOR="#000000"> </FONT>
<FONT COLOR="#000000"> gi->sdp = sdp;</FONT>
<FONT COLOR="#000000"> gi->hash = 0;</FONT>
<FONT COLOR="#000000">- gi->gl = NULL;</FONT>
<FONT COLOR="#000000">- gi->hb_list = NULL;</FONT>
<FONT COLOR="#000000"> gi->seq = NULL;</FONT>
<FONT COLOR="#000000"> memset(gi->string, 0, sizeof(gi->string));</FONT>
<FONT COLOR="#000000"> </FONT>
<FONT COLOR="#000000">- if (gfs2_glock_iter_next(gi)) {</FONT>
<FONT COLOR="#000000">+ read_lock(gl_lock_addr(gi->hash));</FONT>
<FONT COLOR="#000000">+ gi->gl = hlist_entry(gl_hash_table[gi->hash].hb_list.first,</FONT>
<FONT COLOR="#000000">+ struct gfs2_glock, gl_list);</FONT>
<FONT COLOR="#000000">+ if (gi->gl)</FONT>
<FONT COLOR="#000000">+ gfs2_glock_hold(gi->gl);</FONT>
<FONT COLOR="#000000">+ read_unlock(gl_lock_addr(gi->hash));</FONT>
<FONT COLOR="#000000">+</FONT>
<FONT COLOR="#000000">+ if (!gi->gl && gfs2_glock_iter_next(gi)) {</FONT>
<FONT COLOR="#000000"> gfs2_glock_iter_free(gi);</FONT>
<FONT COLOR="#000000"> return NULL;</FONT>
<FONT COLOR="#000000"> }</FONT>
<FONT COLOR="#000000">@@ -2066,7 +2061,7 @@ static void *gfs2_glock_seq_start(struct seq_file *file, loff_t *pos)</FONT>
<FONT COLOR="#000000"> if (!gi)</FONT>
<FONT COLOR="#000000"> return NULL;</FONT>
<FONT COLOR="#000000"> </FONT>
<FONT COLOR="#000000">- while (n--) {</FONT>
<FONT COLOR="#000000">+ while(n--) {</FONT>
<FONT COLOR="#000000"> if (gfs2_glock_iter_next(gi)) {</FONT>
<FONT COLOR="#000000"> gfs2_glock_iter_free(gi);</FONT>
<FONT COLOR="#000000"> return NULL;</FONT>
<FONT COLOR="#000000">@@ -2093,7 +2088,9 @@ static void *gfs2_glock_seq_next(struct seq_file *file, void *iter_ptr,</FONT>
<FONT COLOR="#000000"> </FONT>
<FONT COLOR="#000000"> static void gfs2_glock_seq_stop(struct seq_file *file, void *iter_ptr)</FONT>
<FONT COLOR="#000000"> {</FONT>
<FONT COLOR="#000000">- /* nothing for now */</FONT>
<FONT COLOR="#000000">+ struct glock_iter *gi = iter_ptr;</FONT>
<FONT COLOR="#000000">+ if (gi)</FONT>
<FONT COLOR="#000000">+ gfs2_glock_iter_free(gi);</FONT>
<FONT COLOR="#000000"> }</FONT>
<FONT COLOR="#000000"> </FONT>
<FONT COLOR="#000000"> static int gfs2_glock_seq_show(struct seq_file *file, void *iter_ptr)</FONT>
</PRE>
</BLOCKQUOTE>
</BODY>
</HTML>