<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://purl.org/rss/1.0/" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:syn="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/">
  <channel rdf:about="http://blog.gmane.org/gmane.linux.cluster.redhat.cluster.devel">
    <title>gmane.linux.cluster.redhat.cluster.devel</title>
    <link>http://blog.gmane.org/gmane.linux.cluster.redhat.cluster.devel</link>
    <description/>
    <syn:updatePeriod>hourly</syn:updatePeriod>
    <syn:updateFrequency>1</syn:updateFrequency>
    <syn:updateBase>1901-01-01T00:00+00:00</syn:updateBase>
    <items>
      <rdf:Seq>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7030"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7029"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7028"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7027"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7026"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7025"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7024"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7023"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7022"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7020"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7019"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7018"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7017"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7016"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7015"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7014"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7013"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7012"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7011"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7010"/>
      </rdf:Seq>
    </items>
    <image rdf:resource="http://gmane.org/img/gmane-25t.png"/>
    <textinput rdf:resource=""/>
  </channel>
  <image rdf:about="http://gmane.org/img/gmane-25t.png">
    <title>Gmane</title>
    <url>http://gmane.org/img/gmane-25t.png</url>
    <link>http://gmane.org</link>
  </image>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7030">
    <title>Re: [PATCH 2/3] gfs2_edit: Fix find_mtype and support gfs1 structures</title>
    <link>http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7030</link>
    <description>&lt;pre&gt;Hi,

On Fri, 2012-05-25 at 11:27 +0100, Andrew Price wrote:
I think that makes sense. I don't remember now why I did that with a
bitfield and not flags, but it is probably better to convert it to
flags. We'll want to give them a longer name though, as everything in
the library will land up with a LGFS2_ or lgfs2_ prefix in the end,

Steve.



&lt;/pre&gt;</description>
    <dc:creator>Steven Whitehouse</dc:creator>
    <dc:date>2012-05-25T10:40:07</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7029">
    <title>Re: [PATCH 2/3] gfs2_edit: Fix find_mtype and support gfs1 structures</title>
    <link>http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7029</link>
    <description>&lt;pre&gt;
