rpms/kernel/devel kernel-2.6.spec, 1.3166, 1.3167 linux-2.6-gfs2-update.patch, 1.1, 1.2
Dave Jones (davej)
fedora-extras-commits at redhat.com
Thu May 17 14:40:16 UTC 2007
Author: davej
Update of /cvs/pkgs/rpms/kernel/devel
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv24282
Modified Files:
kernel-2.6.spec linux-2.6-gfs2-update.patch
Log Message:
* Thu May 17 2007 Dave Jones <davej at redhat.com>
- More GFS2 updates.
Index: kernel-2.6.spec
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/kernel-2.6.spec,v
retrieving revision 1.3166
retrieving revision 1.3167
diff -u -r1.3166 -r1.3167
--- kernel-2.6.spec 16 May 2007 23:59:39 -0000 1.3166
+++ kernel-2.6.spec 17 May 2007 14:39:42 -0000 1.3167
@@ -2362,6 +2362,9 @@
%endif
%changelog
+* Thu May 17 2007 Dave Jones <davej at redhat.com>
+- More GFS2 updates.
+
* Wed May 16 2007 Dave Jones <davej at redhat.com>
- Fix ACPI suspend / device suspend ordering problem.
linux-2.6-gfs2-update.patch:
Index: linux-2.6-gfs2-update.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/linux-2.6-gfs2-update.patch,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- linux-2.6-gfs2-update.patch 10 May 2007 15:00:02 -0000 1.1
+++ linux-2.6-gfs2-update.patch 17 May 2007 14:39:42 -0000 1.2
@@ -3021,3 +3021,1616 @@
+From davej Thu May 17 08:51:23 2007
+Return-Path: <swhiteho at redhat.com>
+X-Spam-Checker-Version: SpamAssassin 3.1.8 (2007-02-13) on
+ gelk.kernelslacker.org
+X-Spam-Level:
+X-Spam-Status: No, score=-2.3 required=5.0 tests=AWL,BAYES_00,
+ UNPARSEABLE_RELAY autolearn=ham version=3.1.8
+Received: from pobox.devel.redhat.com [10.11.255.8]
+ by gelk.kernelslacker.org with IMAP (fetchmail-6.3.6)
+ for <davej at localhost> (single-drop); Thu, 17 May 2007 08:51:23 -0400 (EDT)
+Received: from pobox.devel.redhat.com ([unix socket])
+ by pobox.devel.redhat.com (Cyrus v2.2.12-Invoca-RPM-2.2.12-8.1.RHEL4) with LMTPA;
+ Thu, 17 May 2007 08:47:01 -0400
+X-Sieve: CMU Sieve 2.2
+Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254])
+ by pobox.devel.redhat.com (8.13.1/8.13.1) with ESMTP id l4HCl1Wc009963
+ for <davej at pobox.devel.redhat.com>; Thu, 17 May 2007 08:47:01 -0400
+Received: from pobox.fab.redhat.com (pobox.fab.redhat.com [10.33.63.12])
+ by int-mx1.corp.redhat.com (8.13.1/8.13.1) with ESMTP id l4HCkx6Z017932
+ for <davej at int-mx1.corp.redhat.com>; Thu, 17 May 2007 08:47:00 -0400
+Received: from [172.31.0.3] (vpn-14-17.rdu.redhat.com [10.11.14.17])
+ by pobox.fab.redhat.com (8.13.1/8.13.1) with ESMTP id l4HCkv43015770
+ for <davej at redhat.com>; Thu, 17 May 2007 08:46:57 -0400
+Subject: Re: GFS2 updated for FC7
+From: Steven Whitehouse <swhiteho at redhat.com>
+To: Dave Jones <davej at redhat.com>
+In-Reply-To: <20070516160520.GA30166 at redhat.com>
+References: <1178808810.7476.64.camel at quoit>
+ <20070510152305.GB27949 at redhat.com> <1179326555.7476.132.camel at quoit>
+ <20070516160520.GA30166 at redhat.com>
+Content-Type: text/plain
+Organization: Red Hat (UK) Ltd (Registered in England and Wales, No.
+ 3798903) Registered office: Red Hat UK Ltd, Amberley Place, 107-111 Peascod
+ Street, Windsor, Berkshire, SL4 ITE
+Date: Thu, 17 May 2007 13:44:51 +0100
+Message-Id: <1179405891.7476.179.camel at quoit>
+Mime-Version: 1.0
+X-Mailer: Evolution 2.8.3 (2.8.3-2.fc6)
+Content-Transfer-Encoding: 7bit
+Status: RO
+Content-Length: 52941
+Lines: 1569
+
+Hi,
+
+On Wed, 2007-05-16 at 12:05 -0400, Dave Jones wrote:
+> On Wed, May 16, 2007 at 03:42:35PM +0100, Steven Whitehouse wrote:
+> > Hi,
+> >
+> > I've not spotted this in CVS yet... Should this be in the devel subdir?
+>
+> you're probably looking at the old cvs.
+> part of the core/extras merge means we're now in an external cvs.
+> See my people page for info on checking it out.
+>
+> Dave
+>
+
+Yes, it seems I missed out on that change :( Anyway I can see it now and
+I've also attached a further update. I'm going to be on holiday next
+week so thing brings things uptodate nicely before I head off,
+
+Steve.
+
+>From 6eaa8fe6671a3b33d213123789dcfb504651bf01 Mon Sep 17 00:00:00 2001
+From: Robert Peterson <rpeterso at redhat.com>
+Date: Thu, 10 May 2007 16:54:38 -0500
+Subject: [PATCH] [GFS2] Kernel changes to support new gfs2_grow command (part 2)
+
+To avoid code redundancy, I separated out the operational "guts" into
+a new function called read_rindex_entry. Then I made two functions:
+the closer-to-original gfs2_ri_update (without the special condition
+checks) and gfs2_ri_update_special that's designed with that condition
+in mind. (I don't like the name, but if you have a suggestion, I'm
+all ears).
+
+Oh, and there's an added benefit: we don't need all the ugly gotos
+anymore. ;)
+
+This patch has been tested with gfs2_fsck_hellfire (which runs for
+three and a half hours, btw).
+
+Signed-off-By: Bob Peterson <rpeterso at redhat.com>
+Signed-off-by: Steven Whitehouse <swhiteho at redhat.com>
+
+diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c
+index 846c0ff..e0b4e8c 100644
+--- a/fs/gfs2/ops_address.c
++++ b/fs/gfs2/ops_address.c
+@@ -469,7 +469,8 @@ static void adjust_fs_space(struct inode *inode)
+ else
+ new_free = 0;
+ spin_unlock(&sdp->sd_statfs_spin);
+- fs_warn(sdp, "File system extended by %llu blocks.\n", new_free);
++ fs_warn(sdp, "File system extended by %llu blocks.\n",
++ (unsigned long long)new_free);
+ gfs2_statfs_change(sdp, new_free, new_free, 0);
+ }
+
+diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
+index e857f40..48a6461 100644
+--- a/fs/gfs2/rgrp.c
++++ b/fs/gfs2/rgrp.c
+@@ -463,9 +463,62 @@ u64 gfs2_ri_total(struct gfs2_sbd *sdp)
+ }
+
+ /**
+- * gfs2_ri_update - Pull in a new resource index from the disk
++ * read_rindex_entry - Pull in a new resource index entry from the disk
+ * @gl: The glock covering the rindex inode
+ *
++ * Returns: 0 on success, error code otherwise
++ */
++
++static int read_rindex_entry(struct gfs2_inode *ip,
++ struct file_ra_state *ra_state)
++{
++ struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
++ loff_t pos = sdp->sd_rgrps * sizeof(struct gfs2_rindex);
++ char buf[sizeof(struct gfs2_rindex)];
++ int error;
++ struct gfs2_rgrpd *rgd;
++
++ error = gfs2_internal_read(ip, ra_state, buf, &pos,
++ sizeof(struct gfs2_rindex));
++ if (!error)
++ return 0;
++ if (error != sizeof(struct gfs2_rindex)) {
++ if (error > 0)
++ error = -EIO;
++ return error;
++ }
++
++ rgd = kzalloc(sizeof(struct gfs2_rgrpd), GFP_NOFS);
++ error = -ENOMEM;
++ if (!rgd)
++ return error;
++
++ mutex_init(&rgd->rd_mutex);
++ lops_init_le(&rgd->rd_le, &gfs2_rg_lops);
++ rgd->rd_sbd = sdp;
++
++ list_add_tail(&rgd->rd_list, &sdp->sd_rindex_list);
++ list_add_tail(&rgd->rd_list_mru, &sdp->sd_rindex_mru_list);
++
++ gfs2_rindex_in(&rgd->rd_ri, buf);
++ error = compute_bitstructs(rgd);
++ if (error)
++ return error;
++
++ error = gfs2_glock_get(sdp, rgd->rd_ri.ri_addr,
++ &gfs2_rgrp_glops, CREATE, &rgd->rd_gl);
++ if (error)
++ return error;
++
++ rgd->rd_gl->gl_object = rgd;
++ rgd->rd_rg_vn = rgd->rd_gl->gl_vn - 1;
++ return error;
++}
++
++/**
++ * gfs2_ri_update - Pull in a new resource index from the disk
++ * @ip: pointer to the rindex inode
++ *
+ * Returns: 0 on successful update, error code otherwise
+ */
+
+@@ -473,18 +526,11 @@ static int gfs2_ri_update(struct gfs2_inode *ip)
+ {
+ struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
+ struct inode *inode = &ip->i_inode;
+- struct gfs2_rgrpd *rgd;
+- char buf[sizeof(struct gfs2_rindex)];
+ struct file_ra_state ra_state;
+ u64 junk = ip->i_di.di_size;
+ int error;
+
+- /* If someone is holding the rindex file with a glock, they must
+- be updating it, in which case we may have partial entries.
+- In this case, we ignore the partials. */
+- if (!gfs2_glock_is_held_excl(ip->i_gl) &&
+- !gfs2_glock_is_held_shrd(ip->i_gl) &&
+- do_div(junk, sizeof(struct gfs2_rindex))) {
++ if (do_div(junk, sizeof(struct gfs2_rindex))) {
+ gfs2_consist_inode(ip);
+ return -EIO;
+ }
+@@ -493,52 +539,49 @@ static int gfs2_ri_update(struct gfs2_inode *ip)
+
+ file_ra_state_init(&ra_state, inode->i_mapping);
+ for (sdp->sd_rgrps = 0;; sdp->sd_rgrps++) {
+- loff_t pos = sdp->sd_rgrps * sizeof(struct gfs2_rindex);
+-
+- if (pos + sizeof(struct gfs2_rindex) >= ip->i_di.di_size)
+- break;
+- error = gfs2_internal_read(ip, &ra_state, buf, &pos,
+- sizeof(struct gfs2_rindex));
+- if (!error)
+- break;
+- if (error != sizeof(struct gfs2_rindex)) {
+- if (error > 0)
+- error = -EIO;
+- goto fail;
++ error = read_rindex_entry(ip, &ra_state);
++ if (error) {
++ clear_rgrpdi(sdp);
++ return error;
+ }
++ }
+
+- rgd = kzalloc(sizeof(struct gfs2_rgrpd), GFP_NOFS);
+- error = -ENOMEM;
+- if (!rgd)
+- goto fail;
+-
+- mutex_init(&rgd->rd_mutex);
+- lops_init_le(&rgd->rd_le, &gfs2_rg_lops);
+- rgd->rd_sbd = sdp;
+-
+- list_add_tail(&rgd->rd_list, &sdp->sd_rindex_list);
+- list_add_tail(&rgd->rd_list_mru, &sdp->sd_rindex_mru_list);
+-
+- gfs2_rindex_in(&rgd->rd_ri, buf);
+- error = compute_bitstructs(rgd);
+- if (error)
+- goto fail;
++ sdp->sd_rindex_vn = ip->i_gl->gl_vn;
++ return 0;
++}
+
+- error = gfs2_glock_get(sdp, rgd->rd_ri.ri_addr,
+- &gfs2_rgrp_glops, CREATE, &rgd->rd_gl);
+- if (error)
+- goto fail;
++/**
++ * gfs2_ri_update_special - Pull in a new resource index from the disk
++ *
++ * This is a special version that's safe to call from gfs2_inplace_reserve_i.
++ * In this case we know that we don't have any resource groups in memory yet.
++ *
++ * @ip: pointer to the rindex inode
++ *
++ * Returns: 0 on successful update, error code otherwise
++ */
++static int gfs2_ri_update_special(struct gfs2_inode *ip)
++{
++ struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
++ struct inode *inode = &ip->i_inode;
++ struct file_ra_state ra_state;
++ int error;
+
+- rgd->rd_gl->gl_object = rgd;
+- rgd->rd_rg_vn = rgd->rd_gl->gl_vn - 1;
++ file_ra_state_init(&ra_state, inode->i_mapping);
++ for (sdp->sd_rgrps = 0;; sdp->sd_rgrps++) {
++ /* Ignore partials */
++ if ((sdp->sd_rgrps + 1) * sizeof(struct gfs2_rindex) >
++ ip->i_di.di_size)
++ break;
++ error = read_rindex_entry(ip, &ra_state);
++ if (error) {
++ clear_rgrpdi(sdp);
++ return error;
++ }
+ }
+
+ sdp->sd_rindex_vn = ip->i_gl->gl_vn;
+ return 0;
+-
+-fail:
+- clear_rgrpdi(sdp);
+- return error;
+ }
+
+ /**
+@@ -1028,7 +1071,7 @@ int gfs2_inplace_reserve_i(struct gfs2_inode *ip, char *file, unsigned int line)
+ if (ip != GFS2_I(sdp->sd_rindex))
+ error = gfs2_rindex_hold(sdp, &al->al_ri_gh);
+ else if (!sdp->sd_rgrps) /* We may not have the rindex read in, so: */
+- error = gfs2_ri_update(ip);
++ error = gfs2_ri_update_special(ip);
+
+ if (error)
+ return error;
+--
+1.5.1.2
+
+>From cd07e4fdcaba62a0329bfadb6898d31cdd795d43 Mon Sep 17 00:00:00 2001
+From: Robert Peterson <rpeterso at redhat.com>
+Date: Mon, 14 May 2007 12:42:18 -0500
+Subject: [PATCH] [GFS2] Addendum patch 2 for gfs2_grow
+
+This addendum patch 2 corrects three things:
+
+1. It fixes a stupid mistake in the previous addendum that broke gfs2.
+ Ref: https://www.redhat.com/archives/cluster-devel/2007-May/msg00162.html
+2. It fixes a problem that Dave Teigland pointed out regarding the
+ external declarations in ops_address.h being in the wrong place.
+3. It recasts a couple more %llu printks to (unsigned long long)
+ as requested by Steve Whitehouse.
+
+I would have loved to put this all in one revised patch, but there was
+a rush to get some patches for RHEL5. Therefore, the previous patches
+were applied to the git tree "as is" and therefore, I'm posting another
+addendum. Sorry.
+
+Signed-off-by: Bob Peterson <rpeterso at redhat.com>
+Signed-off-by: Steven Whitehouse <swhiteho at redhat.com>
+
+diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
+index 1815429..c66c718 100644
+--- a/fs/gfs2/glock.c
++++ b/fs/gfs2/glock.c
+@@ -1823,7 +1823,8 @@ static int dump_inode(struct glock_iter *gi, struct gfs2_inode *ip)
+
+ print_dbg(gi, " Inode:\n");
+ print_dbg(gi, " num = %llu/%llu\n",
+- ip->i_num.no_formal_ino, ip->i_num.no_addr);
++ (unsigned long long)ip->i_num.no_formal_ino,
++ (unsigned long long)ip->i_num.no_addr);
+ print_dbg(gi, " type = %u\n", IF2DT(ip->i_inode.i_mode));
+ print_dbg(gi, " i_flags =");
+ for (x = 0; x < 32; x++)
+@@ -1909,8 +1910,8 @@ static int dump_glock(struct glock_iter *gi, struct gfs2_glock *gl)
+ }
+ if (test_bit(GLF_DEMOTE, &gl->gl_flags)) {
+ print_dbg(gi, " Demotion req to state %u (%llu uS ago)\n",
+- gl->gl_demote_state,
+- (u64)(jiffies - gl->gl_demote_time)*(1000000/HZ));
++ gl->gl_demote_state, (unsigned long long)
++ (jiffies - gl->gl_demote_time)*(1000000/HZ));
+ }
+ if (gl->gl_ops == &gfs2_inode_glops && gl->gl_object) {
+ if (!test_bit(GLF_LOCK, &gl->gl_flags) &&
+diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c
+index e0b4e8c..4913ef5 100644
+--- a/fs/gfs2/ops_address.c
++++ b/fs/gfs2/ops_address.c
+@@ -32,6 +32,7 @@
+ #include "trans.h"
+ #include "rgrp.h"
+ #include "ops_file.h"
++#include "super.h"
+ #include "util.h"
+ #include "glops.h"
+
+diff --git a/fs/gfs2/ops_address.h b/fs/gfs2/ops_address.h
+index 56c30da..fa1b5b3 100644
+--- a/fs/gfs2/ops_address.h
++++ b/fs/gfs2/ops_address.h
+@@ -18,8 +18,5 @@ extern const struct address_space_operations gfs2_file_aops;
+ extern int gfs2_get_block(struct inode *inode, sector_t lblock,
+ struct buffer_head *bh_result, int create);
+ extern int gfs2_releasepage(struct page *page, gfp_t gfp_mask);
+-extern u64 gfs2_ri_total(struct gfs2_sbd *sdp);
+-extern void gfs2_statfs_change(struct gfs2_sbd *sdp, s64 total, s64 free,
+- s64 dinodes);
+
+ #endif /* __OPS_ADDRESS_DOT_H__ */
+diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
+index 48a6461..a62c0f2 100644
+--- a/fs/gfs2/rgrp.c
++++ b/fs/gfs2/rgrp.c
+@@ -527,10 +527,10 @@ static int gfs2_ri_update(struct gfs2_inode *ip)
+ struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
+ struct inode *inode = &ip->i_inode;
+ struct file_ra_state ra_state;
+- u64 junk = ip->i_di.di_size;
++ u64 rgrp_count = ip->i_di.di_size;
+ int error;
+
+- if (do_div(junk, sizeof(struct gfs2_rindex))) {
++ if (do_div(rgrp_count, sizeof(struct gfs2_rindex))) {
+ gfs2_consist_inode(ip);
+ return -EIO;
+ }
+@@ -538,7 +538,7 @@ static int gfs2_ri_update(struct gfs2_inode *ip)
+ clear_rgrpdi(sdp);
+
+ file_ra_state_init(&ra_state, inode->i_mapping);
+- for (sdp->sd_rgrps = 0;; sdp->sd_rgrps++) {
++ for (sdp->sd_rgrps = 0; sdp->sd_rgrps < rgrp_count; sdp->sd_rgrps++) {
+ error = read_rindex_entry(ip, &ra_state);
+ if (error) {
+ clear_rgrpdi(sdp);
+diff --git a/fs/gfs2/rgrp.h b/fs/gfs2/rgrp.h
+index b01e0cf..b4c6adf 100644
+--- a/fs/gfs2/rgrp.h
++++ b/fs/gfs2/rgrp.h
+@@ -65,5 +65,6 @@ void gfs2_rlist_add(struct gfs2_sbd *sdp, struct gfs2_rgrp_list *rlist,
+ void gfs2_rlist_alloc(struct gfs2_rgrp_list *rlist, unsigned int state,
+ int flags);
+ void gfs2_rlist_free(struct gfs2_rgrp_list *rlist);
++u64 gfs2_ri_total(struct gfs2_sbd *sdp);
+
+ #endif /* __RGRP_DOT_H__ */
+--
+1.5.1.2
+
+>From b7769e272a86b295bd910f98b1628ebd7cbcb28b Mon Sep 17 00:00:00 2001
+From: Steven Whitehouse <swhiteho at redhat.com>
+Date: Mon, 14 May 2007 17:43:26 +0100
+Subject: [PATCH] [GFS2] Reduce size of struct gdlm_lock
+
+This patch removes the completion (which is rather large) from struct
+gdlm_lock in favour of using the wait_on_bit() functions. We don't need
+to add any extra fields to the structure to do this, so we save 32 bytes
+(on x86_64) per structure. This adds up to quite a lot when we may
+potentially have millions of these lock structures,
+
+Signed-off-by: Steven Whitehouse <swhiteho at redhat.com>
+Acked-by: David Teigland <teigland at redhat.com>
+
+diff --git a/fs/gfs2/locking/dlm/lock.c b/fs/gfs2/locking/dlm/lock.c
+index c305255..542a797 100644
+--- a/fs/gfs2/locking/dlm/lock.c
++++ b/fs/gfs2/locking/dlm/lock.c
+@@ -174,7 +174,6 @@ static int gdlm_create_lp(struct gdlm_ls *ls, struct lm_lockname *name,
+ lp->cur = DLM_LOCK_IV;
+ lp->lvb = NULL;
+ lp->hold_null = NULL;
+- init_completion(&lp->ast_wait);
+ INIT_LIST_HEAD(&lp->clist);
+ INIT_LIST_HEAD(&lp->blist);
+ INIT_LIST_HEAD(&lp->delay_list);
+@@ -399,6 +398,12 @@ static void gdlm_del_lvb(struct gdlm_lock *lp)
+ lp->lksb.sb_lvbptr = NULL;
+ }
+
++static int gdlm_ast_wait(void *word)
++{
++ schedule();
++ return 0;
++}
++
+ /* This can do a synchronous dlm request (requiring a lock_dlm thread to get
+ the completion) because gfs won't call hold_lvb() during a callback (from
+ the context of a lock_dlm thread). */
+@@ -424,10 +429,10 @@ static int hold_null_lock(struct gdlm_lock *lp)
+ lpn->lkf = DLM_LKF_VALBLK | DLM_LKF_EXPEDITE;
+ set_bit(LFL_NOBAST, &lpn->flags);
+ set_bit(LFL_INLOCK, &lpn->flags);
++ set_bit(LFL_AST_WAIT, &lpn->flags);
+
+- init_completion(&lpn->ast_wait);
+ gdlm_do_lock(lpn);
+- wait_for_completion(&lpn->ast_wait);
++ wait_on_bit(&lpn->flags, LFL_AST_WAIT, gdlm_ast_wait, TASK_UNINTERRUPTIBLE);
+ error = lpn->lksb.sb_status;
+ if (error) {
+ printk(KERN_INFO "lock_dlm: hold_null_lock dlm error %d\n",
+diff --git a/fs/gfs2/locking/dlm/lock_dlm.h b/fs/gfs2/locking/dlm/lock_dlm.h
+index d074c6e..24d70f7 100644
+--- a/fs/gfs2/locking/dlm/lock_dlm.h
++++ b/fs/gfs2/locking/dlm/lock_dlm.h
+@@ -101,6 +101,7 @@ enum {
+ LFL_NOBAST = 10,
+ LFL_HEADQUE = 11,
+ LFL_UNLOCK_DELETE = 12,
++ LFL_AST_WAIT = 13,
+ };
+
+ struct gdlm_lock {
+@@ -117,7 +118,6 @@ struct gdlm_lock {
+ unsigned long flags; /* lock_dlm flags LFL_ */
+
+ int bast_mode; /* protected by async_lock */
+- struct completion ast_wait;
+
+ struct list_head clist; /* complete */
+ struct list_head blist; /* blocking */
+diff --git a/fs/gfs2/locking/dlm/thread.c b/fs/gfs2/locking/dlm/thread.c
+index 9cf1f16..1aca51e 100644
+--- a/fs/gfs2/locking/dlm/thread.c
++++ b/fs/gfs2/locking/dlm/thread.c
+@@ -44,6 +44,13 @@ static void process_blocking(struct gdlm_lock *lp, int bast_mode)
+ ls->fscb(ls->sdp, cb, &lp->lockname);
+ }
+
++static void wake_up_ast(struct gdlm_lock *lp)
++{
++ clear_bit(LFL_AST_WAIT, &lp->flags);
++ smp_mb__after_clear_bit();
++ wake_up_bit(&lp->flags, LFL_AST_WAIT);
++}
++
+ static void process_complete(struct gdlm_lock *lp)
+ {
+ struct gdlm_ls *ls = lp->ls;
+@@ -136,7 +143,7 @@ static void process_complete(struct gdlm_lock *lp)
+ */
+
+ if (test_and_clear_bit(LFL_SYNC_LVB, &lp->flags)) {
+- complete(&lp->ast_wait);
++ wake_up_ast(lp);
+ return;
+ }
+
+@@ -214,7 +221,7 @@ out:
+ if (test_bit(LFL_INLOCK, &lp->flags)) {
+ clear_bit(LFL_NOBLOCK, &lp->flags);
+ lp->cur = lp->req;
+- complete(&lp->ast_wait);
++ wake_up_ast(lp);
+ return;
+ }
+
+--
+1.5.1.2
+
+>From 94bdbaf759e13ad285148f05d48a8151d9d7e826 Mon Sep 17 00:00:00 2001
+From: Steven Whitehouse <swhiteho at redhat.com>
+Date: Tue, 15 May 2007 15:37:50 +0100
+Subject: [PATCH] [GFS2] Clean up inode number handling
+
+This patch cleans up the inode number handling code. The main difference
+is that instead of looking up the inodes using a struct gfs2_inum_host
+we now use just the no_addr member of this structure. The tests relating
+to no_formal_ino can then be done by the calling code. This has
+advantages in that we want to do different things in different code
+paths if the no_formal_ino doesn't match. In the NFS patch we want to
+return -ESTALE, but in the ->lookup() path, its a bug in the fs if the
+no_formal_ino doesn't match and thus we can withdraw in this case.
+
+In order to later fix bz #201012, we need to be able to look up an inode
+without knowing no_formal_ino, as the only information that is known to
+us is the on-disk location of the inode in question.
+
+This patch will also help us to fix bz #236099 at a later date by
+cleaning up a lot of the code in that area.
+
+There are no user visible changes as a result of this patch and there
+are no changes to the on-disk format either.
+
+Signed-off-by: Steven Whitehouse <swhiteho at redhat.com>
+
+diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c
+index 1c40c4b..e76a887 100644
+--- a/fs/gfs2/bmap.c
++++ b/fs/gfs2/bmap.c
+@@ -1040,7 +1040,7 @@ static int trunc_end(struct gfs2_inode *ip)
+ ip->i_di.di_height = 0;
+ ip->i_di.di_goal_meta =
+ ip->i_di.di_goal_data =
+- ip->i_num.no_addr;
++ ip->i_no_addr;
+ gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode));
+ }
+ ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC;
+diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c
+index a96fa07..9cdd71c 100644
+--- a/fs/gfs2/dir.c
++++ b/fs/gfs2/dir.c
+@@ -1456,7 +1456,7 @@ int gfs2_dir_read(struct inode *inode, u64 *offset, void *opaque,
+ if (dip->i_di.di_entries != g.offset) {
+ fs_warn(sdp, "Number of entries corrupt in dir %llu, "
+ "ip->i_di.di_entries (%u) != g.offset (%u)\n",
+- (unsigned long long)dip->i_num.no_addr,
++ (unsigned long long)dip->i_no_addr,
+ dip->i_di.di_entries,
+ g.offset);
+ error = -EIO;
+@@ -1488,24 +1488,54 @@ out:
+ * Returns: errno
+ */
+
+-int gfs2_dir_search(struct inode *dir, const struct qstr *name,
+- struct gfs2_inum_host *inum, unsigned int *type)
++struct inode *gfs2_dir_search(struct inode *dir, const struct qstr *name)
+ {
+ struct buffer_head *bh;
+ struct gfs2_dirent *dent;
++ struct inode *inode;
++
++ dent = gfs2_dirent_search(dir, name, gfs2_dirent_find, &bh);
++ if (dent) {
++ if (IS_ERR(dent))
++ return ERR_PTR(PTR_ERR(dent));
++ inode = gfs2_inode_lookup(dir->i_sb,
++ be64_to_cpu(dent->de_inum.no_addr),
++ be16_to_cpu(dent->de_type));
++ brelse(bh);
++ return inode;
++ }
++ return ERR_PTR(-ENOENT);
++}
++
++int gfs2_dir_check(struct inode *dir, const struct qstr *name,
++ const struct gfs2_inode *ip)
++{
++ struct buffer_head *bh;
++ struct gfs2_dirent *dent;
++ int ret = -ENOENT;
+
+ dent = gfs2_dirent_search(dir, name, gfs2_dirent_find, &bh);
+ if (dent) {
+ if (IS_ERR(dent))
+ return PTR_ERR(dent);
+- if (inum)
+- gfs2_inum_in(inum, (char *)&dent->de_inum);
+- if (type)
+- *type = be16_to_cpu(dent->de_type);
++ if (ip) {
++ if (be64_to_cpu(dent->de_inum.no_addr) != ip->i_no_addr)
++ goto out;
++ if (be64_to_cpu(dent->de_inum.no_formal_ino) !=
++ ip->i_no_formal_ino)
++ goto out;
++ if (unlikely(IF2DT(ip->i_inode.i_mode) !=
++ be16_to_cpu(dent->de_type))) {
++ gfs2_consist_inode(GFS2_I(dir));
++ ret = -EIO;
++ goto out;
++ }
++ }
++ ret = 0;
++out:
+ brelse(bh);
+- return 0;
+ }
+- return -ENOENT;
++ return ret;
+ }
+
+ static int dir_new_leaf(struct inode *inode, const struct qstr *name)
+@@ -1565,7 +1595,7 @@ static int dir_new_leaf(struct inode *inode, const struct qstr *name)
+ */
+
+ int gfs2_dir_add(struct inode *inode, const struct qstr *name,
+- const struct gfs2_inum_host *inum, unsigned type)
++ const struct gfs2_inode *nip, unsigned type)
+ {
+ struct gfs2_inode *ip = GFS2_I(inode);
+ struct buffer_head *bh;
+@@ -1580,7 +1610,7 @@ int gfs2_dir_add(struct inode *inode, const struct qstr *name,
+ if (IS_ERR(dent))
+ return PTR_ERR(dent);
+ dent = gfs2_init_dirent(inode, dent, name, bh);
+- gfs2_inum_out(inum, (char *)&dent->de_inum);
++ gfs2_inum_out(nip, dent);
+ dent->de_type = cpu_to_be16(type);
+ if (ip->i_di.di_flags & GFS2_DIF_EXHASH) {
+ leaf = (struct gfs2_leaf *)bh->b_data;
+@@ -1700,7 +1730,7 @@ int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *name)
+ */
+
+ int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename,
+- struct gfs2_inum_host *inum, unsigned int new_type)
++ const struct gfs2_inode *nip, unsigned int new_type)
+ {
+ struct buffer_head *bh;
+ struct gfs2_dirent *dent;
+@@ -1715,7 +1745,7 @@ int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename,
+ return PTR_ERR(dent);
+
+ gfs2_trans_add_bh(dip->i_gl, bh, 1);
+- gfs2_inum_out(inum, (char *)&dent->de_inum);
++ gfs2_inum_out(nip, dent);
+ dent->de_type = cpu_to_be16(new_type);
+
+ if (dip->i_di.di_flags & GFS2_DIF_EXHASH) {
+diff --git a/fs/gfs2/dir.h b/fs/gfs2/dir.h
+index 48fe890..8a468ca 100644
+--- a/fs/gfs2/dir.h
++++ b/fs/gfs2/dir.h
+@@ -16,15 +16,16 @@ struct inode;
+ struct gfs2_inode;
+ struct gfs2_inum;
+
+-int gfs2_dir_search(struct inode *dir, const struct qstr *filename,
+- struct gfs2_inum_host *inum, unsigned int *type);
++struct inode *gfs2_dir_search(struct inode *dir, const struct qstr *filename);
++int gfs2_dir_check(struct inode *dir, const struct qstr *filename,
++ const struct gfs2_inode *ip);
+ int gfs2_dir_add(struct inode *inode, const struct qstr *filename,
+- const struct gfs2_inum_host *inum, unsigned int type);
++ const struct gfs2_inode *ip, unsigned int type);
+ int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *filename);
+ int gfs2_dir_read(struct inode *inode, u64 *offset, void *opaque,
+ filldir_t filldir);
+ int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename,
+- struct gfs2_inum_host *new_inum, unsigned int new_type);
++ const struct gfs2_inode *nip, unsigned int new_type);
+
+ int gfs2_dir_exhash_dealloc(struct gfs2_inode *dip);
+
+diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
+index c66c718..b3ed585 100644
+--- a/fs/gfs2/glock.c
++++ b/fs/gfs2/glock.c
+@@ -1823,8 +1823,8 @@ static int dump_inode(struct glock_iter *gi, struct gfs2_inode *ip)
+
+ print_dbg(gi, " Inode:\n");
+ print_dbg(gi, " num = %llu/%llu\n",
+- (unsigned long long)ip->i_num.no_formal_ino,
+- (unsigned long long)ip->i_num.no_addr);
++ (unsigned long long)ip->i_no_formal_ino,
++ (unsigned long long)ip->i_no_addr);
+ print_dbg(gi, " type = %u\n", IF2DT(ip->i_inode.i_mode));
+ print_dbg(gi, " i_flags =");
+ for (x = 0; x < 32; x++)
+diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
+index d995441..00c3004 100644
+--- a/fs/gfs2/incore.h
++++ b/fs/gfs2/incore.h
+@@ -213,8 +213,8 @@ enum {
+
+ struct gfs2_inode {
+ struct inode i_inode;
+- struct gfs2_inum_host i_num;
+-
++ u64 i_no_addr;
++ u64 i_no_formal_ino;
+ unsigned long i_flags; /* GIF_... */
+
+ struct gfs2_dinode_host i_di; /* To be replaced by ref to block */
+diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
+index df0b8b3..58f5a67 100644
+--- a/fs/gfs2/inode.c
++++ b/fs/gfs2/inode.c
+@@ -41,9 +41,9 @@
+ static int iget_test(struct inode *inode, void *opaque)
+ {
+ struct gfs2_inode *ip = GFS2_I(inode);
+- struct gfs2_inum_host *inum = opaque;
++ u64 *no_addr = opaque;
+
+- if (ip->i_num.no_addr == inum->no_addr &&
++ if (ip->i_no_addr == *no_addr &&
+ inode->i_private != NULL)
+ return 1;
+
+@@ -53,37 +53,37 @@ static int iget_test(struct inode *inode, void *opaque)
+ static int iget_set(struct inode *inode, void *opaque)
+ {
+ struct gfs2_inode *ip = GFS2_I(inode);
+- struct gfs2_inum_host *inum = opaque;
++ u64 *no_addr = opaque;
+
+- ip->i_num = *inum;
+- inode->i_ino = inum->no_addr;
++ inode->i_ino = (unsigned long)*no_addr;
++ ip->i_no_addr = *no_addr;
+ return 0;
+ }
+
+-struct inode *gfs2_ilookup(struct super_block *sb, struct gfs2_inum_host *inum)
++struct inode *gfs2_ilookup(struct super_block *sb, u64 no_addr)
+ {
+- return ilookup5(sb, (unsigned long)inum->no_addr,
+- iget_test, inum);
++ unsigned long hash = (unsigned long)no_addr;
++ return ilookup5(sb, hash, iget_test, &no_addr);
+ }
+
+-static struct inode *gfs2_iget(struct super_block *sb, struct gfs2_inum_host *inum)
++static struct inode *gfs2_iget(struct super_block *sb, u64 no_addr)
+ {
+- return iget5_locked(sb, (unsigned long)inum->no_addr,
+- iget_test, iget_set, inum);
++ unsigned long hash = (unsigned long)no_addr;
++ return iget5_locked(sb, hash, iget_test, iget_set, &no_addr);
+ }
+
+ /**
+ * gfs2_inode_lookup - Lookup an inode
+ * @sb: The super block
+- * @inum: The inode number
++ * @no_addr: The inode number
+ * @type: The type of the inode
+ *
+ * Returns: A VFS inode, or an error
+ */
+
+-struct inode *gfs2_inode_lookup(struct super_block *sb, struct gfs2_inum_host *inum, unsigned int type)
++struct inode *gfs2_inode_lookup(struct super_block *sb, u64 no_addr, unsigned int type)
+ {
+- struct inode *inode = gfs2_iget(sb, inum);
++ struct inode *inode = gfs2_iget(sb, no_addr);
+ struct gfs2_inode *ip = GFS2_I(inode);
+ struct gfs2_glock *io_gl;
+ int error;
+@@ -110,12 +110,12 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, struct gfs2_inum_host *i
+ inode->i_op = &gfs2_dev_iops;
+ }
+
+- error = gfs2_glock_get(sdp, inum->no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl);
++ error = gfs2_glock_get(sdp, no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl);
+ if (unlikely(error))
+ goto fail;
+ ip->i_gl->gl_object = ip;
+
+- error = gfs2_glock_get(sdp, inum->no_addr, &gfs2_iopen_glops, CREATE, &io_gl);
++ error = gfs2_glock_get(sdp, no_addr, &gfs2_iopen_glops, CREATE, &io_gl);
+ if (unlikely(error))
+ goto fail_put;
+
+@@ -144,14 +144,12 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf)
+ struct gfs2_dinode_host *di = &ip->i_di;
+ const struct gfs2_dinode *str = buf;
+
+- if (ip->i_num.no_addr != be64_to_cpu(str->di_num.no_addr)) {
++ if (ip->i_no_addr != be64_to_cpu(str->di_num.no_addr)) {
+ if (gfs2_consist_inode(ip))
+ gfs2_dinode_print(ip);
+ return -EIO;
+ }
+- if (ip->i_num.no_formal_ino != be64_to_cpu(str->di_num.no_formal_ino))
+- return -ESTALE;
+-
++ ip->i_no_formal_ino = be64_to_cpu(str->di_num.no_formal_ino);
+ ip->i_inode.i_mode = be32_to_cpu(str->di_mode);
+ ip->i_inode.i_rdev = 0;
+ switch (ip->i_inode.i_mode & S_IFMT) {
+@@ -247,7 +245,7 @@ int gfs2_dinode_dealloc(struct gfs2_inode *ip)
+ if (error)
+ goto out_qs;
+
+- rgd = gfs2_blk2rgrpd(sdp, ip->i_num.no_addr);
++ rgd = gfs2_blk2rgrpd(sdp, ip->i_no_addr);
+ if (!rgd) {
+ gfs2_consist_inode(ip);
+ error = -EIO;
+@@ -366,8 +364,6 @@ struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name,
+ struct super_block *sb = dir->i_sb;
+ struct gfs2_inode *dip = GFS2_I(dir);
+ struct gfs2_holder d_gh;
+- struct gfs2_inum_host inum;
+- unsigned int type;
+ int error;
+ struct inode *inode = NULL;
+ int unlock = 0;
+@@ -395,12 +391,9 @@ struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name,
+ goto out;
+ }
+
+- error = gfs2_dir_search(dir, name, &inum, &type);
+- if (error)
+- goto out;
+-
+- inode = gfs2_inode_lookup(sb, &inum, type);
+-
++ inode = gfs2_dir_search(dir, name);
++ if (IS_ERR(inode))
++ error = PTR_ERR(inode);
+ out:
+ if (unlock)
+ gfs2_glock_dq_uninit(&d_gh);
+@@ -548,7 +541,7 @@ static int create_ok(struct gfs2_inode *dip, const struct qstr *name,
+ if (!dip->i_inode.i_nlink)
+ return -EPERM;
+
+- error = gfs2_dir_search(&dip->i_inode, name, NULL, NULL);
++ error = gfs2_dir_check(&dip->i_inode, name, NULL);
+ switch (error) {
+ case -ENOENT:
+ error = 0;
+@@ -588,8 +581,7 @@ static void munge_mode_uid_gid(struct gfs2_inode *dip, unsigned int *mode,
+ *gid = current->fsgid;
+ }
+
+-static int alloc_dinode(struct gfs2_inode *dip, struct gfs2_inum_host *inum,
+- u64 *generation)
++static int alloc_dinode(struct gfs2_inode *dip, u64 *no_addr, u64 *generation)
+ {
+ struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
+ int error;
+@@ -605,7 +597,7 @@ static int alloc_dinode(struct gfs2_inode *dip, struct gfs2_inum_host *inum,
+ if (error)
+ goto out_ipreserv;
+
+- inum->no_addr = gfs2_alloc_di(dip, generation);
++ *no_addr = gfs2_alloc_di(dip, generation);
+
+ gfs2_trans_end(sdp);
+
+@@ -760,7 +752,7 @@ static int link_dinode(struct gfs2_inode *dip, const struct qstr *name,
+ goto fail_quota_locks;
+ }
+
+- error = gfs2_dir_add(&dip->i_inode, name, &ip->i_num, IF2DT(ip->i_inode.i_mode));
++ error = gfs2_dir_add(&dip->i_inode, name, ip, IF2DT(ip->i_inode.i_mode));
+ if (error)
+ goto fail_end_trans;
+
+@@ -844,7 +836,7 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name,
+ struct gfs2_inode *dip = ghs->gh_gl->gl_object;
+ struct inode *dir = &dip->i_inode;
+ struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
+- struct gfs2_inum_host inum;
++ struct gfs2_inum_host inum = { .no_addr = 0, .no_formal_ino = 0 };
+ int error;
+ u64 generation;
+
+@@ -864,7 +856,7 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name,
+ if (error)
+ goto fail_gunlock;
+
+- error = alloc_dinode(dip, &inum, &generation);
++ error = alloc_dinode(dip, &inum.no_addr, &generation);
+ if (error)
+ goto fail_gunlock;
+
+@@ -877,7 +869,7 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name,
+ if (error)
+ goto fail_gunlock2;
+
+- inode = gfs2_inode_lookup(dir->i_sb, &inum, IF2DT(mode));
++ inode = gfs2_inode_lookup(dir->i_sb, inum.no_addr, IF2DT(mode));
+ if (IS_ERR(inode))
+ goto fail_gunlock2;
+
+@@ -976,10 +968,8 @@ int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name,
+ */
+
+ int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name,
+- struct gfs2_inode *ip)
++ const struct gfs2_inode *ip)
+ {
+- struct gfs2_inum_host inum;
+- unsigned int type;
+ int error;
+
+ if (IS_IMMUTABLE(&ip->i_inode) || IS_APPEND(&ip->i_inode))
+@@ -997,18 +987,10 @@ int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name,
+ if (error)
+ return error;
+
+- error = gfs2_dir_search(&dip->i_inode, name, &inum, &type);
++ error = gfs2_dir_check(&dip->i_inode, name, ip);
+ if (error)
+ return error;
+
+- if (!gfs2_inum_equal(&inum, &ip->i_num))
+- return -ENOENT;
+-
+- if (IF2DT(ip->i_inode.i_mode) != type) {
+- gfs2_consist_inode(dip);
+- return -EIO;
+- }
+-
+ return 0;
+ }
+
+diff --git a/fs/gfs2/inode.h b/fs/gfs2/inode.h
+index b57f448..05fc095 100644
+--- a/fs/gfs2/inode.h
++++ b/fs/gfs2/inode.h
+@@ -10,17 +10,17 @@
+ #ifndef __INODE_DOT_H__
+ #define __INODE_DOT_H__
+
+-static inline int gfs2_is_stuffed(struct gfs2_inode *ip)
++static inline int gfs2_is_stuffed(const struct gfs2_inode *ip)
+ {
+ return !ip->i_di.di_height;
+ }
+
+-static inline int gfs2_is_jdata(struct gfs2_inode *ip)
++static inline int gfs2_is_jdata(const struct gfs2_inode *ip)
+ {
+ return ip->i_di.di_flags & GFS2_DIF_JDATA;
+ }
+
+-static inline int gfs2_is_dir(struct gfs2_inode *ip)
++static inline int gfs2_is_dir(const struct gfs2_inode *ip)
+ {
+ return S_ISDIR(ip->i_inode.i_mode);
+ }
+@@ -32,9 +32,15 @@ static inline void gfs2_set_inode_blocks(struct inode *inode)
+ (GFS2_SB(inode)->sd_sb.sb_bsize_shift - GFS2_BASIC_BLOCK_SHIFT);
+ }
+
++static inline int gfs2_check_inum(const struct gfs2_inode *ip, u64 no_addr,
++ u64 no_formal_ino)
++{
++ return ip->i_no_addr == no_addr && ip->i_no_formal_ino == no_formal_ino;
++}
++
+ void gfs2_inode_attr_in(struct gfs2_inode *ip);
+-struct inode *gfs2_inode_lookup(struct super_block *sb, struct gfs2_inum_host *inum, unsigned type);
+-struct inode *gfs2_ilookup(struct super_block *sb, struct gfs2_inum_host *inum);
++struct inode *gfs2_inode_lookup(struct super_block *sb, u64 no_addr, unsigned type);
++struct inode *gfs2_ilookup(struct super_block *sb, u64 no_addr);
+
+ int gfs2_inode_refresh(struct gfs2_inode *ip);
+
+@@ -47,7 +53,7 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name,
+ int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name,
+ struct gfs2_inode *ip);
+ int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name,
+- struct gfs2_inode *ip);
++ const struct gfs2_inode *ip);
+ int gfs2_ok_to_move(struct gfs2_inode *this, struct gfs2_inode *to);
+ int gfs2_readlinki(struct gfs2_inode *ip, char **buf, unsigned int *len);
+ int gfs2_glock_nq_atime(struct gfs2_holder *gh);
+diff --git a/fs/gfs2/meta_io.h b/fs/gfs2/meta_io.h
+index e037425..527bf19 100644
+--- a/fs/gfs2/meta_io.h
++++ b/fs/gfs2/meta_io.h
+@@ -63,7 +63,7 @@ int gfs2_meta_indirect_buffer(struct gfs2_inode *ip, int height, u64 num,
+ static inline int gfs2_meta_inode_buffer(struct gfs2_inode *ip,
+ struct buffer_head **bhp)
+ {
+- return gfs2_meta_indirect_buffer(ip, 0, ip->i_num.no_addr, 0, bhp);
++ return gfs2_meta_indirect_buffer(ip, 0, ip->i_no_addr, 0, bhp);
+ }
+
+ struct buffer_head *gfs2_meta_ra(struct gfs2_glock *gl, u64 dblock, u32 extlen);
+diff --git a/fs/gfs2/ondisk.c b/fs/gfs2/ondisk.c
+index d9ecfd2..cd4cf05 100644
+--- a/fs/gfs2/ondisk.c
++++ b/fs/gfs2/ondisk.c
+@@ -33,26 +33,10 @@
+ * first arg: the cpu-order structure
+ */
+
+-void gfs2_inum_in(struct gfs2_inum_host *no, const void *buf)
++void gfs2_inum_out(const struct gfs2_inode *ip, struct gfs2_dirent *dent)
+ {
+- const struct gfs2_inum *str = buf;
+-
+- no->no_formal_ino = be64_to_cpu(str->no_formal_ino);
+- no->no_addr = be64_to_cpu(str->no_addr);
+-}
+-
+-void gfs2_inum_out(const struct gfs2_inum_host *no, void *buf)
+-{
+- struct gfs2_inum *str = buf;
+-
+- str->no_formal_ino = cpu_to_be64(no->no_formal_ino);
+- str->no_addr = cpu_to_be64(no->no_addr);
+-}
+-
+-static void gfs2_inum_print(const struct gfs2_inum_host *no)
+-{
+- printk(KERN_INFO " no_formal_ino = %llu\n", (unsigned long long)no->no_formal_ino);
+- printk(KERN_INFO " no_addr = %llu\n", (unsigned long long)no->no_addr);
++ dent->de_inum.no_formal_ino = cpu_to_be64(ip->i_no_formal_ino);
++ dent->de_inum.no_addr = cpu_to_be64(ip->i_no_addr);
+ }
+
+ static void gfs2_meta_header_in(struct gfs2_meta_header_host *mh, const void *buf)
+@@ -74,9 +58,10 @@ void gfs2_sb_in(struct gfs2_sb_host *sb, const void *buf)
+ sb->sb_multihost_format = be32_to_cpu(str->sb_multihost_format);
+ sb->sb_bsize = be32_to_cpu(str->sb_bsize);
+ sb->sb_bsize_shift = be32_to_cpu(str->sb_bsize_shift);
+-
+- gfs2_inum_in(&sb->sb_master_dir, (char *)&str->sb_master_dir);
+- gfs2_inum_in(&sb->sb_root_dir, (char *)&str->sb_root_dir);
++ sb->sb_master_dir.no_addr = be64_to_cpu(str->sb_master_dir.no_addr);
++ sb->sb_master_dir.no_formal_ino = be64_to_cpu(str->sb_master_dir.no_formal_ino);
++ sb->sb_root_dir.no_addr = be64_to_cpu(str->sb_root_dir.no_addr);
++ sb->sb_root_dir.no_formal_ino = be64_to_cpu(str->sb_root_dir.no_formal_ino);
+
+ memcpy(sb->sb_lockproto, str->sb_lockproto, GFS2_LOCKNAME_LEN);
+ memcpy(sb->sb_locktable, str->sb_locktable, GFS2_LOCKNAME_LEN);
+@@ -146,9 +131,8 @@ void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf)
+ str->di_header.__pad0 = 0;
+ str->di_header.mh_format = cpu_to_be32(GFS2_FORMAT_DI);
+ str->di_header.__pad1 = 0;
+-
+- gfs2_inum_out(&ip->i_num, &str->di_num);
+-
++ str->di_num.no_addr = cpu_to_be64(ip->i_no_addr);
++ str->di_num.no_formal_ino = cpu_to_be64(ip->i_no_formal_ino);
+ str->di_mode = cpu_to_be32(ip->i_inode.i_mode);
+ str->di_uid = cpu_to_be32(ip->i_inode.i_uid);
+ str->di_gid = cpu_to_be32(ip->i_inode.i_gid);
+@@ -178,7 +162,8 @@ void gfs2_dinode_print(const struct gfs2_inode *ip)
+ {
+ const struct gfs2_dinode_host *di = &ip->i_di;
+
+- gfs2_inum_print(&ip->i_num);
++ printk(KERN_INFO " no_formal_ino = %llu\n", (unsigned long long)ip->i_no_formal_ino);
++ printk(KERN_INFO " no_addr = %llu\n", (unsigned long long)ip->i_no_addr);
+
+ printk(KERN_INFO " di_size = %llu\n", (unsigned long long)di->di_size);
+ printk(KERN_INFO " di_blocks = %llu\n", (unsigned long long)di->di_blocks);
+diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c
+index 4913ef5..fb84478 100644
+--- a/fs/gfs2/ops_address.c
++++ b/fs/gfs2/ops_address.c
+@@ -757,8 +757,8 @@ static unsigned limit = 0;
+ return;
+
+ fs_warn(sdp, "ip = %llu %llu\n",
+- (unsigned long long)ip->i_num.no_formal_ino,
+- (unsigned long long)ip->i_num.no_addr);
++ (unsigned long long)ip->i_no_formal_ino,
++ (unsigned long long)ip->i_no_addr);
+
+ for (x = 0; x < GFS2_MAX_META_HEIGHT; x++)
+ fs_warn(sdp, "ip->i_cache[%u] = %s\n",
+diff --git a/fs/gfs2/ops_dentry.c b/fs/gfs2/ops_dentry.c
+index a6fdc52..793e334 100644
+--- a/fs/gfs2/ops_dentry.c
++++ b/fs/gfs2/ops_dentry.c
+@@ -21,6 +21,7 @@
+ #include "glock.h"
+ #include "ops_dentry.h"
+ #include "util.h"
++#include "inode.h"
+
+ /**
+ * gfs2_drevalidate - Check directory lookup consistency
+@@ -40,14 +41,15 @@ static int gfs2_drevalidate(struct dentry *dentry, struct nameidata *nd)
+ struct gfs2_inode *dip = GFS2_I(parent->d_inode);
+ struct inode *inode = dentry->d_inode;
+ struct gfs2_holder d_gh;
+- struct gfs2_inode *ip;
+- struct gfs2_inum_host inum;
+- unsigned int type;
++ struct gfs2_inode *ip = NULL;
+ int error;
+ int had_lock=0;
+
+- if (inode && is_bad_inode(inode))
+- goto invalid;
++ if (inode) {
++ if (is_bad_inode(inode))
++ goto invalid;
++ ip = GFS2_I(inode);
++ }
+
+ if (sdp->sd_args.ar_localcaching)
+ goto valid;
+@@ -59,7 +61,7 @@ static int gfs2_drevalidate(struct dentry *dentry, struct nameidata *nd)
+ goto fail;
+ }
+
+- error = gfs2_dir_search(parent->d_inode, &dentry->d_name, &inum, &type);
++ error = gfs2_dir_check(parent->d_inode, &dentry->d_name, ip);
+ switch (error) {
+ case 0:
+ if (!inode)
+@@ -73,16 +75,6 @@ static int gfs2_drevalidate(struct dentry *dentry, struct nameidata *nd)
+ goto fail_gunlock;
+ }
+
+- ip = GFS2_I(inode);
+-
+- if (!gfs2_inum_equal(&ip->i_num, &inum))
+- goto invalid_gunlock;
+-
+- if (IF2DT(ip->i_inode.i_mode) != type) {
+- gfs2_consist_inode(dip);
+- goto fail_gunlock;
+- }
+-
+ valid_gunlock:
+ if (!had_lock)
+ gfs2_glock_dq_uninit(&d_gh);
+diff --git a/fs/gfs2/ops_export.c b/fs/gfs2/ops_export.c
+index aad9183..51a8a14 100644
+--- a/fs/gfs2/ops_export.c
++++ b/fs/gfs2/ops_export.c
+@@ -75,10 +75,10 @@ static int gfs2_encode_fh(struct dentry *dentry, __u32 *p, int *len,
+ (connectable && *len < GFS2_LARGE_FH_SIZE))
+ return 255;
+
+- fh[0] = cpu_to_be32(ip->i_num.no_formal_ino >> 32);
+- fh[1] = cpu_to_be32(ip->i_num.no_formal_ino & 0xFFFFFFFF);
+- fh[2] = cpu_to_be32(ip->i_num.no_addr >> 32);
+- fh[3] = cpu_to_be32(ip->i_num.no_addr & 0xFFFFFFFF);
++ fh[0] = cpu_to_be32(ip->i_no_formal_ino >> 32);
++ fh[1] = cpu_to_be32(ip->i_no_formal_ino & 0xFFFFFFFF);
++ fh[2] = cpu_to_be32(ip->i_no_addr >> 32);
++ fh[3] = cpu_to_be32(ip->i_no_addr & 0xFFFFFFFF);
+ *len = GFS2_SMALL_FH_SIZE;
+
+ if (!connectable || inode == sb->s_root->d_inode)
+@@ -90,10 +90,10 @@ static int gfs2_encode_fh(struct dentry *dentry, __u32 *p, int *len,
+ igrab(inode);
+ spin_unlock(&dentry->d_lock);
+
+- fh[4] = cpu_to_be32(ip->i_num.no_formal_ino >> 32);
+- fh[5] = cpu_to_be32(ip->i_num.no_formal_ino & 0xFFFFFFFF);
+- fh[6] = cpu_to_be32(ip->i_num.no_addr >> 32);
+- fh[7] = cpu_to_be32(ip->i_num.no_addr & 0xFFFFFFFF);
++ fh[4] = cpu_to_be32(ip->i_no_formal_ino >> 32);
++ fh[5] = cpu_to_be32(ip->i_no_formal_ino & 0xFFFFFFFF);
++ fh[6] = cpu_to_be32(ip->i_no_addr >> 32);
++ fh[7] = cpu_to_be32(ip->i_no_addr & 0xFFFFFFFF);
+
+ fh[8] = cpu_to_be32(inode->i_mode);
+ fh[9] = 0; /* pad to double word */
+@@ -144,7 +144,8 @@ static int gfs2_get_name(struct dentry *parent, char *name,
+ ip = GFS2_I(inode);
+
+ *name = 0;
+- gnfd.inum = ip->i_num;
++ gnfd.inum.no_addr = ip->i_no_addr;
++ gnfd.inum.no_formal_ino = ip->i_no_formal_ino;
+ gnfd.name = name;
+
+ error = gfs2_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, &gh);
+@@ -202,9 +203,9 @@ static struct dentry *gfs2_get_dentry(struct super_block *sb, void *inum_obj)
+
+ /* System files? */
+
+- inode = gfs2_ilookup(sb, inum);
++ inode = gfs2_ilookup(sb, inum->no_addr);
+ if (inode) {
+- if (GFS2_I(inode)->i_num.no_formal_ino != inum->no_formal_ino) {
++ if (GFS2_I(inode)->i_no_formal_ino != inum->no_formal_ino) {
+ iput(inode);
+ return ERR_PTR(-ESTALE);
+ }
+@@ -236,7 +237,7 @@ static struct dentry *gfs2_get_dentry(struct super_block *sb, void *inum_obj)
+ gfs2_glock_dq_uninit(&rgd_gh);
+ gfs2_glock_dq_uninit(&ri_gh);
+
+- inode = gfs2_inode_lookup(sb, inum, fh_obj->imode);
++ inode = gfs2_inode_lookup(sb, inum->no_addr, fh_obj->imode);
+ if (!inode)
+ goto fail;
+ if (IS_ERR(inode)) {
+@@ -249,6 +250,10 @@ static struct dentry *gfs2_get_dentry(struct super_block *sb, void *inum_obj)
+ iput(inode);
+ goto fail;
+ }
++ if (GFS2_I(inode)->i_no_formal_ino != inum->no_formal_ino) {
++ iput(inode);
++ goto fail;
++ }
+
+ error = -EIO;
+ if (GFS2_I(inode)->i_di.di_flags & GFS2_DIF_SYSTEM) {
+diff --git a/fs/gfs2/ops_file.c b/fs/gfs2/ops_file.c
+index 064df88..550032c 100644
+--- a/fs/gfs2/ops_file.c
++++ b/fs/gfs2/ops_file.c
+@@ -502,7 +502,7 @@ static int gfs2_lock(struct file *file, int cmd, struct file_lock *fl)
+ struct gfs2_inode *ip = GFS2_I(file->f_mapping->host);
+ struct gfs2_sbd *sdp = GFS2_SB(file->f_mapping->host);
+ struct lm_lockname name =
+- { .ln_number = ip->i_num.no_addr,
++ { .ln_number = ip->i_no_addr,
+ .ln_type = LM_TYPE_PLOCK };
+
+ if (!(fl->fl_flags & FL_POSIX))
+@@ -557,7 +557,7 @@ static int do_flock(struct file *file, int cmd, struct file_lock *fl)
+ gfs2_glock_dq_uninit(fl_gh);
+ } else {
+ error = gfs2_glock_get(GFS2_SB(&ip->i_inode),
+- ip->i_num.no_addr, &gfs2_flock_glops,
++ ip->i_no_addr, &gfs2_flock_glops,
+ CREATE, &gl);
+ if (error)
+ goto out;
+diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
+index 2c5f8e7..c682371 100644
+--- a/fs/gfs2/ops_fstype.c
++++ b/fs/gfs2/ops_fstype.c
+@@ -236,17 +236,17 @@ fail:
+ return error;
+ }
+
+-static struct inode *gfs2_lookup_root(struct super_block *sb,
+- struct gfs2_inum_host *inum)
++static inline struct inode *gfs2_lookup_root(struct super_block *sb,
++ u64 no_addr)
+ {
+- return gfs2_inode_lookup(sb, inum, DT_DIR);
++ return gfs2_inode_lookup(sb, no_addr, DT_DIR);
+ }
+
+ static int init_sb(struct gfs2_sbd *sdp, int silent, int undo)
+ {
+ struct super_block *sb = sdp->sd_vfs;
+ struct gfs2_holder sb_gh;
+- struct gfs2_inum_host *inum;
++ u64 no_addr;
+ struct inode *inode;
+ int error = 0;
+
+@@ -289,10 +289,10 @@ static int init_sb(struct gfs2_sbd *sdp, int silent, int undo)
+ sb_set_blocksize(sb, sdp->sd_sb.sb_bsize);
+
+ /* Get the root inode */
+- inum = &sdp->sd_sb.sb_root_dir;
++ no_addr = sdp->sd_sb.sb_root_dir.no_addr;
+ if (sb->s_type == &gfs2meta_fs_type)
+- inum = &sdp->sd_sb.sb_master_dir;
+- inode = gfs2_lookup_root(sb, inum);
++ no_addr = sdp->sd_sb.sb_master_dir.no_addr;
++ inode = gfs2_lookup_root(sb, no_addr);
+ if (IS_ERR(inode)) {
+ error = PTR_ERR(inode);
+ fs_err(sdp, "can't read in root inode: %d\n", error);
+@@ -449,7 +449,7 @@ static int init_inodes(struct gfs2_sbd *sdp, int undo)
+ if (undo)
+ goto fail_qinode;
+
+- inode = gfs2_lookup_root(sdp->sd_vfs, &sdp->sd_sb.sb_master_dir);
++ inode = gfs2_lookup_root(sdp->sd_vfs, sdp->sd_sb.sb_master_dir.no_addr);
+ if (IS_ERR(inode)) {
+ error = PTR_ERR(inode);
+ fs_err(sdp, "can't read in master directory: %d\n", error);
+diff --git a/fs/gfs2/ops_inode.c b/fs/gfs2/ops_inode.c
+index d85f6e0..f8ecfec 100644
+--- a/fs/gfs2/ops_inode.c
++++ b/fs/gfs2/ops_inode.c
+@@ -157,7 +157,7 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir,
+ if (error)
+ goto out_gunlock;
+
+- error = gfs2_dir_search(dir, &dentry->d_name, NULL, NULL);
++ error = gfs2_dir_check(dir, &dentry->d_name, NULL);
+ switch (error) {
+ case -ENOENT:
+ break;
+@@ -217,8 +217,7 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir,
+ goto out_ipres;
+ }
+
+- error = gfs2_dir_add(dir, &dentry->d_name, &ip->i_num,
+- IF2DT(inode->i_mode));
++ error = gfs2_dir_add(dir, &dentry->d_name, ip, IF2DT(inode->i_mode));
+ if (error)
+ goto out_end_trans;
+
+@@ -275,7 +274,7 @@ static int gfs2_unlink(struct inode *dir, struct dentry *dentry)
+ gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs);
+ gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + 1);
+
+- rgd = gfs2_blk2rgrpd(sdp, ip->i_num.no_addr);
++ rgd = gfs2_blk2rgrpd(sdp, ip->i_no_addr);
+ gfs2_holder_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs + 2);
+
+
+@@ -420,7 +419,7 @@ static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, int mode)
+ dent = (struct gfs2_dirent *)((char*)dent + GFS2_DIRENT_SIZE(1));
+ gfs2_qstr2dirent(&str, dibh->b_size - GFS2_DIRENT_SIZE(1) - sizeof(struct gfs2_dinode), dent);
+
+- gfs2_inum_out(&dip->i_num, &dent->de_inum);
++ gfs2_inum_out(dip, dent);
+ dent->de_type = cpu_to_be16(DT_DIR);
+
+ gfs2_dinode_out(ip, di);
+@@ -472,7 +471,7 @@ static int gfs2_rmdir(struct inode *dir, struct dentry *dentry)
+ gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs);
+ gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + 1);
+
+- rgd = gfs2_blk2rgrpd(sdp, ip->i_num.no_addr);
++ rgd = gfs2_blk2rgrpd(sdp, ip->i_no_addr);
+ gfs2_holder_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs + 2);
+
+ error = gfs2_glock_nq_m(3, ghs);
+@@ -614,7 +613,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
+ * this is the case of the target file already existing
+ * so we unlink before doing the rename
+ */
+- nrgd = gfs2_blk2rgrpd(sdp, nip->i_num.no_addr);
++ nrgd = gfs2_blk2rgrpd(sdp, nip->i_no_addr);
+ if (nrgd)
+ gfs2_holder_init(nrgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs + num_gh++);
+ }
+@@ -653,7 +652,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
+ if (error)
+ goto out_gunlock;
+
+- error = gfs2_dir_search(ndir, &ndentry->d_name, NULL, NULL);
++ error = gfs2_dir_check(ndir, &ndentry->d_name, NULL);
+ switch (error) {
+ case -ENOENT:
+ error = 0;
+@@ -750,7 +749,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
+ if (error)
+ goto out_end_trans;
+
+- error = gfs2_dir_mvino(ip, &name, &ndip->i_num, DT_DIR);
++ error = gfs2_dir_mvino(ip, &name, nip, DT_DIR);
+ if (error)
+ goto out_end_trans;
+ } else {
+@@ -768,8 +767,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
+ if (error)
+ goto out_end_trans;
+
+- error = gfs2_dir_add(ndir, &ndentry->d_name, &ip->i_num,
+- IF2DT(ip->i_inode.i_mode));
++ error = gfs2_dir_add(ndir, &ndentry->d_name, ip, IF2DT(ip->i_inode.i_mode));
+ if (error)
+ goto out_end_trans;
+
+diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
+index a62c0f2..30eb428 100644
+--- a/fs/gfs2/rgrp.c
++++ b/fs/gfs2/rgrp.c
+@@ -1470,7 +1470,7 @@ void gfs2_unlink_di(struct inode *inode)
+ struct gfs2_inode *ip = GFS2_I(inode);
+ struct gfs2_sbd *sdp = GFS2_SB(inode);
+ struct gfs2_rgrpd *rgd;
+- u64 blkno = ip->i_num.no_addr;
++ u64 blkno = ip->i_no_addr;
+
+ rgd = rgblk_free(sdp, blkno, 1, GFS2_BLKST_UNLINKED);
+ if (!rgd)
+@@ -1505,9 +1505,9 @@ static void gfs2_free_uninit_di(struct gfs2_rgrpd *rgd, u64 blkno)
+
+ void gfs2_free_di(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip)
+ {
+- gfs2_free_uninit_di(rgd, ip->i_num.no_addr);
++ gfs2_free_uninit_di(rgd, ip->i_no_addr);
+ gfs2_quota_change(ip, -1, ip->i_inode.i_uid, ip->i_inode.i_gid);
+- gfs2_meta_wipe(ip, ip->i_num.no_addr, 1);
++ gfs2_meta_wipe(ip, ip->i_no_addr, 1);
+ }
+
+ /**
+diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
+index 4fdda97..faccffd 100644
+--- a/fs/gfs2/super.c
++++ b/fs/gfs2/super.c
+@@ -360,7 +360,7 @@ int gfs2_jindex_hold(struct gfs2_sbd *sdp, struct gfs2_holder *ji_gh)
+ name.len = sprintf(buf, "journal%u", sdp->sd_journals);
+ name.hash = gfs2_disk_hash(name.name, name.len);
+
+- error = gfs2_dir_search(sdp->sd_jindex, &name, NULL, NULL);
++ error = gfs2_dir_check(sdp->sd_jindex, &name, NULL);
+ if (error == -ENOENT) {
+ error = 0;
+ break;
+diff --git a/fs/gfs2/util.c b/fs/gfs2/util.c
+index 601eaa1..3f5edc5 100644
+--- a/fs/gfs2/util.c
++++ b/fs/gfs2/util.c
+@@ -115,8 +115,8 @@ int gfs2_consist_inode_i(struct gfs2_inode *ip, int cluster_wide,
+ "GFS2: fsid=%s: inode = %llu %llu\n"
+ "GFS2: fsid=%s: function = %s, file = %s, line = %u\n",
+ sdp->sd_fsname,
+- sdp->sd_fsname, (unsigned long long)ip->i_num.no_formal_ino,
+- (unsigned long long)ip->i_num.no_addr,
++ sdp->sd_fsname, (unsigned long long)ip->i_no_formal_ino,
++ (unsigned long long)ip->i_no_addr,
+ sdp->sd_fsname, function, file, line);
+ return rv;
+ }
+diff --git a/include/linux/gfs2_ondisk.h b/include/linux/gfs2_ondisk.h
+index 8b7e4c1..a82ec8c 100644
+--- a/include/linux/gfs2_ondisk.h
++++ b/include/linux/gfs2_ondisk.h
+@@ -59,13 +59,6 @@ struct gfs2_inum_host {
+ __u64 no_addr;
+ };
+
+-static inline int gfs2_inum_equal(const struct gfs2_inum_host *ino1,
+- const struct gfs2_inum_host *ino2)
+-{
+- return ino1->no_formal_ino == ino2->no_formal_ino &&
+- ino1->no_addr == ino2->no_addr;
+-}
+-
+ /*
+ * Generic metadata head structure
+ * Every inplace buffer logged in the journal must start with this.
+@@ -509,9 +502,9 @@ struct gfs2_quota_change_host {
+
+ #ifdef __KERNEL__
+ /* Translation functions */
++struct gfs2_inode;
+
+-extern void gfs2_inum_in(struct gfs2_inum_host *no, const void *buf);
+-extern void gfs2_inum_out(const struct gfs2_inum_host *no, void *buf);
++extern void gfs2_inum_out(const struct gfs2_inode *ip, struct gfs2_dirent *dent);
+ extern void gfs2_sb_in(struct gfs2_sb_host *sb, const void *buf);
+ extern void gfs2_rindex_in(struct gfs2_rindex_host *ri, const void *buf);
+ extern void gfs2_rindex_out(const struct gfs2_rindex_host *ri, void *buf);
+--
+1.5.1.2
+
+>From 2e8701a15cd6f7c95e74d6660615a69b09e453ef Mon Sep 17 00:00:00 2001
+From: Abhijith Das <adas at redhat.com>
+Date: Wed, 16 May 2007 17:02:19 -0500
+Subject: [PATCH] [GFS2] Quotas non-functional - fix bug
+
+This patch fixes an error in the quota code where a 'struct
+gfs2_quota_lvb*' was being passed to gfs2_adjust_quota() instead of a
+'struct gfs2_quota_data*'. Also moved 'struct gfs2_quota_lvb' from
+fs/gfs2/incore.h to include/linux/gfs2_ondisk.h as per Steve's suggestion.
+
+Signed-off-by: Abhijith Das <adas at redhat.com>
+Signed-off-by: Steven Whitehouse <swhiteho at redhat.com>
+
+diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
+index 00c3004..b2079fc 100644
+--- a/fs/gfs2/incore.h
++++ b/fs/gfs2/incore.h
+@@ -275,14 +275,6 @@ enum {
+ QDF_LOCKED = 2,
+ };
+
+-struct gfs2_quota_lvb {
+- __be32 qb_magic;
+- u32 __pad;
+- __be64 qb_limit; /* Hard limit of # blocks to alloc */
+- __be64 qb_warn; /* Warn user when alloc is above this # */
+- __be64 qb_value; /* Current # blocks allocated */
+-};
+-
+ struct gfs2_quota_data {
+ struct list_head qd_list;
+ unsigned int qd_count;
+diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
+index c186857..fcd3ee2 100644
+--- a/fs/gfs2/quota.c
++++ b/fs/gfs2/quota.c
+@@ -627,6 +627,8 @@ static int gfs2_adjust_quota(struct gfs2_inode *ip, loff_t loc,
+ err = 0;
+ qd->qd_qb.qb_magic = cpu_to_be32(GFS2_MAGIC);
+ qd->qd_qb.qb_value = cpu_to_be64(value);
++ ((struct gfs2_quota_lvb*)(qd->qd_gl->gl_lvb))->qb_magic = cpu_to_be32(GFS2_MAGIC);
++ ((struct gfs2_quota_lvb*)(qd->qd_gl->gl_lvb))->qb_value = cpu_to_be64(value);
+ unlock:
+ unlock_page(page);
+ page_cache_release(page);
+@@ -709,7 +711,7 @@ static int do_sync(unsigned int num_qd, struct gfs2_quota_data **qda)
+ offset = qd2offset(qd);
+ error = gfs2_adjust_quota(ip, offset, qd->qd_change_sync,
+ (struct gfs2_quota_data *)
+- qd->qd_gl->gl_lvb);
++ qd);
+ if (error)
+ goto out_end_trans;
+
+diff --git a/include/linux/gfs2_ondisk.h b/include/linux/gfs2_ondisk.h
+index a82ec8c..028f981 100644
+--- a/include/linux/gfs2_ondisk.h
++++ b/include/linux/gfs2_ondisk.h
+@@ -500,6 +500,14 @@ struct gfs2_quota_change_host {
+ __u32 qc_id;
+ };
+
++struct gfs2_quota_lvb {
++ __be32 qb_magic;
++ u32 __pad;
++ __be64 qb_limit; /* Hard limit of # blocks to alloc */
++ __be64 qb_warn; /* Warn user when alloc is above this # */
++ __be64 qb_value; /* Current # blocks allocated */
++};
++
+ #ifdef __KERNEL__
+ /* Translation functions */
+ struct gfs2_inode;
+--
+1.5.1.2
+
+>From f7028983d9f953ec92a8f865950177897c34a66d Mon Sep 17 00:00:00 2001
+From: Josef Bacik <jwhiter at redhat.com>
+Date: Wed, 16 May 2007 15:56:13 -0400
+Subject: [PATCH] [DLM] keep dlm from panicing when traversing rsb list in debugfs
+
+This problem was originally reported against GFS6.1, but the same issue exists
+in upstream DLM. This patch keeps the rsb iterator assigning under the rsbtbl
+list lock. Each time we process an rsb we grab a reference to it to make sure
+it is not freed out from underneath us, and then put it when we get the next rsb
+in the list or move onto another list.
+
+Signed-off-by: Josef Bacik <jwhiter at redhat.com>
+Signed-off-by: Steven Whitehouse <swhiteho at redhat.com>
+
+diff --git a/fs/dlm/debug_fs.c b/fs/dlm/debug_fs.c
+index 61ba670..9e27a16 100644
+--- a/fs/dlm/debug_fs.c
++++ b/fs/dlm/debug_fs.c
+@@ -17,6 +17,7 @@
+ #include <linux/debugfs.h>
+
+ #include "dlm_internal.h"
++#include "lock.h"
+
+ #define DLM_DEBUG_BUF_LEN 4096
+ static char debug_buf[DLM_DEBUG_BUF_LEN];
+@@ -166,6 +167,9 @@ static int rsb_iter_next(struct rsb_iter *ri)
+ read_lock(&ls->ls_rsbtbl[i].lock);
+ if (!list_empty(&ls->ls_rsbtbl[i].list)) {
+ ri->next = ls->ls_rsbtbl[i].list.next;
++ ri->rsb = list_entry(ri->next, struct dlm_rsb,
++ res_hashchain);
++ dlm_hold_rsb(ri->rsb);
+ read_unlock(&ls->ls_rsbtbl[i].lock);
+ break;
+ }
+@@ -176,6 +180,7 @@ static int rsb_iter_next(struct rsb_iter *ri)
+ if (ri->entry >= ls->ls_rsbtbl_size)
+ return 1;
+ } else {
++ struct dlm_rsb *old = ri->rsb;
+ i = ri->entry;
+ read_lock(&ls->ls_rsbtbl[i].lock);
+ ri->next = ri->next->next;
+@@ -184,11 +189,13 @@ static int rsb_iter_next(struct rsb_iter *ri)
+ ri->next = NULL;
+ ri->entry++;
+ read_unlock(&ls->ls_rsbtbl[i].lock);
++ dlm_put_rsb(old);
+ goto top;
+ }
++ ri->rsb = list_entry(ri->next, struct dlm_rsb, res_hashchain);
+ read_unlock(&ls->ls_rsbtbl[i].lock);
++ dlm_put_rsb(old);
+ }
+- ri->rsb = list_entry(ri->next, struct dlm_rsb, res_hashchain);
+
+ return 0;
+ }
+--
+1.5.1.2
+
+
+
More information about the fedora-extras-commits
mailing list