<!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>