I'm wondering if we should represent the version metadata as flags 
instead of separate gfs1 and gfs2 fields and define some constants so we 
can do the comparison in one go, e.g.

                 if ((m[n].versions &amp;amp; versions) ...

Where versions is some combination of defined constants passed into the 
function like LGFS2_VER_1 | LGFS2_VER_2

But that has its own drawbacks I guess so I'm probably just splitting 
hairs. What do you think?

Andy



&lt;/pre&gt;</description>
    <dc:creator>Andrew Price</dc:creator>
    <dc:date>2012-05-25T10:27:59</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7028">
    <title>Re: [PATCH 3/3] gfs2_edit: Clean up some magic offsets</title>
    <link>http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7028</link>
    <description>&lt;pre&gt;Hi,

Those all look ok to me,

Steve.

On Fri, 2012-05-25 at 11:07 +0100, Andrew Price wrote:



&lt;/pre&gt;</description>
    <dc:creator>Steven Whitehouse</dc:creator>
    <dc:date>2012-05-25T10:19:07</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7027">
    <title>[PATCH 3/3] gfs2_edit: Clean up some magic offsets</title>
    <link>http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7027</link>
    <description>&lt;pre&gt;Replace some uses of magic offsets with equivalent struct member
accesses.

Signed-off-by: Andrew Price &amp;lt;anprice&amp;lt; at &amp;gt;redhat.com&amp;gt;
---
 gfs2/edit/hexedit.c |    9 +++++----
 1 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/gfs2/edit/hexedit.c b/gfs2/edit/hexedit.c
index 8311534..b4e6d15 100644
--- a/gfs2/edit/hexedit.c
+++ b/gfs2/edit/hexedit.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -838,6 +838,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int hexdump(uint64_t startaddr, int len)
 uint64_t l;
 const char *lpBuffer = bh-&amp;gt;b_data;
 int print_field, cursor_line;
+const uint32_t block_type = get_block_type(bh);
 
 strcpy(edit_fmt,"%02x");
 pointer = (unsigned char *)lpBuffer + offset;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -935,7 +936,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int hexdump(uint64_t startaddr, int len)
 }
 print_gfs2("] ");
 if (print_field &amp;gt;= 0) {
-const struct lgfs2_metadata *m = find_mtype(get_block_type(bh), sbd.gfs1);
+const struct lgfs2_metadata *m = find_mtype(block_type, sbd.gfs1);
 if (m) {
 const struct lgfs2_metafield *f;
 unsigned n;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -951,9 +952,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int hexdump(uint64_t startaddr, int len)
 
 }
 if (cursor_line) {
-if (((*(bh-&amp;gt;b_data + 7) == GFS2_METATYPE_IN) ||
-   (*(bh-&amp;gt;b_data + 7) == GFS2_METATYPE_DI &amp;amp;&amp;amp;
-    (*(bh-&amp;gt;b_data + 0x8b) || *(bh-&amp;gt;b_data + 0x8a))))) {
+if (block_type == GFS2_METATYPE_IN ||
+    ((block_type == GFS2_METATYPE_DI) &amp;amp;&amp;amp;
+     ((struct gfs2_dinode*)bh-&amp;gt;b_data)-&amp;gt;di_height)) {
 int ptroffset = edit_row[dmode] * 16 +
 edit_col[dmode];
 
&lt;/pre&gt;</description>
    <dc:creator>Andrew Price</dc:creator>
    <dc:date>2012-05-25T10:07:04</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7026">
    <title>[PATCH 2/3] gfs2_edit: Fix find_mtype and supportgfs1 structures</title>
    <link>http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7026</link>
    <description>&lt;pre&gt;Fixes up find_mtype to really iterate over the metadata array and to
choose between gfs2 and gfs1 structures.

Signed-off-by: Andrew Price &amp;lt;anprice&amp;lt; at &amp;gt;redhat.com&amp;gt;
---
 gfs2/edit/hexedit.c |    9 +++++----
 1 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/gfs2/edit/hexedit.c b/gfs2/edit/hexedit.c
index 69d1940..8311534 100644
--- a/gfs2/edit/hexedit.c
+++ b/gfs2/edit/hexedit.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -813,14 +813,15 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int display_block_type(int from_restore)
 return ret_type;
 }
 
-static const struct lgfs2_metadata *find_mtype(uint32_t mtype)
+static const struct lgfs2_metadata *find_mtype(uint32_t mtype, int gfs1)
 {
 const struct lgfs2_metadata *m = lgfs2_metadata;
 unsigned n = 0;
 
 do {
-if (m-&amp;gt;gfs2 &amp;amp;&amp;amp; m-&amp;gt;mh_type == mtype)
-return m;
+if (((gfs1 &amp;amp;&amp;amp; m[n].gfs1) || (!gfs1 &amp;amp;&amp;amp; m[n].gfs2))
+                         &amp;amp;&amp;amp; m[n].mh_type == mtype)
+return &amp;amp;m[n];
 n++;
 } while (n &amp;lt; lgfs2_metadata_size);
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -934,7 +935,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int hexdump(uint64_t startaddr, int len)
 }
 print_gfs2("] ");
 if (print_field &amp;gt;= 0) {
-const struct lgfs2_metadata *m = find_mtype(get_block_type(bh));
+const struct lgfs2_metadata *m = find_mtype(get_block_type(bh), sbd.gfs1);
 if (m) {
 const struct lgfs2_metafield *f;
 unsigned n;
&lt;/pre&gt;</description>
    <dc:creator>Andrew Price</dc:creator>
    <dc:date>2012-05-25T10:07:03</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7025">
    <title>[PATCH 1/3] gfs2-utils: Remove references tounlinked file tag</title>
    <link>http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7025</link>
    <description>&lt;pre&gt;Remove references to an obsolete unlinked tag file (or file tag).

Signed-off-by: Andrew Price &amp;lt;anprice&amp;lt; at &amp;gt;redhat.com&amp;gt;
---
 gfs2/libgfs2/libgfs2.h |    1 -
 gfs2/man/gfs2_jadd.8   |    3 ---
 gfs2/man/mkfs.gfs2.8   |    3 ---
 gfs2/mkfs/main_mkfs.c  |    5 +----
 4 files changed, 1 insertions(+), 11 deletions(-)

diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index e2a7e45..8ed08dd 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -255,7 +255,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct gfs2_sbd {
 unsigned int bsize;     /* The block size of the FS (in bytes) */
 unsigned int jsize;     /* Size of journals (in MB) */
 unsigned int rgsize;     /* Size of resource groups (in MB) */
-unsigned int utsize;     /* Size of unlinked tag files (in MB) */
 unsigned int qcsize;     /* Size of quota change files (in MB) */
 
 int debug;
diff --git a/gfs2/man/gfs2_jadd.8 b/gfs2/man/gfs2_jadd.8
index a645fb7..5453edd 100644
--- a/gfs2/man/gfs2_jadd.8
+++ b/gfs2/man/gfs2_jadd.8
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -50,9 +50,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; The number of new journals to add.
 \fB-q\fP
 Be quiet.  Don't print anything.
 .TP
-\fB-u MegaBytes\fP
-Initial size of each journal's unlinked tag file
-.TP
 \fB-V\fP
 Version. Print version information, then exit.
 .
diff --git a/gfs2/man/mkfs.gfs2.8 b/gfs2/man/mkfs.gfs2.8
index 63348f8..d17e272 100644
--- a/gfs2/man/mkfs.gfs2.8
+++ b/gfs2/man/mkfs.gfs2.8
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -75,9 +75,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; Fsname is a unique file system name used to distinguish this GFS2 file
 system from others created (1 to 16 characters).  Lock_nolock doesn't
 use this field.
 .TP
-\fB-u\fP \fIMegaBytes\fR
-Initial size of each journal's unlinked tag file
-.TP
 \fB-V\fP
 Print program version information, then exit.
 
diff --git a/gfs2/mkfs/main_mkfs.c b/gfs2/mkfs/main_mkfs.c
index 7c93621..e6b00a0 100644
--- a/gfs2/mkfs/main_mkfs.c
+++ b/gfs2/mkfs/main_mkfs.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -109,7 +109,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void decode_arguments(int argc, char *argv[], struct gfs2_sbd *sdp)
 sdp-&amp;gt;orig_fssize = 0;
 
 while (cont) {
-optchar = getopt(argc, argv, "-b:c:DhJ:j:KOp:qr:t:u:VX");
+optchar = getopt(argc, argv, "-b:c:DhJ:j:KOp:qr:t:VX");
 
 switch (optchar) {
 case 'b':
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -166,9 +166,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void decode_arguments(int argc, char *argv[], struct gfs2_sbd *sdp)
 strcpy(sdp-&amp;gt;locktable, optarg);
 break;
 
-case 'u':
-break;
-
 case 'V':
 printf("gfs2_mkfs %s (built %s %s)\n", VERSION,
        __DATE__, __TIME__);
&lt;/pre&gt;</description>
    <dc:creator>Andrew Price</dc:creator>
    <dc:date>2012-05-25T10:07:02</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7024">
    <title>GFS2 git tree</title>
    <link>http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7024</link>
    <description>&lt;pre&gt;Hi,

Linus has pulled all the patches for the merge window. Although I've got
a few patches queued up, I'll put them in at -rc1 as usual to avoid the
next window's patches getting tangled up with the current window. So the
tree is empty again for the time being,

Steve.



&lt;/pre&gt;</description>
    <dc:creator>Steven Whitehouse</dc:creator>
    <dc:date>2012-05-22T10:28:10</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7023">
    <title>[PATCH] GFS2: Use lvbs for storing rgrp information</title>
    <link>http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7023</link>
    <description>&lt;pre&gt;Instead of reading in the resource groups when gfs2 is checking
for free space to allocate from, gfs2 can store the necessary infromation
in the resource group's lvb.  Also, instead of searching for unlinked
inodes in every resource group that's checked for free space, gfs2 can
store the number of unlinked but inodes in the lvb, and only check for
unlinked inodes if it will find some.

The first time a resource group is locked, the lvb must initialized.
Since this involves counting the unlinked inodes in the resource group,
this takes a little extra time.  But after that, if the resource group
is locked with GL_SKIP, the buffer head won't be read in unless it's
actually needed.

Signed-off-by: Benjamin Marzinski &amp;lt;bmarzins&amp;lt; at &amp;gt;redhat.com&amp;gt;
---
 fs/gfs2/glock.c             |    1 
 fs/gfs2/incore.h            |    1 
 fs/gfs2/rgrp.c              |  138 +++++++++++++++++++++++++++++++++++++++++---
 include/linux/gfs2_ondisk.h |   10 +++
 4 files changed, 141 insertions(+), 9 deletions(-)

Index: gfs2-3.0-nmw/fs/gfs2/glock.c
===================================================================
--- gfs2-3.0-nmw.orig/fs/gfs2/glock.c
+++ gfs2-3.0-nmw/fs/gfs2/glock.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -767,6 +767,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int gfs2_glock_get(struct gfs2_sbd *sdp,
 gl-&amp;gt;gl_stats.stats[GFS2_LKS_DCOUNT] = 0;
 gl-&amp;gt;gl_stats.stats[GFS2_LKS_QCOUNT] = 0;
 memset(&amp;amp;gl-&amp;gt;gl_lksb, 0, sizeof(struct dlm_lksb));
+memset(gl-&amp;gt;gl_lvb, 0, 32 * sizeof(char));
 gl-&amp;gt;gl_lksb.sb_lvbptr = gl-&amp;gt;gl_lvb;
 gl-&amp;gt;gl_tchange = jiffies;
 gl-&amp;gt;gl_object = NULL;
Index: gfs2-3.0-nmw/fs/gfs2/incore.h
===================================================================
--- gfs2-3.0-nmw.orig/fs/gfs2/incore.h
+++ gfs2-3.0-nmw/fs/gfs2/incore.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -89,6 +89,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct gfs2_rgrpd {
 u64 rd_igeneration;
 struct gfs2_bitmap *rd_bits;
 struct gfs2_sbd *rd_sbd;
+struct gfs2_rgrp_lvb *rd_rgl;
 u32 rd_last_alloc;
 u32 rd_flags;
 #define GFS2_RDF_CHECK0x10000000 /* check for unlinked inodes */
Index: gfs2-3.0-nmw/fs/gfs2/rgrp.c
===================================================================
--- gfs2-3.0-nmw.orig/fs/gfs2/rgrp.c
+++ gfs2-3.0-nmw/fs/gfs2/rgrp.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -627,6 +627,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int read_rindex_entry(struct gfs2
 goto fail;
 
 rgd-&amp;gt;rd_gl-&amp;gt;gl_object = rgd;
+rgd-&amp;gt;rd_rgl = (struct gfs2_rgrp_lvb *)rgd-&amp;gt;rd_gl-&amp;gt;gl_lvb;
 rgd-&amp;gt;rd_flags &amp;amp;= ~GFS2_RDF_UPTODATE;
 if (rgd-&amp;gt;rd_data &amp;gt; sdp-&amp;gt;sd_max_rg_data)
 sdp-&amp;gt;sd_max_rg_data = rgd-&amp;gt;rd_data;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -736,9 +737,65 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void gfs2_rgrp_out(struct gfs2_rg
 memset(&amp;amp;str-&amp;gt;rg_reserved, 0, sizeof(str-&amp;gt;rg_reserved));
 }
 
+static int gfs2_rgrp_lvb_valid(struct gfs2_rgrpd *rgd)
+{
+struct gfs2_rgrp_lvb *rgl = rgd-&amp;gt;rd_rgl;
+struct gfs2_rgrp *str = (struct gfs2_rgrp *)rgd-&amp;gt;rd_bits[0].bi_bh-&amp;gt;b_data;
+
+if (rgl-&amp;gt;rl_flags != str-&amp;gt;rg_flags || rgl-&amp;gt;rl_free != str-&amp;gt;rg_free ||
+    rgl-&amp;gt;rl_dinodes != str-&amp;gt;rg_dinodes ||
+    rgl-&amp;gt;rl_igeneration != str-&amp;gt;rg_igeneration)
+return 0;
+return 1;
+}
+
+static void gfs2_rgrp_ondisk2lvb(struct gfs2_rgrp_lvb *rgl, const void *buf)
+{
+const struct gfs2_rgrp *str = buf;
+
+rgl-&amp;gt;rl_magic = cpu_to_be32(GFS2_MAGIC);
+rgl-&amp;gt;rl_flags = str-&amp;gt;rg_flags;
+rgl-&amp;gt;rl_free = str-&amp;gt;rg_free;
+rgl-&amp;gt;rl_dinodes = str-&amp;gt;rg_dinodes;
+rgl-&amp;gt;rl_igeneration = str-&amp;gt;rg_igeneration;
+rgl-&amp;gt;__pad = 0UL;
+}
+
+static void update_rgrp_lvb_unlinked(struct gfs2_rgrpd *rgd, u32 change)
+{
+struct gfs2_rgrp_lvb *rgl = rgd-&amp;gt;rd_rgl;
+u32 unlinked = be32_to_cpu(rgl-&amp;gt;rl_unlinked) + change;
+rgl-&amp;gt;rl_unlinked = cpu_to_be32(unlinked);
+}
+
+static u32 count_unlinked(struct gfs2_rgrpd *rgd)
+{
+struct gfs2_bitmap *bi;
+const u32 length = rgd-&amp;gt;rd_length;
+const u8 *buffer = NULL;
+u32 i, goal, count = 0;
+
+for (i = 0, bi = rgd-&amp;gt;rd_bits; i &amp;lt; length; i++, bi++) {
+goal = 0;
+buffer = bi-&amp;gt;bi_bh-&amp;gt;b_data + bi-&amp;gt;bi_offset;
+WARN_ON(!buffer_uptodate(bi-&amp;gt;bi_bh));
+while (goal &amp;lt; bi-&amp;gt;bi_len * GFS2_NBBY) {
+goal = gfs2_bitfit(buffer, bi-&amp;gt;bi_len, goal,
+   GFS2_BLKST_UNLINKED);
+if (goal == BFITNOENT)
+break;
+count++;
+goal++;
+}
+}
+
+return count;
+}
+
+
 /**
- * gfs2_rgrp_go_lock - Read in a RG's header and bitmaps
- * &amp;lt; at &amp;gt;gh: The glock holder for the resource group
+ * gfs2_rgrp_bh_get - Read in a RG's header and bitmaps
+ * &amp;lt; at &amp;gt;rgd: the struct gfs2_rgrpd describing the RG to read in
  *
  * Read in all of a Resource Group's header and bitmap blocks.
  * Caller must eventually call gfs2_rgrp_relse() to free the bitmaps.
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -746,9 +803,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void gfs2_rgrp_out(struct gfs2_rg
  * Returns: errno
  */
 
-int gfs2_rgrp_go_lock(struct gfs2_holder *gh)
+int gfs2_rgrp_bh_get(struct gfs2_rgrpd *rgd)
 {
-struct gfs2_rgrpd *rgd = gh-&amp;gt;gh_gl-&amp;gt;gl_object;
 struct gfs2_sbd *sdp = rgd-&amp;gt;rd_sbd;
 struct gfs2_glock *gl = rgd-&amp;gt;rd_gl;
 unsigned int length = rgd-&amp;gt;rd_length;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -756,6 +812,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int gfs2_rgrp_go_lock(struct gfs2_holder
 unsigned int x, y;
 int error;
 
+if (rgd-&amp;gt;rd_bits[0].bi_bh != NULL)
+return 0;
+
 for (x = 0; x &amp;lt; length; x++) {
 bi = rgd-&amp;gt;rd_bits + x;
 error = gfs2_meta_read(gl, rgd-&amp;gt;rd_addr + x, 0, &amp;amp;bi-&amp;gt;bi_bh);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -782,6 +841,18 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int gfs2_rgrp_go_lock(struct gfs2_holder
 rgd-&amp;gt;rd_flags |= (GFS2_RDF_UPTODATE | GFS2_RDF_CHECK);
 rgd-&amp;gt;rd_free_clone = rgd-&amp;gt;rd_free;
 }
+if (be32_to_cpu(GFS2_MAGIC) != rgd-&amp;gt;rd_rgl-&amp;gt;rl_magic) {
+rgd-&amp;gt;rd_rgl-&amp;gt;rl_unlinked = cpu_to_be32(count_unlinked(rgd));
+gfs2_rgrp_ondisk2lvb(rgd-&amp;gt;rd_rgl,
+     rgd-&amp;gt;rd_bits[0].bi_bh-&amp;gt;b_data);
+}
+else if (!gfs2_rgrp_lvb_valid(rgd)){
+gfs2_consist_rgrpd(rgd);
+error = -EIO;
+goto fail;
+}
+if (rgd-&amp;gt;rd_rgl-&amp;gt;rl_unlinked == 0)
+rgd-&amp;gt;rd_flags &amp;amp;= ~GFS2_RDF_CHECK;
 
 return 0;
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -796,6 +867,36 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; fail:
 return error;
 }
 
+int update_rgrp_lvb(struct gfs2_rgrpd *rgd)
+{
+u32 rl_flags;
+
+if (rgd-&amp;gt;rd_flags &amp;amp; GFS2_RDF_UPTODATE)
+return 0;
+
+if (be32_to_cpu(GFS2_MAGIC) != rgd-&amp;gt;rd_rgl-&amp;gt;rl_magic)
+return gfs2_rgrp_bh_get(rgd);
+
+rl_flags = be32_to_cpu(rgd-&amp;gt;rd_rgl-&amp;gt;rl_flags);
+rl_flags &amp;amp;= ~GFS2_RDF_MASK;
+rgd-&amp;gt;rd_flags &amp;amp;= GFS2_RDF_MASK;
+rgd-&amp;gt;rd_flags |= (rl_flags | GFS2_RDF_UPTODATE | GFS2_RDF_CHECK);
+if (rgd-&amp;gt;rd_rgl-&amp;gt;rl_unlinked == 0)
+rgd-&amp;gt;rd_flags &amp;amp;= ~GFS2_RDF_CHECK;
+rgd-&amp;gt;rd_free = be32_to_cpu(rgd-&amp;gt;rd_rgl-&amp;gt;rl_free);
+rgd-&amp;gt;rd_free_clone = rgd-&amp;gt;rd_free;
+rgd-&amp;gt;rd_dinodes = be32_to_cpu(rgd-&amp;gt;rd_rgl-&amp;gt;rl_dinodes);
+rgd-&amp;gt;rd_igeneration = be64_to_cpu(rgd-&amp;gt;rd_rgl-&amp;gt;rl_igeneration);
+return 0;
+}
+
+int gfs2_rgrp_go_lock(struct gfs2_holder *gh)
+{
+if (gh-&amp;gt;gh_flags &amp;amp; GL_SKIP)
+return 0;
+return gfs2_rgrp_bh_get((struct gfs2_rgrpd *)gh-&amp;gt;gh_gl-&amp;gt;gl_object);
+}
+
 /**
  * gfs2_rgrp_go_unlock - Release RG bitmaps read in with gfs2_rgrp_bh_get()
  * &amp;lt; at &amp;gt;gh: The glock holder for the resource group
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -809,8 +910,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void gfs2_rgrp_go_unlock(struct gfs2_hol
 
 for (x = 0; x &amp;lt; length; x++) {
 struct gfs2_bitmap *bi = rgd-&amp;gt;rd_bits + x;
-brelse(bi-&amp;gt;bi_bh);
-bi-&amp;gt;bi_bh = NULL;
+if (bi-&amp;gt;bi_bh) {
+brelse(bi-&amp;gt;bi_bh);
+bi-&amp;gt;bi_bh = NULL;
+}
 }
 
 }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -954,6 +1057,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int gfs2_fitrim(struct file *filp, void 
 rgd-&amp;gt;rd_flags |= GFS2_RGF_TRIMMED;
 gfs2_trans_add_bh(rgd-&amp;gt;rd_gl, bh, 1);
 gfs2_rgrp_out(rgd, bh-&amp;gt;b_data);
+gfs2_rgrp_ondisk2lvb(rgd-&amp;gt;rd_rgl, bh-&amp;gt;b_data);
 gfs2_trans_end(sdp);
 }
 }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1115,7 +1219,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int get_local_rgrp(struct gfs2_in
 struct gfs2_sbd *sdp = GFS2_SB(&amp;amp;ip-&amp;gt;i_inode);
 struct gfs2_rgrpd *rgd, *begin = NULL;
 struct gfs2_blkreserv *rs = ip-&amp;gt;i_res;
-int error, rg_locked, flags = LM_FLAG_TRY;
+int error, rg_locked, flags = LM_FLAG_TRY | GL_SKIP;
 int loops = 0;
 
 if (ip-&amp;gt;i_rgd &amp;amp;&amp;amp; rgrp_contains_block(ip-&amp;gt;i_rgd, ip-&amp;gt;i_goal))
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1135,22 +1239,32 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int get_local_rgrp(struct gfs2_in
 } else {
 error = gfs2_glock_nq_init(rgd-&amp;gt;rd_gl, LM_ST_EXCLUSIVE,
    flags, &amp;amp;rs-&amp;gt;rs_rgd_gh);
+if (!error) {
+error = update_rgrp_lvb(rgd);
+if (error) {
+gfs2_glock_dq_uninit(&amp;amp;rs-&amp;gt;rs_rgd_gh);
+return error;
+}
+}
 }
 switch (error) {
 case 0:
 if (try_rgrp_fit(rgd, ip)) {
+gfs2_rgrp_bh_get(rgd);
 ip-&amp;gt;i_rgd = rgd;
 return 0;
 }
-if (rgd-&amp;gt;rd_flags &amp;amp; GFS2_RDF_CHECK)
+if (rgd-&amp;gt;rd_flags &amp;amp; GFS2_RDF_CHECK) {
+gfs2_rgrp_bh_get(rgd);
 try_rgrp_unlink(rgd, last_unlinked, ip-&amp;gt;i_no_addr);
+}
 if (!rg_locked)
 gfs2_glock_dq_uninit(&amp;amp;rs-&amp;gt;rs_rgd_gh);
 /* fall through */
 case GLR_TRYFAILED:
 rgd = gfs2_rgrpd_get_next(rgd);
 if (rgd == begin) {
-flags = 0;
+flags = GL_SKIP;
 loops++;
 }
 break;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1542,6 +1656,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int gfs2_alloc_blocks(struct gfs2_inode 
 
 gfs2_trans_add_bh(rgd-&amp;gt;rd_gl, rgd-&amp;gt;rd_bits[0].bi_bh, 1);
 gfs2_rgrp_out(rgd, rgd-&amp;gt;rd_bits[0].bi_bh-&amp;gt;b_data);
+gfs2_rgrp_ondisk2lvb(rgd-&amp;gt;rd_rgl, rgd-&amp;gt;rd_bits[0].bi_bh-&amp;gt;b_data);
 
 gfs2_statfs_change(sdp, 0, -(s64)*nblocks, dinode ? 1 : 0);
 if (dinode)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1588,6 +1703,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void __gfs2_free_blocks(struct gfs2_inod
 rgd-&amp;gt;rd_flags &amp;amp;= ~GFS2_RGF_TRIMMED;
 gfs2_trans_add_bh(rgd-&amp;gt;rd_gl, rgd-&amp;gt;rd_bits[0].bi_bh, 1);
 gfs2_rgrp_out(rgd, rgd-&amp;gt;rd_bits[0].bi_bh-&amp;gt;b_data);
+gfs2_rgrp_ondisk2lvb(rgd-&amp;gt;rd_rgl, rgd-&amp;gt;rd_bits[0].bi_bh-&amp;gt;b_data);
 
 /* Directories keep their data in the metadata address space */
 if (meta || ip-&amp;gt;i_depth)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1624,6 +1740,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void gfs2_unlink_di(struct inode *inode)
 trace_gfs2_block_alloc(ip, rgd, blkno, 1, GFS2_BLKST_UNLINKED);
 gfs2_trans_add_bh(rgd-&amp;gt;rd_gl, rgd-&amp;gt;rd_bits[0].bi_bh, 1);
 gfs2_rgrp_out(rgd, rgd-&amp;gt;rd_bits[0].bi_bh-&amp;gt;b_data);
+gfs2_rgrp_ondisk2lvb(rgd-&amp;gt;rd_rgl, rgd-&amp;gt;rd_bits[0].bi_bh-&amp;gt;b_data);
+update_rgrp_lvb_unlinked(rgd, 1);
 }
 
 static void gfs2_free_uninit_di(struct gfs2_rgrpd *rgd, u64 blkno)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1643,6 +1761,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void gfs2_free_uninit_di(struct g
 
 gfs2_trans_add_bh(rgd-&amp;gt;rd_gl, rgd-&amp;gt;rd_bits[0].bi_bh, 1);
 gfs2_rgrp_out(rgd, rgd-&amp;gt;rd_bits[0].bi_bh-&amp;gt;b_data);
+gfs2_rgrp_ondisk2lvb(rgd-&amp;gt;rd_rgl, rgd-&amp;gt;rd_bits[0].bi_bh-&amp;gt;b_data);
+update_rgrp_lvb_unlinked(rgd, -1);
 
 gfs2_statfs_change(sdp, 0, +1, -1);
 }
Index: gfs2-3.0-nmw/include/linux/gfs2_ondisk.h
===================================================================
--- gfs2-3.0-nmw.orig/include/linux/gfs2_ondisk.h
+++ gfs2-3.0-nmw/include/linux/gfs2_ondisk.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -170,6 +170,16 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct gfs2_rindex {
 #define GFS2_RGF_NOALLOC0x00000008
 #define GFS2_RGF_TRIMMED0x00000010
 
+struct gfs2_rgrp_lvb {
+__be32 rl_magic;
+__be32 rl_flags;
+__be32 rl_free;
+__be32 rl_dinodes;
+__be64 rl_igeneration;
+__be32 rl_unlinked;
+__be32 __pad;
+};
+
 struct gfs2_rgrp {
 struct gfs2_meta_header rg_header;
 


&lt;/pre&gt;</description>
    <dc:creator>Benjamin Marzinski</dc:creator>
    <dc:date>2012-05-22T05:25:39</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7022">
    <title>Re: [patch] dlm: remove stray unlock</title>
    <link>http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7022</link>
    <description>&lt;pre&gt;
Thanks, will fix that.


&lt;/pre&gt;</description>
    <dc:creator>David Teigland</dc:creator>
    <dc:date>2012-05-21T15:39:32</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7020">
    <title>[GFS2 Patch][TRY #3] GFS2: Fold quota data into thereservations struct</title>
    <link>http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7020</link>
    <description>&lt;pre&gt;Hi,

I posted this patch earlier. The only thing that's changed is
the diff offsets, due to other patches that have gone in.

The question was previously asked: Does it matter that I removed
a bunch of calls to gfs2_qadata_get, which itself called function
gfs2_rindex_update? The answer is yes, it matters, and that's why
I've replaced some of the calls with calls directly to function
gfs2_rindex_update rather. Hopefully I've gotten all the places
that matter. Perhaps someone should check my work. :)

This patch moves the ancillary quota data structures into the
block reservations structure. This saves GFS2 some time and
effort in allocating and deallocating the qadata structure.

Regards,

Bob Peterson
Red Hat File Systems

Signed-off-by: Bob Peterson &amp;lt;rpeterso&amp;lt; at &amp;gt;redhat.com&amp;gt; 
---
diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c
index aba77b5..d652634 100644
--- a/fs/gfs2/aops.c
+++ b/fs/gfs2/aops.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -614,7 +614,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int gfs2_write_begin(struct file *file, struct address_space *mapping,
 unsigned int data_blocks = 0, ind_blocks = 0, rblocks;
 int alloc_required;
 int error = 0;
-struct gfs2_qadata *qa = NULL;
 pgoff_t index = pos &amp;gt;&amp;gt; PAGE_CACHE_SHIFT;
 unsigned from = pos &amp;amp; (PAGE_CACHE_SIZE - 1);
 struct page *page;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -638,15 +637,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int gfs2_write_begin(struct file *file, struct address_space *mapping,
 gfs2_write_calc_reserv(ip, len, &amp;amp;data_blocks, &amp;amp;ind_blocks);
 
 if (alloc_required) {
-qa = gfs2_qadata_get(ip);
-if (!qa) {
-error = -ENOMEM;
-goto out_unlock;
-}
-
 error = gfs2_quota_lock_check(ip);
 if (error)
-goto out_alloc_put;
+goto out_unlock;
 
 error = gfs2_inplace_reserve(ip, data_blocks + ind_blocks);
 if (error)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -708,8 +701,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; out_trans_fail:
 gfs2_inplace_release(ip);
 out_qunlock:
 gfs2_quota_unlock(ip);
-out_alloc_put:
-gfs2_qadata_put(ip);
 }
 out_unlock:
 if (&amp;amp;ip-&amp;gt;i_inode == sdp-&amp;gt;sd_rindex) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -846,7 +837,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int gfs2_write_end(struct file *file, struct address_space *mapping,
 struct gfs2_sbd *sdp = GFS2_SB(inode);
 struct gfs2_inode *m_ip = GFS2_I(sdp-&amp;gt;sd_statfs_inode);
 struct buffer_head *dibh;
-struct gfs2_qadata *qa = ip-&amp;gt;i_qadata;
 unsigned int from = pos &amp;amp; (PAGE_CACHE_SIZE - 1);
 unsigned int to = from + len;
 int ret;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -880,10 +870,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; failed:
 gfs2_trans_end(sdp);
 if (gfs2_mb_reserved(ip))
 gfs2_inplace_release(ip);
-if (qa) {
+if (ip-&amp;gt;i_res-&amp;gt;rs_qa_qd_num)
 gfs2_quota_unlock(ip);
-gfs2_qadata_put(ip);
-}
 if (inode == sdp-&amp;gt;sd_rindex) {
 gfs2_glock_dq(&amp;amp;m_ip-&amp;gt;i_gh);
 gfs2_holder_uninit(&amp;amp;m_ip-&amp;gt;i_gh);
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c
index dab5409..6d957a8 100644
--- a/fs/gfs2/bmap.c
+++ b/fs/gfs2/bmap.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1045,12 +1045,13 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int trunc_dealloc(struct gfs2_inode *ip, u64 size)
 lblock = (size - 1) &amp;gt;&amp;gt; sdp-&amp;gt;sd_sb.sb_bsize_shift;
 
 find_metapath(sdp, lblock, &amp;amp;mp, ip-&amp;gt;i_height);
-if (!gfs2_qadata_get(ip))
-return -ENOMEM;
+error = gfs2_rindex_update(sdp);
+if (error)
+return error;
 
 error = gfs2_quota_hold(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE);
 if (error)
-goto out;
+return error;
 
 while (height--) {
 struct strip_mine sm;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1064,8 +1065,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int trunc_dealloc(struct gfs2_inode *ip, u64 size)
 
 gfs2_quota_unhold(ip);
 
-out:
-gfs2_qadata_put(ip);
 return error;
 }
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1167,19 +1166,14 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int do_grow(struct inode *inode, u64 size)
 struct gfs2_inode *ip = GFS2_I(inode);
 struct gfs2_sbd *sdp = GFS2_SB(inode);
 struct buffer_head *dibh;
-struct gfs2_qadata *qa = NULL;
 int error;
 int unstuff = 0;
 
 if (gfs2_is_stuffed(ip) &amp;amp;&amp;amp;
     (size &amp;gt; (sdp-&amp;gt;sd_sb.sb_bsize - sizeof(struct gfs2_dinode)))) {
-qa = gfs2_qadata_get(ip);
-if (qa == NULL)
-return -ENOMEM;
-
 error = gfs2_quota_lock_check(ip);
 if (error)
-goto do_grow_alloc_put;
+return error;
 
 error = gfs2_inplace_reserve(ip, 1);
 if (error)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1214,8 +1208,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; do_grow_release:
 gfs2_inplace_release(ip);
 do_grow_qunlock:
 gfs2_quota_unlock(ip);
-do_grow_alloc_put:
-gfs2_qadata_put(ip);
 }
 return error;
 }
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c
index a836056..323280d 100644
--- a/fs/gfs2/dir.c
+++ b/fs/gfs2/dir.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1854,14 +1854,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int leaf_dealloc(struct gfs2_inode *dip, u32 index, u32 len,
 if (!ht)
 return -ENOMEM;
 
-if (!gfs2_qadata_get(dip)) {
-error = -ENOMEM;
-goto out;
-}
-
 error = gfs2_quota_hold(dip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE);
 if (error)
-goto out_put;
+goto out;
 
 /*  Count the number of leaves  */
 bh = leaf_bh;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1942,8 +1937,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; out_rg_gunlock:
 out_rlist:
 gfs2_rlist_free(&amp;amp;rlist);
 gfs2_quota_unhold(dip);
-out_put:
-gfs2_qadata_put(dip);
 out:
 kfree(ht);
 return error;
diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c
index 3790617..26e2905 100644
--- a/fs/gfs2/file.c
+++ b/fs/gfs2/file.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -366,7 +366,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
 u64 pos = page-&amp;gt;index &amp;lt;&amp;lt; PAGE_CACHE_SHIFT;
 unsigned int data_blocks, ind_blocks, rblocks;
 struct gfs2_holder gh;
-struct gfs2_qadata *qa;
 loff_t size;
 int ret;
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -397,14 +396,13 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
 goto out_unlock;
 }
 
-ret = -ENOMEM;
-qa = gfs2_qadata_get(ip);
-if (qa == NULL)
+ret = gfs2_rindex_update(sdp);
+if (ret)
 goto out_unlock;
 
 ret = gfs2_quota_lock_check(ip);
 if (ret)
-goto out_alloc_put;
+goto out_unlock;
 gfs2_write_calc_reserv(ip, PAGE_CACHE_SIZE, &amp;amp;data_blocks, &amp;amp;ind_blocks);
 ret = gfs2_inplace_reserve(ip, data_blocks + ind_blocks);
 if (ret)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -451,8 +449,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; out_trans_fail:
 gfs2_inplace_release(ip);
 out_quota_unlock:
 gfs2_quota_unlock(ip);
-out_alloc_put:
-gfs2_qadata_put(ip);
 out_unlock:
 gfs2_glock_dq(&amp;amp;gh);
 out:
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -764,7 +760,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static long gfs2_fallocate(struct file *file, int mode, loff_t offset,
 struct gfs2_inode *ip = GFS2_I(inode);
 unsigned int data_blocks = 0, ind_blocks = 0, rblocks;
 loff_t bytes, max_bytes;
-struct gfs2_qadata *qa;
 int error;
 const loff_t pos = offset;
 const loff_t count = len;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -804,15 +799,13 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static long gfs2_fallocate(struct file *file, int mode, loff_t offset,
 offset += bytes;
 continue;
 }
-qa = gfs2_qadata_get(ip);
-if (!qa) {
-error = -ENOMEM;
+error = gfs2_rindex_update(sdp);
+if (error)
 goto out_unlock;
-}
 
 error = gfs2_quota_lock_check(ip);
 if (error)
-goto out_alloc_put;
+goto out_unlock;
 
 retry:
 gfs2_write_calc_reserv(ip, bytes, &amp;amp;data_blocks, &amp;amp;ind_blocks);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -852,7 +845,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; retry:
 offset += max_bytes;
 gfs2_inplace_release(ip);
 gfs2_quota_unlock(ip);
-gfs2_qadata_put(ip);
 }
 
 if (error == 0)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -863,8 +855,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; out_trans_fail:
 gfs2_inplace_release(ip);
 out_qunlock:
 gfs2_quota_unlock(ip);
-out_alloc_put:
-gfs2_qadata_put(ip);
 out_unlock:
 gfs2_glock_dq(&amp;amp;ip-&amp;gt;i_gh);
 out_uninit:
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index aa9949e..d741153 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -289,16 +289,14 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct gfs2_glock {
 
 #define GFS2_MIN_LVB_SIZE 32/* Min size of LVB that gfs2 supports */
 
-struct gfs2_qadata { /* quota allocation data */
-/* Quota stuff */
-struct gfs2_quota_data *qa_qd[2*MAXQUOTAS];
-struct gfs2_holder qa_qd_ghs[2*MAXQUOTAS];
-unsigned int qa_qd_num;
-};
-
 struct gfs2_blkreserv {
 u32 rs_requested; /* Filled in by caller of gfs2_inplace_reserve() */
 struct gfs2_holder rs_rgd_gh; /* Filled in by gfs2_inplace_reserve() */
+
+/* ancillary quota stuff */
+struct gfs2_quota_data *rs_qa_qd[2 * MAXQUOTAS];
+struct gfs2_holder rs_qa_qd_ghs[2 * MAXQUOTAS];
+unsigned int rs_qa_qd_num;
 };
 
 enum {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -319,7 +317,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct gfs2_inode {
 struct gfs2_glock *i_gl; /* Move into i_gh? */
 struct gfs2_holder i_iopen_gh;
 struct gfs2_holder i_gh; /* for prepare/commit_write only */
-struct gfs2_qadata *i_qadata; /* quota allocation data */
 struct gfs2_blkreserv *i_res; /* resource group block reservation */
 struct gfs2_rgrpd *i_rgd;
 u64 i_goal;/* goal block for allocations */
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index 2a1b4b5..2b035e0 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -521,12 +521,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int make_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl,
 int error;
 
 munge_mode_uid_gid(dip, &amp;amp;mode, &amp;amp;uid, &amp;amp;gid);
-if (!gfs2_qadata_get(dip))
-return -ENOMEM;
 
 error = gfs2_quota_lock(dip, uid, gid);
 if (error)
-goto out;
+return error;
 
 error = gfs2_quota_check(dip, uid, gid);
 if (error)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -542,8 +540,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int make_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl,
 
 out_quota:
 gfs2_quota_unlock(dip);
-out:
-gfs2_qadata_put(dip);
 return error;
 }
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -551,15 +547,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int link_dinode(struct gfs2_inode *dip, const struct qstr *name,
        struct gfs2_inode *ip)
 {
 struct gfs2_sbd *sdp = GFS2_SB(&amp;amp;dip-&amp;gt;i_inode);
-struct gfs2_qadata *qa;
 int alloc_required;
 struct buffer_head *dibh;
 int error;
 
-qa = gfs2_qadata_get(dip);
-if (!qa)
-return -ENOMEM;
-
 error = gfs2_quota_lock(dip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE);
 if (error)
 goto fail;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -611,7 +602,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; fail_quota_locks:
 gfs2_quota_unlock(dip);
 
 fail:
-gfs2_qadata_put(dip);
 return error;
 }
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -734,7 +724,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
 if (gfs2_mb_reserved(dip))
 gfs2_inplace_release(dip);
 gfs2_quota_unlock(dip);
-gfs2_qadata_put(dip);
 mark_inode_dirty(inode);
 gfs2_glock_dq_uninit_m(2, ghs);
 d_instantiate(dentry, inode);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -883,16 +872,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int gfs2_link(struct dentry *old_dentry, struct inode *dir,
 error = 0;
 
 if (alloc_required) {
-struct gfs2_qadata *qa = gfs2_qadata_get(dip);
-
-if (!qa) {
-error = -ENOMEM;
-goto out_gunlock;
-}
-
 error = gfs2_quota_lock_check(dip);
 if (error)
-goto out_alloc;
+goto out_gunlock;
 
 error = gfs2_inplace_reserve(dip, sdp-&amp;gt;sd_max_dirres);
 if (error)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -935,9 +917,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; out_ipres:
 out_gunlock_q:
 if (alloc_required)
 gfs2_quota_unlock(dip);
-out_alloc:
-if (alloc_required)
-gfs2_qadata_put(dip);
 out_gunlock:
 gfs2_glock_dq(ghs + 1);
 out_child:
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1374,16 +1353,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int gfs2_rename(struct inode *odir, struct dentry *odentry,
 goto out_gunlock;
 
 if (alloc_required) {
-struct gfs2_qadata *qa = gfs2_qadata_get(ndip);
-
-if (!qa) {
-error = -ENOMEM;
-goto out_gunlock;
-}
-
 error = gfs2_quota_lock_check(ndip);
 if (error)
-goto out_alloc;
+goto out_gunlock;
 
 error = gfs2_inplace_reserve(ndip, sdp-&amp;gt;sd_max_dirres);
 if (error)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1444,9 +1416,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; out_ipreserv:
 out_gunlock_q:
 if (alloc_required)
 gfs2_quota_unlock(ndip);
-out_alloc:
-if (alloc_required)
-gfs2_qadata_put(ndip);
 out_gunlock:
 while (x--) {
 gfs2_glock_dq(ghs + x);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1607,12 +1576,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int setattr_chown(struct inode *inode, struct iattr *attr)
 if (!(attr-&amp;gt;ia_valid &amp;amp; ATTR_GID) || ogid == ngid)
 ogid = ngid = NO_QUOTA_CHANGE;
 
-if (!gfs2_qadata_get(ip))
-return -ENOMEM;
-
 error = gfs2_quota_lock(ip, nuid, ngid);
 if (error)
-goto out_alloc;
+return error;
 
 if (ouid != NO_QUOTA_CHANGE || ogid != NO_QUOTA_CHANGE) {
 error = gfs2_quota_check(ip, nuid, ngid);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1638,8 +1604,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; out_end_trans:
 gfs2_trans_end(sdp);
 out_gunlock_q:
 gfs2_quota_unlock(ip);
-out_alloc:
-gfs2_qadata_put(ip);
 return error;
 }
 
diff --git a/fs/gfs2/main.c b/fs/gfs2/main.c
index 6cdb0f2..e04d0e0 100644
--- a/fs/gfs2/main.c
+++ b/fs/gfs2/main.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -43,7 +43,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void gfs2_init_inode_once(void *foo)
 inode_init_once(&amp;amp;ip-&amp;gt;i_inode);
 init_rwsem(&amp;amp;ip-&amp;gt;i_rw_mutex);
 INIT_LIST_HEAD(&amp;amp;ip-&amp;gt;i_trunc_list);
-ip-&amp;gt;i_qadata = NULL;
 ip-&amp;gt;i_res = NULL;
 ip-&amp;gt;i_hash_cache = NULL;
 }
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
index 197cc2d..7d1ede7 100644
--- a/fs/gfs2/quota.c
+++ b/fs/gfs2/quota.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -494,11 +494,15 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void qdsb_put(struct gfs2_quota_data *qd)
 int gfs2_quota_hold(struct gfs2_inode *ip, u32 uid, u32 gid)
 {
 struct gfs2_sbd *sdp = GFS2_SB(&amp;amp;ip-&amp;gt;i_inode);
-struct gfs2_qadata *qa = ip-&amp;gt;i_qadata;
-struct gfs2_quota_data **qd = qa-&amp;gt;qa_qd;
+struct gfs2_quota_data **qd;
 int error;
 
-if (gfs2_assert_warn(sdp, !qa-&amp;gt;qa_qd_num) ||
+if (ip-&amp;gt;i_res == NULL)
+gfs2_rs_alloc(ip);
+
+qd = ip-&amp;gt;i_res-&amp;gt;rs_qa_qd;
+
+if (gfs2_assert_warn(sdp, !ip-&amp;gt;i_res-&amp;gt;rs_qa_qd_num) ||
     gfs2_assert_warn(sdp, !test_bit(GIF_QD_LOCKED, &amp;amp;ip-&amp;gt;i_flags)))
 return -EIO;
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -508,20 +512,20 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int gfs2_quota_hold(struct gfs2_inode *ip, u32 uid, u32 gid)
 error = qdsb_get(sdp, QUOTA_USER, ip-&amp;gt;i_inode.i_uid, qd);
 if (error)
 goto out;
-qa-&amp;gt;qa_qd_num++;
+ip-&amp;gt;i_res-&amp;gt;rs_qa_qd_num++;
 qd++;
 
 error = qdsb_get(sdp, QUOTA_GROUP, ip-&amp;gt;i_inode.i_gid, qd);
 if (error)
 goto out;
-qa-&amp;gt;qa_qd_num++;
+ip-&amp;gt;i_res-&amp;gt;rs_qa_qd_num++;
 qd++;
 
 if (uid != NO_QUOTA_CHANGE &amp;amp;&amp;amp; uid != ip-&amp;gt;i_inode.i_uid) {
 error = qdsb_get(sdp, QUOTA_USER, uid, qd);
 if (error)
 goto out;
-qa-&amp;gt;qa_qd_num++;
+ip-&amp;gt;i_res-&amp;gt;rs_qa_qd_num++;
 qd++;
 }
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -529,7 +533,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int gfs2_quota_hold(struct gfs2_inode *ip, u32 uid, u32 gid)
 error = qdsb_get(sdp, QUOTA_GROUP, gid, qd);
 if (error)
 goto out;
-qa-&amp;gt;qa_qd_num++;
+ip-&amp;gt;i_res-&amp;gt;rs_qa_qd_num++;
 qd++;
 }
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -542,16 +546,17 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; out:
 void gfs2_quota_unhold(struct gfs2_inode *ip)
 {
 struct gfs2_sbd *sdp = GFS2_SB(&amp;amp;ip-&amp;gt;i_inode);
-struct gfs2_qadata *qa = ip-&amp;gt;i_qadata;
 unsigned int x;
 
+if (ip-&amp;gt;i_res == NULL)
+return;
 gfs2_assert_warn(sdp, !test_bit(GIF_QD_LOCKED, &amp;amp;ip-&amp;gt;i_flags));
 
-for (x = 0; x &amp;lt; qa-&amp;gt;qa_qd_num; x++) {
-qdsb_put(qa-&amp;gt;qa_qd[x]);
-qa-&amp;gt;qa_qd[x] = NULL;
+for (x = 0; x &amp;lt; ip-&amp;gt;i_res-&amp;gt;rs_qa_qd_num; x++) {
+qdsb_put(ip-&amp;gt;i_res-&amp;gt;rs_qa_qd[x]);
+ip-&amp;gt;i_res-&amp;gt;rs_qa_qd[x] = NULL;
 }
-qa-&amp;gt;qa_qd_num = 0;
+ip-&amp;gt;i_res-&amp;gt;rs_qa_qd_num = 0;
 }
 
 static int sort_qd(const void *a, const void *b)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -919,7 +924,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; fail:
 int gfs2_quota_lock(struct gfs2_inode *ip, u32 uid, u32 gid)
 {
 struct gfs2_sbd *sdp = GFS2_SB(&amp;amp;ip-&amp;gt;i_inode);
-struct gfs2_qadata *qa = ip-&amp;gt;i_qadata;
 struct gfs2_quota_data *qd;
 unsigned int x;
 int error = 0;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -932,15 +936,15 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int gfs2_quota_lock(struct gfs2_inode *ip, u32 uid, u32 gid)
     sdp-&amp;gt;sd_args.ar_quota != GFS2_QUOTA_ON)
 return 0;
 
-sort(qa-&amp;gt;qa_qd, qa-&amp;gt;qa_qd_num, sizeof(struct gfs2_quota_data *),
-     sort_qd, NULL);
+sort(ip-&amp;gt;i_res-&amp;gt;rs_qa_qd, ip-&amp;gt;i_res-&amp;gt;rs_qa_qd_num,
+     sizeof(struct gfs2_quota_data *), sort_qd, NULL);
 
-for (x = 0; x &amp;lt; qa-&amp;gt;qa_qd_num; x++) {
+for (x = 0; x &amp;lt; ip-&amp;gt;i_res-&amp;gt;rs_qa_qd_num; x++) {
 int force = NO_FORCE;
-qd = qa-&amp;gt;qa_qd[x];
+qd = ip-&amp;gt;i_res-&amp;gt;rs_qa_qd[x];
 if (test_and_clear_bit(QDF_REFRESH, &amp;amp;qd-&amp;gt;qd_flags))
 force = FORCE;
-error = do_glock(qd, force, &amp;amp;qa-&amp;gt;qa_qd_ghs[x]);
+error = do_glock(qd, force, &amp;amp;ip-&amp;gt;i_res-&amp;gt;rs_qa_qd_ghs[x]);
 if (error)
 break;
 }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -949,7 +953,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int gfs2_quota_lock(struct gfs2_inode *ip, u32 uid, u32 gid)
 set_bit(GIF_QD_LOCKED, &amp;amp;ip-&amp;gt;i_flags);
 else {
 while (x--)
-gfs2_glock_dq_uninit(&amp;amp;qa-&amp;gt;qa_qd_ghs[x]);
+gfs2_glock_dq_uninit(&amp;amp;ip-&amp;gt;i_res-&amp;gt;rs_qa_qd_ghs[x]);
 gfs2_quota_unhold(ip);
 }
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -994,7 +998,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int need_sync(struct gfs2_quota_data *qd)
 
 void gfs2_quota_unlock(struct gfs2_inode *ip)
 {
-struct gfs2_qadata *qa = ip-&amp;gt;i_qadata;
 struct gfs2_quota_data *qda[4];
 unsigned int count = 0;
 unsigned int x;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1002,14 +1005,14 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void gfs2_quota_unlock(struct gfs2_inode *ip)
 if (!test_and_clear_bit(GIF_QD_LOCKED, &amp;amp;ip-&amp;gt;i_flags))
 goto out;
 
-for (x = 0; x &amp;lt; qa-&amp;gt;qa_qd_num; x++) {
+for (x = 0; x &amp;lt; ip-&amp;gt;i_res-&amp;gt;rs_qa_qd_num; x++) {
 struct gfs2_quota_data *qd;
 int sync;
 
-qd = qa-&amp;gt;qa_qd[x];
+qd = ip-&amp;gt;i_res-&amp;gt;rs_qa_qd[x];
 sync = need_sync(qd);
 
-gfs2_glock_dq_uninit(&amp;amp;qa-&amp;gt;qa_qd_ghs[x]);
+gfs2_glock_dq_uninit(&amp;amp;ip-&amp;gt;i_res-&amp;gt;rs_qa_qd_ghs[x]);
 
 if (sync &amp;amp;&amp;amp; qd_trylock(qd))
 qda[count++] = qd;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1042,7 +1045,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int print_message(struct gfs2_quota_data *qd, char *type)
 int gfs2_quota_check(struct gfs2_inode *ip, u32 uid, u32 gid)
 {
 struct gfs2_sbd *sdp = GFS2_SB(&amp;amp;ip-&amp;gt;i_inode);
-struct gfs2_qadata *qa = ip-&amp;gt;i_qadata;
 struct gfs2_quota_data *qd;
 s64 value;
 unsigned int x;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1054,8 +1056,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int gfs2_quota_check(struct gfs2_inode *ip, u32 uid, u32 gid)
         if (sdp-&amp;gt;sd_args.ar_quota != GFS2_QUOTA_ON)
                 return 0;
 
-for (x = 0; x &amp;lt; qa-&amp;gt;qa_qd_num; x++) {
-qd = qa-&amp;gt;qa_qd[x];
+for (x = 0; x &amp;lt; ip-&amp;gt;i_res-&amp;gt;rs_qa_qd_num; x++) {
+qd = ip-&amp;gt;i_res-&amp;gt;rs_qa_qd[x];
 
 if (!((qd-&amp;gt;qd_id == uid &amp;amp;&amp;amp; test_bit(QDF_USER, &amp;amp;qd-&amp;gt;qd_flags)) ||
       (qd-&amp;gt;qd_id == gid &amp;amp;&amp;amp; !test_bit(QDF_USER, &amp;amp;qd-&amp;gt;qd_flags))))
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1093,7 +1095,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int gfs2_quota_check(struct gfs2_inode *ip, u32 uid, u32 gid)
 void gfs2_quota_change(struct gfs2_inode *ip, s64 change,
        u32 uid, u32 gid)
 {
-struct gfs2_qadata *qa = ip-&amp;gt;i_qadata;
 struct gfs2_quota_data *qd;
 unsigned int x;
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1102,8 +1103,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void gfs2_quota_change(struct gfs2_inode *ip, s64 change,
 if (ip-&amp;gt;i_diskflags &amp;amp; GFS2_DIF_SYSTEM)
 return;
 
-for (x = 0; x &amp;lt; qa-&amp;gt;qa_qd_num; x++) {
-qd = qa-&amp;gt;qa_qd[x];
+for (x = 0; x &amp;lt; ip-&amp;gt;i_res-&amp;gt;rs_qa_qd_num; x++) {
+qd = ip-&amp;gt;i_res-&amp;gt;rs_qa_qd[x];
 
 if ((qd-&amp;gt;qd_id == uid &amp;amp;&amp;amp; test_bit(QDF_USER, &amp;amp;qd-&amp;gt;qd_flags)) ||
     (qd-&amp;gt;qd_id == gid &amp;amp;&amp;amp; !test_bit(QDF_USER, &amp;amp;qd-&amp;gt;qd_flags))) {
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index e944fef..9eca6a9 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1007,25 +1007,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; out:
 }
 
 /**
- * gfs2_qadata_get - get the struct gfs2_qadata structure for an inode
- * &amp;lt; at &amp;gt;ip: the incore GFS2 inode structure
- *
- * Returns: the struct gfs2_qadata
- */
-
-struct gfs2_qadata *gfs2_qadata_get(struct gfs2_inode *ip)
-{
-struct gfs2_sbd *sdp = GFS2_SB(&amp;amp;ip-&amp;gt;i_inode);
-int error;
-BUG_ON(ip-&amp;gt;i_qadata != NULL);
-ip-&amp;gt;i_qadata = kzalloc(sizeof(struct gfs2_qadata), GFP_NOFS);
-error = gfs2_rindex_update(sdp);
-if (error)
-fs_warn(sdp, "rindex update returns %d\n", error);
-return ip-&amp;gt;i_qadata;
-}
-
-/**
  * try_rgrp_fit - See if a given reservation will fit in a given RG
  * &amp;lt; at &amp;gt;rgd: the RG data
  * &amp;lt; at &amp;gt;ip: the inode
diff --git a/fs/gfs2/rgrp.h b/fs/gfs2/rgrp.h
index d9eda5f..5d8314d 100644
--- a/fs/gfs2/rgrp.h
+++ b/fs/gfs2/rgrp.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -29,14 +29,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; extern void gfs2_free_clones(struct gfs2_rgrpd *rgd);
 extern int gfs2_rgrp_go_lock(struct gfs2_holder *gh);
 extern void gfs2_rgrp_go_unlock(struct gfs2_holder *gh);
 
-extern struct gfs2_qadata *gfs2_qadata_get(struct gfs2_inode *ip);
-static inline void gfs2_qadata_put(struct gfs2_inode *ip)
-{
-BUG_ON(ip-&amp;gt;i_qadata == NULL);
-kfree(ip-&amp;gt;i_qadata);
-ip-&amp;gt;i_qadata = NULL;
-}
-
 extern int gfs2_inplace_reserve(struct gfs2_inode *ip, u32 requested);
 extern void gfs2_inplace_release(struct gfs2_inode *ip);
 
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
index a42df66..17c8af2 100644
--- a/fs/gfs2/super.c
+++ b/fs/gfs2/super.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1399,7 +1399,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void gfs2_final_release_pages(struct gfs2_inode *ip)
 static int gfs2_dinode_dealloc(struct gfs2_inode *ip)
 {
 struct gfs2_sbd *sdp = GFS2_SB(&amp;amp;ip-&amp;gt;i_inode);
-struct gfs2_qadata *qa;
 struct gfs2_rgrpd *rgd;
 struct gfs2_holder gh;
 int error;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1409,13 +1408,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int gfs2_dinode_dealloc(struct gfs2_inode *ip)
 return -EIO;
 }
 
-qa = gfs2_qadata_get(ip);
-if (!qa)
-return -ENOMEM;
-
 error = gfs2_quota_hold(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE);
 if (error)
-goto out;
+return error;
 
 rgd = gfs2_blk2rgrpd(sdp, ip-&amp;gt;i_no_addr, 1);
 if (!rgd) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1443,8 +1438,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; out_rg_gunlock:
 gfs2_glock_dq_uninit(&amp;amp;gh);
 out_qs:
 gfs2_quota_unhold(ip);
-out:
-gfs2_qadata_put(ip);
 return error;
 }
 
diff --git a/fs/gfs2/xattr.c b/fs/gfs2/xattr.c
index 927f4df..523c0de 100644
--- a/fs/gfs2/xattr.c
+++ b/fs/gfs2/xattr.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -325,13 +325,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int ea_remove_unstuffed(struct gfs2_inode *ip, struct buffer_head *bh,
        struct gfs2_ea_header *ea,
        struct gfs2_ea_header *prev, int leave)
 {
-struct gfs2_qadata *qa;
 int error;
 
-qa = gfs2_qadata_get(ip);
-if (!qa)
-return -ENOMEM;
-
 error = gfs2_quota_hold(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE);
 if (error)
 goto out_alloc;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -340,7 +335,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int ea_remove_unstuffed(struct gfs2_inode *ip, struct buffer_head *bh,
 
 gfs2_quota_unhold(ip);
 out_alloc:
-gfs2_qadata_put(ip);
 return error;
 }
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -713,17 +707,12 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int ea_alloc_skeleton(struct gfs2_inode *ip, struct gfs2_ea_request *er,
      unsigned int blks,
      ea_skeleton_call_t skeleton_call, void *private)
 {
-struct gfs2_qadata *qa;
 struct buffer_head *dibh;
 int error;
 
-qa = gfs2_qadata_get(ip);
-if (!qa)
-return -ENOMEM;
-
 error = gfs2_quota_lock_check(ip);
 if (error)
-goto out;
+return error;
 
 error = gfs2_inplace_reserve(ip, blks);
 if (error)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -753,8 +742,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; out_ipres:
 gfs2_inplace_release(ip);
 out_gunlock_q:
 gfs2_quota_unlock(ip);
-out:
-gfs2_qadata_put(ip);
 return error;
 }
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1494,16 +1481,11 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; out_gunlock:
 
 int gfs2_ea_dealloc(struct gfs2_inode *ip)
 {
-struct gfs2_qadata *qa;
 int error;
 
-qa = gfs2_qadata_get(ip);
-if (!qa)
-return -ENOMEM;
-
 error = gfs2_quota_hold(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE);
 if (error)
-goto out_alloc;
+return error;
 
 error = ea_foreach(ip, ea_dealloc_unstuffed, NULL);
 if (error)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1519,8 +1501,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int gfs2_ea_dealloc(struct gfs2_inode *ip)
 
 out_quota:
 gfs2_quota_unhold(ip);
-out_alloc:
-gfs2_qadata_put(ip);
 return error;
 }
 


&lt;/pre&gt;</description>
    <dc:creator>Bob Peterson</dc:creator>
    <dc:date>2012-05-18T13:28:23</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7019">
    <title>[GFS2 Patch][TRY 4] GFS2: Extend the life of thereservations structure</title>
    <link>http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7019</link>
    <description>&lt;pre&gt;Hi,

Sorry for the problems encountered on try #3 of this patch.
For Try #4, I've systematically gone through all the places where
a reservation is necessary, and made sure one was created.
I've also tested it with quotas enabled against postmark, fs_mark,
and iozone.

This patch lengthens the lifespan of the reservations structure for
inodes. Before, they were allocated and deallocated for every write
operation. With this patch, they are allocated when the first write
occurs, and deallocated when the last process closes the file.
It's more efficient to do it this way because it saves GFS2 a lot of
unnecessary allocates and frees. It also gives us more flexibility
for the future: (1) we can now fold the qadata structure back into
the structure and save those alloc/frees, (2) we can use this for
multi-block reservations.

Regards,

Bob Peterson
Red Hat File Systems

Signed-off-by: Bob Peterson &amp;lt;rpeterso&amp;lt; at &amp;gt;redhat.com&amp;gt; 
---
diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c
index e80a464..aba77b5 100644
--- a/fs/gfs2/aops.c
+++ b/fs/gfs2/aops.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -878,7 +878,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int gfs2_write_end(struct file *file, struct address_space *mapping,
 brelse(dibh);
 failed:
 gfs2_trans_end(sdp);
-if (ip-&amp;gt;i_res)
+if (gfs2_mb_reserved(ip))
 gfs2_inplace_release(ip);
 if (qa) {
 gfs2_quota_unlock(ip);
diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c
index 31b199f..3790617 100644
--- a/fs/gfs2/file.c
+++ b/fs/gfs2/file.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -376,6 +376,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
  */
 vfs_check_frozen(inode-&amp;gt;i_sb, SB_FREEZE_WRITE);
 
+ret = gfs2_rs_alloc(ip);
+if (ret)
+return ret;
+
 gfs2_holder_init(ip-&amp;gt;i_gl, LM_ST_EXCLUSIVE, 0, &amp;amp;gh);
 ret = gfs2_glock_nq(&amp;amp;gh);
 if (ret)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -569,10 +573,15 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int gfs2_release(struct inode *inode, struct file *file)
 {
 struct gfs2_sbd *sdp = inode-&amp;gt;i_sb-&amp;gt;s_fs_info;
 struct gfs2_file *fp;
+struct gfs2_inode *ip = GFS2_I(inode);
 
 fp = file-&amp;gt;private_data;
 file-&amp;gt;private_data = NULL;
 
+if ((file-&amp;gt;f_mode &amp;amp; FMODE_WRITE) &amp;amp;&amp;amp; ip-&amp;gt;i_res &amp;amp;&amp;amp;
+    (atomic_read(&amp;amp;inode-&amp;gt;i_writecount) == 1))
+gfs2_rs_delete(ip);
+
 if (gfs2_assert_warn(sdp, fp))
 return -EIO;
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -653,12 +662,16 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static ssize_t gfs2_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
    unsigned long nr_segs, loff_t pos)
 {
 struct file *file = iocb-&amp;gt;ki_filp;
+struct dentry *dentry = file-&amp;gt;f_dentry;
+struct gfs2_inode *ip = GFS2_I(dentry-&amp;gt;d_inode);
+int ret;
+
+ret = gfs2_rs_alloc(ip);
+if (ret)
+return ret;
 
 if (file-&amp;gt;f_flags &amp;amp; O_APPEND) {
-struct dentry *dentry = file-&amp;gt;f_dentry;
-struct gfs2_inode *ip = GFS2_I(dentry-&amp;gt;d_inode);
 struct gfs2_holder gh;
-int ret;
 
 ret = gfs2_glock_nq_init(ip-&amp;gt;i_gl, LM_ST_SHARED, 0, &amp;amp;gh);
 if (ret)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -774,6 +787,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static long gfs2_fallocate(struct file *file, int mode, loff_t offset,
 if (bytes == 0)
 bytes = sdp-&amp;gt;sd_sb.sb_bsize;
 
+error = gfs2_rs_alloc(ip);
+if (error)
+return error;
+
 gfs2_holder_init(ip-&amp;gt;i_gl, LM_ST_EXCLUSIVE, 0, &amp;amp;ip-&amp;gt;i_gh);
 error = gfs2_glock_nq(&amp;amp;ip-&amp;gt;i_gh);
 if (unlikely(error))
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index a9ba244..2a1b4b5 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -667,6 +667,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
 if (!name-&amp;gt;len || name-&amp;gt;len &amp;gt; GFS2_FNAMESIZE)
 return -ENAMETOOLONG;
 
+error = gfs2_rs_alloc(dip);
+if (error)
+return error;
+
 error = gfs2_glock_nq_init(dip-&amp;gt;i_gl, LM_ST_EXCLUSIVE, 0, ghs);
 if (error)
 goto fail;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -704,6 +708,11 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
 if (error)
 goto fail_gunlock2;
 
+/* the new inode needs a reservation so it can allocate xattrs. */
+error = gfs2_rs_alloc(GFS2_I(inode));
+if (error)
+goto fail_gunlock2;
+
 error = gfs2_acl_create(dip, inode);
 if (error)
 goto fail_gunlock2;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -722,7 +731,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
 gfs2_trans_end(sdp);
 /* Check if we reserved space in the rgrp. Function link_dinode may
    not, depending on whether alloc is required. */
-if (dip-&amp;gt;i_res)
+if (gfs2_mb_reserved(dip))
 gfs2_inplace_release(dip);
 gfs2_quota_unlock(dip);
 gfs2_qadata_put(dip);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -819,6 +828,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int gfs2_link(struct dentry *old_dentry, struct inode *dir,
 if (S_ISDIR(inode-&amp;gt;i_mode))
 return -EPERM;
 
+error = gfs2_rs_alloc(dip);
+if (error)
+return error;
+
 gfs2_holder_init(dip-&amp;gt;i_gl, LM_ST_EXCLUSIVE, 0, ghs);
 gfs2_holder_init(ip-&amp;gt;i_gl, LM_ST_EXCLUSIVE, 0, ghs + 1);
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1234,6 +1247,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int gfs2_rename(struct inode *odir, struct dentry *odentry,
 if (error)
 return error;
 
+error = gfs2_rs_alloc(ndip);
+if (error)
+return error;
+
 if (odip != ndip) {
 error = gfs2_glock_nq_init(sdp-&amp;gt;sd_rename_gl, LM_ST_EXCLUSIVE,
    0, &amp;amp;r_gh);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1644,6 +1661,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int gfs2_setattr(struct dentry *dentry, struct iattr *attr)
 struct gfs2_holder i_gh;
 int error;
 
+error = gfs2_rs_alloc(ip);
+if (error)
+return error;
+
 error = gfs2_glock_nq_init(ip-&amp;gt;i_gl, LM_ST_EXCLUSIVE, 0, &amp;amp;i_gh);
 if (error)
 return error;
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
index b97178e..197cc2d 100644
--- a/fs/gfs2/quota.c
+++ b/fs/gfs2/quota.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -764,6 +764,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int do_sync(unsigned int num_qd, struct gfs2_quota_data **qda)
 unsigned int nalloc = 0, blocks;
 int error;
 
+error = gfs2_rs_alloc(ip);
+if (error)
+return error;
+
 gfs2_write_calc_reserv(ip, sizeof(struct gfs2_quota),
       &amp;amp;data_blocks, &amp;amp;ind_blocks);
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1549,10 +1553,14 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int gfs2_set_dqblk(struct super_block *sb, int type, qid_t id,
 if (error)
 return error;
 
+error = gfs2_rs_alloc(ip);
+if (error)
+goto out_put;
+
 mutex_lock(&amp;amp;ip-&amp;gt;i_inode.i_mutex);
 error = gfs2_glock_nq_init(qd-&amp;gt;qd_gl, LM_ST_EXCLUSIVE, 0, &amp;amp;q_gh);
 if (error)
-goto out_put;
+goto out_unlockput;
 error = gfs2_glock_nq_init(ip-&amp;gt;i_gl, LM_ST_EXCLUSIVE, 0, &amp;amp;i_gh);
 if (error)
 goto out_q;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1609,8 +1617,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; out_i:
 gfs2_glock_dq_uninit(&amp;amp;i_gh);
 out_q:
 gfs2_glock_dq_uninit(&amp;amp;q_gh);
-out_put:
+out_unlockput:
 mutex_unlock(&amp;amp;ip-&amp;gt;i_inode.i_mutex);
+out_put:
 qd_put(qd);
 return error;
 }
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index f74fb9b..e944fef 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -417,6 +417,39 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void gfs2_free_clones(struct gfs2_rgrpd *rgd)
 }
 }
 
+/**
+ * gfs2_rs_alloc - make sure we have a reservation assigned to the inode
+ * &amp;lt; at &amp;gt;ip: the inode for this reservation
+ */
+int gfs2_rs_alloc(struct gfs2_inode *ip)
+{
+int error = 0;
+
+down_write(&amp;amp;ip-&amp;gt;i_rw_mutex);
+if (!ip-&amp;gt;i_res) {
+ip-&amp;gt;i_res = kmem_cache_zalloc(gfs2_rsrv_cachep, GFP_NOFS);
+if (!ip-&amp;gt;i_res)
+error = -ENOMEM;
+}
+up_write(&amp;amp;ip-&amp;gt;i_rw_mutex);
+return error;
+}
+
+/**
+ * gfs2_rs_delete - delete a reservation
+ * &amp;lt; at &amp;gt;ip: The inode for this reservation
+ *
+ */
+void gfs2_rs_delete(struct gfs2_inode *ip)
+{
+down_write(&amp;amp;ip-&amp;gt;i_rw_mutex);
+if (ip-&amp;gt;i_res) {
+kmem_cache_free(gfs2_rsrv_cachep, ip-&amp;gt;i_res);
+ip-&amp;gt;i_res = NULL;
+}
+up_write(&amp;amp;ip-&amp;gt;i_rw_mutex);
+}
+
 void gfs2_clear_rgrpd(struct gfs2_sbd *sdp)
 {
 struct rb_node *n;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -993,22 +1026,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct gfs2_qadata *gfs2_qadata_get(struct gfs2_inode *ip)
 }
 
 /**
- * gfs2_blkrsv_get - get the struct gfs2_blkreserv structure for an inode
- * &amp;lt; at &amp;gt;ip: the incore GFS2 inode structure
- *
- * Returns: the struct gfs2_qadata
- */
-
-static int gfs2_blkrsv_get(struct gfs2_inode *ip)
-{
-BUG_ON(ip-&amp;gt;i_res != NULL);
-ip-&amp;gt;i_res = kmem_cache_zalloc(gfs2_rsrv_cachep, GFP_NOFS);
-if (!ip-&amp;gt;i_res)
-return -ENOMEM;
-return 0;
-}
-
-/**
  * try_rgrp_fit - See if a given reservation will fit in a given RG
  * &amp;lt; at &amp;gt;rgd: the RG data
  * &amp;lt; at &amp;gt;ip: the inode
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1162,13 +1179,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked)
 return -ENOSPC;
 }
 
-static void gfs2_blkrsv_put(struct gfs2_inode *ip)
-{
-BUG_ON(ip-&amp;gt;i_res == NULL);
-kmem_cache_free(gfs2_rsrv_cachep, ip-&amp;gt;i_res);
-ip-&amp;gt;i_res = NULL;
-}
-
 /**
  * gfs2_inplace_reserve - Reserve space in the filesystem
  * &amp;lt; at &amp;gt;ip: the inode to reserve space for
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1181,14 +1191,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int gfs2_inplace_reserve(struct gfs2_inode *ip, u32 requested)
 {
 struct gfs2_sbd *sdp = GFS2_SB(&amp;amp;ip-&amp;gt;i_inode);
 struct gfs2_blkreserv *rs;
-int error;
+int error = 0;
 u64 last_unlinked = NO_BLOCK;
 int tries = 0;
 
-error = gfs2_blkrsv_get(ip);
-if (error)
-return error;
-
 rs = ip-&amp;gt;i_res;
 rs-&amp;gt;rs_requested = requested;
 if (gfs2_assert_warn(sdp, requested)) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1213,7 +1219,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int gfs2_inplace_reserve(struct gfs2_inode *ip, u32 requested)
 
 out:
 if (error)
-gfs2_blkrsv_put(ip);
+rs-&amp;gt;rs_requested = 0;
 return error;
 }
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1230,7 +1236,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void gfs2_inplace_release(struct gfs2_inode *ip)
 
 if (rs-&amp;gt;rs_rgd_gh.gh_gl)
 gfs2_glock_dq_uninit(&amp;amp;rs-&amp;gt;rs_rgd_gh);
-gfs2_blkrsv_put(ip);
+rs-&amp;gt;rs_requested = 0;
 }
 
 /**
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1496,7 +1502,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *nblocks,
 /* Only happens if there is a bug in gfs2, return something distinctive
  * to ensure that it is noticed.
  */
-if (ip-&amp;gt;i_res == NULL)
+if (ip-&amp;gt;i_res-&amp;gt;rs_requested == 0)
 return -ECANCELED;
 
 rgd = ip-&amp;gt;i_rgd;
diff --git a/fs/gfs2/rgrp.h b/fs/gfs2/rgrp.h
index b4b10f4..d9eda5f 100644
--- a/fs/gfs2/rgrp.h
+++ b/fs/gfs2/rgrp.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -43,6 +43,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; extern void gfs2_inplace_release(struct gfs2_inode *ip);
 extern int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *n,
      bool dinode, u64 *generation);
 
+extern int gfs2_rs_alloc(struct gfs2_inode *ip);
+extern void gfs2_rs_delete(struct gfs2_inode *ip);
 extern void __gfs2_free_blocks(struct gfs2_inode *ip, u64 bstart, u32 blen, int meta);
 extern void gfs2_free_meta(struct gfs2_inode *ip, u64 bstart, u32 blen);
 extern void gfs2_free_di(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -68,4 +70,12 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; extern int gfs2_rgrp_send_discards(struct gfs2_sbd *sdp, u64 offset,
    const struct gfs2_bitmap *bi, unsigned minlen, u64 *ptrimmed);
 extern int gfs2_fitrim(struct file *filp, void __user *argp);
 
+/* This is how to tell if a reservation is "inplace" reserved: */
+static inline int gfs2_mb_reserved(struct gfs2_inode *ip)
+{
+if (ip-&amp;gt;i_res &amp;amp;&amp;amp; ip-&amp;gt;i_res-&amp;gt;rs_requested)
+return 1;
+return 0;
+}
+
 #endif /* __RGRP_DOT_H__ */
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
index 6172fa7..a42df66 100644
--- a/fs/gfs2/super.c
+++ b/fs/gfs2/super.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1554,6 +1554,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; out_unlock:
 out:
 /* Case 3 starts here */
 truncate_inode_pages(&amp;amp;inode-&amp;gt;i_data, 0);
+gfs2_rs_delete(ip);
 end_writeback(inode);
 gfs2_dir_hash_inval(ip);
 ip-&amp;gt;i_gl-&amp;gt;gl_object = NULL;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1576,6 +1577,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static struct inode *gfs2_alloc_inode(struct super_block *sb)
 ip-&amp;gt;i_flags = 0;
 ip-&amp;gt;i_gl = NULL;
 ip-&amp;gt;i_rgd = NULL;
+ip-&amp;gt;i_res = NULL;
 }
 return &amp;amp;ip-&amp;gt;i_inode;
 }
diff --git a/fs/gfs2/trans.h b/fs/gfs2/trans.h
index 125d457..41f42cd 100644
--- a/fs/gfs2/trans.h
+++ b/fs/gfs2/trans.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -31,7 +31,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct gfs2_glock;
 static inline unsigned int gfs2_rg_blocks(const struct gfs2_inode *ip)
 {
 const struct gfs2_blkreserv *rs = ip-&amp;gt;i_res;
-if (rs-&amp;gt;rs_requested &amp;lt; ip-&amp;gt;i_rgd-&amp;gt;rd_length)
+if (rs &amp;amp;&amp;amp; rs-&amp;gt;rs_requested &amp;lt; ip-&amp;gt;i_rgd-&amp;gt;rd_length)
 return rs-&amp;gt;rs_requested + 1;
 return ip-&amp;gt;i_rgd-&amp;gt;rd_length;
 }


&lt;/pre&gt;</description>
    <dc:creator>Bob Peterson</dc:creator>
    <dc:date>2012-05-18T11:00:36</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7018">
    <title>[PATCH 12/24] GFS2: Remove bd_list_tr</title>
    <link>http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7018</link>
    <description>&lt;pre&gt;This is another clean up in the logging code. This per-transaction
list was largely unused. Its main function was to ensure that the
number of buffers in a transaction was correct, however that counter
was only used to check the number of buffers in the bd_list_tr, plus
an assert at the end of each transaction. With the assert now changed
to use the calculated buffer counts, we can remove both bd_list_tr and
its associated counter.

This should make the code easier to understand as well as shrinking
a couple of structures.

Signed-off-by: Steven Whitehouse &amp;lt;swhiteho&amp;lt; at &amp;gt;redhat.com&amp;gt;

diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c
index 56dc1f0..a627b3e 100644
--- a/fs/gfs2/aops.c
+++ b/fs/gfs2/aops.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1084,7 +1084,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int gfs2_releasepage(struct page *page, gfp_t gfp_mask)
 bd = bh-&amp;gt;b_private;
 if (bd) {
 gfs2_assert_warn(sdp, bd-&amp;gt;bd_bh == bh);
-gfs2_assert_warn(sdp, list_empty(&amp;amp;bd-&amp;gt;bd_list_tr));
 if (!list_empty(&amp;amp;bd-&amp;gt;bd_le.le_list)) {
 if (!buffer_pinned(bh))
 list_del_init(&amp;amp;bd-&amp;gt;bd_le.le_list);
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c
index 1656df7..cd3e6fb 100644
--- a/fs/gfs2/glops.c
+++ b/fs/gfs2/glops.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -94,7 +94,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void gfs2_ail_empty_gl(struct gfs2_glock *gl)
 /* A shortened, inline version of gfs2_trans_begin() */
 tr.tr_reserved = 1 + gfs2_struct2blk(sdp, tr.tr_revokes, sizeof(u64));
 tr.tr_ip = (unsigned long)__builtin_return_address(0);
-INIT_LIST_HEAD(&amp;amp;tr.tr_list_buf);
 gfs2_log_reserve(sdp, tr.tr_reserved);
 BUG_ON(current-&amp;gt;journal_info);
 current-&amp;gt;journal_info = &amp;amp;tr;
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index dd97f64..e773fbc 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -118,13 +118,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; TAS_BUFFER_FNS(Zeronew, zeronew)
 struct gfs2_bufdata {
 struct buffer_head *bd_bh;
 struct gfs2_glock *bd_gl;
-
-union {
-struct list_head list_tr;
-u64 blkno;
-} u;
-#define bd_list_tr u.list_tr
-#define bd_blkno u.blkno
+u64 bd_blkno;
 
 struct gfs2_log_element bd_le;
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -411,13 +405,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct gfs2_trans {
 
 int tr_touched;
 
-unsigned int tr_num_buf;
 unsigned int tr_num_buf_new;
 unsigned int tr_num_databuf_new;
 unsigned int tr_num_buf_rm;
 unsigned int tr_num_databuf_rm;
-struct list_head tr_list_buf;
-
 unsigned int tr_num_revoke;
 unsigned int tr_num_revoke_rm;
 };
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c
index f5eacb3..2307218 100644
--- a/fs/gfs2/log.c
+++ b/fs/gfs2/log.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -696,21 +696,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void log_refund(struct gfs2_sbd *sdp, struct gfs2_trans *tr)
 gfs2_log_unlock(sdp);
 }
 
-static void buf_lo_incore_commit(struct gfs2_sbd *sdp, struct gfs2_trans *tr)
-{
-struct list_head *head = &amp;amp;tr-&amp;gt;tr_list_buf;
-struct gfs2_bufdata *bd;
-
-gfs2_log_lock(sdp);
-while (!list_empty(head)) {
-bd = list_entry(head-&amp;gt;next, struct gfs2_bufdata, bd_list_tr);
-list_del_init(&amp;amp;bd-&amp;gt;bd_list_tr);
-tr-&amp;gt;tr_num_buf--;
-}
-gfs2_log_unlock(sdp);
-gfs2_assert_warn(sdp, !tr-&amp;gt;tr_num_buf);
-}
-
 /**
  * gfs2_log_commit - Commit a transaction to the log
  * &amp;lt; at &amp;gt;sdp: the filesystem
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -729,8 +714,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void buf_lo_incore_commit(struct gfs2_sbd *sdp, struct gfs2_trans *tr)
 void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *tr)
 {
 log_refund(sdp, tr);
-buf_lo_incore_commit(sdp, tr);
-
 up_read(&amp;amp;sdp-&amp;gt;sd_log_flush_lock);
 
 if (atomic_read(&amp;amp;sdp-&amp;gt;sd_log_pinned) &amp;gt; atomic_read(&amp;amp;sdp-&amp;gt;sd_log_thresh1) ||
diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c
index 7882671..e9709da 100644
--- a/fs/gfs2/lops.c
+++ b/fs/gfs2/lops.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -396,12 +396,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void buf_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le)
 
 lock_buffer(bd-&amp;gt;bd_bh);
 gfs2_log_lock(sdp);
-if (!list_empty(&amp;amp;bd-&amp;gt;bd_list_tr))
-goto out;
 tr = current-&amp;gt;journal_info;
 tr-&amp;gt;tr_touched = 1;
-tr-&amp;gt;tr_num_buf++;
-list_add(&amp;amp;bd-&amp;gt;bd_list_tr, &amp;amp;tr-&amp;gt;tr_list_buf);
 if (!list_empty(&amp;amp;le-&amp;gt;le_list))
 goto out;
 set_bit(GLF_LFLUSH, &amp;amp;bd-&amp;gt;bd_gl-&amp;gt;gl_flags);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -781,18 +777,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void databuf_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le)
 
 lock_buffer(bd-&amp;gt;bd_bh);
 gfs2_log_lock(sdp);
-if (tr) {
-if (!list_empty(&amp;amp;bd-&amp;gt;bd_list_tr))
-goto out;
+if (tr)
 tr-&amp;gt;tr_touched = 1;
-if (gfs2_is_jdata(ip)) {
-tr-&amp;gt;tr_num_buf++;
-list_add(&amp;amp;bd-&amp;gt;bd_list_tr, &amp;amp;tr-&amp;gt;tr_list_buf);
-}
-}
 if (!list_empty(&amp;amp;le-&amp;gt;le_list))
 goto out;
-
 set_bit(GLF_LFLUSH, &amp;amp;bd-&amp;gt;bd_gl-&amp;gt;gl_flags);
 set_bit(GLF_DIRTY, &amp;amp;bd-&amp;gt;bd_gl-&amp;gt;gl_flags);
 if (gfs2_is_jdata(ip)) {
diff --git a/fs/gfs2/meta_io.c b/fs/gfs2/meta_io.c
index 181586e..8a82a4d 100644
--- a/fs/gfs2/meta_io.c
+++ b/fs/gfs2/meta_io.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -293,7 +293,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void gfs2_attach_bufdata(struct gfs2_glock *gl, struct buffer_head *bh,
 bd-&amp;gt;bd_bh = bh;
 bd-&amp;gt;bd_gl = gl;
 
-INIT_LIST_HEAD(&amp;amp;bd-&amp;gt;bd_list_tr);
 if (meta)
 lops_init_le(&amp;amp;bd-&amp;gt;bd_le, &amp;amp;gfs2_buf_lops);
 else
diff --git a/fs/gfs2/trans.c b/fs/gfs2/trans.c
index 86ac75d..8fb6317 100644
--- a/fs/gfs2/trans.c
+++ b/fs/gfs2/trans.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -50,8 +50,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int gfs2_trans_begin(struct gfs2_sbd *sdp, unsigned int blocks,
 if (revokes)
 tr-&amp;gt;tr_reserved += gfs2_struct2blk(sdp, revokes,
    sizeof(u64));
-INIT_LIST_HEAD(&amp;amp;tr-&amp;gt;tr_list_buf);
-
 gfs2_holder_init(sdp-&amp;gt;sd_trans_gl, LM_ST_SHARED, 0, &amp;amp;tr-&amp;gt;tr_t_gh);
 
 error = gfs2_glock_nq(&amp;amp;tr-&amp;gt;tr_t_gh);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -93,10 +91,21 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void gfs2_log_release(struct gfs2_sbd *sdp, unsigned int blks)
 up_read(&amp;amp;sdp-&amp;gt;sd_log_flush_lock);
 }
 
+static void gfs2_print_trans(const struct gfs2_trans *tr)
+{
+print_symbol(KERN_WARNING "GFS2: Transaction created at: %s\n", tr-&amp;gt;tr_ip);
+printk(KERN_WARNING "GFS2: blocks=%u revokes=%u reserved=%u touched=%d\n",
+       tr-&amp;gt;tr_blocks, tr-&amp;gt;tr_revokes, tr-&amp;gt;tr_reserved, tr-&amp;gt;tr_touched);
+printk(KERN_WARNING "GFS2: Buf %u/%u Databuf %u/%u Revoke %u/%u\n",
+       tr-&amp;gt;tr_num_buf_new, tr-&amp;gt;tr_num_buf_rm,
+       tr-&amp;gt;tr_num_databuf_new, tr-&amp;gt;tr_num_databuf_rm,
+       tr-&amp;gt;tr_num_revoke, tr-&amp;gt;tr_num_revoke_rm);
+}
+
 void gfs2_trans_end(struct gfs2_sbd *sdp)
 {
 struct gfs2_trans *tr = current-&amp;gt;journal_info;
-
+s64 nbuf;
 BUG_ON(!tr);
 current-&amp;gt;journal_info = NULL;
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -110,16 +119,13 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void gfs2_trans_end(struct gfs2_sbd *sdp)
 return;
 }
 
-if (gfs2_assert_withdraw(sdp, tr-&amp;gt;tr_num_buf &amp;lt;= tr-&amp;gt;tr_blocks)) {
-fs_err(sdp, "tr_num_buf = %u, tr_blocks = %u ",
-       tr-&amp;gt;tr_num_buf, tr-&amp;gt;tr_blocks);
-print_symbol(KERN_WARNING "GFS2: Transaction created at: %s\n", tr-&amp;gt;tr_ip);
-}
-if (gfs2_assert_withdraw(sdp, tr-&amp;gt;tr_num_revoke &amp;lt;= tr-&amp;gt;tr_revokes)) {
-fs_err(sdp, "tr_num_revoke = %u, tr_revokes = %u ",
-       tr-&amp;gt;tr_num_revoke, tr-&amp;gt;tr_revokes);
-print_symbol(KERN_WARNING "GFS2: Transaction created at: %s\n", tr-&amp;gt;tr_ip);
-}
+nbuf = tr-&amp;gt;tr_num_buf_new + tr-&amp;gt;tr_num_databuf_new;
+nbuf -= tr-&amp;gt;tr_num_buf_rm;
+nbuf -= tr-&amp;gt;tr_num_databuf_rm;
+
+if (gfs2_assert_withdraw(sdp, (nbuf &amp;lt;= tr-&amp;gt;tr_blocks) &amp;amp;&amp;amp;
+       (tr-&amp;gt;tr_num_revoke &amp;lt;= tr-&amp;gt;tr_revokes)))
+gfs2_print_trans(tr);
 
 gfs2_log_commit(sdp, tr);
 if (tr-&amp;gt;tr_t_gh.gh_gl) {
&lt;/pre&gt;</description>
    <dc:creator>Steven Whitehouse</dc:creator>
    <dc:date>2012-05-17T12:23:19</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7017">
    <title>[PATCH 10/24] GFS2: Clean up log write code path</title>
    <link>http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7017</link>
    <description>&lt;pre&gt;Prior to this patch, we have two ways of sending i/o to the log.
One of those is used when we need to allocate both the data
to be written itself and also a buffer head to submit it. This
is done via sb_getblk and friends. This is used mostly for writing
log headers.

The other method is used when writing blocks which have some
in-place counterpart. This is the case for all the metadata
blocks which are journalled, and when journaled data is in use,
for unescaped journalled data blocks.

This patch replaces both of those two methods, and about half
a dozen separate i/o submission points with a single i/o
submission function. We also go direct to bio rather than
using buffer heads, since this allows us to build i/o
requests of the maximum size for the block device in
question. It also reduces the memory required for flushing
the log, which can be very useful in low memory situations.

Signed-off-by: Steven Whitehouse &amp;lt;swhiteho&amp;lt; at &amp;gt;redhat.com&amp;gt;

diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index 47d0bda..dd97f64 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -716,7 +716,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct gfs2_sbd {
 
 struct rw_semaphore sd_log_flush_lock;
 atomic_t sd_log_in_flight;
+struct bio *sd_log_bio;
 wait_queue_head_t sd_log_flush_wait;
+int sd_log_error;
 
 unsigned int sd_log_flush_head;
 u64 sd_log_flush_wrapped;
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c
index d886a17..f5eacb3 100644
--- a/fs/gfs2/log.c
+++ b/fs/gfs2/log.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -357,18 +357,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; retry:
 return 0;
 }
 
-u64 gfs2_log_bmap(struct gfs2_sbd *sdp, unsigned int lbn)
-{
-struct gfs2_journal_extent *je;
-
-list_for_each_entry(je, &amp;amp;sdp-&amp;gt;sd_jdesc-&amp;gt;extent_list, extent_list) {
-if (lbn &amp;gt;= je-&amp;gt;lblock &amp;amp;&amp;amp; lbn &amp;lt; je-&amp;gt;lblock + je-&amp;gt;blocks)
-return je-&amp;gt;dblock + lbn - je-&amp;gt;lblock;
-}
-
-return -1;
-}
-
 /**
  * log_distance - Compute distance between two journal blocks
  * &amp;lt; at &amp;gt;sdp: The GFS2 superblock
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -464,17 +452,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static unsigned int current_tail(struct gfs2_sbd *sdp)
 return tail;
 }
 
-void gfs2_log_incr_head(struct gfs2_sbd *sdp)
-{
-BUG_ON((sdp-&amp;gt;sd_log_flush_head == sdp-&amp;gt;sd_log_tail) &amp;amp;&amp;amp;
-       (sdp-&amp;gt;sd_log_flush_head != sdp-&amp;gt;sd_log_head));
-
-if (++sdp-&amp;gt;sd_log_flush_head == sdp-&amp;gt;sd_jdesc-&amp;gt;jd_blocks) {
-sdp-&amp;gt;sd_log_flush_head = 0;
-sdp-&amp;gt;sd_log_flush_wrapped = 1;
-}
-}
-
 static void log_pull_tail(struct gfs2_sbd *sdp, unsigned int new_tail)
 {
 unsigned int dist = log_distance(sdp, new_tail, sdp-&amp;gt;sd_log_tail);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -580,23 +557,17 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void gfs2_ordered_wait(struct gfs2_sbd *sdp)
 
 static void log_write_header(struct gfs2_sbd *sdp, u32 flags)
 {
-u64 blkno = gfs2_log_bmap(sdp, sdp-&amp;gt;sd_log_flush_head);
-struct buffer_head *bh;
 struct gfs2_log_header *lh;
 unsigned int tail;
 u32 hash;
-
-bh = sb_getblk(sdp-&amp;gt;sd_vfs, blkno);
-lock_buffer(bh);
-memset(bh-&amp;gt;b_data, 0, bh-&amp;gt;b_size);
-set_buffer_uptodate(bh);
-clear_buffer_dirty(bh);
+int rw = WRITE_FLUSH_FUA | REQ_META;
+struct page *page = mempool_alloc(gfs2_page_pool, GFP_NOIO);
+lh = page_address(page);
+clear_page(lh);
 
 gfs2_ail1_empty(sdp);
 tail = current_tail(sdp);
 
-lh = (struct gfs2_log_header *)bh-&amp;gt;b_data;
-memset(lh, 0, sizeof(struct gfs2_log_header));
 lh-&amp;gt;lh_header.mh_magic = cpu_to_be32(GFS2_MAGIC);
 lh-&amp;gt;lh_header.mh_type = cpu_to_be32(GFS2_METATYPE_LH);
 lh-&amp;gt;lh_header.__pad0 = cpu_to_be64(0);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -606,29 +577,22 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void log_write_header(struct gfs2_sbd *sdp, u32 flags)
 lh-&amp;gt;lh_flags = cpu_to_be32(flags);
 lh-&amp;gt;lh_tail = cpu_to_be32(tail);
 lh-&amp;gt;lh_blkno = cpu_to_be32(sdp-&amp;gt;sd_log_flush_head);
-hash = gfs2_disk_hash(bh-&amp;gt;b_data, sizeof(struct gfs2_log_header));
+hash = gfs2_disk_hash(page_address(page), sizeof(struct gfs2_log_header));
 lh-&amp;gt;lh_hash = cpu_to_be32(hash);
 
-bh-&amp;gt;b_end_io = end_buffer_write_sync;
-get_bh(bh);
 if (test_bit(SDF_NOBARRIERS, &amp;amp;sdp-&amp;gt;sd_flags)) {
 gfs2_ordered_wait(sdp);
 log_flush_wait(sdp);
-submit_bh(WRITE_SYNC | REQ_META | REQ_PRIO, bh);
-} else {
-submit_bh(WRITE_FLUSH_FUA | REQ_META, bh);
+rw = WRITE_SYNC | REQ_META | REQ_PRIO;
 }
-wait_on_buffer(bh);
 
-if (!buffer_uptodate(bh))
-gfs2_io_error_bh(sdp, bh);
-brelse(bh);
+sdp-&amp;gt;sd_log_idle = (tail == sdp-&amp;gt;sd_log_flush_head);
+gfs2_log_write_page(sdp, page);
+gfs2_log_flush_bio(sdp, rw);
+log_flush_wait(sdp);
 
 if (sdp-&amp;gt;sd_log_tail != tail)
 log_pull_tail(sdp, tail);
-
-sdp-&amp;gt;sd_log_idle = (tail == sdp-&amp;gt;sd_log_flush_head);
-gfs2_log_incr_head(sdp);
 }
 
 /**
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -674,6 +638,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl)
 
 gfs2_ordered_write(sdp);
 lops_before_commit(sdp);
+gfs2_log_flush_bio(sdp, WRITE);
 
 if (sdp-&amp;gt;sd_log_head != sdp-&amp;gt;sd_log_flush_head) {
 log_write_header(sdp, 0);
diff --git a/fs/gfs2/log.h b/fs/gfs2/log.h
index ff07454..3fd5215 100644
--- a/fs/gfs2/log.h
+++ b/fs/gfs2/log.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -52,8 +52,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; extern unsigned int gfs2_struct2blk(struct gfs2_sbd *sdp, unsigned int nstruct,
     unsigned int ssize);
 
 extern int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks);
-extern void gfs2_log_incr_head(struct gfs2_sbd *sdp);
-extern u64 gfs2_log_bmap(struct gfs2_sbd *sdp, unsigned int lbn);
 extern void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl);
 extern void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *trans);
 extern void gfs2_remove_from_ail(struct gfs2_bufdata *bd);
diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c
index a5937b3..872d3e6 100644
--- a/fs/gfs2/lops.c
+++ b/fs/gfs2/lops.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -127,118 +127,256 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void gfs2_unpin(struct gfs2_sbd *sdp, struct buffer_head *bh,
 atomic_dec(&amp;amp;sdp-&amp;gt;sd_log_pinned);
 }
 
-
-static inline struct gfs2_log_descriptor *bh_log_desc(struct buffer_head *bh)
+static void gfs2_log_incr_head(struct gfs2_sbd *sdp)
 {
-return (struct gfs2_log_descriptor *)bh-&amp;gt;b_data;
+BUG_ON((sdp-&amp;gt;sd_log_flush_head == sdp-&amp;gt;sd_log_tail) &amp;amp;&amp;amp;
+       (sdp-&amp;gt;sd_log_flush_head != sdp-&amp;gt;sd_log_head));
+
+if (++sdp-&amp;gt;sd_log_flush_head == sdp-&amp;gt;sd_jdesc-&amp;gt;jd_blocks) {
+sdp-&amp;gt;sd_log_flush_head = 0;
+sdp-&amp;gt;sd_log_flush_wrapped = 1;
+}
 }
 
-static inline __be64 *bh_log_ptr(struct buffer_head *bh)
+static u64 gfs2_log_bmap(struct gfs2_sbd *sdp)
 {
-struct gfs2_log_descriptor *ld = bh_log_desc(bh);
-return (__force __be64 *)(ld + 1);
+unsigned int lbn = sdp-&amp;gt;sd_log_flush_head;
+struct gfs2_journal_extent *je;
+u64 block;
+
+list_for_each_entry(je, &amp;amp;sdp-&amp;gt;sd_jdesc-&amp;gt;extent_list, extent_list) {
+if (lbn &amp;gt;= je-&amp;gt;lblock &amp;amp;&amp;amp; lbn &amp;lt; je-&amp;gt;lblock + je-&amp;gt;blocks) {
+block = je-&amp;gt;dblock + lbn - je-&amp;gt;lblock;
+gfs2_log_incr_head(sdp);
+return block;
+}
+}
+
+return -1;
 }
 
-static inline __be64 *bh_ptr_end(struct buffer_head *bh)
+/**
+ * gfs2_end_log_write_bh - end log write of pagecache data with buffers
+ * &amp;lt; at &amp;gt;sdp: The superblock
+ * &amp;lt; at &amp;gt;bvec: The bio_vec
+ * &amp;lt; at &amp;gt;error: The i/o status
+ *
+ * This finds the relavent buffers and unlocks then and sets the
+ * error flag according to the status of the i/o request. This is
+ * used when the log is writing data which has an in-place version
+ * that is pinned in the pagecache.
+ */
+
+static void gfs2_end_log_write_bh(struct gfs2_sbd *sdp, struct bio_vec *bvec,
+  int error)
 {
-return (__force __be64 *)(bh-&amp;gt;b_data + bh-&amp;gt;b_size);
+struct buffer_head *bh, *next;
+struct page *page = bvec-&amp;gt;bv_page;
+unsigned size;
+
+bh = page_buffers(page);
+size = bvec-&amp;gt;bv_len;
+while (bh_offset(bh) &amp;lt; bvec-&amp;gt;bv_offset)
+bh = bh-&amp;gt;b_this_page;
+do {
+if (error)
+set_buffer_write_io_error(bh);
+unlock_buffer(bh);
+next = bh-&amp;gt;b_this_page;
+size -= bh-&amp;gt;b_size;
+brelse(bh);
+bh = next;
+} while(bh &amp;amp;&amp;amp; size);
 }
 
 /**
- * gfs2_log_write_endio - End of I/O for a log buffer
- * &amp;lt; at &amp;gt;bh: The buffer head
- * &amp;lt; at &amp;gt;uptodate: I/O Status
+ * gfs2_end_log_write - end of i/o to the log
+ * &amp;lt; at &amp;gt;bio: The bio
+ * &amp;lt; at &amp;gt;error: Status of i/o request
+ *
+ * Each bio_vec contains either data from the pagecache or data
+ * relating to the log itself. Here we iterate over the bio_vec
+ * array, processing both kinds of data.
  *
  */
 
-static void gfs2_log_write_endio(struct buffer_head *bh, int uptodate)
+static void gfs2_end_log_write(struct bio *bio, int error)
 {
-struct gfs2_sbd *sdp = bh-&amp;gt;b_private;
-bh-&amp;gt;b_private = NULL;
+struct gfs2_sbd *sdp = bio-&amp;gt;bi_private;
+struct bio_vec *bvec;
+struct page *page;
+int i;
+
+if (error) {
+sdp-&amp;gt;sd_log_error = error;
+fs_err(sdp, "Error %d writing to log\n", error);
+}
+
+bio_for_each_segment(bvec, bio, i) {
+page = bvec-&amp;gt;bv_page;
+if (page_has_buffers(page))
+gfs2_end_log_write_bh(sdp, bvec, error);
+else
+mempool_free(page, gfs2_page_pool);
+}
 
-end_buffer_write_sync(bh, uptodate);
+bio_put(bio);
 if (atomic_dec_and_test(&amp;amp;sdp-&amp;gt;sd_log_in_flight))
 wake_up(&amp;amp;sdp-&amp;gt;sd_log_flush_wait);
 }
 
 /**
- * gfs2_log_get_buf - Get and initialize a buffer to use for log control data
- * &amp;lt; at &amp;gt;sdp: The GFS2 superblock
+ * gfs2_log_flush_bio - Submit any pending log bio
+ * &amp;lt; at &amp;gt;sdp: The superblock
+ * &amp;lt; at &amp;gt;rw: The rw flags
  *
- * tReturns: the buffer_head
+ * Submit any pending part-built or full bio to the block device. If
+ * there is no pending bio, then this is a no-op.
  */
 
-static struct buffer_head *gfs2_log_get_buf(struct gfs2_sbd *sdp)
+void gfs2_log_flush_bio(struct gfs2_sbd *sdp, int rw)
 {
-u64 blkno = gfs2_log_bmap(sdp, sdp-&amp;gt;sd_log_flush_head);
-struct buffer_head *bh;
+if (sdp-&amp;gt;sd_log_bio) {
+atomic_inc(&amp;amp;sdp-&amp;gt;sd_log_in_flight);
+submit_bio(rw, sdp-&amp;gt;sd_log_bio);
+sdp-&amp;gt;sd_log_bio = NULL;
+}
+}
 
-bh = sb_getblk(sdp-&amp;gt;sd_vfs, blkno);
-lock_buffer(bh);
-memset(bh-&amp;gt;b_data, 0, bh-&amp;gt;b_size);
-set_buffer_uptodate(bh);
-clear_buffer_dirty(bh);
-gfs2_log_incr_head(sdp);
-atomic_inc(&amp;amp;sdp-&amp;gt;sd_log_in_flight);
-bh-&amp;gt;b_private = sdp;
-bh-&amp;gt;b_end_io = gfs2_log_write_endio;
+/**
+ * gfs2_log_alloc_bio - Allocate a new bio for log writing
+ * &amp;lt; at &amp;gt;sdp: The superblock
+ * &amp;lt; at &amp;gt;blkno: The next device block number we want to write to
+ *
+ * This should never be called when there is a cached bio in the
+ * super block. When it returns, there will be a cached bio in the
+ * super block which will have as many bio_vecs as the device is
+ * happy to handle.
+ *
+ * Returns: Newly allocated bio
+ */
 
-return bh;
+static struct bio *gfs2_log_alloc_bio(struct gfs2_sbd *sdp, u64 blkno)
+{
+struct super_block *sb = sdp-&amp;gt;sd_vfs;
+unsigned nrvecs = bio_get_nr_vecs(sb-&amp;gt;s_bdev);
+struct bio *bio;
+
+BUG_ON(sdp-&amp;gt;sd_log_bio);
+
+while (1) {
+bio = bio_alloc(GFP_NOIO, nrvecs);
+if (likely(bio))
+break;
+nrvecs = max(nrvecs/2, 1U);
+}
+
+bio-&amp;gt;bi_sector = blkno * (sb-&amp;gt;s_blocksize &amp;gt;&amp;gt; 9);
+bio-&amp;gt;bi_bdev = sb-&amp;gt;s_bdev;
+bio-&amp;gt;bi_end_io = gfs2_end_log_write;
+bio-&amp;gt;bi_private = sdp;
+
+sdp-&amp;gt;sd_log_bio = bio;
+
+return bio;
 }
 
 /**
- * gfs2_fake_write_endio - 
- * &amp;lt; at &amp;gt;bh: The buffer head
- * &amp;lt; at &amp;gt;uptodate: The I/O Status
+ * gfs2_log_get_bio - Get cached log bio, or allocate a new one
+ * &amp;lt; at &amp;gt;sdp: The superblock
+ * &amp;lt; at &amp;gt;blkno: The device block number we want to write to
+ *
+ * If there is a cached bio, then if the next block number is sequential
+ * with the previous one, return it, otherwise flush the bio to the
+ * device. If there is not a cached bio, or we just flushed it, then
+ * allocate a new one.
  *
+ * Returns: The bio to use for log writes
  */
 
-static void gfs2_fake_write_endio(struct buffer_head *bh, int uptodate)
+static struct bio *gfs2_log_get_bio(struct gfs2_sbd *sdp, u64 blkno)
 {
-struct buffer_head *real_bh = bh-&amp;gt;b_private;
-struct gfs2_bufdata *bd = real_bh-&amp;gt;b_private;
-struct gfs2_sbd *sdp = bd-&amp;gt;bd_gl-&amp;gt;gl_sbd;
+struct bio *bio = sdp-&amp;gt;sd_log_bio;
+u64 nblk;
+
+if (bio) {
+nblk = bio-&amp;gt;bi_sector + bio_sectors(bio);
+nblk &amp;gt;&amp;gt;= sdp-&amp;gt;sd_fsb2bb_shift;
+if (blkno == nblk)
+return bio;
+gfs2_log_flush_bio(sdp, WRITE);
+}
 
-end_buffer_write_sync(bh, uptodate);
-mempool_free(bh, gfs2_bh_pool);
-unlock_buffer(real_bh);
-brelse(real_bh);
-if (atomic_dec_and_test(&amp;amp;sdp-&amp;gt;sd_log_in_flight))
-wake_up(&amp;amp;sdp-&amp;gt;sd_log_flush_wait);
+return gfs2_log_alloc_bio(sdp, blkno);
 }
 
+
 /**
- * gfs2_log_write_buf - write metadata buffer to log
+ * gfs2_log_write - write to log
  * &amp;lt; at &amp;gt;sdp: the filesystem
- * &amp;lt; at &amp;gt;real: the in-place buffer head
+ * &amp;lt; at &amp;gt;page: the page to write
+ * &amp;lt; at &amp;gt;size: the size of the data to write
+ * &amp;lt; at &amp;gt;offset: the offset within the page 
  *
+ * Try and add the page segment to the current bio. If that fails,
+ * submit the current bio to the device and create a new one, and
+ * then add the page segment to that.
  */
 
-static void gfs2_log_write_buf(struct gfs2_sbd *sdp, struct buffer_head *real)
+static void gfs2_log_write(struct gfs2_sbd *sdp, struct page *page,
+   unsigned size, unsigned offset)
 {
-u64 blkno = gfs2_log_bmap(sdp, sdp-&amp;gt;sd_log_flush_head);
-struct buffer_head *bh;
+u64 blkno = gfs2_log_bmap(sdp);
+struct bio *bio;
+int ret;
+
+bio = gfs2_log_get_bio(sdp, blkno);
+ret = bio_add_page(bio, page, size, offset);
+if (ret == 0) {
+gfs2_log_flush_bio(sdp, WRITE);
+bio = gfs2_log_alloc_bio(sdp, blkno);
+ret = bio_add_page(bio, page, size, offset);
+WARN_ON(ret == 0);
+}
+}
 
-bh = mempool_alloc(gfs2_bh_pool, GFP_NOFS);
-atomic_set(&amp;amp;bh-&amp;gt;b_count, 1);
-bh-&amp;gt;b_state = (1 &amp;lt;&amp;lt; BH_Mapped) | (1 &amp;lt;&amp;lt; BH_Uptodate) | (1 &amp;lt;&amp;lt; BH_Lock);
-set_bh_page(bh, real-&amp;gt;b_page, bh_offset(real));
-bh-&amp;gt;b_blocknr = blkno;
-bh-&amp;gt;b_size = sdp-&amp;gt;sd_sb.sb_bsize;
-bh-&amp;gt;b_bdev = sdp-&amp;gt;sd_vfs-&amp;gt;s_bdev;
-bh-&amp;gt;b_private = real;
-bh-&amp;gt;b_end_io = gfs2_fake_write_endio;
+/**
+ * gfs2_log_write_bh - write a buffer's content to the log
+ * &amp;lt; at &amp;gt;sdp: The super block
+ * &amp;lt; at &amp;gt;bh: The buffer pointing to the in-place location
+ * 
+ * This writes the content of the buffer to the next available location
+ * in the log. The buffer will be unlocked once the i/o to the log has
+ * completed.
+ */
+
+static void gfs2_log_write_bh(struct gfs2_sbd *sdp, struct buffer_head *bh)
+{
+gfs2_log_write(sdp, bh-&amp;gt;b_page, bh-&amp;gt;b_size, bh_offset(bh));
+}
 
-gfs2_log_incr_head(sdp);
-atomic_inc(&amp;amp;sdp-&amp;gt;sd_log_in_flight);
+/**
+ * gfs2_log_write_page - write one block stored in a page, into the log
+ * &amp;lt; at &amp;gt;sdp: The superblock
+ * &amp;lt; at &amp;gt;page: The struct page
+ *
+ * This writes the first block-sized part of the page into the log. Note
+ * that the page must have been allocated from the gfs2_page_pool mempool
+ * and that after this has been called, ownership has been transferred and
+ * the page may be freed at any time.
+ */
 
-submit_bh(WRITE, bh);
+void gfs2_log_write_page(struct gfs2_sbd *sdp, struct page *page)
+{
+struct super_block *sb = sdp-&amp;gt;sd_vfs;
+gfs2_log_write(sdp, page, sb-&amp;gt;s_blocksize, 0);
 }
 
-static struct buffer_head *gfs2_get_log_desc(struct gfs2_sbd *sdp, u32 ld_type)
+static struct page *gfs2_get_log_desc(struct gfs2_sbd *sdp, u32 ld_type)
 {
-struct buffer_head *bh = gfs2_log_get_buf(sdp);
-struct gfs2_log_descriptor *ld = bh_log_desc(bh);
+void *page = mempool_alloc(gfs2_page_pool, GFP_NOIO);
+struct gfs2_log_descriptor *ld = page_address(page);
+clear_page(ld);
 ld-&amp;gt;ld_header.mh_magic = cpu_to_be32(GFS2_MAGIC);
 ld-&amp;gt;ld_header.mh_type = cpu_to_be32(GFS2_METATYPE_LD);
 ld-&amp;gt;ld_header.mh_format = cpu_to_be32(GFS2_FORMAT_LD);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -246,8 +384,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static struct buffer_head *gfs2_get_log_desc(struct gfs2_sbd *sdp, u32 ld_type)
 ld-&amp;gt;ld_length = 0;
 ld-&amp;gt;ld_data1 = 0;
 ld-&amp;gt;ld_data2 = 0;
-memset(ld-&amp;gt;ld_reserved, 0, sizeof(ld-&amp;gt;ld_reserved));
-return bh;
+return page;
 }
 
 static void buf_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -283,9 +420,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; out:
 
 static void buf_lo_before_commit(struct gfs2_sbd *sdp)
 {
-struct buffer_head *bh;
 struct gfs2_log_descriptor *ld;
 struct gfs2_bufdata *bd1 = NULL, *bd2;
+struct page *page;
 unsigned int total;
 unsigned int limit;
 unsigned int num;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -303,10 +440,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void buf_lo_before_commit(struct gfs2_sbd *sdp)
 if (total &amp;gt; limit)
 num = limit;
 gfs2_log_unlock(sdp);
-bh = gfs2_get_log_desc(sdp, GFS2_LOG_DESC_METADATA);
+page = gfs2_get_log_desc(sdp, GFS2_LOG_DESC_METADATA);
+ld = page_address(page);
 gfs2_log_lock(sdp);
-ld = bh_log_desc(bh);
-ptr = bh_log_ptr(bh);
+ptr = (__be64 *)(ld + 1);
 ld-&amp;gt;ld_length = cpu_to_be32(num + 1);
 ld-&amp;gt;ld_data1 = cpu_to_be32(num);
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -319,7 +456,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void buf_lo_before_commit(struct gfs2_sbd *sdp)
 }
 
 gfs2_log_unlock(sdp);
-submit_bh(WRITE, bh);
+gfs2_log_write_page(sdp, page);
 gfs2_log_lock(sdp);
 
 n = 0;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -328,7 +465,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void buf_lo_before_commit(struct gfs2_sbd *sdp)
 get_bh(bd2-&amp;gt;bd_bh);
 gfs2_log_unlock(sdp);
 lock_buffer(bd2-&amp;gt;bd_bh);
-gfs2_log_write_buf(sdp, bd2-&amp;gt;bd_bh);
+gfs2_log_write_bh(sdp, bd2-&amp;gt;bd_bh);
 gfs2_log_lock(sdp);
 if (++n &amp;gt;= num)
 break;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -453,16 +590,16 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void revoke_lo_before_commit(struct gfs2_sbd *sdp)
 {
 struct gfs2_log_descriptor *ld;
 struct gfs2_meta_header *mh;
-struct buffer_head *bh;
 unsigned int offset;
 struct list_head *head = &amp;amp;sdp-&amp;gt;sd_log_le_revoke;
 struct gfs2_bufdata *bd;
+struct page *page;
 
 if (!sdp-&amp;gt;sd_log_num_revoke)
 return;
 
-bh = gfs2_get_log_desc(sdp, GFS2_LOG_DESC_REVOKE);
-ld = bh_log_desc(bh);
+page = gfs2_get_log_desc(sdp, GFS2_LOG_DESC_REVOKE);
+ld = page_address(page);
 ld-&amp;gt;ld_length = cpu_to_be32(gfs2_struct2blk(sdp, sdp-&amp;gt;sd_log_num_revoke,
     sizeof(u64)));
 ld-&amp;gt;ld_data1 = cpu_to_be32(sdp-&amp;gt;sd_log_num_revoke);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -472,22 +609,23 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void revoke_lo_before_commit(struct gfs2_sbd *sdp)
 sdp-&amp;gt;sd_log_num_revoke--;
 
 if (offset + sizeof(u64) &amp;gt; sdp-&amp;gt;sd_sb.sb_bsize) {
-submit_bh(WRITE, bh);
 
-bh = gfs2_log_get_buf(sdp);
-mh = (struct gfs2_meta_header *)bh-&amp;gt;b_data;
+gfs2_log_write_page(sdp, page);
+page = mempool_alloc(gfs2_page_pool, GFP_NOIO);
+mh = page_address(page);
+clear_page(mh);
 mh-&amp;gt;mh_magic = cpu_to_be32(GFS2_MAGIC);
 mh-&amp;gt;mh_type = cpu_to_be32(GFS2_METATYPE_LB);
 mh-&amp;gt;mh_format = cpu_to_be32(GFS2_FORMAT_LB);
 offset = sizeof(struct gfs2_meta_header);
 }
 
-*(__be64 *)(bh-&amp;gt;b_data + offset) = cpu_to_be64(bd-&amp;gt;bd_blkno);
+*(__be64 *)(page_address(page) + offset) = cpu_to_be64(bd-&amp;gt;bd_blkno);
 offset += sizeof(u64);
 }
 gfs2_assert_withdraw(sdp, !sdp-&amp;gt;sd_log_num_revoke);
 
-submit_bh(WRITE, bh);
+gfs2_log_write_page(sdp, page);
 }
 
 static void revoke_lo_after_commit(struct gfs2_sbd *sdp, struct gfs2_ail *ai)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -650,57 +788,51 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void gfs2_check_magic(struct buffer_head *bh)
 kunmap_atomic(kaddr);
 }
 
-static void gfs2_write_blocks(struct gfs2_sbd *sdp, struct buffer_head *bh,
+static void gfs2_write_blocks(struct gfs2_sbd *sdp,
+      struct gfs2_log_descriptor *ld,
+      struct page *page,
       struct list_head *list, struct list_head *done,
       unsigned int n)
 {
-struct buffer_head *bh1;
-struct gfs2_log_descriptor *ld;
 struct gfs2_bufdata *bd;
 __be64 *ptr;
 
-if (!bh)
+if (!ld)
 return;
 
-ld = bh_log_desc(bh);
 ld-&amp;gt;ld_length = cpu_to_be32(n + 1);
 ld-&amp;gt;ld_data1 = cpu_to_be32(n);
-
-ptr = bh_log_ptr(bh);
+ptr = (__force __be64 *)(ld + 1);
 
-get_bh(bh);
-submit_bh(WRITE, bh);
+gfs2_log_write_page(sdp, page);
 gfs2_log_lock(sdp);
-while(!list_empty(list)) {
+while (!list_empty(list)) {
 bd = list_entry(list-&amp;gt;next, struct gfs2_bufdata, bd_le.le_list);
 list_move_tail(&amp;amp;bd-&amp;gt;bd_le.le_list, done);
 get_bh(bd-&amp;gt;bd_bh);
-while (be64_to_cpu(*ptr) != bd-&amp;gt;bd_bh-&amp;gt;b_blocknr) {
-gfs2_log_incr_head(sdp);
-ptr += 2;
-}
 gfs2_log_unlock(sdp);
 lock_buffer(bd-&amp;gt;bd_bh);
 if (buffer_escaped(bd-&amp;gt;bd_bh)) {
 void *kaddr;
-bh1 = gfs2_log_get_buf(sdp);
+page = mempool_alloc(gfs2_page_pool, GFP_NOIO);
+ptr = page_address(page);
 kaddr = kmap_atomic(bd-&amp;gt;bd_bh-&amp;gt;b_page);
-memcpy(bh1-&amp;gt;b_data, kaddr + bh_offset(bd-&amp;gt;bd_bh),
-       bh1-&amp;gt;b_size);
+memcpy(ptr, kaddr + bh_offset(bd-&amp;gt;bd_bh),
+       bd-&amp;gt;bd_bh-&amp;gt;b_size);
 kunmap_atomic(kaddr);
-*(__be32 *)bh1-&amp;gt;b_data = 0;
+*(__be32 *)ptr = 0;
 clear_buffer_escaped(bd-&amp;gt;bd_bh);
 unlock_buffer(bd-&amp;gt;bd_bh);
 brelse(bd-&amp;gt;bd_bh);
-submit_bh(WRITE, bh1);
+gfs2_log_write_page(sdp, page);
 } else {
-gfs2_log_write_buf(sdp, bd-&amp;gt;bd_bh);
+gfs2_log_write_bh(sdp, bd-&amp;gt;bd_bh);
 }
+n--;
 gfs2_log_lock(sdp);
-ptr += 2;
 }
 gfs2_log_unlock(sdp);
-brelse(bh);
+BUG_ON(n != 0);
 }
 
 /**
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -711,7 +843,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void gfs2_write_blocks(struct gfs2_sbd *sdp, struct buffer_head *bh,
 static void databuf_lo_before_commit(struct gfs2_sbd *sdp)
 {
 struct gfs2_bufdata *bd = NULL;
-struct buffer_head *bh = NULL;
+struct gfs2_log_descriptor *ld = NULL;
+struct page *page = NULL;
 unsigned int n = 0;
 __be64 *ptr = NULL, *end = NULL;
 LIST_HEAD(processed);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -721,11 +854,13 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void databuf_lo_before_commit(struct gfs2_sbd *sdp)
 while (!list_empty(&amp;amp;sdp-&amp;gt;sd_log_le_databuf)) {
 if (ptr == end) {
 gfs2_log_unlock(sdp);
-gfs2_write_blocks(sdp, bh, &amp;amp;in_progress, &amp;amp;processed, n);
+gfs2_write_blocks(sdp, ld, page, &amp;amp;in_progress, &amp;amp;processed, n);
 n = 0;
-bh = gfs2_get_log_desc(sdp, GFS2_LOG_DESC_JDATA);
-ptr = bh_log_ptr(bh);
-end = bh_ptr_end(bh) - 1;
+page = gfs2_get_log_desc(sdp, GFS2_LOG_DESC_JDATA);
+ld = page_address(page);
+ptr = (__force __be64 *)(ld + 1);
+end = (__force __be64 *)(page_address(page) + sdp-&amp;gt;sd_vfs-&amp;gt;s_blocksize);
+end--;
 gfs2_log_lock(sdp);
 continue;
 }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -733,11 +868,11 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void databuf_lo_before_commit(struct gfs2_sbd *sdp)
 list_move_tail(&amp;amp;bd-&amp;gt;bd_le.le_list, &amp;amp;in_progress);
 gfs2_check_magic(bd-&amp;gt;bd_bh);
 *ptr++ = cpu_to_be64(bd-&amp;gt;bd_bh-&amp;gt;b_blocknr);
-*ptr++ = cpu_to_be64(buffer_escaped(bh) ? 1 : 0);
+*ptr++ = cpu_to_be64(buffer_escaped(bd-&amp;gt;bd_bh) ? 1 : 0);
 n++;
 }
 gfs2_log_unlock(sdp);
-gfs2_write_blocks(sdp, bh, &amp;amp;in_progress, &amp;amp;processed, n);
+gfs2_write_blocks(sdp, ld, page, &amp;amp;in_progress, &amp;amp;processed, n);
 gfs2_log_lock(sdp);
 list_splice(&amp;amp;processed, &amp;amp;sdp-&amp;gt;sd_log_le_databuf);
 gfs2_log_unlock(sdp);
diff --git a/fs/gfs2/lops.h b/fs/gfs2/lops.h
index 3c0b273..825356d 100644
--- a/fs/gfs2/lops.h
+++ b/fs/gfs2/lops.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -27,6 +27,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; extern const struct gfs2_log_operations gfs2_rg_lops;
 extern const struct gfs2_log_operations gfs2_databuf_lops;
 
 extern const struct gfs2_log_operations *gfs2_log_ops[];
+extern void gfs2_log_write_page(struct gfs2_sbd *sdp, struct page *page);
+extern void gfs2_log_flush_bio(struct gfs2_sbd *sdp, int rw);
 
 static inline unsigned int buf_limit(struct gfs2_sbd *sdp)
 {
diff --git a/fs/gfs2/main.c b/fs/gfs2/main.c
index ce17944..6cdb0f2 100644
--- a/fs/gfs2/main.c
+++ b/fs/gfs2/main.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -70,16 +70,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void gfs2_init_gl_aspace_once(void *foo)
 address_space_init_once(mapping);
 }
 
-static void *gfs2_bh_alloc(gfp_t mask, void *data)
-{
-return alloc_buffer_head(mask);
-}
-
-static void gfs2_bh_free(void *ptr, void *data)
-{
-return free_buffer_head(ptr);
-}
-
 /**
  * init_gfs2_fs - Register GFS2 as a filesystem
  *
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -170,8 +160,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int __init init_gfs2_fs(void)
 if (!gfs2_control_wq)
 goto fail_recovery;
 
-gfs2_bh_pool = mempool_create(1024, gfs2_bh_alloc, gfs2_bh_free, NULL);
-if (!gfs2_bh_pool)
+gfs2_page_pool = mempool_create_page_pool(64, 0);
+if (!gfs2_page_pool)
 goto fail_control;
 
 gfs2_register_debugfs();
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -234,7 +224,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void __exit exit_gfs2_fs(void)
 
 rcu_barrier();
 
-mempool_destroy(gfs2_bh_pool);
+mempool_destroy(gfs2_page_pool);
 kmem_cache_destroy(gfs2_rsrv_cachep);
 kmem_cache_destroy(gfs2_quotad_cachep);
 kmem_cache_destroy(gfs2_rgrpd_cachep);
diff --git a/fs/gfs2/util.c b/fs/gfs2/util.c
index 3afc6ac..f00d7c5 100644
--- a/fs/gfs2/util.c
+++ b/fs/gfs2/util.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -26,7 +26,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct kmem_cache *gfs2_bufdata_cachep __read_mostly;
 struct kmem_cache *gfs2_rgrpd_cachep __read_mostly;
 struct kmem_cache *gfs2_quotad_cachep __read_mostly;
 struct kmem_cache *gfs2_rsrv_cachep __read_mostly;
-mempool_t *gfs2_bh_pool __read_mostly;
+mempool_t *gfs2_page_pool __read_mostly;
 
 void gfs2_assert_i(struct gfs2_sbd *sdp)
 {
diff --git a/fs/gfs2/util.h b/fs/gfs2/util.h
index 8fbe6cf..3586b0d 100644
--- a/fs/gfs2/util.h
+++ b/fs/gfs2/util.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -153,7 +153,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; extern struct kmem_cache *gfs2_bufdata_cachep;
 extern struct kmem_cache *gfs2_rgrpd_cachep;
 extern struct kmem_cache *gfs2_quotad_cachep;
 extern struct kmem_cache *gfs2_rsrv_cachep;
-extern mempool_t *gfs2_bh_pool;
+extern mempool_t *gfs2_page_pool;
 
 static inline unsigned int gfs2_tune_get_i(struct gfs2_tune *gt,
    unsigned int *p)
&lt;/pre&gt;</description>
    <dc:creator>Steven Whitehouse</dc:creator>
    <dc:date>2012-05-17T12:23:17</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7016">
    <title>[PATCH 17/24] GFS2: eliminate log elements andsimplify</title>
    <link>http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7016</link>
    <description>&lt;pre&gt;From: Bob Peterson &amp;lt;rpeterso&amp;lt; at &amp;gt;redhat.com&amp;gt;

This patch eliminates the gfs2_log_element data structure and
rolls its two components into the gfs2_bufdata. This makes the code
easier to understand and makes it easier to migrate to a rbtree
to keep the list sorted.

Signed-off-by: Bob Peterson &amp;lt;rpeterso&amp;lt; at &amp;gt;redhat.com&amp;gt;
Signed-off-by: Steven Whitehouse &amp;lt;swhiteho&amp;lt; at &amp;gt;redhat.com&amp;gt;

diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c
index 695bbe1..e80a464 100644
--- a/fs/gfs2/aops.c
+++ b/fs/gfs2/aops.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -942,8 +942,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void gfs2_discard(struct gfs2_sbd *sdp, struct buffer_head *bh)
 clear_buffer_dirty(bh);
 bd = bh-&amp;gt;b_private;
 if (bd) {
-if (!list_empty(&amp;amp;bd-&amp;gt;bd_le.le_list) &amp;amp;&amp;amp; !buffer_pinned(bh))
-list_del_init(&amp;amp;bd-&amp;gt;bd_le.le_list);
+if (!list_empty(&amp;amp;bd-&amp;gt;bd_list) &amp;amp;&amp;amp; !buffer_pinned(bh))
+list_del_init(&amp;amp;bd-&amp;gt;bd_list);
 else
 gfs2_remove_from_journal(bh, current-&amp;gt;journal_info, 0);
 }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1083,9 +1083,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int gfs2_releasepage(struct page *page, gfp_t gfp_mask)
 bd = bh-&amp;gt;b_private;
 if (bd) {
 gfs2_assert_warn(sdp, bd-&amp;gt;bd_bh == bh);
-if (!list_empty(&amp;amp;bd-&amp;gt;bd_le.le_list)) {
+if (!list_empty(&amp;amp;bd-&amp;gt;bd_list)) {
 if (!buffer_pinned(bh))
-list_del_init(&amp;amp;bd-&amp;gt;bd_le.le_list);
+list_del_init(&amp;amp;bd-&amp;gt;bd_list);
 else
 bd = NULL;
 }
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index f1189a2..aa9949e 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -26,7 +26,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 #define DIO_METADATA0x00000020
 
 struct gfs2_log_operations;
-struct gfs2_log_element;
+struct gfs2_bufdata;
 struct gfs2_holder;
 struct gfs2_glock;
 struct gfs2_quota_data;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -52,7 +52,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct gfs2_log_header_host {
  */
 
 struct gfs2_log_operations {
-void (*lo_add) (struct gfs2_sbd *sdp, struct gfs2_log_element *le);
+void (*lo_add) (struct gfs2_sbd *sdp, struct gfs2_bufdata *bd);
 void (*lo_before_commit) (struct gfs2_sbd *sdp);
 void (*lo_after_commit) (struct gfs2_sbd *sdp, struct gfs2_ail *ai);
 void (*lo_before_scan) (struct gfs2_jdesc *jd,
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -64,11 +64,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct gfs2_log_operations {
 const char *lo_name;
 };
 
-struct gfs2_log_element {
-struct list_head le_list;
-const struct gfs2_log_operations *le_ops;
-};
-
 #define GBF_FULL 1
 
 struct gfs2_bitmap {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -120,7 +115,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct gfs2_bufdata {
 struct gfs2_glock *bd_gl;
 u64 bd_blkno;
 
-struct gfs2_log_element bd_le;
+struct list_head bd_list;
+const struct gfs2_log_operations *bd_ops;
 
 struct gfs2_ail *bd_ail;
 struct list_head bd_ail_st_list;
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c
index db9cb18..f4beeb9 100644
--- a/fs/gfs2/log.c
+++ b/fs/gfs2/log.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -486,8 +486,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int bd_cmp(void *priv, struct list_head *a, struct list_head *b)
 {
 struct gfs2_bufdata *bda, *bdb;
 
-bda = list_entry(a, struct gfs2_bufdata, bd_le.le_list);
-bdb = list_entry(b, struct gfs2_bufdata, bd_le.le_list);
+bda = list_entry(a, struct gfs2_bufdata, bd_list);
+bdb = list_entry(b, struct gfs2_bufdata, bd_list);
 
 if (bda-&amp;gt;bd_bh-&amp;gt;b_blocknr &amp;lt; bdb-&amp;gt;bd_bh-&amp;gt;b_blocknr)
 return -1;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -505,8 +505,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void gfs2_ordered_write(struct gfs2_sbd *sdp)
 gfs2_log_lock(sdp);
 list_sort(NULL, &amp;amp;sdp-&amp;gt;sd_log_le_ordered, &amp;amp;bd_cmp);
 while (!list_empty(&amp;amp;sdp-&amp;gt;sd_log_le_ordered)) {
-bd = list_entry(sdp-&amp;gt;sd_log_le_ordered.next, struct gfs2_bufdata, bd_le.le_list);
-list_move(&amp;amp;bd-&amp;gt;bd_le.le_list, &amp;amp;written);
+bd = list_entry(sdp-&amp;gt;sd_log_le_ordered.next, struct gfs2_bufdata, bd_list);
+list_move(&amp;amp;bd-&amp;gt;bd_list, &amp;amp;written);
 bh = bd-&amp;gt;bd_bh;
 if (!buffer_dirty(bh))
 continue;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -533,7 +533,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void gfs2_ordered_wait(struct gfs2_sbd *sdp)
 
 gfs2_log_lock(sdp);
 while (!list_empty(&amp;amp;sdp-&amp;gt;sd_log_le_ordered)) {
-bd = list_entry(sdp-&amp;gt;sd_log_le_ordered.prev, struct gfs2_bufdata, bd_le.le_list);
+bd = list_entry(sdp-&amp;gt;sd_log_le_ordered.prev, struct gfs2_bufdata, bd_list);
 bh = bd-&amp;gt;bd_bh;
 if (buffer_locked(bh)) {
 get_bh(bh);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -543,7 +543,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void gfs2_ordered_wait(struct gfs2_sbd *sdp)
 gfs2_log_lock(sdp);
 continue;
 }
-list_del_init(&amp;amp;bd-&amp;gt;bd_le.le_list);
+list_del_init(&amp;amp;bd-&amp;gt;bd_list);
 }
 gfs2_log_unlock(sdp);
 }
diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c
index 11fedb5..852c1be 100644
--- a/fs/gfs2/lops.c
+++ b/fs/gfs2/lops.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -388,9 +388,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static struct page *gfs2_get_log_desc(struct gfs2_sbd *sdp, u32 ld_type,
 return page;
 }
 
-static void buf_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le)
+static void buf_lo_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd)
 {
-struct gfs2_bufdata *bd = container_of(le, struct gfs2_bufdata, bd_le);
 struct gfs2_meta_header *mh;
 struct gfs2_trans *tr;
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -398,7 +397,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void buf_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le)
 gfs2_log_lock(sdp);
 tr = current-&amp;gt;journal_info;
 tr-&amp;gt;tr_touched = 1;
-if (!list_empty(&amp;amp;le-&amp;gt;le_list))
+if (!list_empty(&amp;amp;bd-&amp;gt;bd_list))
 goto out;
 set_bit(GLF_LFLUSH, &amp;amp;bd-&amp;gt;bd_gl-&amp;gt;gl_flags);
 set_bit(GLF_DIRTY, &amp;amp;bd-&amp;gt;bd_gl-&amp;gt;gl_flags);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -408,7 +407,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void buf_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le)
 mh-&amp;gt;__pad0 = cpu_to_be64(0);
 mh-&amp;gt;mh_jid = cpu_to_be32(sdp-&amp;gt;sd_jdesc-&amp;gt;jd_jid);
 sdp-&amp;gt;sd_log_num_buf++;
-list_add(&amp;amp;le-&amp;gt;le_list, &amp;amp;sdp-&amp;gt;sd_log_le_buf);
+list_add(&amp;amp;bd-&amp;gt;bd_list, &amp;amp;sdp-&amp;gt;sd_log_le_buf);
 tr-&amp;gt;tr_num_buf_new++;
 out:
 gfs2_log_unlock(sdp);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -440,7 +439,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void gfs2_before_commit(struct gfs2_sbd *sdp, unsigned int limit,
 __be64 *ptr;
 
 gfs2_log_lock(sdp);
-bd1 = bd2 = list_prepare_entry(bd1, blist, bd_le.le_list);
+bd1 = bd2 = list_prepare_entry(bd1, blist, bd_list);
 while(total) {
 num = total;
 if (total &amp;gt; limit)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -452,7 +451,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void gfs2_before_commit(struct gfs2_sbd *sdp, unsigned int limit,
 ptr = (__be64 *)(ld + 1);
 
 n = 0;
-list_for_each_entry_continue(bd1, blist, bd_le.le_list) {
+list_for_each_entry_continue(bd1, blist, bd_list) {
 *ptr++ = cpu_to_be64(bd1-&amp;gt;bd_bh-&amp;gt;b_blocknr);
 if (is_databuf) {
 gfs2_check_magic(bd1-&amp;gt;bd_bh);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -467,7 +466,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void gfs2_before_commit(struct gfs2_sbd *sdp, unsigned int limit,
 gfs2_log_lock(sdp);
 
 n = 0;
-list_for_each_entry_continue(bd2, blist, bd_le.le_list) {
+list_for_each_entry_continue(bd2, blist, bd_list) {
 get_bh(bd2-&amp;gt;bd_bh);
 gfs2_log_unlock(sdp);
 lock_buffer(bd2-&amp;gt;bd_bh);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -513,8 +512,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void buf_lo_after_commit(struct gfs2_sbd *sdp, struct gfs2_ail *ai)
 struct gfs2_bufdata *bd;
 
 while (!list_empty(head)) {
-bd = list_entry(head-&amp;gt;next, struct gfs2_bufdata, bd_le.le_list);
-list_del_init(&amp;amp;bd-&amp;gt;bd_le.le_list);
+bd = list_entry(head-&amp;gt;next, struct gfs2_bufdata, bd_list);
+list_del_init(&amp;amp;bd-&amp;gt;bd_list);
 sdp-&amp;gt;sd_log_num_buf--;
 
 gfs2_unpin(sdp, bd-&amp;gt;bd_bh, ai);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -601,9 +600,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void buf_lo_after_scan(struct gfs2_jdesc *jd, int error, int pass)
         jd-&amp;gt;jd_jid, sdp-&amp;gt;sd_replayed_blocks, sdp-&amp;gt;sd_found_blocks);
 }
 
-static void revoke_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le)
+static void revoke_lo_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd)
 {
-struct gfs2_bufdata *bd = container_of(le, struct gfs2_bufdata, bd_le);
 struct gfs2_glock *gl = bd-&amp;gt;bd_gl;
 struct gfs2_trans *tr;
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -613,7 +611,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void revoke_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le)
 sdp-&amp;gt;sd_log_num_revoke++;
 atomic_inc(&amp;amp;gl-&amp;gt;gl_revokes);
 set_bit(GLF_LFLUSH, &amp;amp;gl-&amp;gt;gl_flags);
-list_add(&amp;amp;le-&amp;gt;le_list, &amp;amp;sdp-&amp;gt;sd_log_le_revoke);
+list_add(&amp;amp;bd-&amp;gt;bd_list, &amp;amp;sdp-&amp;gt;sd_log_le_revoke);
 }
 
 static void revoke_lo_before_commit(struct gfs2_sbd *sdp)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -634,7 +632,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void revoke_lo_before_commit(struct gfs2_sbd *sdp)
 ld = page_address(page);
 offset = sizeof(struct gfs2_log_descriptor);
 
-list_for_each_entry(bd, head, bd_le.le_list) {
+list_for_each_entry(bd, head, bd_list) {
 sdp-&amp;gt;sd_log_num_revoke--;
 
 if (offset + sizeof(u64) &amp;gt; sdp-&amp;gt;sd_sb.sb_bsize) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -664,8 +662,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void revoke_lo_after_commit(struct gfs2_sbd *sdp, struct gfs2_ail *ai)
 struct gfs2_glock *gl;
 
 while (!list_empty(head)) {
-bd = list_entry(head-&amp;gt;next, struct gfs2_bufdata, bd_le.le_list);
-list_del_init(&amp;amp;bd-&amp;gt;bd_le.le_list);
+bd = list_entry(head-&amp;gt;next, struct gfs2_bufdata, bd_list);
+list_del_init(&amp;amp;bd-&amp;gt;bd_list);
 gl = bd-&amp;gt;bd_gl;
 atomic_dec(&amp;amp;gl-&amp;gt;gl_revokes);
 clear_bit(GLF_LFLUSH, &amp;amp;gl-&amp;gt;gl_flags);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -768,9 +766,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void revoke_lo_after_scan(struct gfs2_jdesc *jd, int error, int pass)
  *    blocks, which isn't an enormous overhead but twice as much as
  *    for normal metadata blocks.
  */
-static void databuf_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le)
+static void databuf_lo_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd)
 {
-struct gfs2_bufdata *bd = container_of(le, struct gfs2_bufdata, bd_le);
 struct gfs2_trans *tr = current-&amp;gt;journal_info;
 struct address_space *mapping = bd-&amp;gt;bd_bh-&amp;gt;b_page-&amp;gt;mapping;
 struct gfs2_inode *ip = GFS2_I(mapping-&amp;gt;host);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -779,7 +776,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void databuf_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le)
 gfs2_log_lock(sdp);
 if (tr)
 tr-&amp;gt;tr_touched = 1;
-if (!list_empty(&amp;amp;le-&amp;gt;le_list))
+if (!list_empty(&amp;amp;bd-&amp;gt;bd_list))
 goto out;
 set_bit(GLF_LFLUSH, &amp;amp;bd-&amp;gt;bd_gl-&amp;gt;gl_flags);
 set_bit(GLF_DIRTY, &amp;amp;bd-&amp;gt;bd_gl-&amp;gt;gl_flags);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -787,9 +784,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void databuf_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le)
 gfs2_pin(sdp, bd-&amp;gt;bd_bh);
 tr-&amp;gt;tr_num_databuf_new++;
 sdp-&amp;gt;sd_log_num_databuf++;
-list_add_tail(&amp;amp;le-&amp;gt;le_list, &amp;amp;sdp-&amp;gt;sd_log_le_databuf);
+list_add_tail(&amp;amp;bd-&amp;gt;bd_list, &amp;amp;sdp-&amp;gt;sd_log_le_databuf);
 } else {
-list_add_tail(&amp;amp;le-&amp;gt;le_list, &amp;amp;sdp-&amp;gt;sd_log_le_ordered);
+list_add_tail(&amp;amp;bd-&amp;gt;bd_list, &amp;amp;sdp-&amp;gt;sd_log_le_ordered);
 }
 out:
 gfs2_log_unlock(sdp);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -885,8 +882,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void databuf_lo_after_commit(struct gfs2_sbd *sdp, struct gfs2_ail *ai)
 struct gfs2_bufdata *bd;
 
 while (!list_empty(head)) {
-bd = list_entry(head-&amp;gt;next, struct gfs2_bufdata, bd_le.le_list);
-list_del_init(&amp;amp;bd-&amp;gt;bd_le.le_list);
+bd = list_entry(head-&amp;gt;next, struct gfs2_bufdata, bd_list);
+list_del_init(&amp;amp;bd-&amp;gt;bd_list);
 sdp-&amp;gt;sd_log_num_databuf--;
 gfs2_unpin(sdp, bd-&amp;gt;bd_bh, ai);
 }
diff --git a/fs/gfs2/lops.h b/fs/gfs2/lops.h
index 825356d..954a330 100644
--- a/fs/gfs2/lops.h
+++ b/fs/gfs2/lops.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -46,17 +46,17 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static inline unsigned int databuf_limit(struct gfs2_sbd *sdp)
 return limit;
 }
 
-static inline void lops_init_le(struct gfs2_log_element *le,
+static inline void lops_init_le(struct gfs2_bufdata *bd,
 const struct gfs2_log_operations *lops)
 {
-INIT_LIST_HEAD(&amp;amp;le-&amp;gt;le_list);
-le-&amp;gt;le_ops = lops;
+INIT_LIST_HEAD(&amp;amp;bd-&amp;gt;bd_list);
+bd-&amp;gt;bd_ops = lops;
 }
 
-static inline void lops_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le)
+static inline void lops_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd)
 {
-if (le-&amp;gt;le_ops-&amp;gt;lo_add)
-le-&amp;gt;le_ops-&amp;gt;lo_add(sdp, le);
+if (bd-&amp;gt;bd_ops-&amp;gt;lo_add)
+bd-&amp;gt;bd_ops-&amp;gt;lo_add(sdp, bd);
 }
 
 static inline void lops_before_commit(struct gfs2_sbd *sdp)
diff --git a/fs/gfs2/meta_io.c b/fs/gfs2/meta_io.c
index 8a82a4d..7f69ae2 100644
--- a/fs/gfs2/meta_io.c
+++ b/fs/gfs2/meta_io.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -294,9 +294,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void gfs2_attach_bufdata(struct gfs2_glock *gl, struct buffer_head *bh,
 bd-&amp;gt;bd_gl = gl;
 
 if (meta)
-lops_init_le(&amp;amp;bd-&amp;gt;bd_le, &amp;amp;gfs2_buf_lops);
+lops_init_le(bd, &amp;amp;gfs2_buf_lops);
 else
-lops_init_le(&amp;amp;bd-&amp;gt;bd_le, &amp;amp;gfs2_databuf_lops);
+lops_init_le(bd, &amp;amp;gfs2_databuf_lops);
 bh-&amp;gt;b_private = bd;
 
 if (meta)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -312,7 +312,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void gfs2_remove_from_journal(struct buffer_head *bh, struct gfs2_trans *tr, int
 if (test_clear_buffer_pinned(bh)) {
 trace_gfs2_pin(bd, 0);
 atomic_dec(&amp;amp;sdp-&amp;gt;sd_log_pinned);
-list_del_init(&amp;amp;bd-&amp;gt;bd_le.le_list);
+list_del_init(&amp;amp;bd-&amp;gt;bd_list);
 if (meta) {
 gfs2_assert_warn(sdp, sdp-&amp;gt;sd_log_num_buf);
 sdp-&amp;gt;sd_log_num_buf--;
diff --git a/fs/gfs2/trans.c b/fs/gfs2/trans.c
index 8fb6317..ad3e2fb 100644
--- a/fs/gfs2/trans.c
+++ b/fs/gfs2/trans.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -158,16 +158,16 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void gfs2_trans_add_bh(struct gfs2_glock *gl, struct buffer_head *bh, int meta)
 gfs2_attach_bufdata(gl, bh, meta);
 bd = bh-&amp;gt;b_private;
 }
-lops_add(sdp, &amp;amp;bd-&amp;gt;bd_le);
+lops_add(sdp, bd);
 }
 
 void gfs2_trans_add_revoke(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd)
 {
-BUG_ON(!list_empty(&amp;amp;bd-&amp;gt;bd_le.le_list));
+BUG_ON(!list_empty(&amp;amp;bd-&amp;gt;bd_list));
 BUG_ON(!list_empty(&amp;amp;bd-&amp;gt;bd_ail_st_list));
 BUG_ON(!list_empty(&amp;amp;bd-&amp;gt;bd_ail_gl_list));
-lops_init_le(&amp;amp;bd-&amp;gt;bd_le, &amp;amp;gfs2_revoke_lops);
-lops_add(sdp, &amp;amp;bd-&amp;gt;bd_le);
+lops_init_le(bd, &amp;amp;gfs2_revoke_lops);
+lops_add(sdp, bd);
 }
 
 void gfs2_trans_add_unrevoke(struct gfs2_sbd *sdp, u64 blkno, unsigned int len)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -177,9 +177,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void gfs2_trans_add_unrevoke(struct gfs2_sbd *sdp, u64 blkno, unsigned int len)
 unsigned int n = len;
 
 gfs2_log_lock(sdp);
-list_for_each_entry_safe(bd, tmp, &amp;amp;sdp-&amp;gt;sd_log_le_revoke, bd_le.le_list) {
+list_for_each_entry_safe(bd, tmp, &amp;amp;sdp-&amp;gt;sd_log_le_revoke, bd_list) {
 if ((bd-&amp;gt;bd_blkno &amp;gt;= blkno) &amp;amp;&amp;amp; (bd-&amp;gt;bd_blkno &amp;lt; (blkno + len))) {
-list_del_init(&amp;amp;bd-&amp;gt;bd_le.le_list);
+list_del_init(&amp;amp;bd-&amp;gt;bd_list);
 gfs2_assert_withdraw(sdp, sdp-&amp;gt;sd_log_num_revoke);
 sdp-&amp;gt;sd_log_num_revoke--;
 kmem_cache_free(gfs2_bufdata_cachep, bd);
&lt;/pre&gt;</description>
    <dc:creator>Steven Whitehouse</dc:creator>
    <dc:date>2012-05-17T12:23:24</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7015">
    <title>[PATCH 19/24] GFS2: Remove redundant metadata blocktype check</title>
    <link>http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7015</link>
    <description>&lt;pre&gt;From: Bob Peterson &amp;lt;rpeterso&amp;lt; at &amp;gt;redhat.com&amp;gt;

This patch removes a redundant metadata block check. See description below.

Signed-off-by: Bob Peterson &amp;lt;rpeterso&amp;lt; at &amp;gt;redhat.com&amp;gt;
Signed-off-by: Steven Whitehouse &amp;lt;swhiteho&amp;lt; at &amp;gt;redhat.com&amp;gt;

diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c
index cd3e6fb..4bdcf37 100644
--- a/fs/gfs2/glops.c
+++ b/fs/gfs2/glops.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -378,11 +378,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int gfs2_inode_refresh(struct gfs2_inode *ip)
 if (error)
 return error;
 
-if (gfs2_metatype_check(GFS2_SB(&amp;amp;ip-&amp;gt;i_inode), dibh, GFS2_METATYPE_DI)) {
-brelse(dibh);
-return -EIO;
-}
-
 error = gfs2_dinode_in(ip, dibh-&amp;gt;b_data);
 brelse(dibh);
 clear_bit(GIF_INVALID, &amp;amp;ip-&amp;gt;i_flags);
&lt;/pre&gt;</description>
    <dc:creator>Steven Whitehouse</dc:creator>
    <dc:date>2012-05-17T12:23:26</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7014">
    <title>[PATCH 22/24] GFS2: Eliminate unused "new"parameter to gfs2_meta_indirect_buffer</title>
    <link>http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7014</link>
    <description>&lt;pre&gt;From: Bob Peterson &amp;lt;rpeterso&amp;lt; at &amp;gt;redhat.com&amp;gt;

It turns out that the "new" parameter to function gfs2_meta_indirect_buffer
was always being passed in as zero. Therefore, this patch eliminates it
and simplifies the function.

Signed-off-by: Bob Peterson &amp;lt;rpeterso&amp;lt; at &amp;gt;redhat.com&amp;gt;
Signed-off-by: Steven Whitehouse &amp;lt;swhiteho&amp;lt; at &amp;gt;redhat.com&amp;gt;

diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c
index 420bbeb..dab5409 100644
--- a/fs/gfs2/bmap.c
+++ b/fs/gfs2/bmap.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -324,7 +324,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int lookup_metapath(struct gfs2_inode *ip, struct metapath *mp)
 if (!dblock)
 return x + 1;
 
-ret = gfs2_meta_indirect_buffer(ip, x+1, dblock, 0, &amp;amp;mp-&amp;gt;mp_bh[x+1]);
+ret = gfs2_meta_indirect_buffer(ip, x+1, dblock, &amp;amp;mp-&amp;gt;mp_bh[x+1]);
 if (ret)
 return ret;
 }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -882,7 +882,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int recursive_scan(struct gfs2_inode *ip, struct buffer_head *dibh,
 top = (__be64 *)(bh-&amp;gt;b_data + sizeof(struct gfs2_dinode)) + mp-&amp;gt;mp_list[0];
 bottom = (__be64 *)(bh-&amp;gt;b_data + sizeof(struct gfs2_dinode)) + sdp-&amp;gt;sd_diptrs;
 } else {
-error = gfs2_meta_indirect_buffer(ip, height, block, 0, &amp;amp;bh);
+error = gfs2_meta_indirect_buffer(ip, height, block, &amp;amp;bh);
 if (error)
 return error;
 
diff --git a/fs/gfs2/meta_io.c b/fs/gfs2/meta_io.c
index 7f69ae2..6c1e5d1 100644
--- a/fs/gfs2/meta_io.c
+++ b/fs/gfs2/meta_io.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -374,33 +374,24 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void gfs2_meta_wipe(struct gfs2_inode *ip, u64 bstart, u32 blen)
  * &amp;lt; at &amp;gt;ip: The GFS2 inode
  * &amp;lt; at &amp;gt;height: The level of this buf in the metadata (indir addr) tree (if any)
  * &amp;lt; at &amp;gt;num: The block number (device relative) of the buffer
- * &amp;lt; at &amp;gt;new: Non-zero if we may create a new buffer
  * &amp;lt; at &amp;gt;bhp: the buffer is returned here
  *
  * Returns: errno
  */
 
 int gfs2_meta_indirect_buffer(struct gfs2_inode *ip, int height, u64 num,
-      int new, struct buffer_head **bhp)
+      struct buffer_head **bhp)
 {
 struct gfs2_sbd *sdp = GFS2_SB(&amp;amp;ip-&amp;gt;i_inode);
 struct gfs2_glock *gl = ip-&amp;gt;i_gl;
 struct buffer_head *bh;
 int ret = 0;
+u32 mtype = height ? GFS2_METATYPE_IN : GFS2_METATYPE_DI;
 
-if (new) {
-BUG_ON(height == 0);
-bh = gfs2_meta_new(gl, num);
-gfs2_trans_add_bh(ip-&amp;gt;i_gl, bh, 1);
-gfs2_metatype_set(bh, GFS2_METATYPE_IN, GFS2_FORMAT_IN);
-gfs2_buffer_clear_tail(bh, sizeof(struct gfs2_meta_header));
-} else {
-u32 mtype = height ? GFS2_METATYPE_IN : GFS2_METATYPE_DI;
-ret = gfs2_meta_read(gl, num, DIO_WAIT, &amp;amp;bh);
-if (ret == 0 &amp;amp;&amp;amp; gfs2_metatype_check(sdp, bh, mtype)) {
-brelse(bh);
-ret = -EIO;
-}
+ret = gfs2_meta_read(gl, num, DIO_WAIT, &amp;amp;bh);
+if (ret == 0 &amp;amp;&amp;amp; gfs2_metatype_check(sdp, bh, mtype)) {
+brelse(bh);
+ret = -EIO;
 }
 *bhp = bh;
 return ret;
diff --git a/fs/gfs2/meta_io.h b/fs/gfs2/meta_io.h
index 22c5265..c30973b 100644
--- a/fs/gfs2/meta_io.h
+++ b/fs/gfs2/meta_io.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -65,12 +65,12 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void gfs2_remove_from_journal(struct buffer_head *bh, struct gfs2_trans *tr,
 void gfs2_meta_wipe(struct gfs2_inode *ip, u64 bstart, u32 blen);
 
 int gfs2_meta_indirect_buffer(struct gfs2_inode *ip, int height, u64 num,
-      int new, struct buffer_head **bhp);
+      struct buffer_head **bhp);
 
 static inline int gfs2_meta_inode_buffer(struct gfs2_inode *ip,
  struct buffer_head **bhp)
 {
-return gfs2_meta_indirect_buffer(ip, 0, ip-&amp;gt;i_no_addr, 0, bhp);
+return gfs2_meta_indirect_buffer(ip, 0, ip-&amp;gt;i_no_addr, bhp);
 }
 
 struct buffer_head *gfs2_meta_ra(struct gfs2_glock *gl, u64 dblock, u32 extlen);
&lt;/pre&gt;</description>
    <dc:creator>Steven Whitehouse</dc:creator>
    <dc:date>2012-05-17T12:23:29</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7013">
    <title>[PATCH 20/24] GFS2: Update main gfs2 doc</title>
    <link>http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7013</link>
    <description>&lt;pre&gt;Various items were a bit out of date, so this is a refresh to the
latest info.

Signed-off-by: Steven Whitehouse &amp;lt;swhiteho&amp;lt; at &amp;gt;redhat.com&amp;gt;

diff --git a/Documentation/filesystems/gfs2.txt b/Documentation/filesystems/gfs2.txt
index 4cda926..cc4f230 100644
--- a/Documentation/filesystems/gfs2.txt
+++ b/Documentation/filesystems/gfs2.txt
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1,7 +1,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 Global File System
 ------------------
 
-http://sources.redhat.com/cluster/wiki/
+https://fedorahosted.org/cluster/wiki/HomePage
 
 GFS is a cluster file system. It allows a cluster of computers to
 simultaneously use a block device that is shared between them (with FC,
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -30,7 +30,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; needed, simply:
 
 If you are using Fedora, you need to install the gfs2-utils package
 and, for lock_dlm, you will also need to install the cman package
-and write a cluster.conf as per the documentation.
+and write a cluster.conf as per the documentation. For F17 and above
+cman has been replaced by the dlm package.
 
 GFS2 is not on-disk compatible with previous versions of GFS, but it
 is pretty close.
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -39,8 +40,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; The following man pages can be found at the URL above:
   fsck.gfs2to repair a filesystem
   gfs2_growto expand a filesystem online
   gfs2_jaddto add journals to a filesystem online
-  gfs2_toolto manipulate, examine and tune a filesystem
-  gfs2_quotato examine and change quota values in a filesystem
+  tunegfs2to manipulate, examine and tune a filesystem
   gfs2_convertto convert a gfs filesystem to gfs2 in-place
-  mount.gfs2to help mount(8) mount a filesystem
   mkfs.gfs2to make a filesystem
&lt;/pre&gt;</description>
    <dc:creator>Steven Whitehouse</dc:creator>
    <dc:date>2012-05-17T12:23:27</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7012">
    <title>[PATCH 09/24] GFS2: Use variable rather than qa todetermine if unstuff necessary</title>
    <link>http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7012</link>
    <description>&lt;pre&gt;From: Bob Peterson &amp;lt;rpeterso&amp;lt; at &amp;gt;redhat.com&amp;gt;

In the future, the qadata structure will be eliminated and merged
back in with the block reservation structure, after we extend the
lifespan of that. This patch is a step forward in eliminating the
qadata structure. It adds a variable to the do_grow function to
determine when unstuffing is necessary, and has been done.

Signed-off-by: Bob Peterson &amp;lt;rpeterso&amp;lt; at &amp;gt;redhat.com&amp;gt;
Signed-off-by: Steven Whitehouse &amp;lt;swhiteho&amp;lt; at &amp;gt;redhat.com&amp;gt;

diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c
index 03c04fe..420bbeb 100644
--- a/fs/gfs2/bmap.c
+++ b/fs/gfs2/bmap.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1169,6 +1169,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int do_grow(struct inode *inode, u64 size)
 struct buffer_head *dibh;
 struct gfs2_qadata *qa = NULL;
 int error;
+int unstuff = 0;
 
 if (gfs2_is_stuffed(ip) &amp;amp;&amp;amp;
     (size &amp;gt; (sdp-&amp;gt;sd_sb.sb_bsize - sizeof(struct gfs2_dinode)))) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1183,13 +1184,14 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int do_grow(struct inode *inode, u64 size)
 error = gfs2_inplace_reserve(ip, 1);
 if (error)
 goto do_grow_qunlock;
+unstuff = 1;
 }
 
 error = gfs2_trans_begin(sdp, RES_DINODE + RES_STATFS + RES_RG_BIT, 0);
 if (error)
 goto do_grow_release;
 
-if (qa) {
+if (unstuff) {
 error = gfs2_unstuff_dinode(ip, NULL);
 if (error)
 goto do_end_trans;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1208,7 +1210,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int do_grow(struct inode *inode, u64 size)
 do_end_trans:
 gfs2_trans_end(sdp);
 do_grow_release:
-if (qa) {
+if (unstuff) {
 gfs2_inplace_release(ip);
 do_grow_qunlock:
 gfs2_quota_unlock(ip);
&lt;/pre&gt;</description>
    <dc:creator>Steven Whitehouse</dc:creator>
    <dc:date>2012-05-17T12:23:16</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7011">
    <title>[PATCH 13/24] GFS2: Remove unused argument fromgfs2_internal_read</title>
    <link>http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7011</link>
    <description>&lt;pre&gt;From: Andrew Price &amp;lt;anprice&amp;lt; at &amp;gt;redhat.com&amp;gt;

gfs2_internal_read accepts an unused ra_state argument, left over from
when we did readahead on the rindex. Since there are currently no plans
to add back this readahead, this patch removes the ra_state parameter
and updates the functions which call gfs2_internal_read accordingly.

Signed-off-by: Andrew Price &amp;lt;anprice&amp;lt; at &amp;gt;redhat.com&amp;gt;
Signed-off-by: Steven Whitehouse &amp;lt;swhiteho&amp;lt; at &amp;gt;redhat.com&amp;gt;

diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c
index a627b3e..695bbe1 100644
--- a/fs/gfs2/aops.c
+++ b/fs/gfs2/aops.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -517,15 +517,14 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; out:
 /**
  * gfs2_internal_read - read an internal file
  * &amp;lt; at &amp;gt;ip: The gfs2 inode
- * &amp;lt; at &amp;gt;ra_state: The readahead state (or NULL for no readahead)
  * &amp;lt; at &amp;gt;buf: The buffer to fill
  * &amp;lt; at &amp;gt;pos: The file position
  * &amp;lt; at &amp;gt;size: The amount to read
  *
  */
 
-int gfs2_internal_read(struct gfs2_inode *ip, struct file_ra_state *ra_state,
-                       char *buf, loff_t *pos, unsigned size)
+int gfs2_internal_read(struct gfs2_inode *ip, char *buf, loff_t *pos,
+                       unsigned size)
 {
 struct address_space *mapping = ip-&amp;gt;i_inode.i_mapping;
 unsigned long index = *pos / PAGE_CACHE_SIZE;
diff --git a/fs/gfs2/inode.h b/fs/gfs2/inode.h
index 5d345b4..c53c747 100644
--- a/fs/gfs2/inode.h
+++ b/fs/gfs2/inode.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -17,7 +17,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 
 extern int gfs2_releasepage(struct page *page, gfp_t gfp_mask);
 extern int gfs2_internal_read(struct gfs2_inode *ip,
-      struct file_ra_state *ra_state,
       char *buf, loff_t *pos, unsigned size);
 extern void gfs2_set_aops(struct inode *inode);
 
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
index 6019da3..45d9171 100644
--- a/fs/gfs2/quota.c
+++ b/fs/gfs2/quota.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -652,7 +652,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int gfs2_adjust_quota(struct gfs2_inode *ip, loff_t loc,
 }
 
 memset(&amp;amp;q, 0, sizeof(struct gfs2_quota));
-err = gfs2_internal_read(ip, NULL, (char *)&amp;amp;q, &amp;amp;loc, sizeof(q));
+err = gfs2_internal_read(ip, (char *)&amp;amp;q, &amp;amp;loc, sizeof(q));
 if (err &amp;lt; 0)
 return err;
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -852,7 +852,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int update_qd(struct gfs2_sbd *sdp, struct gfs2_quota_data *qd)
 
 memset(&amp;amp;q, 0, sizeof(struct gfs2_quota));
 pos = qd2offset(qd);
-error = gfs2_internal_read(ip, NULL, (char *)&amp;amp;q, &amp;amp;pos, sizeof(q));
+error = gfs2_internal_read(ip, (char *)&amp;amp;q, &amp;amp;pos, sizeof(q));
 if (error &amp;lt; 0)
 return error;
 
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index 7a1cf67..b550e5c 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -541,16 +541,14 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; u64 gfs2_ri_total(struct gfs2_sbd *sdp)
 struct inode *inode = sdp-&amp;gt;sd_rindex;
 struct gfs2_inode *ip = GFS2_I(inode);
 char buf[sizeof(struct gfs2_rindex)];
-struct file_ra_state ra_state;
 int error, rgrps;
 
-file_ra_state_init(&amp;amp;ra_state, inode-&amp;gt;i_mapping);
 for (rgrps = 0;; rgrps++) {
 loff_t pos = rgrps * sizeof(struct gfs2_rindex);
 
 if (pos + sizeof(struct gfs2_rindex) &amp;gt; i_size_read(inode))
 break;
-error = gfs2_internal_read(ip, &amp;amp;ra_state, buf, &amp;amp;pos,
+error = gfs2_internal_read(ip, buf, &amp;amp;pos,
    sizeof(struct gfs2_rindex));
 if (error != sizeof(struct gfs2_rindex))
 break;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -586,14 +584,12 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int rgd_insert(struct gfs2_rgrpd *rgd)
 
 /**
  * read_rindex_entry - Pull in a new resource index entry from the disk
- * &amp;lt; at &amp;gt;ip: The GFS2 inode
- * &amp;lt; at &amp;gt;ra_state: The read-ahead state
+ * &amp;lt; at &amp;gt;ip: Pointer to the rindex inode
  *
  * Returns: 0 on success, &amp;gt; 0 on EOF, error code otherwise
  */
 
-static int read_rindex_entry(struct gfs2_inode *ip,
-     struct file_ra_state *ra_state)
+static int read_rindex_entry(struct gfs2_inode *ip)
 {
 struct gfs2_sbd *sdp = GFS2_SB(&amp;amp;ip-&amp;gt;i_inode);
 loff_t pos = sdp-&amp;gt;sd_rgrps * sizeof(struct gfs2_rindex);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -604,7 +600,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int read_rindex_entry(struct gfs2_inode *ip,
 if (pos &amp;gt;= i_size_read(&amp;amp;ip-&amp;gt;i_inode))
 return 1;
 
-error = gfs2_internal_read(ip, ra_state, (char *)&amp;amp;buf, &amp;amp;pos,
+error = gfs2_internal_read(ip, (char *)&amp;amp;buf, &amp;amp;pos,
    sizeof(struct gfs2_rindex));
 
 if (error != sizeof(struct gfs2_rindex))
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -660,13 +656,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; fail:
 static int gfs2_ri_update(struct gfs2_inode *ip)
 {
 struct gfs2_sbd *sdp = GFS2_SB(&amp;amp;ip-&amp;gt;i_inode);
-struct inode *inode = &amp;amp;ip-&amp;gt;i_inode;
-struct file_ra_state ra_state;
 int error;
 
-file_ra_state_init(&amp;amp;ra_state, inode-&amp;gt;i_mapping);
 do {
-error = read_rindex_entry(ip, &amp;amp;ra_state);
+error = read_rindex_entry(ip);
 } while (error == 0);
 
 if (error &amp;lt; 0)
&lt;/pre&gt;</description>
    <dc:creator>Steven Whitehouse</dc:creator>
    <dc:date>2012-05-17T12:23:20</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7010">
    <title>[PATCH 07/24] GFS2: Fix function parameter commentsin rgrp.c</title>
    <link>http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7010</link>
    <description>&lt;pre&gt;From: Bob Peterson &amp;lt;rpeterso&amp;lt; at &amp;gt;redhat.com&amp;gt;

This patch just fixes a bunch of function parameter comments.
Slowly, over the years, the comments have gotten out of date
(mostly my fault, as I haven't been good at keeping them up to date).
This patch rectifies some of that.

Signed-off-by: Bob Peterson &amp;lt;rpeterso&amp;lt; at &amp;gt;redhat.com&amp;gt;
Signed-off-by: Steven Whitehouse &amp;lt;swhiteho&amp;lt; at &amp;gt;redhat.com&amp;gt;

diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index 55dd010..5968eae 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -119,6 +119,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static inline void gfs2_setbit(struct gfs2_rgrpd *rgd, unsigned char *buf1,
 
 /**
  * gfs2_testbit - test a bit in the bitmaps
+ * &amp;lt; at &amp;gt;rgd: the resource group descriptor
  * &amp;lt; at &amp;gt;buffer: the buffer that holds the bitmaps
  * &amp;lt; at &amp;gt;buflen: the length (in bytes) of the buffer
  * &amp;lt; at &amp;gt;block: the block to read
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -180,7 +181,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static inline u64 gfs2_bit_search(const __le64 *ptr, u64 mask, u8 state)
 /**
  * gfs2_bitfit - Search an rgrp's bitmap buffer to find a bit-pair representing
  *       a block in a given allocation state.
- * &amp;lt; at &amp;gt;buffer: the buffer that holds the bitmaps
+ * &amp;lt; at &amp;gt;buf: the buffer that holds the bitmaps
  * &amp;lt; at &amp;gt;len: the length (in bytes) of the buffer
  * &amp;lt; at &amp;gt;goal: start search at this block's bit-pair (within &amp;lt; at &amp;gt;buffer)
  * &amp;lt; at &amp;gt;state: GFS2_BLKST_XXX the state of the block we're looking for.
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -232,6 +233,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static u32 gfs2_bitfit(const u8 *buf, const unsigned int len,
 
 /**
  * gfs2_bitcount - count the number of bits in a certain state
+ * &amp;lt; at &amp;gt;rgd: the resource group descriptor
  * &amp;lt; at &amp;gt;buffer: the buffer that holds the bitmaps
  * &amp;lt; at &amp;gt;buflen: the length (in bytes) of the buffer
  * &amp;lt; at &amp;gt;state: the state of the block we're looking for
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -265,7 +267,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static u32 gfs2_bitcount(struct gfs2_rgrpd *rgd, const u8 *buffer,
 
 /**
  * gfs2_rgrp_verify - Verify that a resource group is consistent
- * &amp;lt; at &amp;gt;sdp: the filesystem
  * &amp;lt; at &amp;gt;rgd: the rgrp
  *
  */
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -323,7 +324,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static inline int rgrp_contains_block(struct gfs2_rgrpd *rgd, u64 block)
 /**
  * gfs2_blk2rgrpd - Find resource group for a given data/meta block number
  * &amp;lt; at &amp;gt;sdp: The GFS2 superblock
- * &amp;lt; at &amp;gt;n: The data block number
+ * &amp;lt; at &amp;gt;blk: The data block number
+ * &amp;lt; at &amp;gt;exact: True if this needs to be an exact match
  *
  * Returns: The resource group, or NULL if not found
  */
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -381,7 +383,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct gfs2_rgrpd *gfs2_rgrpd_get_first(struct gfs2_sbd *sdp)
 
 /**
  * gfs2_rgrpd_get_next - get the next RG
- * &amp;lt; at &amp;gt;rgd: A RG
+ * &amp;lt; at &amp;gt;rgd: the resource group descriptor
  *
  * Returns: The next rgrp
  */
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -530,6 +532,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int compute_bitstructs(struct gfs2_rgrpd *rgd)
 
 /**
  * gfs2_ri_total - Total up the file system space, according to the rindex.
+ * &amp;lt; at &amp;gt;sdp: the filesystem
  *
  */
 u64 gfs2_ri_total(struct gfs2_sbd *sdp)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -583,7 +586,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int rgd_insert(struct gfs2_rgrpd *rgd)
 
 /**
  * read_rindex_entry - Pull in a new resource index entry from the disk
- * &amp;lt; at &amp;gt;gl: The glock covering the rindex inode
+ * &amp;lt; at &amp;gt;ip: The GFS2 inode
+ * &amp;lt; at &amp;gt;ra_state: The read-ahead state
  *
  * Returns: 0 on success, &amp;gt; 0 on EOF, error code otherwise
  */
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -742,7 +746,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void gfs2_rgrp_out(struct gfs2_rgrpd *rgd, void *buf)
 
 /**
  * gfs2_rgrp_go_lock - Read in a RG's header and bitmaps
- * &amp;lt; at &amp;gt;rgd: the struct gfs2_rgrpd describing the RG to read in
+ * &amp;lt; at &amp;gt;gh: The glock holder for the resource group
  *
  * Read in all of a Resource Group's header and bitmap blocks.
  * Caller must eventually call gfs2_rgrp_relse() to free the bitmaps.
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -802,7 +806,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; fail:
 
 /**
  * gfs2_rgrp_go_unlock - Release RG bitmaps read in with gfs2_rgrp_bh_get()
- * &amp;lt; at &amp;gt;rgd: the struct gfs2_rgrpd describing the RG to read in
+ * &amp;lt; at &amp;gt;gh: The glock holder for the resource group
  *
  */
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1041,6 +1045,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static inline u32 gfs2_bi2rgd_blk(struct gfs2_bitmap *bi, u32 blk)
 /**
  * try_rgrp_unlink - Look for any unlinked, allocated, but unused inodes
  * &amp;lt; at &amp;gt;rgd: The rgrp
+ * &amp;lt; at &amp;gt;last_unlinked: block address of the last dinode we unlinked
+ * &amp;lt; at &amp;gt;skip: block address we should explicitly not unlink
  *
  * Returns: 0 if no error
  *          The inode, if one has been found, in inode.
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1105,7 +1111,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked, u64 skip
 /**
  * get_local_rgrp - Choose and lock a rgrp for allocation
  * &amp;lt; at &amp;gt;ip: the inode to reserve space for
- * &amp;lt; at &amp;gt;rgp: the chosen and locked rgrp
+ * &amp;lt; at &amp;gt;last_unlinked: the last unlinked block
  *
  * Try to acquire rgrp in way which avoids contending with others.
  *
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1174,6 +1180,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void gfs2_blkrsv_put(struct gfs2_inode *ip)
 /**
  * gfs2_inplace_reserve - Reserve space in the filesystem
  * &amp;lt; at &amp;gt;ip: the inode to reserve space for
+ * &amp;lt; at &amp;gt;requested: the number of blocks to be reserved
  *
  * Returns: errno
  */
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1272,7 +1279,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static unsigned char gfs2_get_block_type(struct gfs2_rgrpd *rgd, u64 block)
  * &amp;lt; at &amp;gt;rgd: the resource group descriptor
  * &amp;lt; at &amp;gt;goal: the goal block within the RG (start here to search for avail block)
  * &amp;lt; at &amp;gt;state: GFS2_BLKST_XXX the before-allocation state to find
- * &amp;lt; at &amp;gt;dinode: TRUE if the first block we allocate is for a dinode
  * &amp;lt; at &amp;gt;rbi: address of the pointer to the bitmap containing the block found
  *
  * Walk rgrp's bitmap to find bits that represent a block in &amp;lt; at &amp;gt;state.
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1286,8 +1292,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static unsigned char gfs2_get_block_type(struct gfs2_rgrpd *rgd, u64 block)
  * Returns: the block number found relative to the bitmap rbi
  */
 
-static u32 rgblk_search(struct gfs2_rgrpd *rgd, u32 goal,
-unsigned char state,
+static u32 rgblk_search(struct gfs2_rgrpd *rgd, u32 goal, unsigned char state,
 struct gfs2_bitmap **rbi)
 {
 struct gfs2_bitmap *bi = NULL;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1756,7 +1761,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void gfs2_rlist_add(struct gfs2_inode *ip, struct gfs2_rgrp_list *rlist,
  *      and initialize an array of glock holders for them
  * &amp;lt; at &amp;gt;rlist: the list of resource groups
  * &amp;lt; at &amp;gt;state: the lock state to acquire the RG lock in
- * &amp;lt; at &amp;gt;flags: the modifier flags for the holder structures
  *
  * FIXME: Don't use NOFAIL
  *
&lt;/pre&gt;</description>
    <dc:creator>Steven Whitehouse</dc:creator>
    <dc:date>2012-05-17T12:23:14</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7009">
    <title>[PATCH 11/24] GFS2: Remove duplicate log code</title>
    <link>http://permalink.gmane.org/gmane.linux.cluster.redhat.cluster.devel/7009</link>
    <description>&lt;pre&gt;The main part of this patch merges the two functions used to
write metadata and data buffers to the log. Most of the code
is common between the two functions, so this provides a nice
clean up, and makes the code more readable.

The gfs2_get_log_desc() function is also extended to take two more
arguments, and thus avoid having to set the length and data1
fields of this strucuture as a separate operation.

Signed-off-by: Steven Whitehouse &amp;lt;swhiteho&amp;lt; at &amp;gt;redhat.com&amp;gt;

diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c
index 872d3e6..7882671 100644
--- a/fs/gfs2/lops.c
+++ b/fs/gfs2/lops.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -372,7 +372,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void gfs2_log_write_page(struct gfs2_sbd *sdp, struct page *page)
 gfs2_log_write(sdp, page, sb-&amp;gt;s_blocksize, 0);
 }
 
-static struct page *gfs2_get_log_desc(struct gfs2_sbd *sdp, u32 ld_type)
+static struct page *gfs2_get_log_desc(struct gfs2_sbd *sdp, u32 ld_type,
+      u32 ld_length, u32 ld_data1)
 {
 void *page = mempool_alloc(gfs2_page_pool, GFP_NOIO);
 struct gfs2_log_descriptor *ld = page_address(page);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -381,8 +382,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static struct page *gfs2_get_log_desc(struct gfs2_sbd *sdp, u32 ld_type)
 ld-&amp;gt;ld_header.mh_type = cpu_to_be32(GFS2_METATYPE_LD);
 ld-&amp;gt;ld_header.mh_format = cpu_to_be32(GFS2_FORMAT_LD);
 ld-&amp;gt;ld_type = cpu_to_be32(ld_type);
-ld-&amp;gt;ld_length = 0;
-ld-&amp;gt;ld_data1 = 0;
+ld-&amp;gt;ld_length = cpu_to_be32(ld_length);
+ld-&amp;gt;ld_data1 = cpu_to_be32(ld_data1);
 ld-&amp;gt;ld_data2 = 0;
 return page;
 }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -418,39 +419,49 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; out:
 unlock_buffer(bd-&amp;gt;bd_bh);
 }
 
-static void buf_lo_before_commit(struct gfs2_sbd *sdp)
+static void gfs2_check_magic(struct buffer_head *bh)
+{
+void *kaddr;
+__be32 *ptr;
+
+clear_buffer_escaped(bh);
+kaddr = kmap_atomic(bh-&amp;gt;b_page);
+ptr = kaddr + bh_offset(bh);
+if (*ptr == cpu_to_be32(GFS2_MAGIC))
+set_buffer_escaped(bh);
+kunmap_atomic(kaddr);
+}
+
+static void gfs2_before_commit(struct gfs2_sbd *sdp, unsigned int limit,
+unsigned int total, struct list_head *blist,
+bool is_databuf)
 {
 struct gfs2_log_descriptor *ld;
 struct gfs2_bufdata *bd1 = NULL, *bd2;
 struct page *page;
-unsigned int total;
-unsigned int limit;
 unsigned int num;
 unsigned n;
 __be64 *ptr;
 
-limit = buf_limit(sdp);
-/* for 4k blocks, limit = 503 */
-
 gfs2_log_lock(sdp);
-total = sdp-&amp;gt;sd_log_num_buf;
-bd1 = bd2 = list_prepare_entry(bd1, &amp;amp;sdp-&amp;gt;sd_log_le_buf, bd_le.le_list);
+bd1 = bd2 = list_prepare_entry(bd1, blist, bd_le.le_list);
 while(total) {
 num = total;
 if (total &amp;gt; limit)
 num = limit;
 gfs2_log_unlock(sdp);
-page = gfs2_get_log_desc(sdp, GFS2_LOG_DESC_METADATA);
+page = gfs2_get_log_desc(sdp, GFS2_LOG_DESC_METADATA, num + 1, num);
 ld = page_address(page);
 gfs2_log_lock(sdp);
 ptr = (__be64 *)(ld + 1);
-ld-&amp;gt;ld_length = cpu_to_be32(num + 1);
-ld-&amp;gt;ld_data1 = cpu_to_be32(num);
 
 n = 0;
-list_for_each_entry_continue(bd1, &amp;amp;sdp-&amp;gt;sd_log_le_buf,
-     bd_le.le_list) {
+list_for_each_entry_continue(bd1, blist, bd_le.le_list) {
 *ptr++ = cpu_to_be64(bd1-&amp;gt;bd_bh-&amp;gt;b_blocknr);
+if (is_databuf) {
+gfs2_check_magic(bd1-&amp;gt;bd_bh);
+*ptr++ = cpu_to_be64(buffer_escaped(bd1-&amp;gt;bd_bh) ? 1 : 0);
+}
 if (++n &amp;gt;= num)
 break;
 }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -460,12 +471,27 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void buf_lo_before_commit(struct gfs2_sbd *sdp)
 gfs2_log_lock(sdp);
 
 n = 0;
-list_for_each_entry_continue(bd2, &amp;amp;sdp-&amp;gt;sd_log_le_buf,
-     bd_le.le_list) {
+list_for_each_entry_continue(bd2, blist, bd_le.le_list) {
 get_bh(bd2-&amp;gt;bd_bh);
 gfs2_log_unlock(sdp);
 lock_buffer(bd2-&amp;gt;bd_bh);
-gfs2_log_write_bh(sdp, bd2-&amp;gt;bd_bh);
+
+if (buffer_escaped(bd2-&amp;gt;bd_bh)) {
+void *kaddr;
+page = mempool_alloc(gfs2_page_pool, GFP_NOIO);
+ptr = page_address(page);
+kaddr = kmap_atomic(bd2-&amp;gt;bd_bh-&amp;gt;b_page);
+memcpy(ptr, kaddr + bh_offset(bd2-&amp;gt;bd_bh),
+       bd2-&amp;gt;bd_bh-&amp;gt;b_size);
+kunmap_atomic(kaddr);
+*(__be32 *)ptr = 0;
+clear_buffer_escaped(bd2-&amp;gt;bd_bh);
+unlock_buffer(bd2-&amp;gt;bd_bh);
+brelse(bd2-&amp;gt;bd_bh);
+gfs2_log_write_page(sdp, page);
+} else {
+gfs2_log_write_bh(sdp, bd2-&amp;gt;bd_bh);
+}
 gfs2_log_lock(sdp);
 if (++n &amp;gt;= num)
 break;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -477,6 +503,14 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void buf_lo_before_commit(struct gfs2_sbd *sdp)
 gfs2_log_unlock(sdp);
 }
 
+static void buf_lo_before_commit(struct gfs2_sbd *sdp)
+{
+unsigned int limit = buf_limit(sdp); /* 503 for 4k blocks */
+
+gfs2_before_commit(sdp, limit, sdp-&amp;gt;sd_log_num_buf,
+   &amp;amp;sdp-&amp;gt;sd_log_le_buf, 0);
+}
+
 static void buf_lo_after_commit(struct gfs2_sbd *sdp, struct gfs2_ail *ai)
 {
 struct list_head *head = &amp;amp;sdp-&amp;gt;sd_log_le_buf;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -594,15 +628,14 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void revoke_lo_before_commit(struct gfs2_sbd *sdp)
 struct list_head *head = &amp;amp;sdp-&amp;gt;sd_log_le_revoke;
 struct gfs2_bufdata *bd;
 struct page *page;
+unsigned int length;
 
 if (!sdp-&amp;gt;sd_log_num_revoke)
 return;
 
-page = gfs2_get_log_desc(sdp, GFS2_LOG_DESC_REVOKE);
+length = gfs2_struct2blk(sdp, sdp-&amp;gt;sd_log_num_revoke, sizeof(u64));
+page = gfs2_get_log_desc(sdp, GFS2_LOG_DESC_REVOKE, length, sdp-&amp;gt;sd_log_num_revoke);
 ld = page_address(page);
-ld-&amp;gt;ld_length = cpu_to_be32(gfs2_struct2blk(sdp, sdp-&amp;gt;sd_log_num_revoke,
-    sizeof(u64)));
-ld-&amp;gt;ld_data1 = cpu_to_be32(sdp-&amp;gt;sd_log_num_revoke);
 offset = sizeof(struct gfs2_log_descriptor);
 
 list_for_each_entry(bd, head, bd_le.le_list) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -775,66 +808,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; out:
 unlock_buffer(bd-&amp;gt;bd_bh);
 }
 
-static void gfs2_check_magic(struct buffer_head *bh)
-{
-void *kaddr;
-__be32 *ptr;
-
-clear_buffer_escaped(bh);
-kaddr = kmap_atomic(bh-&amp;gt;b_page);
-ptr = kaddr + bh_offset(bh);
-if (*ptr == cpu_to_be32(GFS2_MAGIC))
-set_buffer_escaped(bh);
-kunmap_atomic(kaddr);
-}
-
-static void gfs2_write_blocks(struct gfs2_sbd *sdp,
-      struct gfs2_log_descriptor *ld,
-      struct page *page,
-      struct list_head *list, struct list_head *done,
-      unsigned int n)
-{
-struct gfs2_bufdata *bd;
-__be64 *ptr;
-
-if (!ld)
-return;
-
-ld-&amp;gt;ld_length = cpu_to_be32(n + 1);
-ld-&amp;gt;ld_data1 = cpu_to_be32(n);
-ptr = (__force __be64 *)(ld + 1);
-
-gfs2_log_write_page(sdp, page);
-gfs2_log_lock(sdp);
-while (!list_empty(list)) {
-bd = list_entry(list-&amp;gt;next, struct gfs2_bufdata, bd_le.le_list);
-list_move_tail(&amp;amp;bd-&amp;gt;bd_le.le_list, done);
-get_bh(bd-&amp;gt;bd_bh);
-gfs2_log_unlock(sdp);
-lock_buffer(bd-&amp;gt;bd_bh);
-if (buffer_escaped(bd-&amp;gt;bd_bh)) {
-void *kaddr;
-page = mempool_alloc(gfs2_page_pool, GFP_NOIO);
-ptr = page_address(page);
-kaddr = kmap_atomic(bd-&amp;gt;bd_bh-&amp;gt;b_page);
-memcpy(ptr, kaddr + bh_offset(bd-&amp;gt;bd_bh),
-       bd-&amp;gt;bd_bh-&amp;gt;b_size);
-kunmap_atomic(kaddr);
-*(__be32 *)ptr = 0;
-clear_buffer_escaped(bd-&amp;gt;bd_bh);
-unlock_buffer(bd-&amp;gt;bd_bh);
-brelse(bd-&amp;gt;bd_bh);
-gfs2_log_write_page(sdp, page);
-} else {
-gfs2_log_write_bh(sdp, bd-&amp;gt;bd_bh);
-}
-n--;
-gfs2_log_lock(sdp);
-}
-gfs2_log_unlock(sdp);
-BUG_ON(n != 0);
-}
-
 /**
  * databuf_lo_before_commit - Scan the data buffers, writing as we go
  *
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -842,40 +815,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void gfs2_write_blocks(struct gfs2_sbd *sdp,
 
 static void databuf_lo_before_commit(struct gfs2_sbd *sdp)
 {
-struct gfs2_bufdata *bd = NULL;
-struct gfs2_log_descriptor *ld = NULL;
-struct page *page = NULL;
-unsigned int n = 0;
-__be64 *ptr = NULL, *end = NULL;
-LIST_HEAD(processed);
-LIST_HEAD(in_progress);
+unsigned int limit = buf_limit(sdp) / 2;
 
-gfs2_log_lock(sdp);
-while (!list_empty(&amp;amp;sdp-&amp;gt;sd_log_le_databuf)) {
-if (ptr == end) {
-gfs2_log_unlock(sdp);
-gfs2_write_blocks(sdp, ld, page, &amp;amp;in_progress, &amp;amp;processed, n);
-n = 0;
-page = gfs2_get_log_desc(sdp, GFS2_LOG_DESC_JDATA);
-ld = page_address(page);
-ptr = (__force __be64 *)(ld + 1);
-end = (__force __be64 *)(page_address(page) + sdp-&amp;gt;sd_vfs-&amp;gt;s_blocksize);
-end--;
-gfs2_log_lock(sdp);
-continue;
-}
-bd = list_entry(sdp-&amp;gt;sd_log_le_databuf.next, struct gfs2_bufdata, bd_le.le_list);
-list_move_tail(&amp;amp;bd-&amp;gt;bd_le.le_list, &amp;amp;in_progress);
-gfs2_check_magic(bd-&amp;gt;bd_bh);
-*ptr++ = cpu_to_be64(bd-&amp;gt;bd_bh-&amp;gt;b_blocknr);
-*ptr++ = cpu_to_be64(buffer_escaped(bd-&amp;gt;bd_bh) ? 1 : 0);
-n++;
-}
-gfs2_log_unlock(sdp);
-gfs2_write_blocks(sdp, ld, page, &amp;amp;in_progress, &amp;amp;processed, n);
-gfs2_log_lock(sdp);
-list_splice(&amp;amp;processed, &amp;amp;sdp-&amp;gt;sd_log_le_databuf);
-gfs2_log_unlock(sdp);
+gfs2_before_commit(sdp, limit, sdp-&amp;gt;sd_log_num_databuf,
+   &amp;amp;sdp-&amp;gt;sd_log_le_databuf, 1);
 }
 
 static int databuf_lo_scan_elements(struct gfs2_jdesc *jd, unsigned int start,
&lt;/pre&gt;</description>
    <dc:creator>Steven Whitehouse</dc:creator>
    <dc:date>2012-05-17T12:23:18</dc:date>
  </item>
  <textinput rdf:about="http://search.gmane.org/?group=$group=gmane.linux.cluster.redhat.cluster.devel">
    <title>Search Engine</title>
    <description>Search the mailing list at Gmane</description>
    <name>query</name>
    <link>http://search.gmane.org/?group=$group=gmane.linux.cluster.redhat.cluster.devel</link>
  </textinput>
</rdf:RDF>

