[GFS2] Fix unlinked file handling

This patch fixes the way we have been dealing with unlinked,
but still open files. It removes all limits (other than memory
for inodes, as per every other filesystem) on numbers of these
which we can support on GFS2. It also means that (like other
fs) its the responsibility of the last process to close the file
to deallocate the storage, rather than the person who did the
unlinking. Note that with GFS2, those two events might take place
on different nodes.

Also there are a number of other changes:

 o We use the Linux inode subsystem as it was intended to be
used, wrt allocating GFS2 inodes
 o The Linux inode cache is now the point which we use for
local enforcement of only holding one copy of the inode in
core at once (previous to this we used the glock layer).
 o We no longer use the unlinked "special" file. We just ignore it
completely. This makes unlinking more efficient.
 o We now use the 4th block allocation state. The previously unused
state is used to track unlinked but still open inodes.
 o gfs2_inoded is no longer needed
 o Several fields are now no longer needed (and removed) from the in
core struct gfs2_inode
 o Several fields are no longer needed (and removed) from the in core
superblock

There are a number of future possible optimisations and clean ups
which have been made possible by this patch.

Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
diff --git a/fs/gfs2/Makefile b/fs/gfs2/Makefile
index 9974201..0b79776 100644
--- a/fs/gfs2/Makefile
+++ b/fs/gfs2/Makefile
@@ -3,7 +3,7 @@
 	glops.o inode.o lm.o log.o lops.o locking.o lvb.o main.o meta_io.o \
 	mount.o ondisk.o ops_address.o ops_dentry.o ops_export.o ops_file.o \
 	ops_fstype.o ops_inode.o ops_super.o ops_vm.o page.o quota.o \
-	recovery.o rgrp.o super.o sys.o trans.o unlinked.o util.o
+	recovery.o rgrp.o super.o sys.o trans.o util.o
 
 obj-$(CONFIG_GFS2_FS_LOCKING_NOLOCK) += locking/nolock/
 obj-$(CONFIG_GFS2_FS_LOCKING_DLM) += locking/dlm/
diff --git a/fs/gfs2/acl.c b/fs/gfs2/acl.c
index 343dbe3..9ef4cf2 100644
--- a/fs/gfs2/acl.c
+++ b/fs/gfs2/acl.c
@@ -73,7 +73,7 @@
 
 int gfs2_acl_validate_remove(struct gfs2_inode *ip, int access)
 {
-	if (!ip->i_sbd->sd_args.ar_posix_acl)
+	if (!GFS2_SB(&ip->i_inode)->sd_args.ar_posix_acl)
 		return -EOPNOTSUPP;
 	if (current->fsuid != ip->i_di.di_uid && !capable(CAP_FOWNER))
 		return -EPERM;
@@ -160,7 +160,7 @@
 	struct posix_acl *acl = NULL;
 	int error;
 
-	error = acl_get(inode->u.generic_ip, ACL_ACCESS, &acl, NULL, NULL, NULL);
+	error = acl_get(GFS2_I(inode), ACL_ACCESS, &acl, NULL, NULL, NULL);
 	if (error)
 		return error;
 
@@ -175,7 +175,7 @@
 
 int gfs2_check_acl(struct inode *inode, int mask)
 {
-	struct gfs2_inode *ip = inode->u.generic_ip;
+	struct gfs2_inode *ip = GFS2_I(inode);
 	struct gfs2_holder i_gh;
 	int error;
 
@@ -192,7 +192,7 @@
 
 static int munge_mode(struct gfs2_inode *ip, mode_t mode)
 {
-	struct gfs2_sbd *sdp = ip->i_sbd;
+	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
 	struct buffer_head *dibh;
 	int error;
 
@@ -217,7 +217,7 @@
 
 int gfs2_acl_create(struct gfs2_inode *dip, struct gfs2_inode *ip)
 {
-	struct gfs2_sbd *sdp = dip->i_sbd;
+	struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
 	struct posix_acl *acl = NULL, *clone;
 	struct gfs2_ea_request er;
 	mode_t mode = ip->i_di.di_mode;
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c
index 41abd3f..98fa07c 100644
--- a/fs/gfs2/bmap.c
+++ b/fs/gfs2/bmap.c
@@ -136,7 +136,7 @@
 
 static unsigned int calc_tree_height(struct gfs2_inode *ip, uint64_t size)
 {
-	struct gfs2_sbd *sdp = ip->i_sbd;
+	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
 	uint64_t *arr;
 	unsigned int max, height;
 
@@ -169,7 +169,7 @@
 
 static int build_height(struct inode *inode, unsigned height)
 {
-	struct gfs2_inode *ip = inode->u.generic_ip;
+	struct gfs2_inode *ip = GFS2_I(inode);
 	unsigned new_height = height - ip->i_di.di_height;
 	struct buffer_head *dibh;
 	struct buffer_head *blocks[GFS2_MAX_META_HEIGHT];
@@ -283,7 +283,7 @@
 static void find_metapath(struct gfs2_inode *ip, uint64_t block,
 			  struct metapath *mp)
 {
-	struct gfs2_sbd *sdp = ip->i_sbd;
+	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
 	uint64_t b = block;
 	unsigned int i;
 
@@ -382,8 +382,8 @@
 					       int *boundary,
 					       struct metapath *mp)
 {
-	struct gfs2_inode *ip = inode->u.generic_ip;
-	struct gfs2_sbd *sdp = ip->i_sbd;
+	struct gfs2_inode *ip = GFS2_I(inode);
+	struct gfs2_sbd *sdp = GFS2_SB(inode);
 	struct buffer_head *bh;
 	int create = *new;
 	unsigned int bsize;
@@ -446,7 +446,7 @@
 
 static inline void bmap_lock(struct inode *inode, int create)
 {
-	struct gfs2_inode *ip = inode->u.generic_ip;
+	struct gfs2_inode *ip = GFS2_I(inode);
 	if (create)
 		down_write(&ip->i_rw_mutex);
 	else
@@ -455,7 +455,7 @@
 
 static inline void bmap_unlock(struct inode *inode, int create)
 {
-	struct gfs2_inode *ip = inode->u.generic_ip;
+	struct gfs2_inode *ip = GFS2_I(inode);
 	if (create)
 		up_write(&ip->i_rw_mutex);
 	else
@@ -481,8 +481,8 @@
 
 int gfs2_extent_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, unsigned *extlen)
 {
-	struct gfs2_inode *ip = inode->u.generic_ip;
-	struct gfs2_sbd *sdp = ip->i_sbd;
+	struct gfs2_inode *ip = GFS2_I(inode);
+	struct gfs2_sbd *sdp = GFS2_SB(inode);
 	struct metapath mp;
 	struct buffer_head *bh;
 	int boundary;
@@ -541,7 +541,7 @@
 			  uint64_t block, int first, block_call_t bc,
 			  void *data)
 {
-	struct gfs2_sbd *sdp = ip->i_sbd;
+	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
 	struct buffer_head *bh = NULL;
 	uint64_t *top, *bottom;
 	uint64_t bn;
@@ -609,8 +609,8 @@
 		    struct buffer_head *bh, uint64_t *top, uint64_t *bottom,
 		    unsigned int height, void *data)
 {
-	struct strip_mine *sm = (struct strip_mine *)data;
-	struct gfs2_sbd *sdp = ip->i_sbd;
+	struct strip_mine *sm = data;
+	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
 	struct gfs2_rgrp_list rlist;
 	uint64_t bn, bstart;
 	uint32_t blen;
@@ -756,7 +756,7 @@
 
 static int do_grow(struct gfs2_inode *ip, uint64_t size)
 {
-	struct gfs2_sbd *sdp = ip->i_sbd;
+	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
 	struct gfs2_alloc *al;
 	struct buffer_head *dibh;
 	unsigned int h;
@@ -795,7 +795,7 @@
 		h = calc_tree_height(ip, size);
 		if (ip->i_di.di_height < h) {
 			down_write(&ip->i_rw_mutex);
-			error = build_height(ip->i_vnode, h);
+			error = build_height(&ip->i_inode, h);
 			up_write(&ip->i_rw_mutex);
 			if (error)
 				goto out_end_trans;
@@ -830,7 +830,7 @@
 
 static int trunc_start(struct gfs2_inode *ip, uint64_t size)
 {
-	struct gfs2_sbd *sdp = ip->i_sbd;
+	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
 	struct buffer_head *dibh;
 	int journaled = gfs2_is_jdata(ip);
 	int error;
@@ -854,7 +854,7 @@
 
 	} else {
 		if (size & (uint64_t)(sdp->sd_sb.sb_bsize - 1))
-			error = gfs2_block_truncate_page(ip->i_vnode->i_mapping);
+			error = gfs2_block_truncate_page(ip->i_inode.i_mapping);
 
 		if (!error) {
 			ip->i_di.di_size = size;
@@ -883,7 +883,7 @@
 	if (!size)
 		lblock = 0;
 	else
-		lblock = (size - 1) >> ip->i_sbd->sd_sb.sb_bsize_shift;
+		lblock = (size - 1) >> GFS2_SB(&ip->i_inode)->sd_sb.sb_bsize_shift;
 
 	find_metapath(ip, lblock, &mp);
 	gfs2_alloc_get(ip);
@@ -911,7 +911,7 @@
 
 static int trunc_end(struct gfs2_inode *ip)
 {
-	struct gfs2_sbd *sdp = ip->i_sbd;
+	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
 	struct buffer_head *dibh;
 	int error;
 
@@ -990,7 +990,7 @@
 {
 	int error;
 
-	if (gfs2_assert_warn(ip->i_sbd, S_ISREG(ip->i_di.di_mode)))
+	if (gfs2_assert_warn(GFS2_SB(&ip->i_inode), S_ISREG(ip->i_di.di_mode)))
 		return -EINVAL;
 
 	if (size > ip->i_di.di_size)
@@ -1027,7 +1027,7 @@
 void gfs2_write_calc_reserv(struct gfs2_inode *ip, unsigned int len,
 			    unsigned int *data_blocks, unsigned int *ind_blocks)
 {
-	struct gfs2_sbd *sdp = ip->i_sbd;
+	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
 	unsigned int tmp;
 
 	if (gfs2_is_dir(ip)) {
@@ -1057,7 +1057,7 @@
 int gfs2_write_alloc_required(struct gfs2_inode *ip, uint64_t offset,
 			      unsigned int len, int *alloc_required)
 {
-	struct gfs2_sbd *sdp = ip->i_sbd;
+	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
 	uint64_t lblock, lblock_stop, dblock;
 	uint32_t extlen;
 	int new = 0;
@@ -1088,7 +1088,7 @@
 	}
 
 	for (; lblock < lblock_stop; lblock += extlen) {
-		error = gfs2_extent_map(ip->i_vnode, lblock, &new, &dblock, &extlen);
+		error = gfs2_extent_map(&ip->i_inode, lblock, &new, &dblock, &extlen);
 		if (error)
 			return error;
 
diff --git a/fs/gfs2/daemon.c b/fs/gfs2/daemon.c
index 9e7b9f2..1453605 100644
--- a/fs/gfs2/daemon.c
+++ b/fs/gfs2/daemon.c
@@ -25,7 +25,6 @@
 #include "quota.h"
 #include "recovery.h"
 #include "super.h"
-#include "unlinked.h"
 #include "util.h"
 
 /* This uses schedule_timeout() instead of msleep() because it's good for
@@ -195,29 +194,3 @@
 	return 0;
 }
 
-/**
- * gfs2_inoded - Deallocate unlinked inodes
- * @sdp: Pointer to GFS2 superblock
- *
- */
-
-int gfs2_inoded(void *data)
-{
-	struct gfs2_sbd *sdp = data;
-	unsigned long t;
-	int error;
-
-	while (!kthread_should_stop()) {
-		error = gfs2_unlinked_dealloc(sdp);
-		if (error &&
-		    error != -EROFS &&
-		    !test_bit(SDF_SHUTDOWN, &sdp->sd_flags))
-			fs_err(sdp, "inoded: error = %d\n", error);
-
-		t = gfs2_tune_get(sdp, gt_inoded_secs) * HZ;
-		schedule_timeout_interruptible(t);
-	}
-
-	return 0;
-}
-
diff --git a/fs/gfs2/daemon.h b/fs/gfs2/daemon.h
index aa68e7a..aa93eb6 100644
--- a/fs/gfs2/daemon.h
+++ b/fs/gfs2/daemon.h
@@ -15,6 +15,5 @@
 int gfs2_recoverd(void *data);
 int gfs2_logd(void *data);
 int gfs2_quotad(void *data);
-int gfs2_inoded(void *data);
 
 #endif /* __DAEMON_DOT_H__ */
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c
index 6918a58..b035388 100644
--- a/fs/gfs2/dir.c
+++ b/fs/gfs2/dir.c
@@ -113,7 +113,7 @@
 	error = gfs2_meta_read(ip->i_gl, block, DIO_START | DIO_WAIT, &bh);
 	if (error)
 		return error;
-	if (gfs2_metatype_check(ip->i_sbd, bh, GFS2_METATYPE_JD)) {
+	if (gfs2_metatype_check(GFS2_SB(&ip->i_inode), bh, GFS2_METATYPE_JD)) {
 		brelse(bh);
 		return -EIO;
 	}
@@ -158,7 +158,7 @@
 static int gfs2_dir_write_data(struct gfs2_inode *ip, const char *buf,
 			       uint64_t offset, unsigned int size)
 {
-	struct gfs2_sbd *sdp = ip->i_sbd;
+	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
 	struct buffer_head *dibh;
 	uint64_t lblock, dblock;
 	uint32_t extlen = 0;
@@ -197,7 +197,7 @@
 
 		if (!extlen) {
 			new = 1;
-			error = gfs2_extent_map(ip->i_vnode, lblock, &new,
+			error = gfs2_extent_map(&ip->i_inode, lblock, &new,
 						&dblock, &extlen);
 			if (error)
 				goto fail;
@@ -277,7 +277,7 @@
 static int gfs2_dir_read_data(struct gfs2_inode *ip, char *buf,
 			      uint64_t offset, unsigned int size)
 {
-	struct gfs2_sbd *sdp = ip->i_sbd;
+	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
 	uint64_t lblock, dblock;
 	uint32_t extlen = 0;
 	unsigned int o;
@@ -314,7 +314,7 @@
 
 		if (!extlen) {
 			new = 0;
-			error = gfs2_extent_map(ip->i_vnode, lblock, &new,
+			error = gfs2_extent_map(&ip->i_inode, lblock, &new,
 						&dblock, &extlen);
 			if (error)
 				goto fail;
@@ -534,7 +534,7 @@
 	}
 
 consist_inode:
-	gfs2_consist_inode(inode->u.generic_ip);
+	gfs2_consist_inode(GFS2_I(inode));
 	return ERR_PTR(-EIO);
 }
 
@@ -556,13 +556,13 @@
 	struct gfs2_meta_header *h = (struct gfs2_meta_header *)bh->b_data;
 
 	if (be32_to_cpu(h->mh_type) == GFS2_METATYPE_LF) {
-		if (gfs2_meta_check(dip->i_sbd, bh))
+		if (gfs2_meta_check(GFS2_SB(&dip->i_inode), bh))
 			return -EIO;
 		*dent = (struct gfs2_dirent *)(bh->b_data +
 					       sizeof(struct gfs2_leaf));
 		return IS_LEAF;
 	} else {
-		if (gfs2_metatype_check(dip->i_sbd, bh, GFS2_METATYPE_DI))
+		if (gfs2_metatype_check(GFS2_SB(&dip->i_inode), bh, GFS2_METATYPE_DI))
 			return -EIO;
 		*dent = (struct gfs2_dirent *)(bh->b_data +
 					       sizeof(struct gfs2_dinode));
@@ -674,7 +674,7 @@
 					    const struct qstr *name,
 					    struct buffer_head *bh)
 {
-	struct gfs2_inode *ip = inode->u.generic_ip;
+	struct gfs2_inode *ip = GFS2_I(inode);
 	struct gfs2_dirent *ndent;
 	unsigned offset = 0, totlen;
 
@@ -707,8 +707,10 @@
 	int error;
 
 	error = gfs2_meta_read(dip->i_gl, leaf_no, DIO_START | DIO_WAIT, bhp);
-	if (!error && gfs2_metatype_check(dip->i_sbd, *bhp, GFS2_METATYPE_LF))
+	if (!error && gfs2_metatype_check(GFS2_SB(&dip->i_inode), *bhp, GFS2_METATYPE_LF)) {
+		/* printk(KERN_INFO "block num=%llu\n", leaf_no); */
 		error = -EIO;
+	}
 
 	return error;
 }
@@ -759,7 +761,7 @@
 {
 	struct buffer_head *bh;
 	struct gfs2_dirent *dent;
-	struct gfs2_inode *ip = inode->u.generic_ip;
+	struct gfs2_inode *ip = GFS2_I(inode);
 	int error;
 
 	if (ip->i_di.di_flags & GFS2_DIF_EXHASH) {
@@ -771,7 +773,7 @@
 			gfs2_consist_inode(ip);
 			return ERR_PTR(-EIO);
 		}
-
+		
 		index = name->hash >> (32 - ip->i_di.di_depth);
 		error = get_first_leaf(ip, index, &bh);
 		if (error)
@@ -786,12 +788,14 @@
 			brelse(bh);
 			if (!ln)
 				break;
+			
 			error = get_leaf(ip, ln, &bh);
 		} while(!error);
 
 		return error ? ERR_PTR(error) : NULL;
 	}
 
+	
 	error = gfs2_meta_inode_buffer(ip, &bh);
 	if (error)
 		return ERR_PTR(error);
@@ -807,7 +811,7 @@
 
 static struct gfs2_leaf *new_leaf(struct inode *inode, struct buffer_head **pbh, u16 depth)
 {
-	struct gfs2_inode *ip = inode->u.generic_ip;
+	struct gfs2_inode *ip = GFS2_I(inode);
 	u64 bn = gfs2_alloc_meta(ip);
 	struct buffer_head *bh = gfs2_meta_new(ip->i_gl, bn);
 	struct gfs2_leaf *leaf;
@@ -815,6 +819,7 @@
 	struct qstr name = { .name = "", .len = 0, .hash = 0 };
 	if (!bh)
 		return NULL;
+	
 	gfs2_trans_add_bh(ip->i_gl, bh, 1);
 	gfs2_metatype_set(bh, GFS2_METATYPE_LF, GFS2_FORMAT_LF);
 	leaf = (struct gfs2_leaf *)bh->b_data;
@@ -838,8 +843,8 @@
 
 static int dir_make_exhash(struct inode *inode)
 {
-	struct gfs2_inode *dip = inode->u.generic_ip;
-	struct gfs2_sbd *sdp = dip->i_sbd;
+	struct gfs2_inode *dip = GFS2_I(inode);
+	struct gfs2_sbd *sdp = GFS2_SB(inode);
 	struct gfs2_dirent *dent;
 	struct qstr args;
 	struct buffer_head *bh, *dibh;
@@ -874,7 +879,7 @@
 	args.len = bh->b_size - sizeof(struct gfs2_dinode) +
 		   sizeof(struct gfs2_leaf);
 	args.name = bh->b_data;
-	dent = gfs2_dirent_scan(dip->i_vnode, bh->b_data, bh->b_size,
+	dent = gfs2_dirent_scan(&dip->i_inode, bh->b_data, bh->b_size,
 				gfs2_dirent_last, &args, NULL);
 	if (!dent) {
 		brelse(bh);
@@ -933,7 +938,7 @@
 
 static int dir_split_leaf(struct inode *inode, const struct qstr *name)
 {
-	struct gfs2_inode *dip = inode->u.generic_ip;
+	struct gfs2_inode *dip = GFS2_I(inode);
 	struct buffer_head *nbh, *obh, *dibh;
 	struct gfs2_leaf *nleaf, *oleaf;
 	struct gfs2_dirent *dent, *prev = NULL, *next = NULL, *new;
@@ -1044,7 +1049,7 @@
 	oleaf->lf_depth = nleaf->lf_depth;
 
 	error = gfs2_meta_inode_buffer(dip, &dibh);
-	if (!gfs2_assert_withdraw(dip->i_sbd, !error)) {
+	if (!gfs2_assert_withdraw(GFS2_SB(&dip->i_inode), !error)) {
 		dip->i_di.di_blocks++;
 		gfs2_dinode_out(&dip->i_di, dibh->b_data);
 		brelse(dibh);
@@ -1073,7 +1078,7 @@
 
 static int dir_double_exhash(struct gfs2_inode *dip)
 {
-	struct gfs2_sbd *sdp = dip->i_sbd;
+	struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
 	struct buffer_head *dibh;
 	uint32_t hsize;
 	uint64_t *buf;
@@ -1268,7 +1273,7 @@
 			      gfs2_filldir_t filldir, int *copied,
 			      unsigned *depth, u64 leaf_no)
 {
-	struct gfs2_inode *ip = inode->u.generic_ip;
+	struct gfs2_inode *ip = GFS2_I(inode);
 	struct buffer_head *bh;
 	struct gfs2_leaf *lf;
 	unsigned entries = 0;
@@ -1348,8 +1353,8 @@
 static int dir_e_read(struct inode *inode, uint64_t *offset, void *opaque,
 		      gfs2_filldir_t filldir)
 {
-	struct gfs2_inode *dip = inode->u.generic_ip;
-	struct gfs2_sbd *sdp = dip->i_sbd;
+	struct gfs2_inode *dip = GFS2_I(inode);
+	struct gfs2_sbd *sdp = GFS2_SB(inode);
 	uint32_t hsize, len = 0;
 	uint32_t ht_offset, lp_offset, ht_offset_cur = -1;
 	uint32_t hash, index;
@@ -1407,7 +1412,7 @@
 int gfs2_dir_read(struct inode *inode, uint64_t *offset, void *opaque,
 		  gfs2_filldir_t filldir)
 {
-	struct gfs2_inode *dip = inode->u.generic_ip;
+	struct gfs2_inode *dip = GFS2_I(inode);
 	struct dirent_gather g;
 	const struct gfs2_dirent **darr, *dent;
 	struct buffer_head *dibh;
@@ -1490,7 +1495,7 @@
 static int dir_new_leaf(struct inode *inode, const struct qstr *name)
 {
 	struct buffer_head *bh, *obh;
-	struct gfs2_inode *ip = inode->u.generic_ip;
+	struct gfs2_inode *ip = GFS2_I(inode);
 	struct gfs2_leaf *leaf, *oleaf;
 	int error;
 	u32 index;
@@ -1545,7 +1550,7 @@
 int gfs2_dir_add(struct inode *inode, const struct qstr *name,
 		 const struct gfs2_inum *inum, unsigned type)
 {
-	struct gfs2_inode *ip = inode->u.generic_ip;
+	struct gfs2_inode *ip = GFS2_I(inode);
 	struct buffer_head *bh;
 	struct gfs2_dirent *dent;
 	struct gfs2_leaf *leaf;
@@ -1623,7 +1628,7 @@
 
 	/* Returns _either_ the entry (if its first in block) or the
 	   previous entry otherwise */
-	dent = gfs2_dirent_search(dip->i_vnode, name, gfs2_dirent_prev, &bh);
+	dent = gfs2_dirent_search(&dip->i_inode, name, gfs2_dirent_prev, &bh);
 	if (!dent) {
 		gfs2_consist_inode(dip);
 		return -EIO;
@@ -1659,6 +1664,7 @@
 	dip->i_di.di_mtime = dip->i_di.di_ctime = get_seconds();
 	gfs2_dinode_out(&dip->i_di, bh->b_data);
 	brelse(bh);
+	mark_inode_dirty(&dip->i_inode);
 
 	return error;
 }
@@ -1683,7 +1689,7 @@
 	struct gfs2_dirent *dent;
 	int error;
 
-	dent = gfs2_dirent_search(dip->i_vnode, filename, gfs2_dirent_find, &bh);
+	dent = gfs2_dirent_search(&dip->i_inode, filename, gfs2_dirent_find, &bh);
 	if (!dent) {
 		gfs2_consist_inode(dip);
 		return -EIO;
@@ -1720,7 +1726,7 @@
 
 static int foreach_leaf(struct gfs2_inode *dip, leaf_call_t lc, void *data)
 {
-	struct gfs2_sbd *sdp = dip->i_sbd;
+	struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
 	struct buffer_head *bh;
 	struct gfs2_leaf *leaf;
 	uint32_t hsize, len;
@@ -1800,7 +1806,7 @@
 static int leaf_dealloc(struct gfs2_inode *dip, uint32_t index, uint32_t len,
 			uint64_t leaf_no, void *data)
 {
-	struct gfs2_sbd *sdp = dip->i_sbd;
+	struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
 	struct gfs2_leaf *tmp_leaf;
 	struct gfs2_rgrp_list rlist;
 	struct buffer_head *bh, *dibh;
@@ -1920,7 +1926,7 @@
 
 int gfs2_dir_exhash_dealloc(struct gfs2_inode *dip)
 {
-	struct gfs2_sbd *sdp = dip->i_sbd;
+	struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
 	struct buffer_head *bh;
 	int error;
 
diff --git a/fs/gfs2/eaops.c b/fs/gfs2/eaops.c
index 1c5ac31..b7e6a37 100644
--- a/fs/gfs2/eaops.c
+++ b/fs/gfs2/eaops.c
@@ -58,7 +58,7 @@
 
 static int user_eo_get(struct gfs2_inode *ip, struct gfs2_ea_request *er)
 {
-	struct inode *inode = ip->i_vnode;
+	struct inode *inode = &ip->i_inode;
 	int error = permission(inode, MAY_READ, NULL);
 	if (error)
 		return error;
@@ -68,7 +68,7 @@
 
 static int user_eo_set(struct gfs2_inode *ip, struct gfs2_ea_request *er)
 {
-	struct inode *inode = ip->i_vnode;
+	struct inode *inode = &ip->i_inode;
 
 	if (S_ISREG(inode->i_mode) ||
 	    (S_ISDIR(inode->i_mode) && !(inode->i_mode & S_ISVTX))) {
@@ -83,7 +83,7 @@
 
 static int user_eo_remove(struct gfs2_inode *ip, struct gfs2_ea_request *er)
 {
-	struct inode *inode = ip->i_vnode;
+	struct inode *inode = &ip->i_inode;
 
 	if (S_ISREG(inode->i_mode) ||
 	    (S_ISDIR(inode->i_mode) && !(inode->i_mode & S_ISVTX))) {
@@ -103,7 +103,7 @@
 	    !capable(CAP_SYS_ADMIN))
 		return -EPERM;
 
-	if (ip->i_sbd->sd_args.ar_posix_acl == 0 &&
+	if (GFS2_SB(&ip->i_inode)->sd_args.ar_posix_acl == 0 &&
 	    (GFS2_ACL_IS_ACCESS(er->er_name, er->er_name_len) ||
 	     GFS2_ACL_IS_DEFAULT(er->er_name, er->er_name_len)))
 		return -EOPNOTSUPP;
@@ -172,7 +172,7 @@
 
 static int security_eo_get(struct gfs2_inode *ip, struct gfs2_ea_request *er)
 {
-	struct inode *inode = ip->i_vnode;
+	struct inode *inode = &ip->i_inode;
 	int error = permission(inode, MAY_READ, NULL);
 	if (error)
 		return error;
@@ -182,7 +182,7 @@
 
 static int security_eo_set(struct gfs2_inode *ip, struct gfs2_ea_request *er)
 {
-	struct inode *inode = ip->i_vnode;
+	struct inode *inode = &ip->i_inode;
 	int error = permission(inode, MAY_WRITE, NULL);
 	if (error)
 		return error;
@@ -192,7 +192,7 @@
 
 static int security_eo_remove(struct gfs2_inode *ip, struct gfs2_ea_request *er)
 {
-	struct inode *inode = ip->i_vnode;
+	struct inode *inode = &ip->i_inode;
 	int error = permission(inode, MAY_WRITE, NULL);
 	if (error)
 		return error;
diff --git a/fs/gfs2/eattr.c b/fs/gfs2/eattr.c
index 2e114c0..967369322 100644
--- a/fs/gfs2/eattr.c
+++ b/fs/gfs2/eattr.c
@@ -80,7 +80,7 @@
 	struct gfs2_ea_header *ea, *prev = NULL;
 	int error = 0;
 
-	if (gfs2_metatype_check(ip->i_sbd, bh, GFS2_METATYPE_EA))
+	if (gfs2_metatype_check(GFS2_SB(&ip->i_inode), bh, GFS2_METATYPE_EA))
 		return -EIO;
 
 	for (ea = GFS2_EA_BH2FIRST(bh);; prev = ea, ea = GFS2_EA2NEXT(ea)) {
@@ -128,13 +128,13 @@
 		goto out;
 	}
 
-	if (gfs2_metatype_check(ip->i_sbd, bh, GFS2_METATYPE_IN)) {
+	if (gfs2_metatype_check(GFS2_SB(&ip->i_inode), bh, GFS2_METATYPE_IN)) {
 		error = -EIO;
 		goto out;
 	}
 
 	eablk = (uint64_t *)(bh->b_data + sizeof(struct gfs2_meta_header));
-	end = eablk + ip->i_sbd->sd_inptrs;
+	end = eablk + GFS2_SB(&ip->i_inode)->sd_inptrs;
 
 	for (; eablk < end; eablk++) {
 		uint64_t bn;
@@ -232,7 +232,7 @@
 				struct gfs2_ea_header *prev, void *private)
 {
 	int *leave = private;
-	struct gfs2_sbd *sdp = ip->i_sbd;
+	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
 	struct gfs2_rgrpd *rgd;
 	struct gfs2_holder rg_gh;
 	struct buffer_head *dibh;
@@ -338,7 +338,7 @@
 	if (error)
 		goto out_alloc;
 
-	error = gfs2_rindex_hold(ip->i_sbd, &al->al_ri_gh);
+	error = gfs2_rindex_hold(GFS2_SB(&ip->i_inode), &al->al_ri_gh);
 	if (error)
 		goto out_quota;
 
@@ -459,7 +459,7 @@
 static int ea_get_unstuffed(struct gfs2_inode *ip, struct gfs2_ea_header *ea,
 			    char *data)
 {
-	struct gfs2_sbd *sdp = ip->i_sbd;
+	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
 	struct buffer_head **bh;
 	unsigned int amount = GFS2_EA_DATA_LEN(ea);
 	unsigned int nptrs = DIV_ROUND_UP(amount, sdp->sd_jbsize);
@@ -604,7 +604,7 @@
 
 static int ea_alloc_blk(struct gfs2_inode *ip, struct buffer_head **bhp)
 {
-	struct gfs2_sbd *sdp = ip->i_sbd;
+	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
 	struct gfs2_ea_header *ea;
 	uint64_t block;
 
@@ -641,7 +641,7 @@
 static int ea_write(struct gfs2_inode *ip, struct gfs2_ea_header *ea,
 		    struct gfs2_ea_request *er)
 {
-	struct gfs2_sbd *sdp = ip->i_sbd;
+	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
 
 	ea->ea_data_len = cpu_to_be32(er->er_data_len);
 	ea->ea_name_len = er->er_name_len;
@@ -723,7 +723,7 @@
 	if (error)
 		goto out_gunlock_q;
 
-	error = gfs2_trans_begin(ip->i_sbd,
+	error = gfs2_trans_begin(GFS2_SB(&ip->i_inode),
 				 blks + al->al_rgd->rd_ri.ri_length +
 				 RES_DINODE + RES_STATFS + RES_QUOTA, 0);
 	if (error)
@@ -736,7 +736,7 @@
 	error = gfs2_meta_inode_buffer(ip, &dibh);
 	if (!error) {
 		if (er->er_flags & GFS2_ERF_MODE) {
-			gfs2_assert_withdraw(ip->i_sbd,
+			gfs2_assert_withdraw(GFS2_SB(&ip->i_inode),
 					    (ip->i_di.di_mode & S_IFMT) ==
 					    (er->er_mode & S_IFMT));
 			ip->i_di.di_mode = er->er_mode;
@@ -748,7 +748,7 @@
 	}
 
  out_end_trans:
-	gfs2_trans_end(ip->i_sbd);
+	gfs2_trans_end(GFS2_SB(&ip->i_inode));
 
  out_ipres:
 	gfs2_inplace_release(ip);
@@ -790,7 +790,7 @@
 
 static int ea_init(struct gfs2_inode *ip, struct gfs2_ea_request *er)
 {
-	unsigned int jbsize = ip->i_sbd->sd_jbsize;
+	unsigned int jbsize = GFS2_SB(&ip->i_inode)->sd_jbsize;
 	unsigned int blks = 1;
 
 	if (GFS2_EAREQ_SIZE_STUFFED(er) > jbsize)
@@ -830,7 +830,7 @@
 		return;
 	} else if (GFS2_EA2NEXT(prev) != ea) {
 		prev = GFS2_EA2NEXT(prev);
-		gfs2_assert_withdraw(ip->i_sbd, GFS2_EA2NEXT(prev) == ea);
+		gfs2_assert_withdraw(GFS2_SB(&ip->i_inode), GFS2_EA2NEXT(prev) == ea);
 	}
 
 	len = GFS2_EA_REC_LEN(prev) + GFS2_EA_REC_LEN(ea);
@@ -857,7 +857,7 @@
 	struct buffer_head *dibh;
 	int error;
 
-	error = gfs2_trans_begin(ip->i_sbd, RES_DINODE + 2 * RES_EATTR, 0);
+	error = gfs2_trans_begin(GFS2_SB(&ip->i_inode), RES_DINODE + 2 * RES_EATTR, 0);
 	if (error)
 		return error;
 
@@ -876,7 +876,7 @@
 		goto out;
 
 	if (er->er_flags & GFS2_ERF_MODE) {
-		gfs2_assert_withdraw(ip->i_sbd,
+		gfs2_assert_withdraw(GFS2_SB(&ip->i_inode),
 			(ip->i_di.di_mode & S_IFMT) == (er->er_mode & S_IFMT));
 		ip->i_di.di_mode = er->er_mode;
 	}
@@ -885,7 +885,7 @@
 	gfs2_dinode_out(&ip->i_di, dibh->b_data);
 	brelse(dibh);
  out:
-	gfs2_trans_end(ip->i_sbd);
+	gfs2_trans_end(GFS2_SB(&ip->i_inode));
 
 	return error;
 }
@@ -921,7 +921,7 @@
 	int stuffed;
 	int error;
 
-	stuffed = ea_calc_size(ip->i_sbd, es->es_er, &size);
+	stuffed = ea_calc_size(GFS2_SB(&ip->i_inode), es->es_er, &size);
 
 	if (ea->ea_type == GFS2_EATYPE_UNUSED) {
 		if (GFS2_EA_REC_LEN(ea) < size)
@@ -947,7 +947,7 @@
 		es->es_bh = bh;
 		es->es_ea = ea;
 		blks = 2 + DIV_ROUND_UP(es->es_er->er_data_len,
-					ip->i_sbd->sd_jbsize);
+					GFS2_SB(&ip->i_inode)->sd_jbsize);
 
 		error = ea_alloc_skeleton(ip, es->es_er, blks,
 					  ea_set_simple_alloc, es);
@@ -961,7 +961,7 @@
 static int ea_set_block(struct gfs2_inode *ip, struct gfs2_ea_request *er,
 			void *private)
 {
-	struct gfs2_sbd *sdp = ip->i_sbd;
+	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
 	struct buffer_head *indbh, *newbh;
 	uint64_t *eablk;
 	int error;
@@ -1050,8 +1050,8 @@
 
 	if (!(ip->i_di.di_flags & GFS2_DIF_EA_INDIRECT))
 		blks++;
-	if (GFS2_EAREQ_SIZE_STUFFED(er) > ip->i_sbd->sd_jbsize)
-		blks += DIV_ROUND_UP(er->er_data_len, ip->i_sbd->sd_jbsize);
+	if (GFS2_EAREQ_SIZE_STUFFED(er) > GFS2_SB(&ip->i_inode)->sd_jbsize)
+		blks += DIV_ROUND_UP(er->er_data_len, GFS2_SB(&ip->i_inode)->sd_jbsize);
 
 	return ea_alloc_skeleton(ip, er, blks, ea_set_block, el);
 }
@@ -1061,7 +1061,7 @@
 {
 	if (el->el_prev && GFS2_EA2NEXT(el->el_prev) != el->el_ea) {
 		el->el_prev = GFS2_EA2NEXT(el->el_prev);
-		gfs2_assert_withdraw(ip->i_sbd,
+		gfs2_assert_withdraw(GFS2_SB(&ip->i_inode),
 				     GFS2_EA2NEXT(el->el_prev) == el->el_ea);
 	}
 
@@ -1119,7 +1119,7 @@
 		er->er_data = NULL;
 		er->er_data_len = 0;
 	}
-	error = ea_check_size(ip->i_sbd, er);
+	error = ea_check_size(GFS2_SB(&ip->i_inode), er);
 	if (error)
 		return error;
 
@@ -1127,7 +1127,7 @@
 	if (error)
 		return error;
 
-	if (IS_IMMUTABLE(ip->i_vnode))
+	if (IS_IMMUTABLE(&ip->i_inode))
 		error = -EPERM;
 	else
 		error = gfs2_ea_ops[er->er_type]->eo_set(ip, er);
@@ -1144,7 +1144,7 @@
 	struct buffer_head *dibh;
 	int error;
 
-	error = gfs2_trans_begin(ip->i_sbd, RES_DINODE + RES_EATTR, 0);
+	error = gfs2_trans_begin(GFS2_SB(&ip->i_inode), RES_DINODE + RES_EATTR, 0);
 	if (error)
 		return error;
 
@@ -1169,7 +1169,7 @@
 		brelse(dibh);
 	}	
 
-	gfs2_trans_end(ip->i_sbd);
+	gfs2_trans_end(GFS2_SB(&ip->i_inode));
 
 	return error;
 }
@@ -1219,7 +1219,7 @@
 	if (error)
 		return error;
 
-	if (IS_IMMUTABLE(ip->i_vnode) || IS_APPEND(ip->i_vnode))
+	if (IS_IMMUTABLE(&ip->i_inode) || IS_APPEND(&ip->i_inode))
 		error = -EPERM;
 	else
 		error = gfs2_ea_ops[er->er_type]->eo_remove(ip, er);
@@ -1232,7 +1232,7 @@
 static int ea_acl_chmod_unstuffed(struct gfs2_inode *ip,
 				  struct gfs2_ea_header *ea, char *data)
 {
-	struct gfs2_sbd *sdp = ip->i_sbd;
+	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
 	struct buffer_head **bh;
 	unsigned int amount = GFS2_EA_DATA_LEN(ea);
 	unsigned int nptrs = DIV_ROUND_UP(amount, sdp->sd_jbsize);
@@ -1304,7 +1304,7 @@
 	int error;
 
 	if (GFS2_EA_IS_STUFFED(el->el_ea)) {
-		error = gfs2_trans_begin(ip->i_sbd, RES_DINODE + RES_EATTR, 0);
+		error = gfs2_trans_begin(GFS2_SB(&ip->i_inode), RES_DINODE + RES_EATTR, 0);
 		if (error)
 			return error;
 
@@ -1320,22 +1320,22 @@
 
 	error = gfs2_meta_inode_buffer(ip, &dibh);
 	if (!error) {
-		error = inode_setattr(ip->i_vnode, attr);
-		gfs2_assert_warn(ip->i_sbd, !error);
+		error = inode_setattr(&ip->i_inode, attr);
+		gfs2_assert_warn(GFS2_SB(&ip->i_inode), !error);
 		gfs2_inode_attr_out(ip);
 		gfs2_trans_add_bh(ip->i_gl, dibh, 1);
 		gfs2_dinode_out(&ip->i_di, dibh->b_data);
 		brelse(dibh);
 	}
 
-	gfs2_trans_end(ip->i_sbd);
+	gfs2_trans_end(GFS2_SB(&ip->i_inode));
 
 	return error;
 }
 
 static int ea_dealloc_indirect(struct gfs2_inode *ip)
 {
-	struct gfs2_sbd *sdp = ip->i_sbd;
+	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
 	struct gfs2_rgrp_list rlist;
 	struct buffer_head *indbh, *dibh;
 	uint64_t *eablk, *end;
@@ -1456,7 +1456,7 @@
 
 static int ea_dealloc_block(struct gfs2_inode *ip)
 {
-	struct gfs2_sbd *sdp = ip->i_sbd;
+	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
 	struct gfs2_alloc *al = &ip->i_alloc;
 	struct gfs2_rgrpd *rgd;
 	struct buffer_head *dibh;
@@ -1518,7 +1518,7 @@
 	if (error)
 		goto out_alloc;
 
-	error = gfs2_rindex_hold(ip->i_sbd, &al->al_ri_gh);
+	error = gfs2_rindex_hold(GFS2_SB(&ip->i_inode), &al->al_ri_gh);
 	if (error)
 		goto out_quota;
 
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 0603a6d..35bac908 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -654,7 +654,7 @@
  * Gives caller exclusive access to manipulate a glock structure.
  */
 
-void gfs2_glmutex_lock(struct gfs2_glock *gl)
+static void gfs2_glmutex_lock(struct gfs2_glock *gl)
 {
 	struct gfs2_holder gh;
 
@@ -704,7 +704,7 @@
  *
  */
 
-void gfs2_glmutex_unlock(struct gfs2_glock *gl)
+static void gfs2_glmutex_unlock(struct gfs2_glock *gl)
 {
 	spin_lock(&gl->gl_spin);
 	clear_bit(GLF_LOCK, &gl->gl_flags);
@@ -726,7 +726,7 @@
 {
 	struct gfs2_holder *gh, *new_gh = NULL;
 
- restart:
+restart:
 	spin_lock(&gl->gl_spin);
 
 	list_for_each_entry(gh, &gl->gl_waiters2, gh_list) {
@@ -752,13 +752,27 @@
 		goto restart;
 	}
 
- out:
+out:
 	spin_unlock(&gl->gl_spin);
 
 	if (new_gh)
 		gfs2_holder_put(new_gh);
 }
 
+void gfs2_glock_inode_squish(struct inode *inode)
+{
+	struct gfs2_holder gh;
+	struct gfs2_glock *gl = GFS2_I(inode)->i_gl;
+	gfs2_holder_init(gl, LM_ST_UNLOCKED, 0, &gh);
+	set_bit(HIF_DEMOTE, &gh.gh_iflags);
+	spin_lock(&gl->gl_spin);
+	gfs2_assert(inode->i_sb->s_fs_info, list_empty(&gl->gl_holders));
+	list_add_tail(&gh.gh_list, &gl->gl_waiters2);
+	run_queue(gl);
+	spin_unlock(&gl->gl_spin);
+	gfs2_holder_uninit(&gh);
+}
+
 /**
  * state_change - record that the glock is now in a different state
  * @gl: the glock
@@ -1383,8 +1397,7 @@
 	struct greedy *gr;
 	struct gfs2_holder *gh;
 
-	if (!time ||
-	    gl->gl_sbd->sd_args.ar_localcaching ||
+	if (!time || gl->gl_sbd->sd_args.ar_localcaching ||
 	    test_and_set_bit(GLF_GREEDY, &gl->gl_flags))
 		return 1;
 
@@ -1785,43 +1798,6 @@
 }
 
 /**
- * gfs2_try_toss_inode - try to remove a particular inode struct from cache
- * sdp: the filesystem
- * inum: the inode number
- *
- */
-
-void gfs2_try_toss_inode(struct gfs2_sbd *sdp, struct gfs2_inum *inum)
-{
-	struct gfs2_glock *gl;
-	struct gfs2_inode *ip;
-	int error;
-
-	error = gfs2_glock_get(sdp, inum->no_addr, &gfs2_inode_glops,
-			       NO_CREATE, &gl);
-	if (error || !gl)
-		return;
-
-	if (!gfs2_glmutex_trylock(gl))
-		goto out;
-
-	ip = gl->gl_object;
-	if (!ip)
-		goto out_unlock;
-
-	if (atomic_read(&ip->i_count))
-		goto out_unlock;
-
-	gfs2_inode_destroy(ip, 1);
-
- out_unlock:
-	gfs2_glmutex_unlock(gl);
-
- out:
-	gfs2_glock_put(gl);
-}
-
-/**
  * gfs2_iopen_go_callback - Try to kick the inode/vnode associated with an
  *                          iopen glock from memory
  * @io_gl: the iopen glock
@@ -1831,34 +1807,10 @@
 
 void gfs2_iopen_go_callback(struct gfs2_glock *io_gl, unsigned int state)
 {
-	struct gfs2_glock *i_gl;
 
 	if (state != LM_ST_UNLOCKED)
 		return;
-
-	spin_lock(&io_gl->gl_spin);
-	i_gl = io_gl->gl_object;
-	if (i_gl) {
-		gfs2_glock_hold(i_gl);
-		spin_unlock(&io_gl->gl_spin);
-	} else {
-		spin_unlock(&io_gl->gl_spin);
-		return;
-	}
-
-	if (gfs2_glmutex_trylock(i_gl)) {
-		struct gfs2_inode *ip = i_gl->gl_object;
-		if (ip) {
-			gfs2_try_toss_vnode(ip);
-			gfs2_glmutex_unlock(i_gl);
-			gfs2_glock_schedule_for_reclaim(i_gl);
-			goto out;
-		}
-		gfs2_glmutex_unlock(i_gl);
-	}
-
- out:
-	gfs2_glock_put(i_gl);
+	/* FIXME: remove this? */
 }
 
 /**
@@ -1935,11 +1887,6 @@
 	atomic_inc(&sdp->sd_reclaimed);
 
 	if (gfs2_glmutex_trylock(gl)) {
-		if (gl->gl_ops == &gfs2_inode_glops) {
-			struct gfs2_inode *ip = gl->gl_object;
-			if (ip && !atomic_read(&ip->i_count))
-				gfs2_inode_destroy(ip, 1);
-		}
 		if (queue_empty(gl, &gl->gl_holders) &&
 		    gl->gl_state != LM_ST_UNLOCKED &&
 		    demote_ok(gl))
@@ -2018,7 +1965,7 @@
 	if (gfs2_glmutex_trylock(gl)) {
 		if (gl->gl_ops == &gfs2_inode_glops) {
 			struct gfs2_inode *ip = gl->gl_object;
-			if (ip && !atomic_read(&ip->i_count))
+			if (ip)
 				goto out_schedule;
 		}
 		if (queue_empty(gl, &gl->gl_holders) &&
@@ -2078,11 +2025,6 @@
 	}
 
 	if (gfs2_glmutex_trylock(gl)) {
-		if (gl->gl_ops == &gfs2_inode_glops) {
-			struct gfs2_inode *ip = gl->gl_object;
-			if (ip && !atomic_read(&ip->i_count))
-				gfs2_inode_destroy(ip, 1);
-		}
 		if (queue_empty(gl, &gl->gl_holders) &&
 		    gl->gl_state != LM_ST_UNLOCKED)
 			handle_callback(gl, LM_ST_UNLOCKED);
@@ -2199,13 +2141,11 @@
 		    (unsigned long long)ip->i_num.no_formal_ino,
 		    (unsigned long long)ip->i_num.no_addr);
 	printk(KERN_INFO "    type = %u\n", IF2DT(ip->i_di.di_mode));
-	printk(KERN_INFO "    i_count = %d\n", atomic_read(&ip->i_count));
 	printk(KERN_INFO "    i_flags =");
 	for (x = 0; x < 32; x++)
 		if (test_bit(x, &ip->i_flags))
 			printk(" %u", x);
 	printk(" \n");
-	printk(KERN_INFO "    vnode = %s\n", (ip->i_vnode) ? "yes" : "no");
 
 	error = 0;
 
diff --git a/fs/gfs2/glock.h b/fs/gfs2/glock.h
index 2e0a2ba..fdf58db 100644
--- a/fs/gfs2/glock.h
+++ b/fs/gfs2/glock.h
@@ -88,9 +88,6 @@
 void gfs2_glock_xmote_th(struct gfs2_glock *gl, unsigned int state, int flags);
 void gfs2_glock_drop_th(struct gfs2_glock *gl);
 
-void gfs2_glmutex_lock(struct gfs2_glock *gl);
-void gfs2_glmutex_unlock(struct gfs2_glock *gl);
-
 int gfs2_glock_nq(struct gfs2_holder *gh);
 int gfs2_glock_poll(struct gfs2_holder *gh);
 int gfs2_glock_wait(struct gfs2_holder *gh);
@@ -110,6 +107,7 @@
 void gfs2_glock_prefetch_num(struct gfs2_sbd *sdp, uint64_t number,
 			     struct gfs2_glock_operations *glops,
 			     unsigned int state, int flags);
+void gfs2_glock_inode_squish(struct inode *inode);
 
 /**
  * gfs2_glock_nq_init - intialize a holder and enqueue it on a glock
@@ -143,7 +141,6 @@
 
 void gfs2_glock_cb(lm_fsdata_t *fsdata, unsigned int type, void *data);
 
-void gfs2_try_toss_inode(struct gfs2_sbd *sdp, struct gfs2_inum *inum);
 void gfs2_iopen_go_callback(struct gfs2_glock *gl, unsigned int state);
 
 void gfs2_glock_schedule_for_reclaim(struct gfs2_glock *gl);
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c
index e262f22..013bf5f 100644
--- a/fs/gfs2/glops.c
+++ b/fs/gfs2/glops.c
@@ -129,6 +129,7 @@
 
 static void inode_go_drop_th(struct gfs2_glock *gl)
 {
+	printk(KERN_INFO "drop th %p\n", gl->gl_object);
 	gfs2_pte_inval(gl);
 	gfs2_glock_drop_th(gl);
 }
@@ -147,6 +148,7 @@
 
 	if (test_bit(GLF_DIRTY, &gl->gl_flags)) {
 		if (meta && data) {
+			printk(KERN_INFO "sync all\n");
 			gfs2_page_sync(gl, flags | DIO_START);
 			gfs2_log_flush(gl->gl_sbd, gl);
 			gfs2_meta_sync(gl, flags | DIO_START | DIO_WAIT);
@@ -224,6 +226,7 @@
 		return 0;
 
 	if (ip->i_vn != gl->gl_vn) {
+		printk(KERN_INFO "refresh inode %p\n", &ip->i_inode);
 		error = gfs2_inode_refresh(ip);
 		if (error)
 			return error;
@@ -288,7 +291,7 @@
 
 	spin_unlock(&ip->i_spin);
 
-	gfs2_inode_put(ip);
+	iput(&ip->i_inode);
 }
 
 /**
@@ -361,14 +364,14 @@
 static void trans_go_xmote_bh(struct gfs2_glock *gl)
 {
 	struct gfs2_sbd *sdp = gl->gl_sbd;
-	struct gfs2_inode *ip = sdp->sd_jdesc->jd_inode->u.generic_ip;
+	struct gfs2_inode *ip = GFS2_I(sdp->sd_jdesc->jd_inode);
 	struct gfs2_glock *j_gl = ip->i_gl;
 	struct gfs2_log_header head;
 	int error;
 
 	if (gl->gl_state != LM_ST_UNLOCKED &&
 	    test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) {
-		gfs2_meta_cache_flush(sdp->sd_jdesc->jd_inode->u.generic_ip);
+		gfs2_meta_cache_flush(GFS2_I(sdp->sd_jdesc->jd_inode));
 		j_gl->gl_ops->go_inval(j_gl, DIO_METADATA | DIO_DATA);
 
 		error = gfs2_find_jhead(sdp->sd_jdesc, &head);
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index 8caefec..9a67a59 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
@@ -33,7 +33,6 @@
 struct gfs2_file;
 struct gfs2_revoke;
 struct gfs2_revoke_replay;
-struct gfs2_unlinked;
 struct gfs2_quota_data;
 struct gfs2_log_buf;
 struct gfs2_trans;
@@ -245,16 +244,12 @@
 	struct inode i_inode;
 	struct gfs2_inum i_num;
 
-	atomic_t i_count;
 	unsigned long i_flags;		/* GIF_... */
 
 	uint64_t i_vn;
-	struct gfs2_dinode i_di;
+	struct gfs2_dinode i_di; /* To be replaced by ref to block */
 
-	struct gfs2_glock *i_gl;
-	struct gfs2_sbd *i_sbd;
-	struct inode *i_vnode;
-
+	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_alloc i_alloc;
@@ -262,18 +257,27 @@
 
 	spinlock_t i_spin;
 	struct rw_semaphore i_rw_mutex;
-
 	unsigned int i_greedy;
 	unsigned long i_last_pfault;
 
 	struct buffer_head *i_cache[GFS2_MAX_META_HEIGHT];
 };
 
+/*
+ * Since i_inode is the first element of struct gfs2_inode,
+ * this is effectively a cast.
+ */
 static inline struct gfs2_inode *GFS2_I(struct inode *inode)
 {
 	return container_of(inode, struct gfs2_inode, i_inode);
 }
 
+/* To be removed? */
+static inline struct gfs2_sbd *GFS2_SB(struct inode *inode)
+{
+	return inode->i_sb->s_fs_info;
+}
+
 enum {
 	GFF_DID_DIRECT_ALLOC	= 0,
 };
@@ -296,18 +300,6 @@
 };
 
 enum {
-	ULF_LOCKED		= 0,
-};
-
-struct gfs2_unlinked {
-	struct list_head ul_list;
-	unsigned int ul_count;
-	struct gfs2_unlinked_tag ul_ut;
-	unsigned long ul_flags;		/* ULF_... */
-	unsigned int ul_slot;
-};
-
-enum {
 	QDF_USER		= 0,
 	QDF_CHANGE		= 1,
 	QDF_LOCKED		= 2,
@@ -436,7 +428,6 @@
 	unsigned int gt_recoverd_secs;
 	unsigned int gt_logd_secs;
 	unsigned int gt_quotad_secs;
-	unsigned int gt_inoded_secs;
 
 	unsigned int gt_quota_simul_sync; /* Max quotavals to sync at once */
 	unsigned int gt_quota_warn_period; /* Secs between quota warn msgs */
@@ -495,7 +486,6 @@
 	uint32_t sd_hash_bsize;	/* sizeof(exhash block) */
 	uint32_t sd_hash_bsize_shift;
 	uint32_t sd_hash_ptrs;	/* Number of pointers in a hash block */
-	uint32_t sd_ut_per_block;
 	uint32_t sd_qc_per_block;
 	uint32_t sd_max_dirres;	/* Max blocks needed to add a directory entry */
 	uint32_t sd_max_height;	/* Max height of a file's metadata tree */
@@ -527,7 +517,6 @@
 	struct inode *sd_statfs_inode;
 	struct inode *sd_ir_inode;
 	struct inode *sd_sc_inode;
-	struct inode *sd_ut_inode;
 	struct inode *sd_qc_inode;
 	struct inode *sd_rindex;
 	struct inode *sd_quota_inode;
@@ -569,7 +558,6 @@
 
 	struct gfs2_holder sd_ir_gh;
 	struct gfs2_holder sd_sc_gh;
-	struct gfs2_holder sd_ut_gh;
 	struct gfs2_holder sd_qc_gh;
 
 	/* Daemon stuff */
@@ -578,21 +566,9 @@
 	struct task_struct *sd_recoverd_process;
 	struct task_struct *sd_logd_process;
 	struct task_struct *sd_quotad_process;
-	struct task_struct *sd_inoded_process;
 	struct task_struct *sd_glockd_process[GFS2_GLOCKD_MAX];
 	unsigned int sd_glockd_num;
 
-	/* Unlinked inode stuff */
-
-	struct list_head sd_unlinked_list;
-	atomic_t sd_unlinked_count;
-	spinlock_t sd_unlinked_spin;
-	struct mutex sd_unlinked_mutex;
-
-	unsigned int sd_unlinked_slots;
-	unsigned int sd_unlinked_chunks;
-	unsigned char **sd_unlinked_bitmap;
-
 	/* Quota stuff */
 
 	struct list_head sd_quota_list;
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index c2c7d2b..4e9c421 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -35,7 +35,6 @@
 #include "quota.h"
 #include "rgrp.h"
 #include "trans.h"
-#include "unlinked.h"
 #include "util.h"
 
 /**
@@ -72,7 +71,7 @@
 	inode->i_ctime.tv_nsec = 0;
 	inode->i_blksize = PAGE_SIZE;
 	inode->i_blocks = ip->i_di.di_blocks <<
-		(ip->i_sbd->sd_sb.sb_bsize_shift - GFS2_BASIC_BLOCK_SHIFT);
+		(GFS2_SB(inode)->sd_sb.sb_bsize_shift - GFS2_BASIC_BLOCK_SHIFT);
 
 	if (ip->i_di.di_flags & GFS2_DIF_IMMUTABLE)
 		inode->i_flags |= S_IMMUTABLE;
@@ -93,13 +92,8 @@
 
 void gfs2_inode_attr_in(struct gfs2_inode *ip)
 {
-	struct inode *inode;
-
-	inode = gfs2_ip2v_lookup(ip);
-	if (inode) {
-		inode_attr_in(ip, inode);
-		iput(inode);
-	}
+	struct inode *inode = &ip->i_inode;
+	inode_attr_in(ip, inode);
 }
 
 /**
@@ -112,9 +106,9 @@
 
 void gfs2_inode_attr_out(struct gfs2_inode *ip)
 {
-	struct inode *inode = ip->i_vnode;
+	struct inode *inode = &ip->i_inode;
 
-	gfs2_assert_withdraw(ip->i_sbd,
+	gfs2_assert_withdraw(GFS2_SB(inode),
 		(ip->i_di.di_mode & S_IFMT) == (inode->i_mode & S_IFMT));
 	ip->i_di.di_mode = inode->i_mode;
 	ip->i_di.di_uid = inode->i_uid;
@@ -124,95 +118,10 @@
 	ip->i_di.di_ctime = inode->i_ctime.tv_sec;
 }
 
-/**
- * gfs2_ip2v_lookup - Get the struct inode for a struct gfs2_inode
- * @ip: the struct gfs2_inode to get the struct inode for
- *
- * Returns: A VFS inode, or NULL if none
- */
-
-struct inode *gfs2_ip2v_lookup(struct gfs2_inode *ip)
-{
-	struct inode *inode = NULL;
-
-	gfs2_assert_warn(ip->i_sbd, test_bit(GIF_MIN_INIT, &ip->i_flags));
-
-	spin_lock(&ip->i_spin);
-	if (ip->i_vnode)
-		inode = igrab(ip->i_vnode);
-	spin_unlock(&ip->i_spin);
-
-	return inode;
-}
-
-/**
- * gfs2_ip2v - Get/Create a struct inode for a struct gfs2_inode
- * @ip: the struct gfs2_inode to get the struct inode for
- *
- * Returns: A VFS inode, or NULL if no mem
- */
-
-struct inode *gfs2_ip2v(struct gfs2_inode *ip)
-{
-	struct inode *inode, *tmp;
-
-	inode = gfs2_ip2v_lookup(ip);
-	if (inode)
-		return inode;
-
-	tmp = new_inode(ip->i_sbd->sd_vfs);
-	if (!tmp)
-		return NULL;
-
-	inode_attr_in(ip, tmp);
-
-	if (S_ISREG(ip->i_di.di_mode)) {
-		tmp->i_op = &gfs2_file_iops;
-		tmp->i_fop = &gfs2_file_fops;
-		tmp->i_mapping->a_ops = &gfs2_file_aops;
-	} else if (S_ISDIR(ip->i_di.di_mode)) {
-		tmp->i_op = &gfs2_dir_iops;
-		tmp->i_fop = &gfs2_dir_fops;
-	} else if (S_ISLNK(ip->i_di.di_mode)) {
-		tmp->i_op = &gfs2_symlink_iops;
-	} else {
-		tmp->i_op = &gfs2_dev_iops;
-		init_special_inode(tmp, tmp->i_mode, tmp->i_rdev);
-	}
-
-	tmp->u.generic_ip = NULL;
-
-	for (;;) {
-		spin_lock(&ip->i_spin);
-		if (!ip->i_vnode)
-			break;
-		inode = igrab(ip->i_vnode);
-		spin_unlock(&ip->i_spin);
-
-		if (inode) {
-			iput(tmp);
-			return inode;
-		}
-		yield();
-	}
-
-	inode = tmp;
-
-	gfs2_inode_hold(ip);
-	ip->i_vnode = inode;
-	inode->u.generic_ip = ip;
-
-	spin_unlock(&ip->i_spin);
-
-	insert_inode_hash(inode);
-
-	return inode;
-}
-
 static int iget_test(struct inode *inode, void *opaque)
 {
-	struct gfs2_inode *ip = inode->u.generic_ip;
-	struct gfs2_inum *inum = (struct gfs2_inum *)opaque;
+	struct gfs2_inode *ip = GFS2_I(inode);
+	struct gfs2_inum *inum = opaque;
 
 	if (ip && ip->i_num.no_addr == inum->no_addr)
 		return 1;
@@ -220,18 +129,89 @@
 	return 0;
 }
 
-struct inode *gfs2_iget(struct super_block *sb, struct gfs2_inum *inum)
+static int iget_set(struct inode *inode, void *opaque)
+{
+	struct gfs2_inode *ip = GFS2_I(inode);
+	struct gfs2_inum *inum = opaque;
+
+	ip->i_num = *inum;
+	return 0;
+}
+
+struct inode *gfs2_ilookup(struct super_block *sb, struct gfs2_inum *inum)
 {
 	return ilookup5(sb, (unsigned long)inum->no_formal_ino,
 			iget_test, inum);
 }
 
-void gfs2_inode_min_init(struct gfs2_inode *ip, unsigned int type)
+static struct inode *gfs2_iget(struct super_block *sb, struct gfs2_inum *inum)
 {
-	if (!test_and_set_bit(GIF_MIN_INIT, &ip->i_flags)) {
-		ip->i_di.di_nlink = 1;
-		ip->i_di.di_mode = DT2IF(type);
+	return iget5_locked(sb, (unsigned long)inum->no_formal_ino,
+		     iget_test, iget_set, inum);
+}
+
+/**
+ * gfs2_inode_lookup - Lookup an inode
+ * @sb: The super block
+ * @inum: 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 *inum, unsigned int type)
+{
+	struct inode *inode = gfs2_iget(sb, inum);
+	struct gfs2_inode *ip = GFS2_I(inode);
+	struct gfs2_glock *io_gl;
+	int error;
+
+	if (inode->i_state & I_NEW) {
+		struct gfs2_sbd *sdp = GFS2_SB(inode);
+		umode_t mode = DT2IF(type);
+		inode->u.generic_ip = ip;
+		inode->i_mode = mode;
+
+		if (S_ISREG(mode)) {
+			inode->i_op = &gfs2_file_iops;
+			inode->i_fop = &gfs2_file_fops;
+			inode->i_mapping->a_ops = &gfs2_file_aops;
+		} else if (S_ISDIR(mode)) {
+			inode->i_op = &gfs2_dir_iops;
+			inode->i_fop = &gfs2_dir_fops;
+		} else if (S_ISLNK(mode)) {
+			inode->i_op = &gfs2_symlink_iops;
+		} else {
+			inode->i_op = &gfs2_dev_iops;
+		}
+
+		error = gfs2_glock_get(sdp, inum->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);
+		if (unlikely(error))
+			goto fail_put;
+
+		ip->i_vn = ip->i_gl->gl_vn - 1;
+		error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT, &ip->i_iopen_gh);
+		if (unlikely(error))
+			goto fail_iopen;
+
+		gfs2_glock_put(io_gl);
+		unlock_new_inode(inode);
 	}
+
+	return inode;
+fail_iopen:
+	gfs2_glock_put(io_gl);
+fail_put:
+	ip->i_gl->gl_object = NULL;
+	gfs2_glock_put(ip->i_gl);
+fail:
+	iput(inode);
+	return ERR_PTR(error);
 }
 
 /**
@@ -250,7 +230,7 @@
 	if (error)
 		return error;
 
-	if (gfs2_metatype_check(ip->i_sbd, dibh, GFS2_METATYPE_DI)) {
+	if (gfs2_metatype_check(GFS2_SB(&ip->i_inode), dibh, GFS2_METATYPE_DI)) {
 		brelse(dibh);
 		return -EIO;
 	}
@@ -273,151 +253,9 @@
 	return 0;
 }
 
-/**
- * inode_create - create a struct gfs2_inode
- * @i_gl: The glock covering the inode
- * @inum: The inode number
- * @io_gl: the iopen glock to acquire/hold (using holder in new gfs2_inode)
- * @io_state: the state the iopen glock should be acquired in
- * @ipp: pointer to put the returned inode in
- *
- * Returns: errno
- */
-
-static int inode_create(struct gfs2_glock *i_gl, const struct gfs2_inum *inum,
-			struct gfs2_glock *io_gl, unsigned int io_state,
-			struct gfs2_inode **ipp, int need_lock)
+int gfs2_dinode_dealloc(struct gfs2_inode *ip)
 {
-	struct gfs2_sbd *sdp = i_gl->gl_sbd;
-	struct gfs2_inode *ip;
-	int error = 0;
-
-	ip = kmem_cache_alloc(gfs2_inode_cachep, GFP_KERNEL);
-	if (!ip)
-		return -ENOMEM;
-	memset(ip, 0, sizeof(struct gfs2_inode));
-	ip->i_num = *inum;
-	atomic_set(&ip->i_count, 1);
-	ip->i_vn = i_gl->gl_vn - 1;
-	ip->i_gl = i_gl;
-	ip->i_sbd = sdp;
-	spin_lock_init(&ip->i_spin);
-	init_rwsem(&ip->i_rw_mutex);
-	ip->i_greedy = gfs2_tune_get(sdp, gt_greedy_default);
-
-	if (need_lock) {
-		error = gfs2_glock_nq_init(io_gl,
-					   io_state, GL_LOCAL_EXCL | GL_EXACT,
-					   &ip->i_iopen_gh);
-		if (error)
-			goto fail;
-
-		spin_lock(&io_gl->gl_spin);
-		gfs2_glock_hold(i_gl);
-		io_gl->gl_object = i_gl;
-		spin_unlock(&io_gl->gl_spin);
-	}
-
-	gfs2_glock_hold(i_gl);
-	i_gl->gl_object = ip;
-	atomic_inc(&sdp->sd_inode_count);
-	*ipp = ip;
-	return 0;
-
-fail:
-	gfs2_meta_cache_flush(ip);
-	kmem_cache_free(gfs2_inode_cachep, ip);
-	*ipp = NULL;
-	return error;
-}
-
-/**
- * gfs2_inode_get - Create or get a reference on an inode
- * @i_gl: The glock covering the inode
- * @inum: The inode number
- * @create:
- * @ipp: pointer to put the returned inode in
- *
- * Returns: errno
- */
-
-int gfs2_inode_get(struct gfs2_glock *i_gl, const struct gfs2_inum *inum,
-		   int create, struct gfs2_inode **ipp)
-{
-	struct gfs2_sbd *sdp = i_gl->gl_sbd;
-	struct gfs2_glock *io_gl;
-	int error = 0;
-
-	gfs2_glmutex_lock(i_gl);
-
-	*ipp = i_gl->gl_object;
-	if (*ipp) {
-		error = -ESTALE;
-		if ((*ipp)->i_num.no_formal_ino != inum->no_formal_ino)
-			goto out;
-		atomic_inc(&(*ipp)->i_count);
-		error = 0;
-		goto out;
-	}
-
-	if (!create)
-		goto out;
-
-	error = gfs2_glock_get(sdp, inum->no_addr, &gfs2_iopen_glops,
-			       CREATE, &io_gl);
-	if (!error) {
-		error = inode_create(i_gl, inum, io_gl, LM_ST_SHARED, ipp, 1);
-		gfs2_glock_put(io_gl);
-	}
-
- out:
-	gfs2_glmutex_unlock(i_gl);
-
-	return error;
-}
-
-void gfs2_inode_hold(struct gfs2_inode *ip)
-{
-	gfs2_assert(ip->i_sbd, atomic_read(&ip->i_count) > 0);
-	atomic_inc(&ip->i_count);
-}
-
-void gfs2_inode_put(struct gfs2_inode *ip)
-{
-	gfs2_assert(ip->i_sbd, atomic_read(&ip->i_count) > 0);
-	atomic_dec(&ip->i_count);
-}
-
-void gfs2_inode_destroy(struct gfs2_inode *ip, int unlock)
-{
-	struct gfs2_sbd *sdp = ip->i_sbd;
-	struct gfs2_glock *i_gl = ip->i_gl;
-
-	gfs2_assert_warn(sdp, !atomic_read(&ip->i_count));
-	if (unlock) {
-		struct gfs2_glock *io_gl = ip->i_iopen_gh.gh_gl;
-		gfs2_assert(sdp, io_gl->gl_object == i_gl);
-	
-		spin_lock(&io_gl->gl_spin);
-		io_gl->gl_object = NULL;
-		spin_unlock(&io_gl->gl_spin);
-		gfs2_glock_put(i_gl);
-	
-		gfs2_glock_dq_uninit(&ip->i_iopen_gh);
-	}
-
-	gfs2_meta_cache_flush(ip);
-	kmem_cache_free(gfs2_inode_cachep, ip);
-
-	i_gl->gl_object = NULL;
-	gfs2_glock_put(i_gl);
-
-	atomic_dec(&sdp->sd_inode_count);
-}
-
-static int dinode_dealloc(struct gfs2_inode *ip, struct gfs2_unlinked *ul)
-{
-	struct gfs2_sbd *sdp = ip->i_sbd;
+	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
 	struct gfs2_alloc *al;
 	struct gfs2_rgrpd *rgd;
 	int error;
@@ -450,7 +288,7 @@
 	if (error)
 		goto out_rindex_relse;
 
-	error = gfs2_trans_begin(sdp, RES_RG_BIT + RES_UNLINKED +
+	error = gfs2_trans_begin(sdp, RES_RG_BIT + 
 				 RES_STATFS + RES_QUOTA, 1);
 	if (error)
 		goto out_rg_gunlock;
@@ -459,192 +297,21 @@
 
 	gfs2_free_di(rgd, ip);
 
-	error = gfs2_unlinked_ondisk_rm(sdp, ul);
-
 	gfs2_trans_end(sdp);
 	clear_bit(GLF_STICKY, &ip->i_gl->gl_flags);
 
- out_rg_gunlock:
+out_rg_gunlock:
 	gfs2_glock_dq_uninit(&al->al_rgd_gh);
-
- out_rindex_relse:
+out_rindex_relse:
 	gfs2_glock_dq_uninit(&al->al_ri_gh);
-
- out_qs:
+out_qs:
 	gfs2_quota_unhold(ip);
-
- out:
-	gfs2_alloc_put(ip);
-
-	return error;
-}
-
-/**
- * inode_dealloc - Deallocate all on-disk blocks for an inode (dinode)
- * @sdp: the filesystem
- * @inum: the inode number to deallocate
- * @io_gh: a holder for the iopen glock for this inode
- *
- * N.B. When we enter this we already hold the iopen glock and getting
- * the glock for the inode means that we are grabbing the locks in the
- * "wrong" order so we must only so a try lock operation and fail if we
- * don't get the lock. Thats ok, since if we fail it means someone else
- * is using the inode still and thus we shouldn't be deallocating it
- * anyway.
- *
- * Returns: errno
- */
-
-static int inode_dealloc(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul,
-			 struct gfs2_holder *io_gh)
-{
-	struct gfs2_inode *ip;
-	struct gfs2_holder i_gh;
-	int error;
-
-	error = gfs2_glock_nq_num(sdp, ul->ul_ut.ut_inum.no_addr,
-				  &gfs2_inode_glops, LM_ST_EXCLUSIVE,
-				  LM_FLAG_TRY_1CB|GL_DUMP, &i_gh);
-	switch(error) {
-	case 0:
-		break;
-	case GLR_TRYFAILED:
-		return 1; /* or back off and relock in different order? */
-	default:
-		return error;
-	}
-
-	gfs2_assert_warn(sdp, !i_gh.gh_gl->gl_object);
-	error = inode_create(i_gh.gh_gl, &ul->ul_ut.ut_inum, io_gh->gh_gl,
-			     LM_ST_EXCLUSIVE, &ip, 0);
-
-	if (error)
-		goto out;
-
-	error = gfs2_inode_refresh(ip);
-	if (error)
-		goto out_iput;
-
-	if (ip->i_di.di_nlink) {
-		if (gfs2_consist_inode(ip))
-			gfs2_dinode_print(&ip->i_di);
-		error = -EIO;
-		goto out_iput;
-	}
-
-	if (S_ISDIR(ip->i_di.di_mode) &&
-	    (ip->i_di.di_flags & GFS2_DIF_EXHASH)) {
-		error = gfs2_dir_exhash_dealloc(ip);
-		if (error)
-			goto out_iput;
-	}
-
-	if (ip->i_di.di_eattr) {
-		error = gfs2_ea_dealloc(ip);
-		if (error)
-			goto out_iput;
-	}
-
-	if (!gfs2_is_stuffed(ip)) {
-		error = gfs2_file_dealloc(ip);
-		if (error)
-			goto out_iput;
-	}
-
-	error = dinode_dealloc(ip, ul);
-	if (error)
-		goto out_iput;
-
-out_iput:
-	gfs2_glmutex_lock(i_gh.gh_gl);
-	gfs2_inode_put(ip);
-	gfs2_inode_destroy(ip, 0);
-	gfs2_glmutex_unlock(i_gh.gh_gl);
-
 out:
-	gfs2_glock_dq_uninit(&i_gh);
-
+	gfs2_alloc_put(ip);
 	return error;
 }
 
 /**
- * try_inode_dealloc - Try to deallocate an inode and all its blocks
- * @sdp: the filesystem
- *
- * Returns: 0 on success, -errno on error, 1 on busy (inode open)
- */
-
-static int try_inode_dealloc(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul)
-{
-	int error = 0;
-	struct gfs2_holder iogh;
-
-	gfs2_try_toss_inode(sdp, &ul->ul_ut.ut_inum);
-	error = gfs2_glock_nq_num(sdp, ul->ul_ut.ut_inum.no_addr,
-				  &gfs2_iopen_glops, LM_ST_EXCLUSIVE,
-				  LM_FLAG_TRY_1CB, &iogh);
-	switch (error) {
-	case 0:
-		break;
-	case GLR_TRYFAILED:
-		return 1;
-	default:
-		return error;
-	}
-
-	error = inode_dealloc(sdp, ul, &iogh);
-	gfs2_glock_dq_uninit(&iogh);
-
-	return error;
-}
-
-static int inode_dealloc_uninit(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul)
-{
-	struct gfs2_rgrpd *rgd;
-	struct gfs2_holder ri_gh, rgd_gh;
-	int error;
-
-	error = gfs2_rindex_hold(sdp, &ri_gh);
-	if (error)
-		return error;
-
-	rgd = gfs2_blk2rgrpd(sdp, ul->ul_ut.ut_inum.no_addr);
-	if (!rgd) {
-		gfs2_consist(sdp);
-		error = -EIO;
-		goto out;
-	}
-
-	error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, &rgd_gh);
-	if (error)
-		goto out;
-
-	error = gfs2_trans_begin(sdp, RES_RG_BIT + RES_UNLINKED + RES_STATFS, 0);
-	if (error)
-		goto out_gunlock;
-
-	gfs2_free_uninit_di(rgd, ul->ul_ut.ut_inum.no_addr);
-	gfs2_unlinked_ondisk_rm(sdp, ul);
-
-	gfs2_trans_end(sdp);
-
- out_gunlock:
-	gfs2_glock_dq_uninit(&rgd_gh);
- out:
-	gfs2_glock_dq_uninit(&ri_gh);
-
-	return error;
-}
-
-int gfs2_inode_dealloc(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul)
-{
-	if (ul->ul_ut.ut_flags & GFS2_UTF_UNINIT)
-		return inode_dealloc_uninit(sdp, ul);
-	else
-		return try_inode_dealloc(sdp, ul);
-}
-
-/**
  * gfs2_change_nlink - Change nlink count on inode
  * @ip: The GFS2 inode
  * @diff: The change in the nlink count required
@@ -654,6 +321,7 @@
 
 int gfs2_change_nlink(struct gfs2_inode *ip, int diff)
 {
+	struct gfs2_sbd *sdp = ip->i_inode.i_sb->s_fs_info;
 	struct buffer_head *dibh;
 	uint32_t nlink;
 	int error;
@@ -678,8 +346,30 @@
 	gfs2_trans_add_bh(ip->i_gl, dibh, 1);
 	gfs2_dinode_out(&ip->i_di, dibh->b_data);
 	brelse(dibh);
+	mark_inode_dirty(&ip->i_inode);
 
-	return 0;
+	if (ip->i_di.di_nlink == 0) {
+		struct gfs2_rgrpd *rgd;
+		struct gfs2_holder ri_gh, rg_gh;
+
+		error = gfs2_rindex_hold(sdp, &ri_gh);
+		if (error)
+			goto out;
+		error = -EIO;
+		rgd = gfs2_blk2rgrpd(sdp, ip->i_num.no_addr);
+		if (!rgd)
+			goto out_norgrp;
+		error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, &rg_gh);
+		if (error)
+			goto out_norgrp;
+
+		gfs2_unlink_di(&ip->i_inode); /* mark inode unlinked */
+		gfs2_glock_dq_uninit(&rg_gh);
+out_norgrp:
+		gfs2_glock_dq_uninit(&ri_gh);
+	}
+out:
+	return error;
 }
 
 struct inode *gfs2_lookup_simple(struct inode *dip, const char *name)
@@ -703,18 +393,15 @@
  * Returns: errno
  */
 
-struct inode *gfs2_lookupi(struct inode *dir, struct qstr *name, int is_root,
-			   struct nameidata *nd)
+struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name,
+			   int is_root, struct nameidata *nd)
 		 
 {
 	struct super_block *sb = dir->i_sb;
-	struct gfs2_inode *ipp;
-	struct gfs2_inode *dip = dir->u.generic_ip;
-	struct gfs2_sbd *sdp = dip->i_sbd;
+	struct gfs2_inode *dip = GFS2_I(dir);
 	struct gfs2_holder d_gh;
 	struct gfs2_inum inum;
 	unsigned int type;
-	struct gfs2_glock *gl;
 	int error = 0;
 	struct inode *inode = NULL;
 
@@ -742,34 +429,18 @@
 	if (error)
 		goto out;
 
-	error = gfs2_glock_get(sdp, inum.no_addr, &gfs2_inode_glops,
-			       CREATE, &gl);
-	if (error)
-		goto out;
-
-	error = gfs2_inode_get(gl, &inum, CREATE, &ipp);
-	if (!error)
-		gfs2_inode_min_init(ipp, type);
-
-	gfs2_glock_put(gl);
+	inode = gfs2_inode_lookup(sb, &inum, type);
 
 out:
 	gfs2_glock_dq_uninit(&d_gh);
 	if (error == -ENOENT)
 		return NULL;
-	if (error == 0) {
-		inode = gfs2_ip2v(ipp);
-		gfs2_inode_put(ipp);
-		if (!inode)
-			return ERR_PTR(-ENOMEM);
-		return inode;
-	}
-	return ERR_PTR(error);
+	return inode;
 }
 
 static int pick_formal_ino_1(struct gfs2_sbd *sdp, uint64_t *formal_ino)
 {
-	struct gfs2_inode *ip = sdp->sd_ir_inode->u.generic_ip;
+	struct gfs2_inode *ip = GFS2_I(sdp->sd_ir_inode);
 	struct buffer_head *bh;
 	struct gfs2_inum_range ir;
 	int error;
@@ -810,8 +481,8 @@
 
 static int pick_formal_ino_2(struct gfs2_sbd *sdp, uint64_t *formal_ino)
 {
-	struct gfs2_inode *ip = sdp->sd_ir_inode->u.generic_ip;
-	struct gfs2_inode *m_ip = sdp->sd_inum_inode->u.generic_ip;
+	struct gfs2_inode *ip = GFS2_I(sdp->sd_ir_inode);
+	struct gfs2_inode *m_ip = GFS2_I(sdp->sd_inum_inode);
 	struct gfs2_holder gh;
 	struct buffer_head *bh;
 	struct gfs2_inum_range ir;
@@ -895,12 +566,12 @@
  * Returns: errno
  */
 
-static int create_ok(struct gfs2_inode *dip, struct qstr *name,
+static int create_ok(struct gfs2_inode *dip, const struct qstr *name,
 		     unsigned int mode)
 {
 	int error;
 
-	error = gfs2_repermission(dip->i_vnode, MAY_WRITE | MAY_EXEC, NULL);
+	error = gfs2_repermission(&dip->i_inode, MAY_WRITE | MAY_EXEC, NULL);
 	if (error)
 		return error;
 
@@ -908,7 +579,7 @@
 	if (!dip->i_di.di_nlink)
 		return -EPERM;
 
-	error = gfs2_dir_search(dip->i_vnode, name, NULL, NULL);
+	error = gfs2_dir_search(&dip->i_inode, name, NULL, NULL);
 	switch (error) {
 	case -ENOENT:
 		error = 0;
@@ -930,7 +601,7 @@
 static void munge_mode_uid_gid(struct gfs2_inode *dip, unsigned int *mode,
 			       unsigned int *uid, unsigned int *gid)
 {
-	if (dip->i_sbd->sd_args.ar_suiddir &&
+	if (GFS2_SB(&dip->i_inode)->sd_args.ar_suiddir &&
 	    (dip->i_di.di_mode & S_ISUID) &&
 	    dip->i_di.di_uid) {
 		if (S_ISDIR(*mode))
@@ -949,9 +620,9 @@
 		*gid = current->fsgid;
 }
 
-static int alloc_dinode(struct gfs2_inode *dip, struct gfs2_unlinked *ul)
+static int alloc_dinode(struct gfs2_inode *dip, struct gfs2_inum *inum)
 {
-	struct gfs2_sbd *sdp = dip->i_sbd;
+	struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
 	int error;
 
 	gfs2_alloc_get(dip);
@@ -961,15 +632,11 @@
 	if (error)
 		goto out;
 
-	error = gfs2_trans_begin(sdp, RES_RG_BIT + RES_UNLINKED +
-				 RES_STATFS, 0);
+	error = gfs2_trans_begin(sdp, RES_RG_BIT + RES_STATFS, 0);
 	if (error)
 		goto out_ipreserv;
 
-	ul->ul_ut.ut_inum.no_addr = gfs2_alloc_di(dip);
-
-	ul->ul_ut.ut_flags = GFS2_UTF_UNINIT;
-	error = gfs2_unlinked_ondisk_add(sdp, ul);
+	inum->no_addr = gfs2_alloc_di(dip);
 
 	gfs2_trans_end(sdp);
 
@@ -997,7 +664,7 @@
 			struct gfs2_inum *inum, unsigned int mode,
 			unsigned int uid, unsigned int gid)
 {
-	struct gfs2_sbd *sdp = dip->i_sbd;
+	struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
 	struct gfs2_dinode *di;
 	struct buffer_head *dibh;
 
@@ -1049,9 +716,9 @@
 }
 
 static int make_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl,
-		       unsigned int mode, struct gfs2_unlinked *ul)
+		       unsigned int mode, struct gfs2_inum *inum)
 {
-	struct gfs2_sbd *sdp = dip->i_sbd;
+	struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
 	unsigned int uid, gid;
 	int error;
 
@@ -1066,28 +733,25 @@
 	if (error)
 		goto out_quota;
 
-	error = gfs2_trans_begin(sdp, RES_DINODE + RES_UNLINKED + RES_QUOTA, 0);
+	error = gfs2_trans_begin(sdp, RES_DINODE + RES_QUOTA, 0);
 	if (error)
 		goto out_quota;
 
-	ul->ul_ut.ut_flags = 0;
-	error = gfs2_unlinked_ondisk_munge(sdp, ul);
-	init_dinode(dip, gl, &ul->ul_ut.ut_inum, mode, uid, gid);
+	init_dinode(dip, gl, inum, mode, uid, gid);
 	gfs2_quota_change(dip, +1, uid, gid);
 	gfs2_trans_end(sdp);
 
- out_quota:
+out_quota:
 	gfs2_quota_unlock(dip);
-
- out:
+out:
 	gfs2_alloc_put(dip);
 	return error;
 }
 
-static int link_dinode(struct gfs2_inode *dip, struct qstr *name,
-		       struct gfs2_inode *ip, struct gfs2_unlinked *ul)
+static int link_dinode(struct gfs2_inode *dip, const struct qstr *name,
+		       struct gfs2_inode *ip)
 {
-	struct gfs2_sbd *sdp = dip->i_sbd;
+	struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
 	struct gfs2_alloc *al;
 	int alloc_required;
 	struct buffer_head *dibh;
@@ -1099,7 +763,7 @@
 	if (error)
 		goto fail;
 
-	error = alloc_required = gfs2_diradd_alloc_required(dip->i_vnode, name);
+	error = alloc_required = gfs2_diradd_alloc_required(&dip->i_inode, name);
 	if (alloc_required < 0)
 		goto fail;
 	if (alloc_required) {
@@ -1116,20 +780,17 @@
 
 		error = gfs2_trans_begin(sdp, sdp->sd_max_dirres +
 					 al->al_rgd->rd_ri.ri_length +
-					 2 * RES_DINODE + RES_UNLINKED +
+					 2 * RES_DINODE + 
 					 RES_STATFS + RES_QUOTA, 0);
 		if (error)
 			goto fail_ipreserv;
 	} else {
-		error = gfs2_trans_begin(sdp,
-					 RES_LEAF +
-					 2 * RES_DINODE +
-					 RES_UNLINKED, 0);
+		error = gfs2_trans_begin(sdp, RES_LEAF + 2 * RES_DINODE, 0);
 		if (error)
 			goto fail_quota_locks;
 	}
 
-	error = gfs2_dir_add(dip->i_vnode, name, &ip->i_num, IF2DT(ip->i_di.di_mode));
+	error = gfs2_dir_add(&dip->i_inode, name, &ip->i_num, IF2DT(ip->i_di.di_mode));
 	if (error)
 		goto fail_end_trans;
 
@@ -1140,11 +801,6 @@
 	gfs2_trans_add_bh(ip->i_gl, dibh, 1);
 	gfs2_dinode_out(&ip->i_di, dibh->b_data);
 	brelse(dibh);
-
-	error = gfs2_unlinked_ondisk_rm(sdp, ul);
-	if (error)
-		goto fail_end_trans;
-
 	return 0;
 
 fail_end_trans:
@@ -1178,23 +834,19 @@
  * Returns: An inode
  */
 
-struct inode *gfs2_createi(struct gfs2_holder *ghs, struct qstr *name,
+struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name,
 			   unsigned int mode)
 {
 	struct inode *inode;
 	struct gfs2_inode *dip = ghs->gh_gl->gl_object;
-	struct gfs2_sbd *sdp = dip->i_sbd;
-	struct gfs2_unlinked *ul;
-	struct gfs2_inode *ip;
+	struct inode *dir = &dip->i_inode;
+	struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
+	struct gfs2_inum inum;
 	int error;
 
 	if (!name->len || name->len > GFS2_FNAMESIZE)
 		return ERR_PTR(-ENAMETOOLONG);
 
-	error = gfs2_unlinked_get(sdp, &ul);
-	if (error)
-		return ERR_PTR(error);
-
 	gfs2_holder_reinit(LM_ST_EXCLUSIVE, 0, ghs);
 	error = gfs2_glock_nq(ghs);
 	if (error)
@@ -1204,22 +856,21 @@
 	if (error)
 		goto fail_gunlock;
 
-	error = pick_formal_ino(sdp, &ul->ul_ut.ut_inum.no_formal_ino);
+	error = pick_formal_ino(sdp, &inum.no_formal_ino);
 	if (error)
 		goto fail_gunlock;
 
-	error = alloc_dinode(dip, ul);
+	error = alloc_dinode(dip, &inum);
 	if (error)
 		goto fail_gunlock;
 
-	if (ul->ul_ut.ut_inum.no_addr < dip->i_num.no_addr) {
+	if (inum.no_addr < dip->i_num.no_addr) {
 		gfs2_glock_dq(ghs);
 
-		error = gfs2_glock_nq_num(sdp, ul->ul_ut.ut_inum.no_addr,
+		error = gfs2_glock_nq_num(sdp, inum.no_addr,
 					  &gfs2_inode_glops, LM_ST_EXCLUSIVE,
 					  GL_SKIP, ghs + 1);
 		if (error) {
-			gfs2_unlinked_put(sdp, ul);
 			return ERR_PTR(error);
 		}
 
@@ -1227,7 +878,6 @@
 		error = gfs2_glock_nq(ghs);
 		if (error) {
 			gfs2_glock_dq_uninit(ghs + 1);
-			gfs2_unlinked_put(sdp, ul);
 			return ERR_PTR(error);
 		}
 
@@ -1235,95 +885,48 @@
 		if (error)
 			goto fail_gunlock2;
 	} else {
-		error = gfs2_glock_nq_num(sdp, ul->ul_ut.ut_inum.no_addr,
+		error = gfs2_glock_nq_num(sdp, inum.no_addr,
 					  &gfs2_inode_glops, LM_ST_EXCLUSIVE,
 					  GL_SKIP, ghs + 1);
 		if (error)
 			goto fail_gunlock;
 	}
 
-	error = make_dinode(dip, ghs[1].gh_gl, mode, ul);
+	error = make_dinode(dip, ghs[1].gh_gl, mode, &inum);
 	if (error)
 		goto fail_gunlock2;
 
-	error = gfs2_inode_get(ghs[1].gh_gl, &ul->ul_ut.ut_inum, CREATE, &ip);
-	if (error)
+	inode = gfs2_inode_lookup(dir->i_sb, &inum, IF2DT(mode));
+	if (IS_ERR(inode))
 		goto fail_gunlock2;
 
-	error = gfs2_inode_refresh(ip);
+	error = gfs2_inode_refresh(GFS2_I(inode));
 	if (error)
 		goto fail_iput;
 
-	error = gfs2_acl_create(dip, ip);
+	error = gfs2_acl_create(dip, GFS2_I(inode));
 	if (error)
 		goto fail_iput;
 
-	error = link_dinode(dip, name, ip, ul);
+	error = link_dinode(dip, name, GFS2_I(inode));
 	if (error)
 		goto fail_iput;
 
-	gfs2_unlinked_put(sdp, ul);
-
-	inode = gfs2_ip2v(ip);
-	gfs2_inode_put(ip);
 	if (!inode)
 		return ERR_PTR(-ENOMEM);
 	return inode;
 
 fail_iput:
-	gfs2_inode_put(ip);
-
+	iput(inode);
 fail_gunlock2:
 	gfs2_glock_dq_uninit(ghs + 1);
-
 fail_gunlock:
 	gfs2_glock_dq(ghs);
-
 fail:
-	gfs2_unlinked_put(sdp, ul);
 	return ERR_PTR(error);
 }
 
 /**
- * gfs2_unlinki - Unlink a file
- * @dip: The inode of the directory
- * @name: The name of the file to be unlinked
- * @ip: The inode of the file to be removed
- *
- * Assumes Glocks on both dip and ip are held.
- *
- * Returns: errno
- */
-
-int gfs2_unlinki(struct gfs2_inode *dip, struct qstr *name,
-		 struct gfs2_inode *ip, struct gfs2_unlinked *ul)
-{
-	struct gfs2_sbd *sdp = dip->i_sbd;
-	int error;
-
-	error = gfs2_dir_del(dip, name);
-	if (error)
-		return error;
-
-	error = gfs2_change_nlink(ip, -1);
-	if (error)
-		return error;
-
-	/* If this inode is being unlinked from the directory structure,
-	   we need to mark that in the log so that it isn't lost during
-	   a crash. */
-
-	if (!ip->i_di.di_nlink) {
-		ul->ul_ut.ut_inum = ip->i_num;
-		error = gfs2_unlinked_ondisk_add(sdp, ul);
-		if (!error)
-			set_bit(GLF_STICKY, &ip->i_gl->gl_flags);
-	}
-
-	return error;
-}
-
-/**
  * gfs2_rmdiri - Remove a directory
  * @dip: The parent directory of the directory to be removed
  * @name: The name of the directory to be removed
@@ -1334,10 +937,9 @@
  * Returns: errno
  */
 
-int gfs2_rmdiri(struct gfs2_inode *dip, struct qstr *name,
-		struct gfs2_inode *ip, struct gfs2_unlinked *ul)
+int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name,
+		struct gfs2_inode *ip)
 {
-	struct gfs2_sbd *sdp = dip->i_sbd;
 	struct qstr dotname;
 	int error;
 
@@ -1360,9 +962,7 @@
 	if (error)
 		return error;
 
-	dotname.len = 2;
-	dotname.name = "..";
-	dotname.hash = gfs2_disk_hash(dotname.name, dotname.len);
+	gfs2_str2qstr(&dotname, "..");
 	error = gfs2_dir_del(ip, &dotname);
 	if (error)
 		return error;
@@ -1371,15 +971,6 @@
 	if (error)
 		return error;
 
-	/* This inode is being unlinked from the directory structure and
-	   we need to mark that in the log so that it isn't lost during
-	   a crash. */
-
-	ul->ul_ut.ut_inum = ip->i_num;
-	error = gfs2_unlinked_ondisk_add(sdp, ul);
-	if (!error)
-		set_bit(GLF_STICKY, &ip->i_gl->gl_flags);
-
 	return error;
 }
 
@@ -1394,30 +985,29 @@
  * Returns: 0 if the parent/child relationship is correct, errno if it isn't
  */
 
-int gfs2_unlink_ok(struct gfs2_inode *dip, struct qstr *name,
+int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name,
 		   struct gfs2_inode *ip)
 {
 	struct gfs2_inum inum;
 	unsigned int type;
 	int error;
 
-	if (IS_IMMUTABLE(ip->i_vnode) || IS_APPEND(ip->i_vnode))
+	if (IS_IMMUTABLE(&ip->i_inode) || IS_APPEND(&ip->i_inode))
 		return -EPERM;
 
 	if ((dip->i_di.di_mode & S_ISVTX) &&
 	    dip->i_di.di_uid != current->fsuid &&
-	    ip->i_di.di_uid != current->fsuid &&
-	    !capable(CAP_FOWNER))
+	    ip->i_di.di_uid != current->fsuid && !capable(CAP_FOWNER))
 		return -EPERM;
 
-	if (IS_APPEND(dip->i_vnode))
+	if (IS_APPEND(&dip->i_inode))
 		return -EPERM;
 
-	error = gfs2_repermission(dip->i_vnode, MAY_WRITE | MAY_EXEC, NULL);
+	error = gfs2_repermission(&dip->i_inode, MAY_WRITE | MAY_EXEC, NULL);
 	if (error)
 		return error;
 
-	error = gfs2_dir_search(dip->i_vnode, name, &inum, &type);
+	error = gfs2_dir_search(&dip->i_inode, name, &inum, &type);
 	if (error)
 		return error;
 
@@ -1445,7 +1035,7 @@
 
 int gfs2_ok_to_move(struct gfs2_inode *this, struct gfs2_inode *to)
 {
-	struct inode *dir = to->i_vnode;
+	struct inode *dir = &to->i_inode;
 	struct super_block *sb = dir->i_sb;
 	struct inode *tmp;
 	struct qstr dotdot;
@@ -1456,7 +1046,7 @@
 	igrab(dir);
 
 	for (;;) {
-		if (dir == this->i_vnode) {
+		if (dir == &this->i_inode) {
 			error = -EINVAL;
 			break;
 		}
@@ -1528,12 +1118,10 @@
 	memcpy(*buf, dibh->b_data + sizeof(struct gfs2_dinode), x);
 	*len = x;
 
- out_brelse:
+out_brelse:
 	brelse(dibh);
-
- out:
+out:
 	gfs2_glock_dq_uninit(&i_gh);
-
 	return error;
 }
 
@@ -1622,12 +1210,10 @@
 
 	return 0;
 
- fail_end_trans:
+fail_end_trans:
 	gfs2_trans_end(sdp);
-
- fail:
+fail:
 	gfs2_glock_dq(gh);
-
 	return error;
 }
 
@@ -1722,49 +1308,6 @@
 	return error;
 }
 
-/**
- * gfs2_try_toss_vnode - See if we can toss a vnode from memory
- * @ip: the inode
- *
- * Returns:  1 if the vnode was tossed
- */
-
-void gfs2_try_toss_vnode(struct gfs2_inode *ip)
-{
-	struct inode *inode;
-
-	inode = gfs2_ip2v_lookup(ip);
-	if (!inode)
-		return;
-
-	d_prune_aliases(inode);
-
-	if (S_ISDIR(ip->i_di.di_mode)) {
-		struct list_head *head = &inode->i_dentry;
-		struct dentry *d = NULL;
-
-		spin_lock(&dcache_lock);
-		if (list_empty(head))
-			spin_unlock(&dcache_lock);
-		else {
-			d = list_entry(head->next, struct dentry, d_alias);
-			dget_locked(d);
-			spin_unlock(&dcache_lock);
-
-			if (have_submounts(d))
-				dput(d);
-			else {
-				shrink_dcache_parent(d);
-				dput(d);
-				d_prune_aliases(inode);
-			}
-		}
-	}
-
-	inode->i_nlink = 0;
-	iput(inode);
-}
-
 
 static int
 __gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr)
@@ -1774,8 +1317,8 @@
 
 	error = gfs2_meta_inode_buffer(ip, &dibh);
 	if (!error) {
-		error = inode_setattr(ip->i_vnode, attr);
-		gfs2_assert_warn(ip->i_sbd, !error);
+		error = inode_setattr(&ip->i_inode, attr);
+		gfs2_assert_warn(GFS2_SB(&ip->i_inode), !error);
 		gfs2_inode_attr_out(ip);
 
 		gfs2_trans_add_bh(ip->i_gl, dibh, 1);
@@ -1802,13 +1345,13 @@
 	if (current->journal_info)
 		return __gfs2_setattr_simple(ip, attr);
 
-	error = gfs2_trans_begin(ip->i_sbd, RES_DINODE, 0);
+	error = gfs2_trans_begin(GFS2_SB(&ip->i_inode), RES_DINODE, 0);
 	if (error)
 		return error;
 
 	error = __gfs2_setattr_simple(ip, attr);
 
-	gfs2_trans_end(ip->i_sbd);
+	gfs2_trans_end(GFS2_SB(&ip->i_inode));
 
 	return error;
 }
diff --git a/fs/gfs2/inode.h b/fs/gfs2/inode.h
index 5ef2131..30cfcc1 100644
--- a/fs/gfs2/inode.h
+++ b/fs/gfs2/inode.h
@@ -27,32 +27,20 @@
 
 void gfs2_inode_attr_in(struct gfs2_inode *ip);
 void gfs2_inode_attr_out(struct gfs2_inode *ip);
-struct inode *gfs2_ip2v_lookup(struct gfs2_inode *ip);
-struct inode *gfs2_ip2v(struct gfs2_inode *ip);
-struct inode *gfs2_iget(struct super_block *sb, struct gfs2_inum *inum);
+struct inode *gfs2_inode_lookup(struct super_block *sb, struct gfs2_inum *inum, unsigned type);
+struct inode *gfs2_ilookup(struct super_block *sb, struct gfs2_inum *inum);
 
-void gfs2_inode_min_init(struct gfs2_inode *ip, unsigned int type);
 int gfs2_inode_refresh(struct gfs2_inode *ip);
 
-int gfs2_inode_get(struct gfs2_glock *i_gl,
-		   const struct gfs2_inum *inum, int create,
-		   struct gfs2_inode **ipp);
-void gfs2_inode_hold(struct gfs2_inode *ip);
-void gfs2_inode_put(struct gfs2_inode *ip);
-void gfs2_inode_destroy(struct gfs2_inode *ip, int unlock);
-
-int gfs2_inode_dealloc(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul);
-
+int gfs2_dinode_dealloc(struct gfs2_inode *inode);
 int gfs2_change_nlink(struct gfs2_inode *ip, int diff);
-struct inode *gfs2_lookupi(struct inode *dir, struct qstr *name, int is_root,
-			   struct nameidata *nd);
-struct inode *gfs2_createi(struct gfs2_holder *ghs, struct qstr *name,
+struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name, 
+			   int is_root, struct nameidata *nd);
+struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name,
 			   unsigned int mode);
-int gfs2_unlinki(struct gfs2_inode *dip, struct qstr *name,
-		 struct gfs2_inode *ip, struct gfs2_unlinked *ul);
-int gfs2_rmdiri(struct gfs2_inode *dip, struct qstr *name,
-		struct gfs2_inode *ip, struct gfs2_unlinked *ul);
-int gfs2_unlink_ok(struct gfs2_inode *dip, 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);
 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);
@@ -60,8 +48,6 @@
 int gfs2_glock_nq_atime(struct gfs2_holder *gh);
 int gfs2_glock_nq_m_atime(unsigned int num_gh, struct gfs2_holder *ghs);
 
-void gfs2_try_toss_vnode(struct gfs2_inode *ip);
-
 int gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr);
 
 int gfs2_repermission(struct inode *inode, int mask, struct nameidata *nd);
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c
index 2a8b4b7..483d4fa 100644
--- a/fs/gfs2/log.c
+++ b/fs/gfs2/log.c
@@ -213,6 +213,9 @@
 	int bdy;
 
 	error = gfs2_block_map(sdp->sd_jdesc->jd_inode, lbn, &new, &dbn, &bdy);
+	if (!(!error && dbn)) {
+		printk(KERN_INFO "error=%d, dbn=%llu lbn=%u", error, dbn, lbn);
+	}
 	gfs2_assert_withdraw(sdp, !error && dbn);
 
 	return dbn;
diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c
index e4c75a7..a76f1a7 100644
--- a/fs/gfs2/lops.c
+++ b/fs/gfs2/lops.c
@@ -184,8 +184,7 @@
 static void buf_lo_before_scan(struct gfs2_jdesc *jd,
 			       struct gfs2_log_header *head, int pass)
 {
-	struct gfs2_inode *ip = jd->jd_inode->u.generic_ip;
-	struct gfs2_sbd *sdp = ip->i_sbd;
+	struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
 
 	if (pass != 0)
 		return;
@@ -198,8 +197,8 @@
 				struct gfs2_log_descriptor *ld, __be64 *ptr,
 				int pass)
 {
-	struct gfs2_inode *ip = jd->jd_inode->u.generic_ip;
-	struct gfs2_sbd *sdp = ip->i_sbd;
+	struct gfs2_inode *ip = GFS2_I(jd->jd_inode);
+	struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
 	struct gfs2_glock *gl = ip->i_gl;
 	unsigned int blks = be32_to_cpu(ld->ld_data1);
 	struct buffer_head *bh_log, *bh_ip;
@@ -245,8 +244,8 @@
 
 static void buf_lo_after_scan(struct gfs2_jdesc *jd, int error, int pass)
 {
-	struct gfs2_inode *ip = jd->jd_inode->u.generic_ip;
-	struct gfs2_sbd *sdp = ip->i_sbd;
+	struct gfs2_inode *ip = GFS2_I(jd->jd_inode);
+	struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
 
 	if (error) {
 		gfs2_meta_sync(ip->i_gl,
@@ -332,8 +331,7 @@
 static void revoke_lo_before_scan(struct gfs2_jdesc *jd,
 				  struct gfs2_log_header *head, int pass)
 {
-	struct gfs2_inode *ip = jd->jd_inode->u.generic_ip;
-	struct gfs2_sbd *sdp = ip->i_sbd;
+	struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
 
 	if (pass != 0)
 		return;
@@ -346,8 +344,7 @@
 				   struct gfs2_log_descriptor *ld, __be64 *ptr,
 				   int pass)
 {
-	struct gfs2_inode *ip = jd->jd_inode->u.generic_ip;
-	struct gfs2_sbd *sdp = ip->i_sbd;
+	struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
 	unsigned int blks = be32_to_cpu(ld->ld_length);
 	unsigned int revokes = be32_to_cpu(ld->ld_data1);
 	struct buffer_head *bh;
@@ -393,8 +390,7 @@
 
 static void revoke_lo_after_scan(struct gfs2_jdesc *jd, int error, int pass)
 {
-	struct gfs2_inode *ip = jd->jd_inode->u.generic_ip;
-	struct gfs2_sbd *sdp = ip->i_sbd;
+	struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
 
 	if (error) {
 		gfs2_revoke_clean(sdp);
@@ -465,7 +461,7 @@
 	struct gfs2_bufdata *bd = container_of(le, struct gfs2_bufdata, bd_le);
 	struct gfs2_trans *tr = current->journal_info;
 	struct address_space *mapping = bd->bd_bh->b_page->mapping;
-	struct gfs2_inode *ip = mapping->host->u.generic_ip;
+	struct gfs2_inode *ip = GFS2_I(mapping->host);
 
 	tr->tr_touched = 1;
 	if (!list_empty(&bd->bd_list_tr) &&
@@ -665,8 +661,8 @@
 				    struct gfs2_log_descriptor *ld,
 				    __be64 *ptr, int pass)
 {
-	struct gfs2_inode *ip = jd->jd_inode->u.generic_ip;
-	struct gfs2_sbd *sdp = ip->i_sbd;
+	struct gfs2_inode *ip = GFS2_I(jd->jd_inode);
+	struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
 	struct gfs2_glock *gl = ip->i_gl;
 	unsigned int blks = be32_to_cpu(ld->ld_data1);
 	struct buffer_head *bh_log, *bh_ip;
@@ -716,8 +712,8 @@
 
 static void databuf_lo_after_scan(struct gfs2_jdesc *jd, int error, int pass)
 {
-	struct gfs2_inode *ip = jd->jd_inode->u.generic_ip;
-	struct gfs2_sbd *sdp = ip->i_sbd;
+	struct gfs2_inode *ip = GFS2_I(jd->jd_inode);
+	struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
 
 	if (error) {
 		gfs2_meta_sync(ip->i_gl,
diff --git a/fs/gfs2/main.c b/fs/gfs2/main.c
index b24d0b4..c112943 100644
--- a/fs/gfs2/main.c
+++ b/fs/gfs2/main.c
@@ -29,8 +29,6 @@
 	if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
 	    SLAB_CTOR_CONSTRUCTOR) {
 		inode_init_once(&ip->i_inode);
-		atomic_set(&ip->i_count, 0);
-		ip->i_vnode = &ip->i_inode;
 		spin_lock_init(&ip->i_spin);
 		init_rwsem(&ip->i_rw_mutex);
 		memset(ip->i_cache, 0, sizeof(ip->i_cache));
diff --git a/fs/gfs2/meta_io.c b/fs/gfs2/meta_io.c
index c785172..2523d42 100644
--- a/fs/gfs2/meta_io.c
+++ b/fs/gfs2/meta_io.c
@@ -91,9 +91,6 @@
 		fs_warn(sdp, "ip = %llu %llu\n",
 			(unsigned long long)ip->i_num.no_formal_ino,
 			(unsigned long long)ip->i_num.no_addr);
-		fs_warn(sdp, "ip->i_count = %d, ip->i_vnode = %s\n",
-			atomic_read(&ip->i_count),
-			(ip->i_vnode) ? "!NULL" : "NULL");
 
 		for (x = 0; x < GFS2_MAX_META_HEIGHT; x++)
 			fs_warn(sdp, "ip->i_cache[%u] = %s\n",
@@ -567,7 +564,6 @@
 
 	bd = kmem_cache_alloc(gfs2_bufdata_cachep, GFP_NOFS | __GFP_NOFAIL),
 	memset(bd, 0, sizeof(struct gfs2_bufdata));
-
 	bd->bd_bh = bh;
 	bd->bd_gl = gl;
 
@@ -664,7 +660,7 @@
 
 void gfs2_meta_wipe(struct gfs2_inode *ip, uint64_t bstart, uint32_t blen)
 {
-	struct gfs2_sbd *sdp = ip->i_sbd;
+	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
 	struct inode *aspace = ip->i_gl->gl_aspace;
 	struct buffer_head *bh;
 
@@ -770,7 +766,7 @@
 		if (new)
 			meta_prep_new(bh);
 		else {
-			error = gfs2_meta_reread(ip->i_sbd, bh,
+			error = gfs2_meta_reread(GFS2_SB(&ip->i_inode), bh,
 						 DIO_START | DIO_WAIT);
 			if (error) {
 				brelse(bh);
@@ -797,7 +793,7 @@
 	}
 
 	if (new) {
-		if (gfs2_assert_warn(ip->i_sbd, height)) {
+		if (gfs2_assert_warn(GFS2_SB(&ip->i_inode), height)) {
 			brelse(bh);
 			return -EIO;
 		}
@@ -805,7 +801,7 @@
 		gfs2_metatype_set(bh, GFS2_METATYPE_IN, GFS2_FORMAT_IN);
 		gfs2_buffer_clear_tail(bh, sizeof(struct gfs2_meta_header));
 
-	} else if (gfs2_metatype_check(ip->i_sbd, bh,
+	} else if (gfs2_metatype_check(GFS2_SB(&ip->i_inode), bh,
 			     (height) ? GFS2_METATYPE_IN : GFS2_METATYPE_DI)) {
 		brelse(bh);
 		return -EIO;
diff --git a/fs/gfs2/ondisk.c b/fs/gfs2/ondisk.c
index be5c86e..09154ad 100644
--- a/fs/gfs2/ondisk.c
+++ b/fs/gfs2/ondisk.c
@@ -293,23 +293,6 @@
 	str->sc_dinodes = cpu_to_be64(sc->sc_dinodes);
 }
 
-void gfs2_unlinked_tag_in(struct gfs2_unlinked_tag *ut, char *buf)
-{
-	struct gfs2_unlinked_tag *str = (struct gfs2_unlinked_tag *)buf;
-
-	gfs2_inum_in(&ut->ut_inum, buf);
-	ut->ut_flags = be32_to_cpu(str->ut_flags);
-}
-
-void gfs2_unlinked_tag_out(struct gfs2_unlinked_tag *ut, char *buf)
-{
-	struct gfs2_unlinked_tag *str = (struct gfs2_unlinked_tag *)buf;
-
-	gfs2_inum_out(&ut->ut_inum, buf);
-	str->ut_flags = cpu_to_be32(ut->ut_flags);
-	str->__pad = 0;
-}
-
 void gfs2_quota_change_in(struct gfs2_quota_change *qc, char *buf)
 {
 	struct gfs2_quota_change *str = (struct gfs2_quota_change *)buf;
diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c
index 16d3ebd..207363a 100644
--- a/fs/gfs2/ops_address.c
+++ b/fs/gfs2/ops_address.c
@@ -81,7 +81,6 @@
 static int get_block_noalloc(struct inode *inode, sector_t lblock,
 			     struct buffer_head *bh_result, int create)
 {
-	struct gfs2_inode *ip = inode->u.generic_ip;
 	int new = 0;
 	uint64_t dblock;
 	int error;
@@ -93,7 +92,7 @@
 
 	if (dblock)
 		map_bh(bh_result, inode->i_sb, dblock);
-	else if (gfs2_assert_withdraw(ip->i_sbd, !create))
+	else if (gfs2_assert_withdraw(GFS2_SB(inode), !create))
 		error = -EIO;
 	if (boundary)
 		set_buffer_boundary(bh_result);
@@ -114,8 +113,8 @@
 static int gfs2_writepage(struct page *page, struct writeback_control *wbc)
 {
 	struct inode *inode = page->mapping->host;
-	struct gfs2_inode *ip = page->mapping->host->u.generic_ip;
-	struct gfs2_sbd *sdp = ip->i_sbd;
+	struct gfs2_inode *ip = GFS2_I(page->mapping->host);
+	struct gfs2_sbd *sdp = GFS2_SB(page->mapping->host);
 	loff_t i_size = i_size_read(inode);
 	pgoff_t end_index = i_size >> PAGE_CACHE_SHIFT;
 	unsigned offset;
@@ -216,8 +215,8 @@
 
 static int gfs2_readpage(struct file *file, struct page *page)
 {
-	struct gfs2_inode *ip = page->mapping->host->u.generic_ip;
-	struct gfs2_sbd *sdp = ip->i_sbd;
+	struct gfs2_inode *ip = GFS2_I(page->mapping->host);
+	struct gfs2_sbd *sdp = GFS2_SB(page->mapping->host);
 	struct gfs2_holder gh;
 	int error;
 
@@ -271,8 +270,8 @@
 			  struct list_head *pages, unsigned nr_pages)
 {
 	struct inode *inode = mapping->host;
-	struct gfs2_inode *ip = inode->u.generic_ip;
-	struct gfs2_sbd *sdp = ip->i_sbd;
+	struct gfs2_inode *ip = GFS2_I(inode);
+	struct gfs2_sbd *sdp = GFS2_SB(inode);
 	struct gfs2_holder gh;
 	unsigned page_idx;
 	int ret;
@@ -345,8 +344,8 @@
 static int gfs2_prepare_write(struct file *file, struct page *page,
 			      unsigned from, unsigned to)
 {
-	struct gfs2_inode *ip = page->mapping->host->u.generic_ip;
-	struct gfs2_sbd *sdp = ip->i_sbd;
+	struct gfs2_inode *ip = GFS2_I(page->mapping->host);
+	struct gfs2_sbd *sdp = GFS2_SB(page->mapping->host);
 	unsigned int data_blocks, ind_blocks, rblocks;
 	int alloc_required;
 	int error = 0;
@@ -440,8 +439,8 @@
 			     unsigned from, unsigned to)
 {
 	struct inode *inode = page->mapping->host;
-	struct gfs2_inode *ip = inode->u.generic_ip;
-	struct gfs2_sbd *sdp = ip->i_sbd;
+	struct gfs2_inode *ip = GFS2_I(inode);
+	struct gfs2_sbd *sdp = GFS2_SB(inode);
 	int error = -EOPNOTSUPP;
 	struct buffer_head *dibh;
 	struct gfs2_alloc *al = &ip->i_alloc;;
@@ -520,7 +519,7 @@
 
 static sector_t gfs2_bmap(struct address_space *mapping, sector_t lblock)
 {
-	struct gfs2_inode *ip = mapping->host->u.generic_ip;
+	struct gfs2_inode *ip = GFS2_I(mapping->host);
 	struct gfs2_holder i_gh;
 	sector_t dblock = 0;
 	int error;
@@ -594,7 +593,7 @@
 {
 	struct file *file = iocb->ki_filp;
 	struct inode *inode = file->f_mapping->host;
-	struct gfs2_inode *ip = inode->u.generic_ip;
+	struct gfs2_inode *ip = GFS2_I(inode);
 	struct gfs2_holder gh;
 	int rv;
 
@@ -641,8 +640,8 @@
 {
 	struct file *file = iocb->ki_filp;
 	struct inode *inode = file->f_mapping->host;
-	struct gfs2_inode *ip = inode->u.generic_ip;
-	struct gfs2_sbd *sdp = ip->i_sbd;
+	struct gfs2_inode *ip = GFS2_I(inode);
+	struct gfs2_sbd *sdp = GFS2_SB(inode);
 
 	if (rw == WRITE)
 		return gfs2_direct_IO_write(iocb, iov, offset, nr_segs);
diff --git a/fs/gfs2/ops_dentry.c b/fs/gfs2/ops_dentry.c
index fef415e..fd55979 100644
--- a/fs/gfs2/ops_dentry.c
+++ b/fs/gfs2/ops_dentry.c
@@ -38,8 +38,8 @@
 static int gfs2_drevalidate(struct dentry *dentry, struct nameidata *nd)
 {
 	struct dentry *parent = dget_parent(dentry);
-	struct gfs2_sbd *sdp = parent->d_inode->i_sb->s_fs_info;
-	struct gfs2_inode *dip = parent->d_inode->u.generic_ip;
+	struct gfs2_sbd *sdp = GFS2_SB(parent->d_inode);
+	struct gfs2_inode *dip = GFS2_I(parent->d_inode);
 	struct inode *inode = dentry->d_inode;
 	struct gfs2_holder d_gh;
 	struct gfs2_inode *ip;
@@ -71,7 +71,7 @@
 		goto fail_gunlock;
 	}
 
-	ip = inode->u.generic_ip;
+	ip = GFS2_I(inode);
 
 	if (!gfs2_inum_equal(&ip->i_num, &inum))
 		goto invalid_gunlock;
diff --git a/fs/gfs2/ops_export.c b/fs/gfs2/ops_export.c
index a376ead..eacc1c0 100644
--- a/fs/gfs2/ops_export.c
+++ b/fs/gfs2/ops_export.c
@@ -66,7 +66,7 @@
 {
 	struct inode *inode = dentry->d_inode;
 	struct super_block *sb = inode->i_sb;
-	struct gfs2_inode *ip = inode->u.generic_ip;
+	struct gfs2_inode *ip = GFS2_I(inode);
 
 	if (*len < 4 || (connectable && *len < 8))
 		return 255;
@@ -86,8 +86,8 @@
 
 	spin_lock(&dentry->d_lock);
 	inode = dentry->d_parent->d_inode;
-	ip = inode->u.generic_ip;
-	gfs2_inode_hold(ip);
+	ip = GFS2_I(inode);
+	igrab(inode);
 	spin_unlock(&dentry->d_lock);
 
 	fh[4] = ip->i_num.no_formal_ino >> 32;
@@ -100,7 +100,7 @@
 	fh[7] = cpu_to_be32(fh[7]);
 	*len = 8;
 
-	gfs2_inode_put(ip);
+	iput(inode);
 
 	return *len;
 }
@@ -142,8 +142,8 @@
 	if (!S_ISDIR(dir->i_mode) || !inode)
 		return -EINVAL;
 
-	dip = dir->u.generic_ip;
-	ip = inode->u.generic_ip;
+	dip = GFS2_I(dir);
+	ip = GFS2_I(inode);
 
 	*name = 0;
 	gnfd.inum = ip->i_num;
@@ -189,39 +189,30 @@
 static struct dentry *gfs2_get_dentry(struct super_block *sb, void *inum_p)
 {
 	struct gfs2_sbd *sdp = sb->s_fs_info;
-	struct gfs2_inum *inum = (struct gfs2_inum *)inum_p;
+	struct gfs2_inum *inum = inum_p;
 	struct gfs2_holder i_gh, ri_gh, rgd_gh;
 	struct gfs2_rgrpd *rgd;
-	struct gfs2_inode *ip;
 	struct inode *inode;
 	struct dentry *dentry;
 	int error;
 
 	/* System files? */
 
-	inode = gfs2_iget(sb, inum);
+	inode = gfs2_ilookup(sb, inum);
 	if (inode) {
-		ip = inode->u.generic_ip;
-		if (ip->i_num.no_formal_ino != inum->no_formal_ino) {
+		if (GFS2_I(inode)->i_num.no_formal_ino != inum->no_formal_ino) {
 			iput(inode);
 			return ERR_PTR(-ESTALE);
 		}
 		goto out_inode;
 	}
 
-	error = gfs2_glock_nq_num(sdp,
-				  inum->no_addr, &gfs2_inode_glops,
+	error = gfs2_glock_nq_num(sdp, inum->no_addr, &gfs2_inode_glops,
 				  LM_ST_SHARED, LM_FLAG_ANY | GL_LOCAL_EXCL,
 				  &i_gh);
 	if (error)
 		return ERR_PTR(error);
 
-	error = gfs2_inode_get(i_gh.gh_gl, inum, NO_CREATE, &ip);
-	if (error)
-		goto fail;
-	if (ip)
-		goto out_ip;
-
 	error = gfs2_rindex_hold(sdp, &ri_gh);
 	if (error)
 		goto fail;
@@ -242,32 +233,29 @@
 	gfs2_glock_dq_uninit(&rgd_gh);
 	gfs2_glock_dq_uninit(&ri_gh);
 
-	error = gfs2_inode_get(i_gh.gh_gl, inum, CREATE, &ip);
-	if (error)
+	inode = gfs2_inode_lookup(sb, inum, DT_UNKNOWN);
+	if (!inode)
 		goto fail;
-
-	error = gfs2_inode_refresh(ip);
-	if (error) {
-		gfs2_inode_put(ip);
+	if (IS_ERR(inode)) {
+		error = PTR_ERR(inode);
 		goto fail;
 	}
 
- out_ip:
+	error = gfs2_inode_refresh(GFS2_I(inode));
+	if (error) {
+		iput(inode);
+		goto fail;
+	}
+
 	error = -EIO;
-	if (ip->i_di.di_flags & GFS2_DIF_SYSTEM) {
-		gfs2_inode_put(ip);
+	if (GFS2_I(inode)->i_di.di_flags & GFS2_DIF_SYSTEM) {
+		iput(inode);
 		goto fail;
 	}
 
 	gfs2_glock_dq_uninit(&i_gh);
 
-	inode = gfs2_ip2v(ip);
-	gfs2_inode_put(ip);
-
-	if (!inode)
-		return ERR_PTR(-ENOMEM);
-
- out_inode:
+out_inode:
 	dentry = d_alloc_anon(inode);
 	if (!dentry) {
 		iput(inode);
@@ -276,13 +264,13 @@
 
 	return dentry;
 
- fail_rgd:
+fail_rgd:
 	gfs2_glock_dq_uninit(&rgd_gh);
 
- fail_rindex:
+fail_rindex:
 	gfs2_glock_dq_uninit(&ri_gh);
 
- fail:
+fail:
 	gfs2_glock_dq_uninit(&i_gh);
 	return ERR_PTR(error);
 }
diff --git a/fs/gfs2/ops_file.c b/fs/gfs2/ops_file.c
index 1e8f602..222f3be 100644
--- a/fs/gfs2/ops_file.c
+++ b/fs/gfs2/ops_file.c
@@ -105,7 +105,7 @@
 int gfs2_internal_read(struct gfs2_inode *ip, struct file_ra_state *ra_state,
 		       char *buf, loff_t *pos, unsigned size)
 {
-	struct inode *inode = ip->i_vnode;
+	struct inode *inode = &ip->i_inode;
 	read_descriptor_t desc;
 	desc.written = 0;
 	desc.arg.buf = buf;
@@ -131,7 +131,7 @@
 
 static loff_t gfs2_llseek(struct file *file, loff_t offset, int origin)
 {
-	struct gfs2_inode *ip = file->f_mapping->host->u.generic_ip;
+	struct gfs2_inode *ip = GFS2_I(file->f_mapping->host);
 	struct gfs2_holder i_gh;
 	loff_t error;
 
@@ -178,7 +178,7 @@
 				    unsigned long nr_segs, loff_t *ppos)
 {
 	struct file *filp = iocb->ki_filp;
-	struct gfs2_inode *ip = filp->f_mapping->host->u.generic_ip;
+	struct gfs2_inode *ip = GFS2_I(filp->f_mapping->host);
 	struct gfs2_holder gh;
 	ssize_t retval;
 	unsigned long seg;
@@ -361,13 +361,13 @@
 static int readdir_reg(struct file *file, void *dirent, filldir_t filldir)
 {
 	struct inode *dir = file->f_mapping->host;
-	struct gfs2_inode *dip = dir->u.generic_ip;
+	struct gfs2_inode *dip = GFS2_I(dir);
 	struct filldir_reg fdr;
 	struct gfs2_holder d_gh;
 	uint64_t offset = file->f_pos;
 	int error;
 
-	fdr.fdr_sbd = dip->i_sbd;
+	fdr.fdr_sbd = GFS2_SB(dir);
 	fdr.fdr_prefetch = 1;
 	fdr.fdr_filldir = filldir;
 	fdr.fdr_opaque = dirent;
@@ -451,8 +451,8 @@
 static int readdir_bad(struct file *file, void *dirent, filldir_t filldir)
 {
 	struct inode *dir = file->f_mapping->host;
-	struct gfs2_inode *dip = dir->u.generic_ip;
-	struct gfs2_sbd *sdp = dip->i_sbd;
+	struct gfs2_inode *dip = GFS2_I(dir);
+	struct gfs2_sbd *sdp = GFS2_SB(dir);
 	struct filldir_reg fdr;
 	unsigned int entries, size;
 	struct filldir_bad *fdb;
@@ -561,7 +561,7 @@
 static int gfs2_get_flags(struct file *filp, u32 __user *ptr)
 {
 	struct inode *inode = filp->f_dentry->d_inode;
-	struct gfs2_inode *ip = inode->u.generic_ip;
+	struct gfs2_inode *ip = GFS2_I(inode);
 	struct gfs2_holder gh;
 	int error;
 	u32 iflags;
@@ -601,8 +601,8 @@
 static int do_gfs2_set_flags(struct file *filp, u32 reqflags, u32 mask)
 {
 	struct inode *inode = filp->f_dentry->d_inode;
-	struct gfs2_inode *ip = inode->u.generic_ip;
-	struct gfs2_sbd *sdp = ip->i_sbd;
+	struct gfs2_inode *ip = GFS2_I(inode);
+	struct gfs2_sbd *sdp = GFS2_SB(inode);
 	struct buffer_head *bh;
 	struct gfs2_holder gh;
 	int error;
@@ -693,7 +693,7 @@
 
 static int gfs2_mmap(struct file *file, struct vm_area_struct *vma)
 {
-	struct gfs2_inode *ip = file->f_mapping->host->u.generic_ip;
+	struct gfs2_inode *ip = GFS2_I(file->f_mapping->host);
 	struct gfs2_holder i_gh;
 	int error;
 
@@ -728,7 +728,7 @@
 
 static int gfs2_open(struct inode *inode, struct file *file)
 {
-	struct gfs2_inode *ip = inode->u.generic_ip;
+	struct gfs2_inode *ip = GFS2_I(inode);
 	struct gfs2_holder i_gh;
 	struct gfs2_file *fp;
 	int error;
@@ -739,7 +739,7 @@
 
 	mutex_init(&fp->f_fl_mutex);
 
-	gfs2_assert_warn(ip->i_sbd, !file->private_data);
+	gfs2_assert_warn(GFS2_SB(inode), !file->private_data);
 	file->private_data = fp;
 
 	if (S_ISREG(ip->i_di.di_mode)) {
@@ -808,7 +808,7 @@
 
 static int gfs2_fsync(struct file *file, struct dentry *dentry, int datasync)
 {
-	struct gfs2_inode *ip = dentry->d_inode->u.generic_ip;
+	struct gfs2_inode *ip = GFS2_I(dentry->d_inode);
 
 	gfs2_log_flush(ip->i_gl->gl_sbd, ip->i_gl);
 
@@ -826,8 +826,8 @@
 
 static int gfs2_lock(struct file *file, int cmd, struct file_lock *fl)
 {
-	struct gfs2_inode *ip = file->f_mapping->host->u.generic_ip;
-	struct gfs2_sbd *sdp = ip->i_sbd;
+	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_type = LM_TYPE_PLOCK };
@@ -881,7 +881,7 @@
 {
 	struct gfs2_file *fp = file->private_data;
 	struct gfs2_holder *fl_gh = &fp->f_fl_gh;
-	struct gfs2_inode *ip = file->f_dentry->d_inode->u.generic_ip;
+	struct gfs2_inode *ip = GFS2_I(file->f_dentry->d_inode);
 	struct gfs2_glock *gl;
 	unsigned int state;
 	int flags;
@@ -901,7 +901,7 @@
 				     &(struct file_lock){.fl_type = F_UNLCK});		
 		gfs2_glock_dq_uninit(fl_gh);
 	} else {
-		error = gfs2_glock_get(ip->i_sbd,
+		error = gfs2_glock_get(GFS2_SB(&ip->i_inode),
 				      ip->i_num.no_addr, &gfs2_flock_glops,
 				      CREATE, &gl);
 		if (error)
@@ -918,7 +918,7 @@
 			error = -EAGAIN;
 	} else {
 		error = flock_lock_file_wait(file, fl);
-		gfs2_assert_warn(ip->i_sbd, !error);
+		gfs2_assert_warn(GFS2_SB(&ip->i_inode), !error);
 	}
 
  out:
@@ -950,8 +950,8 @@
 
 static int gfs2_flock(struct file *file, int cmd, struct file_lock *fl)
 {
-	struct gfs2_inode *ip = file->f_mapping->host->u.generic_ip;
-	struct gfs2_sbd *sdp = ip->i_sbd;
+	struct gfs2_inode *ip = GFS2_I(file->f_mapping->host);
+	struct gfs2_sbd *sdp = GFS2_SB(file->f_mapping->host);
 
 	if (!(fl->fl_flags & FL_FLOCK))
 		return -ENOLCK;
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
index a459820..b68eb6b 100644
--- a/fs/gfs2/ops_fstype.c
+++ b/fs/gfs2/ops_fstype.c
@@ -32,7 +32,6 @@
 #include "recovery.h"
 #include "rgrp.h"
 #include "super.h"
-#include "unlinked.h"
 #include "sys.h"
 #include "util.h"
 
@@ -80,10 +79,6 @@
 	spin_lock_init(&sdp->sd_jindex_spin);
 	mutex_init(&sdp->sd_jindex_mutex);
 
-	INIT_LIST_HEAD(&sdp->sd_unlinked_list);
-	spin_lock_init(&sdp->sd_unlinked_spin);
-	mutex_init(&sdp->sd_unlinked_mutex);
-
 	INIT_LIST_HEAD(&sdp->sd_quota_list);
 	spin_lock_init(&sdp->sd_quota_spin);
 	mutex_init(&sdp->sd_quota_mutex);
@@ -248,19 +243,19 @@
 
 	return 0;
 
- fail_trans:
+fail_trans:
 	gfs2_glock_put(sdp->sd_trans_gl);
 
- fail_rename:
+fail_rename:
 	gfs2_glock_put(sdp->sd_rename_gl);
 
- fail_live:
+fail_live:
 	gfs2_glock_dq_uninit(&sdp->sd_live_gh);
 
- fail_mount:
+fail_mount:
 	gfs2_glock_dq_uninit(mount_gh);
 
- fail:
+fail:
 	while (sdp->sd_glockd_num--)
 		kthread_stop(sdp->sd_glockd_process[sdp->sd_glockd_num]);
 
@@ -269,28 +264,10 @@
 	return error;
 }
 
-static struct inode *gfs2_lookup_root(struct gfs2_sbd *sdp,
-				      const struct gfs2_inum *inum)
+static struct inode *gfs2_lookup_root(struct super_block *sb,
+				      struct gfs2_inum *inum)
 {
-        int error;
-	struct gfs2_glock *gl;
-	struct gfs2_inode *ip;
-	struct inode *inode;
-
-	error = gfs2_glock_get(sdp, inum->no_addr, &gfs2_inode_glops,
-			       CREATE, &gl);
-        if (!error) {
-               	error = gfs2_inode_get(gl, inum, CREATE, &ip);
-		if (!error) {
-			gfs2_inode_min_init(ip, DT_DIR);
-			inode = gfs2_ip2v(ip);
-			gfs2_inode_put(ip);
-			gfs2_glock_put(gl);
-			return inode;
-		}
-                gfs2_glock_put(gl);
-        }
-        return ERR_PTR(error);
+	return gfs2_inode_lookup(sb, inum, DT_DIR);
 }
 
 static int init_sb(struct gfs2_sbd *sdp, int silent, int undo)
@@ -305,8 +282,7 @@
 		return 0;
 	}
 	
-	error = gfs2_glock_nq_num(sdp,
-				 GFS2_SB_LOCK, &gfs2_meta_glops,
+	error = gfs2_glock_nq_num(sdp, GFS2_SB_LOCK, &gfs2_meta_glops,
 				 LM_ST_SHARED, 0, &sb_gh);
 	if (error) {
 		fs_err(sdp, "can't acquire superblock glock: %d\n", error);
@@ -345,7 +321,7 @@
 	inum = &sdp->sd_sb.sb_root_dir;
 	if (sb->s_type == &gfs2meta_fs_type)
 		inum = &sdp->sd_sb.sb_master_dir;
-	inode = gfs2_lookup_root(sdp, inum);
+	inode = gfs2_lookup_root(sb, inum);
 	if (IS_ERR(inode)) {
 		error = PTR_ERR(inode);
 		fs_err(sdp, "can't read in root inode: %d\n", error);
@@ -382,7 +358,7 @@
 		fs_err(sdp, "can't lookup journal index: %d\n", error);
 		return PTR_ERR(sdp->sd_jindex);
 	}
-	ip = sdp->sd_jindex->u.generic_ip;
+	ip = GFS2_I(sdp->sd_jindex);
 	set_bit(GLF_STICKY, &ip->i_gl->gl_flags);
 
 	/* Load in the journal index special file */
@@ -413,8 +389,7 @@
 		}
 		sdp->sd_jdesc = gfs2_jdesc_find(sdp, sdp->sd_lockstruct.ls_jid);
 
-		error = gfs2_glock_nq_num(sdp,
-					  sdp->sd_lockstruct.ls_jid,
+		error = gfs2_glock_nq_num(sdp, sdp->sd_lockstruct.ls_jid,
 					  &gfs2_journal_glops,
 					  LM_ST_EXCLUSIVE, LM_FLAG_NOEXP,
 					  &sdp->sd_journal_gh);
@@ -423,9 +398,8 @@
 			goto fail_jindex;
 		}
 
-		ip = sdp->sd_jdesc->jd_inode->u.generic_ip;
-		error = gfs2_glock_nq_init(ip->i_gl,
-					   LM_ST_SHARED,
+		ip = GFS2_I(sdp->sd_jdesc->jd_inode);
+		error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED,
 					   LM_FLAG_NOEXP | GL_EXACT,
 					   &sdp->sd_jinode_gh);
 		if (error) {
@@ -509,7 +483,7 @@
 	if (undo)
 		goto fail_qinode;
 
-	inode = gfs2_lookup_root(sdp, &sdp->sd_sb.sb_master_dir);
+	inode = gfs2_lookup_root(sdp->sd_vfs, &sdp->sd_sb.sb_master_dir);
 	if (IS_ERR(inode)) {
 		error = PTR_ERR(inode);
 		fs_err(sdp, "can't read in master directory: %d\n", error);
@@ -545,7 +519,7 @@
 		fs_err(sdp, "can't get resource index inode: %d\n", error);
 		goto fail_statfs;
 	}
-	ip = sdp->sd_rindex->u.generic_ip;
+	ip = GFS2_I(sdp->sd_rindex);
 	set_bit(GLF_STICKY, &ip->i_gl->gl_flags);
 	sdp->sd_rindex_vn = ip->i_gl->gl_vn - 1;
 
@@ -614,14 +588,6 @@
 		goto fail_ir_i;
 	}
 
-	sprintf(buf, "unlinked_tag%u", sdp->sd_jdesc->jd_jid);
-	sdp->sd_ut_inode = gfs2_lookup_simple(pn, buf);
-	if (IS_ERR(sdp->sd_ut_inode)) {
-		error = PTR_ERR(sdp->sd_ut_inode);
-		fs_err(sdp, "can't find local \"ut\" file: %d\n", error);
-		goto fail_sc_i;
-	}
-
 	sprintf(buf, "quota_change%u", sdp->sd_jdesc->jd_jid);
 	sdp->sd_qc_inode = gfs2_lookup_simple(pn, buf);
 	if (IS_ERR(sdp->sd_qc_inode)) {
@@ -633,7 +599,7 @@
 	iput(pn);
 	pn = NULL;
 
-	ip = sdp->sd_ir_inode->u.generic_ip;
+	ip = GFS2_I(sdp->sd_ir_inode);
 	error = gfs2_glock_nq_init(ip->i_gl,
 				   LM_ST_EXCLUSIVE, 0,
 				   &sdp->sd_ir_gh);
@@ -642,7 +608,7 @@
 		goto fail_qc_i;
 	}
 
-	ip = sdp->sd_sc_inode->u.generic_ip;
+	ip = GFS2_I(sdp->sd_sc_inode);
 	error = gfs2_glock_nq_init(ip->i_gl,
 				   LM_ST_EXCLUSIVE, 0,
 				   &sdp->sd_sc_gh);
@@ -651,16 +617,7 @@
 		goto fail_ir_gh;
 	}
 
-	ip = sdp->sd_ut_inode->u.generic_ip;
-	error = gfs2_glock_nq_init(ip->i_gl,
-				   LM_ST_EXCLUSIVE, 0,
-				   &sdp->sd_ut_gh);
-	if (error) {
-		fs_err(sdp, "can't lock local \"ut\" file: %d\n", error);
-		goto fail_sc_gh;
-	}
-
-	ip = sdp->sd_qc_inode->u.generic_ip;
+	ip = GFS2_I(sdp->sd_qc_inode);
 	error = gfs2_glock_nq_init(ip->i_gl,
 				   LM_ST_EXCLUSIVE, 0,
 				   &sdp->sd_qc_gh);
@@ -675,9 +632,7 @@
 	gfs2_glock_dq_uninit(&sdp->sd_qc_gh);
 
  fail_ut_gh:
-	gfs2_glock_dq_uninit(&sdp->sd_ut_gh);
 
- fail_sc_gh:
 	gfs2_glock_dq_uninit(&sdp->sd_sc_gh);
 
  fail_ir_gh:
@@ -687,9 +642,7 @@
 	iput(sdp->sd_qc_inode);
 
  fail_ut_i:
-	iput(sdp->sd_ut_inode);
 
- fail_sc_i:
 	iput(sdp->sd_sc_inode);
 
  fail_ir_i:
@@ -707,7 +660,7 @@
 	int error = 0;
 
 	if (undo)
-		goto fail_inoded;
+		goto fail_quotad;
 
 	sdp->sd_log_flush_time = jiffies;
 	sdp->sd_jindex_refresh_time = jiffies;
@@ -731,25 +684,13 @@
 	}
 	sdp->sd_quotad_process = p;
 
-	p = kthread_run(gfs2_inoded, sdp, "gfs2_inoded");
-	error = IS_ERR(p);
-	if (error) {
-		fs_err(sdp, "can't start inoded thread: %d\n", error);
-		goto fail_quotad;
-	}
-	sdp->sd_inoded_process = p;
-
 	return 0;
 
- fail_inoded:
-	kthread_stop(sdp->sd_inoded_process);
 
- fail_quotad:
+fail_quotad:
 	kthread_stop(sdp->sd_quotad_process);
-
- fail:
+fail:
 	kthread_stop(sdp->sd_logd_process);
-	
 	return error;
 }
 
diff --git a/fs/gfs2/ops_inode.c b/fs/gfs2/ops_inode.c
index 0c06f92..f678f6b 100644
--- a/fs/gfs2/ops_inode.c
+++ b/fs/gfs2/ops_inode.c
@@ -38,7 +38,6 @@
 #include "quota.h"
 #include "rgrp.h"
 #include "trans.h"
-#include "unlinked.h"
 #include "util.h"
 
 /**
@@ -53,8 +52,8 @@
 static int gfs2_create(struct inode *dir, struct dentry *dentry,
 		       int mode, struct nameidata *nd)
 {
-	struct gfs2_inode *dip = dir->u.generic_ip;
-	struct gfs2_sbd *sdp = dip->i_sbd;
+	struct gfs2_inode *dip = GFS2_I(dir);
+	struct gfs2_sbd *sdp = GFS2_SB(dir);
 	struct gfs2_holder ghs[2];
 	struct inode *inode;
 	int new = 1;
@@ -141,10 +140,10 @@
 static int gfs2_link(struct dentry *old_dentry, struct inode *dir,
 		     struct dentry *dentry)
 {
-	struct gfs2_inode *dip = dir->u.generic_ip;
-	struct gfs2_sbd *sdp = dip->i_sbd;
+	struct gfs2_inode *dip = GFS2_I(dir);
+	struct gfs2_sbd *sdp = GFS2_SB(dir);
 	struct inode *inode = old_dentry->d_inode;
-	struct gfs2_inode *ip = inode->u.generic_ip;
+	struct gfs2_inode *ip = GFS2_I(inode);
 	struct gfs2_holder ghs[2];
 	int alloc_required;
 	int error;
@@ -231,30 +230,29 @@
 
 	error = gfs2_change_nlink(ip, +1);
 
- out_end_trans:
+out_end_trans:
 	gfs2_trans_end(sdp);
 
- out_ipres:
+out_ipres:
 	if (alloc_required)
 		gfs2_inplace_release(dip);
 
- out_gunlock_q:
+out_gunlock_q:
 	if (alloc_required)
 		gfs2_quota_unlock(dip);
 
- out_alloc:
+out_alloc:
 	if (alloc_required)
 		gfs2_alloc_put(dip);
 
- out_gunlock:
+out_gunlock:
 	gfs2_glock_dq_m(2, ghs);
 
- out:
+out:
 	gfs2_holder_uninit(ghs);
 	gfs2_holder_uninit(ghs + 1);
 
 	if (!error) {
-		atomic_inc(&inode->i_count);
 		d_instantiate(dentry, inode);
 		mark_inode_dirty(inode);
 	}
@@ -274,17 +272,12 @@
 
 static int gfs2_unlink(struct inode *dir, struct dentry *dentry)
 {
-	struct gfs2_inode *dip = dir->u.generic_ip;
-	struct gfs2_sbd *sdp = dip->i_sbd;
-	struct gfs2_inode *ip = dentry->d_inode->u.generic_ip;
-	struct gfs2_unlinked *ul;
+	struct gfs2_inode *dip = GFS2_I(dir);
+	struct gfs2_sbd *sdp = GFS2_SB(dir);
+	struct gfs2_inode *ip = GFS2_I(dentry->d_inode);
 	struct gfs2_holder ghs[2];
 	int error;
 
-	error = gfs2_unlinked_get(sdp, &ul);
-	if (error)
-		return error;
-
 	gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs);
 	gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + 1);
 
@@ -296,24 +289,23 @@
 	if (error)
 		goto out_gunlock;
 
-	error = gfs2_trans_begin(sdp, 2 * RES_DINODE + RES_LEAF +
-				RES_UNLINKED, 0);
+	error = gfs2_trans_begin(sdp, 2*RES_DINODE + RES_LEAF + RES_RG_BIT, 0);
 	if (error)
 		goto out_gunlock;
 
-	error = gfs2_unlinki(dip, &dentry->d_name, ip, ul);
+	error = gfs2_dir_del(dip, &dentry->d_name);
+        if (error)
+                goto out_end_trans;
 
+	error = gfs2_change_nlink(ip, -1);
+
+out_end_trans:
 	gfs2_trans_end(sdp);
-
- out_gunlock:
+out_gunlock:
 	gfs2_glock_dq_m(2, ghs);
-
- out:
+out:
 	gfs2_holder_uninit(ghs);
 	gfs2_holder_uninit(ghs + 1);
-
-	gfs2_unlinked_put(sdp, ul);
-
 	return error;
 }
 
@@ -329,8 +321,8 @@
 static int gfs2_symlink(struct inode *dir, struct dentry *dentry,
 			const char *symname)
 {
-	struct gfs2_inode *dip = dir->u.generic_ip, *ip;
-	struct gfs2_sbd *sdp = dip->i_sbd;
+	struct gfs2_inode *dip = GFS2_I(dir), *ip;
+	struct gfs2_sbd *sdp = GFS2_SB(dir);
 	struct gfs2_holder ghs[2];
 	struct inode *inode;
 	struct buffer_head *dibh;
@@ -388,8 +380,8 @@
 
 static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, int mode)
 {
-	struct gfs2_inode *dip = dir->u.generic_ip, *ip;
-	struct gfs2_sbd *sdp = dip->i_sbd;
+	struct gfs2_inode *dip = GFS2_I(dir), *ip;
+	struct gfs2_sbd *sdp = GFS2_SB(dir);
 	struct gfs2_holder ghs[2];
 	struct inode *inode;
 	struct buffer_head *dibh;
@@ -466,17 +458,12 @@
 
 static int gfs2_rmdir(struct inode *dir, struct dentry *dentry)
 {
-	struct gfs2_inode *dip = dir->u.generic_ip;
-	struct gfs2_sbd *sdp = dip->i_sbd;
-	struct gfs2_inode *ip = dentry->d_inode->u.generic_ip;
-	struct gfs2_unlinked *ul;
+	struct gfs2_inode *dip = GFS2_I(dir);
+	struct gfs2_sbd *sdp = GFS2_SB(dir);
+	struct gfs2_inode *ip = GFS2_I(dentry->d_inode);
 	struct gfs2_holder ghs[2];
 	int error;
 
-	error = gfs2_unlinked_get(sdp, &ul);
-	if (error)
-		return error;
-
 	gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs);
 	gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + 1);
 
@@ -499,12 +486,11 @@
 		goto out_gunlock;
 	}
 
-	error = gfs2_trans_begin(sdp, 2 * RES_DINODE + 3 * RES_LEAF +
-				RES_UNLINKED, 0);
+	error = gfs2_trans_begin(sdp, 2 * RES_DINODE + 3 * RES_LEAF + RES_RG_BIT, 0);
 	if (error)
 		goto out_gunlock;
 
-	error = gfs2_rmdiri(dip, &dentry->d_name, ip, ul);
+	error = gfs2_rmdiri(dip, &dentry->d_name, ip);
 
 	gfs2_trans_end(sdp);
 
@@ -515,8 +501,6 @@
 	gfs2_holder_uninit(ghs);
 	gfs2_holder_uninit(ghs + 1);
 
-	gfs2_unlinked_put(sdp, ul);
-
 	return error;
 }
 
@@ -532,8 +516,8 @@
 static int gfs2_mknod(struct inode *dir, struct dentry *dentry, int mode,
 		      dev_t dev)
 {
-	struct gfs2_inode *dip = dir->u.generic_ip, *ip;
-	struct gfs2_sbd *sdp = dip->i_sbd;
+	struct gfs2_inode *dip = GFS2_I(dir), *ip;
+	struct gfs2_sbd *sdp = GFS2_SB(dir);
 	struct gfs2_holder ghs[2];
 	struct inode *inode;
 	struct buffer_head *dibh;
@@ -600,12 +584,11 @@
 static int gfs2_rename(struct inode *odir, struct dentry *odentry,
 		       struct inode *ndir, struct dentry *ndentry)
 {
-	struct gfs2_inode *odip = odir->u.generic_ip;
-	struct gfs2_inode *ndip = ndir->u.generic_ip;
-	struct gfs2_inode *ip = odentry->d_inode->u.generic_ip;
+	struct gfs2_inode *odip = GFS2_I(odir);
+	struct gfs2_inode *ndip = GFS2_I(ndir);
+	struct gfs2_inode *ip = GFS2_I(odentry->d_inode);
 	struct gfs2_inode *nip = NULL;
-	struct gfs2_sbd *sdp = odip->i_sbd;
-	struct gfs2_unlinked *ul;
+	struct gfs2_sbd *sdp = GFS2_SB(odir);
 	struct gfs2_holder ghs[4], r_gh;
 	unsigned int num_gh;
 	int dir_rename = 0;
@@ -614,15 +597,11 @@
 	int error;
 
 	if (ndentry->d_inode) {
-		nip = ndentry->d_inode->u.generic_ip;
+		nip = GFS2_I(ndentry->d_inode);
 		if (ip == nip)
 			return 0;
 	}
 
-	error = gfs2_unlinked_get(sdp, &ul);
-	if (error)
-		return error;
-
 	/* Make sure we aren't trying to move a dirctory into it's subdir */
 
 	if (S_ISDIR(ip->i_di.di_mode) && odip != ndip) {
@@ -743,14 +722,12 @@
 		error = gfs2_trans_begin(sdp, sdp->sd_max_dirres +
 					 al->al_rgd->rd_ri.ri_length +
 					 4 * RES_DINODE + 4 * RES_LEAF +
-					 RES_UNLINKED + RES_STATFS +
-					 RES_QUOTA, 0);
+					 RES_STATFS + RES_QUOTA, 0);
 		if (error)
 			goto out_ipreserv;
 	} else {
 		error = gfs2_trans_begin(sdp, 4 * RES_DINODE +
-					 5 * RES_LEAF +
-					 RES_UNLINKED, 0);
+					 5 * RES_LEAF, 0);
 		if (error)
 			goto out_gunlock;
 	}
@@ -759,9 +736,13 @@
 
 	if (nip) {
 		if (S_ISDIR(nip->i_di.di_mode))
-			error = gfs2_rmdiri(ndip, &ndentry->d_name, nip, ul);
-		else
-			error = gfs2_unlinki(ndip, &ndentry->d_name, nip, ul);
+			error = gfs2_rmdiri(ndip, &ndentry->d_name, nip);
+		else {
+			error = gfs2_dir_del(ndip, &ndentry->d_name);
+			if (error)
+				goto out_end_trans;
+			error = gfs2_change_nlink(nip, -1);
+		}
 		if (error)
 			goto out_end_trans;
 	}
@@ -800,35 +781,26 @@
 	if (error)
 		goto out_end_trans;
 
- out_end_trans:
+out_end_trans:
 	gfs2_trans_end(sdp);
-
- out_ipreserv:
+out_ipreserv:
 	if (alloc_required)
 		gfs2_inplace_release(ndip);
-
- out_gunlock_q:
+out_gunlock_q:
 	if (alloc_required)
 		gfs2_quota_unlock(ndip);
-
- out_alloc:
+out_alloc:
 	if (alloc_required)
 		gfs2_alloc_put(ndip);
-
- out_gunlock:
+out_gunlock:
 	gfs2_glock_dq_m(num_gh, ghs);
-
- out_uninit:
+out_uninit:
 	for (x = 0; x < num_gh; x++)
 		gfs2_holder_uninit(ghs + x);
-
- out_gunlock_r:
+out_gunlock_r:
 	if (dir_rename)
 		gfs2_glock_dq_uninit(&r_gh);
-
- out:
-	gfs2_unlinked_put(sdp, ul);
-
+out:
 	return error;
 }
 
@@ -844,7 +816,7 @@
 static int gfs2_readlink(struct dentry *dentry, char __user *user_buf,
 			 int user_size)
 {
-	struct gfs2_inode *ip = dentry->d_inode->u.generic_ip;
+	struct gfs2_inode *ip = GFS2_I(dentry->d_inode);
 	char array[GFS2_FAST_NAME_SIZE], *buf = array;
 	unsigned int len = GFS2_FAST_NAME_SIZE;
 	int error;
@@ -880,7 +852,7 @@
 
 static void *gfs2_follow_link(struct dentry *dentry, struct nameidata *nd)
 {
-	struct gfs2_inode *ip = dentry->d_inode->u.generic_ip;
+	struct gfs2_inode *ip = GFS2_I(dentry->d_inode);
 	char array[GFS2_FAST_NAME_SIZE], *buf = array;
 	unsigned int len = GFS2_FAST_NAME_SIZE;
 	int error;
@@ -906,7 +878,7 @@
 
 static int gfs2_permission(struct inode *inode, int mask, struct nameidata *nd)
 {
-	struct gfs2_inode *ip = inode->u.generic_ip;
+	struct gfs2_inode *ip = GFS2_I(inode);
 	struct gfs2_holder i_gh;
 	int error;
 
@@ -926,7 +898,7 @@
 
 static int setattr_size(struct inode *inode, struct iattr *attr)
 {
-	struct gfs2_inode *ip = inode->u.generic_ip;
+	struct gfs2_inode *ip = GFS2_I(inode);
 	int error;
 
 	if (attr->ia_size != ip->i_di.di_size) {
@@ -944,8 +916,8 @@
 
 static int setattr_chown(struct inode *inode, struct iattr *attr)
 {
-	struct gfs2_inode *ip = inode->u.generic_ip;
-	struct gfs2_sbd *sdp = ip->i_sbd;
+	struct gfs2_inode *ip = GFS2_I(inode);
+	struct gfs2_sbd *sdp = GFS2_SB(inode);
 	struct buffer_head *dibh;
 	uint32_t ouid, ogid, nuid, ngid;
 	int error;
@@ -1021,7 +993,7 @@
 static int gfs2_setattr(struct dentry *dentry, struct iattr *attr)
 {
 	struct inode *inode = dentry->d_inode;
-	struct gfs2_inode *ip = inode->u.generic_ip;
+	struct gfs2_inode *ip = GFS2_I(inode);
 	struct gfs2_holder i_gh;
 	int error;
 
@@ -1068,7 +1040,7 @@
 			struct kstat *stat)
 {
 	struct inode *inode = dentry->d_inode;
-	struct gfs2_inode *ip = inode->u.generic_ip;
+	struct gfs2_inode *ip = GFS2_I(inode);
 	struct gfs2_holder gh;
 	int error;
 
@@ -1084,7 +1056,7 @@
 static int gfs2_setxattr(struct dentry *dentry, const char *name,
 			 const void *data, size_t size, int flags)
 {
-	struct gfs2_inode *ip = dentry->d_inode->u.generic_ip;
+	struct inode *inode = dentry->d_inode;
 	struct gfs2_ea_request er;
 
 	memset(&er, 0, sizeof(struct gfs2_ea_request));
@@ -1096,9 +1068,9 @@
 	er.er_data_len = size;
 	er.er_flags = flags;
 
-	gfs2_assert_warn(ip->i_sbd, !(er.er_flags & GFS2_ERF_MODE));
+	gfs2_assert_warn(GFS2_SB(inode), !(er.er_flags & GFS2_ERF_MODE));
 
-	return gfs2_ea_set(ip, &er);
+	return gfs2_ea_set(GFS2_I(inode), &er);
 }
 
 static ssize_t gfs2_getxattr(struct dentry *dentry, const char *name,
@@ -1114,7 +1086,7 @@
 	er.er_name_len = strlen(er.er_name);
 	er.er_data_len = size;
 
-	return gfs2_ea_get(dentry->d_inode->u.generic_ip, &er);
+	return gfs2_ea_get(GFS2_I(dentry->d_inode), &er);
 }
 
 static ssize_t gfs2_listxattr(struct dentry *dentry, char *buffer, size_t size)
@@ -1125,7 +1097,7 @@
 	er.er_data = (size) ? buffer : NULL;
 	er.er_data_len = size;
 
-	return gfs2_ea_list(dentry->d_inode->u.generic_ip, &er);
+	return gfs2_ea_list(GFS2_I(dentry->d_inode), &er);
 }
 
 static int gfs2_removexattr(struct dentry *dentry, const char *name)
@@ -1138,7 +1110,7 @@
 		return -EOPNOTSUPP;
 	er.er_name_len = strlen(er.er_name);
 
-	return gfs2_ea_remove(dentry->d_inode->u.generic_ip, &er);
+	return gfs2_ea_remove(GFS2_I(dentry->d_inode), &er);
 }
 
 struct inode_operations gfs2_file_iops = {
diff --git a/fs/gfs2/ops_super.c b/fs/gfs2/ops_super.c
index 1c17acc..317d497 100644
--- a/fs/gfs2/ops_super.c
+++ b/fs/gfs2/ops_super.c
@@ -19,6 +19,7 @@
 #include <linux/kthread.h>
 #include <linux/delay.h>
 #include <linux/gfs2_ondisk.h>
+#include <linux/crc32.h>
 
 #include "gfs2.h"
 #include "lm_interface.h"
@@ -36,6 +37,10 @@
 #include "super.h"
 #include "sys.h"
 #include "util.h"
+#include "trans.h"
+#include "dir.h"
+#include "eattr.h"
+#include "bmap.h"
 
 /**
  * gfs2_write_inode - Make sure the inode is stable on the disk
@@ -47,12 +52,15 @@
 
 static int gfs2_write_inode(struct inode *inode, int sync)
 {
-	struct gfs2_inode *ip = inode->u.generic_ip;
+	struct gfs2_inode *ip = GFS2_I(inode);
 
-	if (current->flags & PF_MEMALLOC)
-		return 0;
-	if (ip && sync)
-		gfs2_log_flush(ip->i_gl->gl_sbd, ip->i_gl);
+	/* Check this is a "normal" inode */
+	if (inode->u.generic_ip) {
+		if (current->flags & PF_MEMALLOC)
+			return 0;
+		if (sync)
+			gfs2_log_flush(ip->i_gl->gl_sbd, ip->i_gl);
+	}
 
 	return 0;
 }
@@ -78,7 +86,6 @@
 		gfs2_glock_dq_uninit(&sdp->sd_freeze_gh);
 	mutex_unlock(&sdp->sd_freeze_lock);
 
-	kthread_stop(sdp->sd_inoded_process);
 	kthread_stop(sdp->sd_quotad_process);
 	kthread_stop(sdp->sd_logd_process);
 	kthread_stop(sdp->sd_recoverd_process);
@@ -110,11 +117,9 @@
 		gfs2_glock_dq_uninit(&sdp->sd_jinode_gh);
 		gfs2_glock_dq_uninit(&sdp->sd_ir_gh);
 		gfs2_glock_dq_uninit(&sdp->sd_sc_gh);
-		gfs2_glock_dq_uninit(&sdp->sd_ut_gh);
 		gfs2_glock_dq_uninit(&sdp->sd_qc_gh);
 		iput(sdp->sd_ir_inode);
 		iput(sdp->sd_sc_inode);
-		iput(sdp->sd_ut_inode);
 		iput(sdp->sd_qc_inode);
 	}
 
@@ -274,16 +279,20 @@
 
 static void gfs2_clear_inode(struct inode *inode)
 {
-	struct gfs2_inode *ip = inode->u.generic_ip;
-
-	if (ip) {
-		spin_lock(&ip->i_spin);
-		ip->i_vnode = NULL;
-		inode->u.generic_ip = NULL;
-		spin_unlock(&ip->i_spin);
-
+	/* This tells us its a "real" inode and not one which only
+	 * serves to contain an address space (see rgrp.c, meta_io.c)
+	 * which therefore doesn't have its own glocks.
+	 */
+	if (inode->u.generic_ip) {
+		struct gfs2_inode *ip = GFS2_I(inode);
+		gfs2_glock_inode_squish(inode);
+		gfs2_assert(inode->i_sb->s_fs_info, ip->i_gl->gl_state == LM_ST_UNLOCKED);
+		ip->i_gl->gl_object = NULL;
 		gfs2_glock_schedule_for_reclaim(ip->i_gl);
-		gfs2_inode_put(ip);
+		gfs2_glock_put(ip->i_gl);
+		ip->i_gl = NULL;
+		if (ip->i_iopen_gh.gh_gl)
+			gfs2_glock_dq_uninit(&ip->i_iopen_gh);
 	}
 }
 
@@ -361,6 +370,70 @@
 	return 0;
 }
 
+/* 
+ * We have to (at the moment) hold the inodes main lock to cover
+ * the gap between unlocking the shared lock on the iopen lock and
+ * taking the exclusive lock. I'd rather do a shared -> exclusive
+ * conversion on the iopen lock, but we can change that later. This
+ * is safe, just less efficient.
+ */
+static void gfs2_delete_inode(struct inode *inode)
+{
+	struct gfs2_sbd *sdp = inode->i_sb->s_fs_info;
+	struct gfs2_inode *ip = GFS2_I(inode);
+	struct gfs2_holder gh;
+	int error;
+
+	if (!inode->u.generic_ip)
+		goto out;
+
+	error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, LM_FLAG_TRY_1CB | GL_NOCACHE, &gh);
+	if (unlikely(error)) {
+		gfs2_glock_dq_uninit(&ip->i_iopen_gh);
+		goto out;
+	}
+
+	gfs2_glock_dq(&ip->i_iopen_gh);
+	gfs2_holder_reinit(LM_ST_EXCLUSIVE, LM_FLAG_TRY_1CB | GL_NOCACHE, &ip->i_iopen_gh);
+	error = gfs2_glock_nq(&ip->i_iopen_gh);
+	if (error)
+		goto out_uninit;
+
+	if (S_ISDIR(ip->i_di.di_mode) &&
+	    (ip->i_di.di_flags & GFS2_DIF_EXHASH)) {
+		error = gfs2_dir_exhash_dealloc(ip);
+		if (error)
+			goto out_unlock;
+	}
+
+	if (ip->i_di.di_eattr) {
+		error = gfs2_ea_dealloc(ip);
+		if (error)
+			goto out_unlock;
+	}
+
+	if (!gfs2_is_stuffed(ip)) {
+		error = gfs2_file_dealloc(ip);
+		if (error)
+			goto out_unlock;
+	}
+
+	error = gfs2_dinode_dealloc(ip);
+
+out_unlock:
+	gfs2_glock_dq(&ip->i_iopen_gh);
+out_uninit:
+	gfs2_holder_uninit(&ip->i_iopen_gh);
+	gfs2_glock_dq_uninit(&gh);
+	if (error)
+		fs_warn(sdp, "gfs2_delete_inode: %d\n", error);
+out:
+	truncate_inode_pages(&inode->i_data, 0);
+	clear_inode(inode);
+}
+
+
+
 static struct inode *gfs2_alloc_inode(struct super_block *sb)
 {
 	struct gfs2_sbd *sdp = sb->s_fs_info;
@@ -370,8 +443,6 @@
 	if (ip) {
 		ip->i_flags = 0;
 		ip->i_gl = NULL;
-		ip->i_sbd = sdp;
-		ip->i_vnode = &ip->i_inode;
 		ip->i_greedy = gfs2_tune_get(sdp, gt_greedy_default);
 		ip->i_last_pfault = jiffies;
 	}
@@ -387,6 +458,7 @@
 	.alloc_inode = gfs2_alloc_inode,
 	.destroy_inode = gfs2_destroy_inode,
 	.write_inode = gfs2_write_inode,
+	.delete_inode = gfs2_delete_inode,
 	.put_super = gfs2_put_super,
 	.write_super = gfs2_write_super,
 	.write_super_lockfs = gfs2_write_super_lockfs,
diff --git a/fs/gfs2/ops_vm.c b/fs/gfs2/ops_vm.c
index 263c1fb..08709f1 100644
--- a/fs/gfs2/ops_vm.c
+++ b/fs/gfs2/ops_vm.c
@@ -38,15 +38,15 @@
 	ip->i_last_pfault = jiffies;
 	spin_unlock(&ip->i_spin);
 
-	gfs2_inode_hold(ip);
+	igrab(&ip->i_inode);
 	if (gfs2_glock_be_greedy(ip->i_gl, time))
-		gfs2_inode_put(ip);
+		iput(&ip->i_inode);
 }
 
 static struct page *gfs2_private_nopage(struct vm_area_struct *area,
 					unsigned long address, int *type)
 {
-	struct gfs2_inode *ip = area->vm_file->f_mapping->host->u.generic_ip;
+	struct gfs2_inode *ip = GFS2_I(area->vm_file->f_mapping->host);
 	struct gfs2_holder i_gh;
 	struct page *result;
 	int error;
@@ -69,7 +69,7 @@
 
 static int alloc_page_backing(struct gfs2_inode *ip, struct page *page)
 {
-	struct gfs2_sbd *sdp = ip->i_sbd;
+	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
 	unsigned long index = page->index;
 	uint64_t lblock = index << (PAGE_CACHE_SHIFT -
 				    sdp->sd_sb.sb_bsize_shift);
@@ -114,7 +114,7 @@
 		unsigned int extlen;
 		int new = 1;
 
-		error = gfs2_extent_map(ip->i_vnode, lblock, &new, &dblock, &extlen);
+		error = gfs2_extent_map(&ip->i_inode, lblock, &new, &dblock, &extlen);
 		if (error)
 			goto out_trans;
 
@@ -142,7 +142,7 @@
 static struct page *gfs2_sharewrite_nopage(struct vm_area_struct *area,
 					   unsigned long address, int *type)
 {
-	struct gfs2_inode *ip = area->vm_file->f_mapping->host->u.generic_ip;
+	struct gfs2_inode *ip = GFS2_I(area->vm_file->f_mapping->host);
 	struct gfs2_holder i_gh;
 	struct page *result = NULL;
 	unsigned long index = ((address - area->vm_start) >> PAGE_CACHE_SHIFT) +
diff --git a/fs/gfs2/page.c b/fs/gfs2/page.c
index cd93644..a8165a6 100644
--- a/fs/gfs2/page.c
+++ b/fs/gfs2/page.c
@@ -38,20 +38,17 @@
 	struct inode *inode;
 
 	ip = gl->gl_object;
+	inode = &ip->i_inode;
 	if (!ip || !S_ISREG(ip->i_di.di_mode))
 		return;
 
 	if (!test_bit(GIF_PAGED, &ip->i_flags))
 		return;
 
-	inode = gfs2_ip2v_lookup(ip);
-	if (inode) {
-		unmap_shared_mapping_range(inode->i_mapping, 0, 0);
-		iput(inode);
+	unmap_shared_mapping_range(inode->i_mapping, 0, 0);
 
-		if (test_bit(GIF_SW_PAGED, &ip->i_flags))
-			set_bit(GLF_DIRTY, &gl->gl_flags);
-	}
+	if (test_bit(GIF_SW_PAGED, &ip->i_flags))
+		set_bit(GLF_DIRTY, &gl->gl_flags);
 
 	clear_bit(GIF_SW_PAGED, &ip->i_flags);
 }
@@ -68,19 +65,12 @@
 	struct inode *inode;
 
 	ip = gl->gl_object;
+	inode = &ip->i_inode;
 	if (!ip || !S_ISREG(ip->i_di.di_mode))
 		return;
 
-	inode = gfs2_ip2v_lookup(ip);
-	if (inode) {
-		struct address_space *mapping = inode->i_mapping;
-
-		truncate_inode_pages(mapping, 0);
-		gfs2_assert_withdraw(ip->i_sbd, !mapping->nrpages);
-
-		iput(inode);
-	}
-
+	truncate_inode_pages(inode->i_mapping, 0);
+	gfs2_assert_withdraw(GFS2_SB(&ip->i_inode), !inode->i_mapping->nrpages);
 	clear_bit(GIF_PAGED, &ip->i_flags);
 }
 
@@ -97,32 +87,30 @@
 {
 	struct gfs2_inode *ip;
 	struct inode *inode;
+	struct address_space *mapping;
+	int error = 0;
 
 	ip = gl->gl_object;
+	inode = &ip->i_inode;
 	if (!ip || !S_ISREG(ip->i_di.di_mode))
 		return;
 
-	inode = gfs2_ip2v_lookup(ip);
-	if (inode) {
-		struct address_space *mapping = inode->i_mapping;
-		int error = 0;
+	mapping = inode->i_mapping;
 
-		if (flags & DIO_START)
-			filemap_fdatawrite(mapping);
-		if (!error && (flags & DIO_WAIT))
-			error = filemap_fdatawait(mapping);
+	if (flags & DIO_START)
+		filemap_fdatawrite(mapping);
+	if (!error && (flags & DIO_WAIT))
+		error = filemap_fdatawait(mapping);
 
-		/* Put back any errors cleared by filemap_fdatawait()
-		   so they can be caught by someone who can pass them
-		   up to user space. */
+	/* Put back any errors cleared by filemap_fdatawait()
+	   so they can be caught by someone who can pass them
+	   up to user space. */
 
-		if (error == -ENOSPC)
-			set_bit(AS_ENOSPC, &mapping->flags);
-		else if (error)
-			set_bit(AS_EIO, &mapping->flags);
+	if (error == -ENOSPC)
+		set_bit(AS_ENOSPC, &mapping->flags);
+	else if (error)
+		set_bit(AS_EIO, &mapping->flags);
 
-		iput(inode);
-	}
 }
 
 /**
@@ -138,8 +126,8 @@
 int gfs2_unstuffer_page(struct gfs2_inode *ip, struct buffer_head *dibh,
 			uint64_t block, void *private)
 {
-	struct gfs2_sbd *sdp = ip->i_sbd;
-	struct inode *inode = ip->i_vnode;
+	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
+	struct inode *inode = &ip->i_inode;
 	struct page *page = (struct page *)private;
 	struct buffer_head *bh;
 	int release = 0;
@@ -193,8 +181,8 @@
 int gfs2_block_truncate_page(struct address_space *mapping)
 {
 	struct inode *inode = mapping->host;
-	struct gfs2_inode *ip = inode->u.generic_ip;
-	struct gfs2_sbd *sdp = ip->i_sbd;
+	struct gfs2_inode *ip = GFS2_I(inode);
+	struct gfs2_sbd *sdp = GFS2_SB(inode);
 	loff_t from = inode->i_size;
 	unsigned long index = from >> PAGE_CACHE_SHIFT;
 	unsigned offset = from & (PAGE_CACHE_SIZE-1);
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
index f752b01..d3cd517 100644
--- a/fs/gfs2/quota.c
+++ b/fs/gfs2/quota.c
@@ -248,7 +248,7 @@
 static int bh_get(struct gfs2_quota_data *qd)
 {
 	struct gfs2_sbd *sdp = qd->qd_gl->gl_sbd;
-	struct gfs2_inode *ip = sdp->sd_qc_inode->u.generic_ip;
+	struct gfs2_inode *ip = GFS2_I(sdp->sd_qc_inode);
 	unsigned int block, offset;
 	uint64_t dblock;
 	int new = 0;
@@ -266,7 +266,7 @@
 	block = qd->qd_slot / sdp->sd_qc_per_block;
 	offset = qd->qd_slot % sdp->sd_qc_per_block;;
 
-	error = gfs2_block_map(ip->i_vnode, block, &new, &dblock, &boundary);
+	error = gfs2_block_map(&ip->i_inode, block, &new, &dblock, &boundary);
 	if (error)
 		goto fail;
 	error = gfs2_meta_read(ip->i_gl, dblock, DIO_START | DIO_WAIT, &bh);
@@ -444,7 +444,7 @@
 
 int gfs2_quota_hold(struct gfs2_inode *ip, uint32_t uid, uint32_t gid)
 {
-	struct gfs2_sbd *sdp = ip->i_sbd;
+	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
 	struct gfs2_alloc *al = &ip->i_alloc;
 	struct gfs2_quota_data **qd = al->al_qd;
 	int error;
@@ -493,7 +493,7 @@
 
 void gfs2_quota_unhold(struct gfs2_inode *ip)
 {
-	struct gfs2_sbd *sdp = ip->i_sbd;
+	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
 	struct gfs2_alloc *al = &ip->i_alloc;
 	unsigned int x;
 
@@ -531,7 +531,7 @@
 static void do_qc(struct gfs2_quota_data *qd, int64_t change)
 {
 	struct gfs2_sbd *sdp = qd->qd_gl->gl_sbd;
-	struct gfs2_inode *ip = sdp->sd_qc_inode->u.generic_ip;
+	struct gfs2_inode *ip = GFS2_I(sdp->sd_qc_inode);
 	struct gfs2_quota_change *qc = qd->qd_bh_qc;
 	int64_t x;
 
@@ -578,7 +578,7 @@
 static int gfs2_adjust_quota(struct gfs2_inode *ip, loff_t loc,
 			     int64_t change, struct gfs2_quota_data *qd)
 {
-	struct inode *inode = ip->i_vnode;
+	struct inode *inode = &ip->i_inode;
 	struct address_space *mapping = inode->i_mapping;
 	unsigned long index = loc >> PAGE_CACHE_SHIFT;
 	unsigned offset = loc & (PAGE_CACHE_SHIFT - 1);
@@ -647,7 +647,7 @@
 static int do_sync(unsigned int num_qd, struct gfs2_quota_data **qda)
 {
 	struct gfs2_sbd *sdp = (*qda)->qd_gl->gl_sbd;
-	struct gfs2_inode *ip = sdp->sd_quota_inode->u.generic_ip;
+	struct gfs2_inode *ip = GFS2_I(sdp->sd_quota_inode);
 	unsigned int data_blocks, ind_blocks;
 	struct file_ra_state ra_state;
 	struct gfs2_holder *ghs, i_gh;
@@ -716,7 +716,7 @@
 			goto out_gunlock;
 	}
 
-	file_ra_state_init(&ra_state, ip->i_vnode->i_mapping);
+	file_ra_state_init(&ra_state, ip->i_inode.i_mapping);
 	for (x = 0; x < num_qd; x++) {
 		qd = qda[x];
 		offset = qd2offset(qd);
@@ -758,7 +758,7 @@
 		    struct gfs2_holder *q_gh)
 {
 	struct gfs2_sbd *sdp = qd->qd_gl->gl_sbd;
-	struct gfs2_inode *ip = sdp->sd_quota_inode->u.generic_ip;
+	struct gfs2_inode *ip = GFS2_I(sdp->sd_quota_inode);
 	struct gfs2_holder i_gh;
 	struct gfs2_quota q;
 	char buf[sizeof(struct gfs2_quota)];
@@ -829,7 +829,7 @@
 
 int gfs2_quota_lock(struct gfs2_inode *ip, uint32_t uid, uint32_t gid)
 {
-	struct gfs2_sbd *sdp = ip->i_sbd;
+	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
 	struct gfs2_alloc *al = &ip->i_alloc;
 	unsigned int x;
 	int error = 0;
@@ -958,7 +958,7 @@
 
 int gfs2_quota_check(struct gfs2_inode *ip, uint32_t uid, uint32_t gid)
 {
-	struct gfs2_sbd *sdp = ip->i_sbd;
+	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
 	struct gfs2_alloc *al = &ip->i_alloc;
 	struct gfs2_quota_data *qd;
 	int64_t value;
@@ -1008,7 +1008,7 @@
 	unsigned int x;
 	unsigned int found = 0;
 
-	if (gfs2_assert_warn(ip->i_sbd, change))
+	if (gfs2_assert_warn(GFS2_SB(&ip->i_inode), change))
 		return;
 	if (ip->i_di.di_flags & GFS2_DIF_SYSTEM)
 		return;
@@ -1126,7 +1126,7 @@
 
 int gfs2_quota_init(struct gfs2_sbd *sdp)
 {
-	struct gfs2_inode *ip = sdp->sd_qc_inode->u.generic_ip;
+	struct gfs2_inode *ip = GFS2_I(sdp->sd_qc_inode);
 	unsigned int blocks = ip->i_di.di_size >> sdp->sd_sb.sb_bsize_shift;
 	unsigned int x, slot = 0;
 	unsigned int found = 0;
@@ -1162,7 +1162,7 @@
 
 		if (!extlen) {
 			int new = 0;
-			error = gfs2_extent_map(ip->i_vnode, x, &new, &dblock, &extlen);
+			error = gfs2_extent_map(&ip->i_inode, x, &new, &dblock, &extlen);
 			if (error)
 				goto fail;
 		}
diff --git a/fs/gfs2/recovery.c b/fs/gfs2/recovery.c
index c504ac1..7aabc03 100644
--- a/fs/gfs2/recovery.c
+++ b/fs/gfs2/recovery.c
@@ -32,14 +32,14 @@
 int gfs2_replay_read_block(struct gfs2_jdesc *jd, unsigned int blk,
 			   struct buffer_head **bh)
 {
-	struct gfs2_inode *ip = jd->jd_inode->u.generic_ip;
+	struct gfs2_inode *ip = GFS2_I(jd->jd_inode);
 	struct gfs2_glock *gl = ip->i_gl;
 	int new = 0;
 	uint64_t dblock;
 	uint32_t extlen;
 	int error;
 
-	error = gfs2_extent_map(ip->i_vnode, blk, &new, &dblock, &extlen);
+	error = gfs2_extent_map(&ip->i_inode, blk, &new, &dblock, &extlen);
 	if (error)
 		return error;
 	if (!dblock) {
@@ -190,7 +190,7 @@
 			*blk = 0;
 
 		if (*blk == orig_blk) {
-			gfs2_consist_inode(jd->jd_inode->u.generic_ip);
+			gfs2_consist_inode(GFS2_I(jd->jd_inode));
 			return -EIO;
 		}
 	}
@@ -224,7 +224,7 @@
 			continue;
 
 		if (lh.lh_sequence == head->lh_sequence) {
-			gfs2_consist_inode(jd->jd_inode->u.generic_ip);
+			gfs2_consist_inode(GFS2_I(jd->jd_inode));
 			return -EIO;
 		}
 		if (lh.lh_sequence < head->lh_sequence)
@@ -300,8 +300,7 @@
 static int foreach_descriptor(struct gfs2_jdesc *jd, unsigned int start,
 			      unsigned int end, int pass)
 {
-	struct gfs2_inode *ip = jd->jd_inode->u.generic_ip;
-	struct gfs2_sbd *sdp = ip->i_sbd;
+	struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
 	struct buffer_head *bh;
 	struct gfs2_log_descriptor *ld;
 	int error = 0;
@@ -330,7 +329,7 @@
 				continue;
 			}
 			if (error == 1) {
-				gfs2_consist_inode(jd->jd_inode->u.generic_ip);
+				gfs2_consist_inode(GFS2_I(jd->jd_inode));
 				error = -EIO;
 			}
 			brelse(bh);
@@ -367,8 +366,8 @@
 
 static int clean_journal(struct gfs2_jdesc *jd, struct gfs2_log_header *head)
 {
-	struct gfs2_inode *ip = jd->jd_inode->u.generic_ip;
-	struct gfs2_sbd *sdp = ip->i_sbd;
+	struct gfs2_inode *ip = GFS2_I(jd->jd_inode);
+	struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
 	unsigned int lblock;
 	int new = 0;
 	uint64_t dblock;
@@ -380,7 +379,7 @@
 
 	lblock = head->lh_blkno;
 	gfs2_replay_incr_blk(sdp, &lblock);
-	error = gfs2_block_map(ip->i_vnode, lblock, &new, &dblock, &boundary);
+	error = gfs2_block_map(&ip->i_inode, lblock, &new, &dblock, &boundary);
 	if (error)
 		return error;
 	if (!dblock) {
@@ -426,8 +425,8 @@
 
 int gfs2_recover_journal(struct gfs2_jdesc *jd)
 {
-	struct gfs2_inode *ip = jd->jd_inode->u.generic_ip;
-	struct gfs2_sbd *sdp = ip->i_sbd;
+	struct gfs2_inode *ip = GFS2_I(jd->jd_inode);
+	struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
 	struct gfs2_log_header head;
 	struct gfs2_holder j_gh, ji_gh, t_gh;
 	unsigned long t;
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index 691e6f3..75df79e 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -34,17 +34,19 @@
 /*
  * These routines are used by the resource group routines (rgrp.c)
  * to keep track of block allocation.  Each block is represented by two
- * bits.  One bit indicates whether or not the block is used.  (1=used,
- * 0=free)  The other bit indicates whether or not the block contains a
- * dinode or not.  (1=dinode, 0=not-dinode) So, each byte represents
- * GFS2_NBBY (i.e. 4) blocks.
+ * bits.  So, each byte represents GFS2_NBBY (i.e. 4) blocks.
+ *
+ * 0 = Free
+ * 1 = Used (not metadata)
+ * 2 = Unlinked (still in use) inode
+ * 3 = Used (metadata)
  */
 
 static const char valid_change[16] = {
 	        /* current */
-	/* n */ 0, 1, 0, 1,
+	/* n */ 0, 1, 1, 1,
 	/* e */ 1, 0, 0, 0,
-	/* w */ 0, 0, 0, 0,
+	/* w */ 0, 0, 0, 1,
 	        1, 0, 0, 0
 };
 
@@ -228,26 +230,27 @@
 	tmp = rgd->rd_ri.ri_data -
 		rgd->rd_rg.rg_free -
 		rgd->rd_rg.rg_dinodes;
-	if (count[1] != tmp) {
+	if (count[1] + count[2] != tmp) {
 		if (gfs2_consist_rgrpd(rgd))
 			fs_err(sdp, "used data mismatch:  %u != %u\n",
 			       count[1], tmp);
 		return;
 	}
 
-	if (count[2]) {
-		if (gfs2_consist_rgrpd(rgd))
-			fs_err(sdp, "free metadata mismatch:  %u != 0\n",
-			       count[2]);
-		return;
-	}
-
 	if (count[3] != rgd->rd_rg.rg_dinodes) {
 		if (gfs2_consist_rgrpd(rgd))
 			fs_err(sdp, "used metadata mismatch:  %u != %u\n",
 			       count[3], rgd->rd_rg.rg_dinodes);
 		return;
 	}
+
+	if (count[2] > count[3]) {
+		if (gfs2_consist_rgrpd(rgd))
+			fs_err(sdp, "unlinked inodes > inodes:  %u\n",
+			       count[2]);
+		return;
+	}
+
 }
 
 static inline int rgrp_contains_block(struct gfs2_rindex *ri, uint64_t block)
@@ -368,6 +371,9 @@
 	uint32_t bytes_left, bytes;
 	int x;
 
+	if (!length)
+		return -EINVAL;
+
 	rgd->rd_bits = kcalloc(length, sizeof(struct gfs2_bitmap), GFP_KERNEL);
 	if (!rgd->rd_bits)
 		return -ENOMEM;
@@ -433,14 +439,16 @@
 
 static int gfs2_ri_update(struct gfs2_inode *ip)
 {
-	struct gfs2_sbd *sdp = ip->i_sbd;
-	struct inode *inode = ip->i_vnode;
+	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;
 	uint64_t junk = ip->i_di.di_size;
 	int error;
 
+	printk(KERN_INFO "gfs2_ri_update inode=%p\n", inode);
+
 	if (do_div(junk, sizeof(struct gfs2_rindex))) {
 		gfs2_consist_inode(ip);
 		return -EIO;
@@ -448,9 +456,12 @@
 
 	clear_rgrpdi(sdp);
 
+	printk(KERN_INFO "rgrps cleared\n");
+
 	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);
+		printk(KERN_INFO "reading rgrp %d\n", sdp->sd_rgrps);
 		error = gfs2_internal_read(ip, &ra_state, buf, &pos,
 					    sizeof(struct gfs2_rindex));
 		if (!error)
@@ -474,13 +485,15 @@
 		list_add_tail(&rgd->rd_list_mru, &sdp->sd_rindex_mru_list);
 
 		gfs2_rindex_in(&rgd->rd_ri, buf);
-
+		printk(KERN_INFO "compute bitstructs\n");
 		error = compute_bitstructs(rgd);
 		if (error)
 			goto fail;
 
+		printk(KERN_INFO "gfs2_glock_get\n");
 		error = gfs2_glock_get(sdp, rgd->rd_ri.ri_addr,
 				       &gfs2_rgrp_glops, CREATE, &rgd->rd_gl);
+		printk(KERN_INFO "gfs2_glock_got one\n");
 		if (error)
 			goto fail;
 
@@ -488,13 +501,14 @@
 		rgd->rd_rg_vn = rgd->rd_gl->gl_vn - 1;
 	}
 
+	printk(KERN_INFO "ok, finished\n");
 	sdp->sd_rindex_vn = ip->i_gl->gl_vn;
-
 	return 0;
 
- fail:
+fail:
+	printk(KERN_INFO "fail\n");
 	clear_rgrpdi(sdp);
-
+	printk(KERN_INFO "cleared rgrps\n");
 	return error;
 }
 
@@ -518,7 +532,7 @@
 
 int gfs2_rindex_hold(struct gfs2_sbd *sdp, struct gfs2_holder *ri_gh)
 {
-	struct gfs2_inode *ip = sdp->sd_rindex->u.generic_ip;
+	struct gfs2_inode *ip = GFS2_I(sdp->sd_rindex);
 	struct gfs2_glock *gl = ip->i_gl;
 	int error;
 
@@ -583,8 +597,7 @@
 		error = gfs2_meta_reread(sdp, bi->bi_bh, DIO_WAIT);
 		if (error)
 			goto fail;
-		if (gfs2_metatype_check(sdp, bi->bi_bh,
-					(y) ? GFS2_METATYPE_RB :
+		if (gfs2_metatype_check(sdp, bi->bi_bh, y ? GFS2_METATYPE_RB :
 					      GFS2_METATYPE_RG)) {
 			error = -EIO;
 			goto fail;
@@ -605,7 +618,7 @@
 
 	return 0;
 
- fail:
+fail:
 	while (x--) {
 		bi = rgd->rd_bits + x;
 		brelse(bi->bi_bh);
@@ -667,8 +680,7 @@
 		if (!bi->bi_clone)
 			continue;
 		memcpy(bi->bi_clone + bi->bi_offset,
-		       bi->bi_bh->b_data + bi->bi_offset,
-		       bi->bi_len);
+		       bi->bi_bh->b_data + bi->bi_offset, bi->bi_len);
 	}
 
 	spin_lock(&sdp->sd_rindex_spin);
@@ -757,13 +769,11 @@
 			goto out;
 	}
 
- first:
+first:
 	rgd = list_entry(sdp->sd_rindex_recent_list.next, struct gfs2_rgrpd,
 			 rd_recent);
-
- out:
+out:
 	spin_unlock(&sdp->sd_rindex_spin);
-
 	return rgd;
 }
 
@@ -805,9 +815,8 @@
 	if (!list_empty(head))
 		rgd = list_entry(head->next, struct gfs2_rgrpd, rd_recent);
 
- out:
+out:
 	spin_unlock(&sdp->sd_rindex_spin);
-
 	return rgd;
 }
 
@@ -835,7 +844,7 @@
 	}
 	list_add_tail(&new_rgd->rd_recent, &sdp->sd_rindex_recent_list);
 
- out:
+out:
 	spin_unlock(&sdp->sd_rindex_spin);
 }
 
@@ -898,7 +907,7 @@
 
 static int get_local_rgrp(struct gfs2_inode *ip)
 {
-	struct gfs2_sbd *sdp = ip->i_sbd;
+	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
 	struct gfs2_rgrpd *rgd, *begin = NULL;
 	struct gfs2_alloc *al = &ip->i_alloc;
 	int flags = LM_FLAG_TRY;
@@ -965,7 +974,7 @@
 		}
 	}
 
- out:
+out:
 	ip->i_last_rg_alloc = rgd->rd_ri.ri_addr;
 
 	if (begin) {
@@ -988,7 +997,7 @@
 
 int gfs2_inplace_reserve_i(struct gfs2_inode *ip, char *file, unsigned int line)
 {
-	struct gfs2_sbd *sdp = ip->i_sbd;
+	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
 	struct gfs2_alloc *al = &ip->i_alloc;
 	int error;
 
@@ -1020,7 +1029,7 @@
 
 void gfs2_inplace_release(struct gfs2_inode *ip)
 {
-	struct gfs2_sbd *sdp = ip->i_sbd;
+	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
 	struct gfs2_alloc *al = &ip->i_alloc;
 
 	if (gfs2_assert_warn(sdp, al->al_alloced <= al->al_requested) == -1)
@@ -1061,8 +1070,7 @@
 	gfs2_assert(rgd->rd_sbd, buf < length);
 	buf_block = rgrp_block - bi->bi_start * GFS2_NBBY;
 
-	type = gfs2_testbit(rgd,
-			   bi->bi_bh->b_data + bi->bi_offset,
+	type = gfs2_testbit(rgd, bi->bi_bh->b_data + bi->bi_offset,
 			   bi->bi_len, buf_block);
 
 	return type;
@@ -1210,7 +1218,7 @@
 
 uint64_t gfs2_alloc_data(struct gfs2_inode *ip)
 {
-	struct gfs2_sbd *sdp = ip->i_sbd;
+	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
 	struct gfs2_alloc *al = &ip->i_alloc;
 	struct gfs2_rgrpd *rgd = al->al_rgd;
 	uint32_t goal, blk;
@@ -1254,7 +1262,7 @@
 
 uint64_t gfs2_alloc_meta(struct gfs2_inode *ip)
 {
-	struct gfs2_sbd *sdp = ip->i_sbd;
+	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
 	struct gfs2_alloc *al = &ip->i_alloc;
 	struct gfs2_rgrpd *rgd = al->al_rgd;
 	uint32_t goal, blk;
@@ -1299,7 +1307,7 @@
 
 uint64_t gfs2_alloc_di(struct gfs2_inode *dip)
 {
-	struct gfs2_sbd *sdp = dip->i_sbd;
+	struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
 	struct gfs2_alloc *al = &dip->i_alloc;
 	struct gfs2_rgrpd *rgd = al->al_rgd;
 	uint32_t blk;
@@ -1341,7 +1349,7 @@
 
 void gfs2_free_data(struct gfs2_inode *ip, uint64_t bstart, uint32_t blen)
 {
-	struct gfs2_sbd *sdp = ip->i_sbd;
+	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
 	struct gfs2_rgrpd *rgd;
 
 	rgd = rgblk_free(sdp, bstart, blen, GFS2_BLKST_FREE);
@@ -1370,7 +1378,7 @@
 
 void gfs2_free_meta(struct gfs2_inode *ip, uint64_t bstart, uint32_t blen)
 {
-	struct gfs2_sbd *sdp = ip->i_sbd;
+	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
 	struct gfs2_rgrpd *rgd;
 
 	rgd = rgblk_free(sdp, bstart, blen, GFS2_BLKST_FREE);
@@ -1385,11 +1393,25 @@
 	gfs2_trans_add_rg(rgd);
 
 	gfs2_statfs_change(sdp, 0, +blen, 0);
-	gfs2_quota_change(ip, -(int64_t)blen,
-			 ip->i_di.di_uid, ip->i_di.di_gid);
+	gfs2_quota_change(ip, -(int64_t)blen, ip->i_di.di_uid, ip->i_di.di_gid);
 	gfs2_meta_wipe(ip, bstart, blen);
 }
 
+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;
+
+	rgd = rgblk_free(sdp, blkno, 1, GFS2_BLKST_UNLINKED);
+	if (!rgd)
+		return;
+	gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1);
+	gfs2_rgrp_out(&rgd->rd_rg, rgd->rd_bits[0].bi_bh->b_data);
+	gfs2_trans_add_rg(rgd);
+}
+
 void gfs2_free_uninit_di(struct gfs2_rgrpd *rgd, uint64_t blkno)
 {
 	struct gfs2_sbd *sdp = rgd->rd_sbd;
@@ -1412,12 +1434,6 @@
 	gfs2_trans_add_rg(rgd);
 }
 
-/**
- * gfs2_free_uninit_di - free a dinode block
- * @rgd: the resource group that contains the dinode
- * @ip: the inode
- *
- */
 
 void gfs2_free_di(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip)
 {
diff --git a/fs/gfs2/rgrp.h b/fs/gfs2/rgrp.h
index d2db371..e86a532 100644
--- a/fs/gfs2/rgrp.h
+++ b/fs/gfs2/rgrp.h
@@ -45,6 +45,7 @@
 void gfs2_free_meta(struct gfs2_inode *ip, uint64_t bstart, uint32_t blen);
 void gfs2_free_uninit_di(struct gfs2_rgrpd *rgd, uint64_t blkno);
 void gfs2_free_di(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip);
+void gfs2_unlink_di(struct inode *inode);
 
 struct gfs2_rgrp_list {
 	unsigned int rl_rgrps;
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
index a943a50..f2d2876 100644
--- a/fs/gfs2/super.c
+++ b/fs/gfs2/super.c
@@ -31,7 +31,6 @@
 #include "rgrp.h"
 #include "super.h"
 #include "trans.h"
-#include "unlinked.h"
 #include "util.h"
 
 /**
@@ -55,7 +54,6 @@
 	gt->gt_recoverd_secs = 60;
 	gt->gt_logd_secs = 1;
 	gt->gt_quotad_secs = 5;
-	gt->gt_inoded_secs = 15;
 	gt->gt_quota_simul_sync = 64;
 	gt->gt_quota_warn_period = 10;
 	gt->gt_quota_scale_num = 1;
@@ -202,9 +200,6 @@
 	sdp->sd_hash_bsize = sdp->sd_sb.sb_bsize / 2;
 	sdp->sd_hash_bsize_shift = sdp->sd_sb.sb_bsize_shift - 1;
 	sdp->sd_hash_ptrs = sdp->sd_hash_bsize / sizeof(uint64_t);
-	sdp->sd_ut_per_block = (sdp->sd_sb.sb_bsize -
-				sizeof(struct gfs2_meta_header)) /
-			       sizeof(struct gfs2_unlinked_tag);
 	sdp->sd_qc_per_block = (sdp->sd_sb.sb_bsize -
 				sizeof(struct gfs2_meta_header)) /
 			       sizeof(struct gfs2_quota_change);
@@ -277,7 +272,7 @@
 
 int gfs2_jindex_hold(struct gfs2_sbd *sdp, struct gfs2_holder *ji_gh)
 {
-	struct gfs2_inode *dip = sdp->sd_jindex->u.generic_ip;
+	struct gfs2_inode *dip = GFS2_I(sdp->sd_jindex);
 	struct qstr name;
 	char buf[20];
 	struct gfs2_jdesc *jd;
@@ -296,8 +291,7 @@
 		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_search(sdp->sd_jindex, &name, NULL, NULL);
 		if (error == -ENOENT) {
 			error = 0;
 			break;
@@ -423,22 +417,19 @@
 
 int gfs2_jdesc_check(struct gfs2_jdesc *jd)
 {
-	struct gfs2_inode *ip = jd->jd_inode->u.generic_ip;
-	struct gfs2_sbd *sdp = ip->i_sbd;
+	struct gfs2_inode *ip = GFS2_I(jd->jd_inode);
+	struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
 	int ar;
 	int error;
 
-	if (ip->i_di.di_size < (8 << 20) ||
-	    ip->i_di.di_size > (1 << 30) ||
+	if (ip->i_di.di_size < (8 << 20) || ip->i_di.di_size > (1 << 30) ||
 	    (ip->i_di.di_size & (sdp->sd_sb.sb_bsize - 1))) {
 		gfs2_consist_inode(ip);
 		return -EIO;
 	}
 	jd->jd_blocks = ip->i_di.di_size >> sdp->sd_sb.sb_bsize_shift;
 
-	error = gfs2_write_alloc_required(ip,
-					  0, ip->i_di.di_size,
-					  &ar);
+	error = gfs2_write_alloc_required(ip, 0, ip->i_di.di_size, &ar);
 	if (!error && ar) {
 		gfs2_consist_inode(ip);
 		error = -EIO;
@@ -456,7 +447,7 @@
 
 int gfs2_make_fs_rw(struct gfs2_sbd *sdp)
 {
-	struct gfs2_inode *ip = sdp->sd_jdesc->jd_inode->u.generic_ip;
+	struct gfs2_inode *ip = GFS2_I(sdp->sd_jdesc->jd_inode);
 	struct gfs2_glock *j_gl = ip->i_gl;
 	struct gfs2_holder t_gh;
 	struct gfs2_log_header head;
@@ -484,9 +475,6 @@
 	sdp->sd_log_sequence = head.lh_sequence + 1;
 	gfs2_log_pointers_init(sdp, head.lh_blkno);
 
-	error = gfs2_unlinked_init(sdp);
-	if (error)
-		goto fail;
 	error = gfs2_quota_init(sdp);
 	if (error)
 		goto fail_unlinked;
@@ -498,7 +486,6 @@
 	return 0;
 
  fail_unlinked:
-	gfs2_unlinked_cleanup(sdp);
 
  fail:
 	t_gh.gh_flags |= GL_NOCACHE;
@@ -519,7 +506,6 @@
 	struct gfs2_holder t_gh;
 	int error;
 
-	gfs2_unlinked_dealloc(sdp);
 	gfs2_quota_sync(sdp);
 	gfs2_statfs_sync(sdp);
 
@@ -537,7 +523,6 @@
 	if (t_gh.gh_gl)
 		gfs2_glock_dq_uninit(&t_gh);
 
-	gfs2_unlinked_cleanup(sdp);
 	gfs2_quota_cleanup(sdp);
 
 	return error;
@@ -545,9 +530,9 @@
 
 int gfs2_statfs_init(struct gfs2_sbd *sdp)
 {
-	struct gfs2_inode *m_ip = sdp->sd_statfs_inode->u.generic_ip;
+	struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode);
 	struct gfs2_statfs_change *m_sc = &sdp->sd_statfs_master;
-	struct gfs2_inode *l_ip = sdp->sd_sc_inode->u.generic_ip;
+	struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode);
 	struct gfs2_statfs_change *l_sc = &sdp->sd_statfs_local;
 	struct buffer_head *m_bh, *l_bh;
 	struct gfs2_holder gh;
@@ -594,7 +579,7 @@
 void gfs2_statfs_change(struct gfs2_sbd *sdp, int64_t total, int64_t free,
 			int64_t dinodes)
 {
-	struct gfs2_inode *l_ip = sdp->sd_sc_inode->u.generic_ip;
+	struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode);
 	struct gfs2_statfs_change *l_sc = &sdp->sd_statfs_local;
 	struct buffer_head *l_bh;
 	int error;
@@ -620,8 +605,8 @@
 
 int gfs2_statfs_sync(struct gfs2_sbd *sdp)
 {
-	struct gfs2_inode *m_ip = sdp->sd_statfs_inode->u.generic_ip;
-	struct gfs2_inode *l_ip = sdp->sd_sc_inode->u.generic_ip;
+	struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode);
+	struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode);
 	struct gfs2_statfs_change *m_sc = &sdp->sd_statfs_master;
 	struct gfs2_statfs_change *l_sc = &sdp->sd_statfs_local;
 	struct gfs2_holder gh;
@@ -852,10 +837,8 @@
 			error = -ENOMEM;
 			goto out;
 		}
-		ip = jd->jd_inode->u.generic_ip;
-		error = gfs2_glock_nq_init(ip->i_gl,
-					   LM_ST_SHARED, 0,
-					   &lfcc->gh);
+		ip = GFS2_I(jd->jd_inode);
+		error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, 0, &lfcc->gh);
 		if (error) {
 			kfree(lfcc);
 			goto out;
diff --git a/fs/gfs2/sys.c b/fs/gfs2/sys.c
index d32a2c5..3c4cb45 100644
--- a/fs/gfs2/sys.c
+++ b/fs/gfs2/sys.c
@@ -453,7 +453,6 @@
 TUNE_ATTR_DAEMON(recoverd_secs, recoverd_process);
 TUNE_ATTR_DAEMON(logd_secs, logd_process);
 TUNE_ATTR_DAEMON(quotad_secs, quotad_process);
-TUNE_ATTR_DAEMON(inoded_secs, inoded_process);
 TUNE_ATTR_3(quota_scale, quota_scale_show, quota_scale_store);
 
 static struct attribute *tune_attrs[] = {
@@ -485,7 +484,6 @@
 	&tune_attr_recoverd_secs.attr,
 	&tune_attr_logd_secs.attr,
 	&tune_attr_quotad_secs.attr,
-	&tune_attr_inoded_secs.attr,
 	&tune_attr_quota_scale.attr,
 	&tune_attr_new_files_jdata.attr,
 	&tune_attr_new_files_directio.attr,
diff --git a/fs/gfs2/trans.h b/fs/gfs2/trans.h
index 60ef163..fbef3f5 100644
--- a/fs/gfs2/trans.h
+++ b/fs/gfs2/trans.h
@@ -17,7 +17,6 @@
 #define RES_LEAF	1
 #define RES_RG_BIT	2
 #define RES_EATTR	1
-#define RES_UNLINKED	1
 #define RES_STATFS	1
 #define RES_QUOTA	2
 
diff --git a/fs/gfs2/unlinked.c b/fs/gfs2/unlinked.c
deleted file mode 100644
index b92d730..0000000
--- a/fs/gfs2/unlinked.c
+++ /dev/null
@@ -1,459 +0,0 @@
-/*
- * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
- * Copyright (C) 2004-2006 Red Hat, Inc.  All rights reserved.
- *
- * This copyrighted material is made available to anyone wishing to use,
- * modify, copy, or redistribute it subject to the terms and conditions
- * of the GNU General Public License v.2.
- */
-
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/completion.h>
-#include <linux/buffer_head.h>
-#include <linux/kthread.h>
-#include <linux/gfs2_ondisk.h>
-
-#include "gfs2.h"
-#include "lm_interface.h"
-#include "incore.h"
-#include "bmap.h"
-#include "inode.h"
-#include "meta_io.h"
-#include "trans.h"
-#include "unlinked.h"
-#include "util.h"
-
-static int munge_ondisk(struct gfs2_sbd *sdp, unsigned int slot,
-			struct gfs2_unlinked_tag *ut)
-{
-	struct gfs2_inode *ip = sdp->sd_ut_inode->u.generic_ip;
-	unsigned int block, offset;
-	uint64_t dblock;
-	int new = 0;
-	struct buffer_head *bh;
-	int error;
-	int boundary;
-
-	block = slot / sdp->sd_ut_per_block;
-	offset = slot % sdp->sd_ut_per_block;
-
-	error = gfs2_block_map(ip->i_vnode, block, &new, &dblock, &boundary);
-	if (error)
-		return error;
-	error = gfs2_meta_read(ip->i_gl, dblock, DIO_START | DIO_WAIT, &bh);
-	if (error)
-		return error;
-	if (gfs2_metatype_check(sdp, bh, GFS2_METATYPE_UT)) {
-		error = -EIO;
-		goto out;
-	}
-
-	mutex_lock(&sdp->sd_unlinked_mutex);
-	gfs2_trans_add_bh(ip->i_gl, bh, 1);
-	gfs2_unlinked_tag_out(ut, bh->b_data +
-				  sizeof(struct gfs2_meta_header) +
-				  offset * sizeof(struct gfs2_unlinked_tag));
-	mutex_unlock(&sdp->sd_unlinked_mutex);
-
- out:
-	brelse(bh);
-
-	return error;
-}
-
-static void ul_hash(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul)
-{
-	spin_lock(&sdp->sd_unlinked_spin);
-	list_add(&ul->ul_list, &sdp->sd_unlinked_list);
-	gfs2_assert(sdp, ul->ul_count);
-	ul->ul_count++;
-	atomic_inc(&sdp->sd_unlinked_count);
-	spin_unlock(&sdp->sd_unlinked_spin);
-}
-
-static void ul_unhash(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul)
-{
-	spin_lock(&sdp->sd_unlinked_spin);
-	list_del_init(&ul->ul_list);
-	gfs2_assert(sdp, ul->ul_count > 1);
-	ul->ul_count--;
-	gfs2_assert_warn(sdp, atomic_read(&sdp->sd_unlinked_count) > 0);
-	atomic_dec(&sdp->sd_unlinked_count);
-	spin_unlock(&sdp->sd_unlinked_spin);
-}
-
-static struct gfs2_unlinked *ul_fish(struct gfs2_sbd *sdp)
-{
-	struct list_head *head;
-	struct gfs2_unlinked *ul;
-	int found = 0;
-
-	if (sdp->sd_vfs->s_flags & MS_RDONLY)
-		return NULL;
-
-	spin_lock(&sdp->sd_unlinked_spin);
-
-	head = &sdp->sd_unlinked_list;
-
-	list_for_each_entry(ul, head, ul_list) {
-		if (test_bit(ULF_LOCKED, &ul->ul_flags))
-			continue;
-
-		list_move_tail(&ul->ul_list, head);
-		ul->ul_count++;
-		set_bit(ULF_LOCKED, &ul->ul_flags);
-		found = 1;
-
-		break;
-	}
-
-	if (!found)
-		ul = NULL;
-
-	spin_unlock(&sdp->sd_unlinked_spin);
-
-	return ul;
-}
-
-/**
- * enforce_limit - limit the number of inodes waiting to be deallocated
- * @sdp: the filesystem
- *
- * Returns: errno
- */
-
-static void enforce_limit(struct gfs2_sbd *sdp)
-{
-	unsigned int tries = 0, min = 0;
-	int error;
-
-	if (atomic_read(&sdp->sd_unlinked_count) <
-	    gfs2_tune_get(sdp, gt_ilimit))
-		return;
-
-	tries = gfs2_tune_get(sdp, gt_ilimit_tries);
-	min = gfs2_tune_get(sdp, gt_ilimit_min);
-
-	while (tries--) {
-		struct gfs2_unlinked *ul = ul_fish(sdp);
-		if (!ul)
-			break;
-		error = gfs2_inode_dealloc(sdp, ul);
-		gfs2_unlinked_put(sdp, ul);
-
-		if (!error) {
-			if (!--min)
-				break;
-		} else if (error != 1)
-			break;
-	}
-}
-
-static struct gfs2_unlinked *ul_alloc(struct gfs2_sbd *sdp)
-{
-	struct gfs2_unlinked *ul;
-
-	ul = kzalloc(sizeof(struct gfs2_unlinked), GFP_KERNEL);
-	if (ul) {
-		INIT_LIST_HEAD(&ul->ul_list);
-		ul->ul_count = 1;
-		set_bit(ULF_LOCKED, &ul->ul_flags);
-	}
-
-	return ul;
-}
-
-int gfs2_unlinked_get(struct gfs2_sbd *sdp, struct gfs2_unlinked **ul)
-{
-	unsigned int c, o = 0, b;
-	unsigned char byte = 0;
-
-	enforce_limit(sdp);
-
-	*ul = ul_alloc(sdp);
-	if (!*ul)
-		return -ENOMEM;
-
-	spin_lock(&sdp->sd_unlinked_spin);
-
-	for (c = 0; c < sdp->sd_unlinked_chunks; c++)
-		for (o = 0; o < PAGE_SIZE; o++) {
-			byte = sdp->sd_unlinked_bitmap[c][o];
-			if (byte != 0xFF)
-				goto found;
-		}
-
-	goto fail;
-
-found:
-	for (b = 0; b < 8; b++)
-		if (!(byte & (1 << b)))
-			break;
-	(*ul)->ul_slot = c * (8 * PAGE_SIZE) + o * 8 + b;
-
-	if ((*ul)->ul_slot >= sdp->sd_unlinked_slots)
-		goto fail;
-
-	sdp->sd_unlinked_bitmap[c][o] |= 1 << b;
-
-	spin_unlock(&sdp->sd_unlinked_spin);
-
-	return 0;
-
-fail:
-	spin_unlock(&sdp->sd_unlinked_spin);
-	kfree(*ul);
-	return -ENOSPC;
-}
-
-void gfs2_unlinked_put(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul)
-{
-	gfs2_assert_warn(sdp, test_and_clear_bit(ULF_LOCKED, &ul->ul_flags));
-
-	spin_lock(&sdp->sd_unlinked_spin);
-	gfs2_assert(sdp, ul->ul_count);
-	ul->ul_count--;
-	if (!ul->ul_count) {
-		gfs2_icbit_munge(sdp, sdp->sd_unlinked_bitmap, ul->ul_slot, 0);
-		spin_unlock(&sdp->sd_unlinked_spin);
-		kfree(ul);
-	} else
-		spin_unlock(&sdp->sd_unlinked_spin);
-}
-
-int gfs2_unlinked_ondisk_add(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul)
-{
-	int error;
-
-	gfs2_assert_warn(sdp, test_bit(ULF_LOCKED, &ul->ul_flags));
-	gfs2_assert_warn(sdp, list_empty(&ul->ul_list));
-
-	error = munge_ondisk(sdp, ul->ul_slot, &ul->ul_ut);
-	if (!error)
-		ul_hash(sdp, ul);
-
-	return error;
-}
-
-int gfs2_unlinked_ondisk_munge(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul)
-{
-	int error;
-
-	gfs2_assert_warn(sdp, test_bit(ULF_LOCKED, &ul->ul_flags));
-	gfs2_assert_warn(sdp, !list_empty(&ul->ul_list));
-
-	error = munge_ondisk(sdp, ul->ul_slot, &ul->ul_ut);
-
-	return error;
-}
-
-int gfs2_unlinked_ondisk_rm(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul)
-{
-	struct gfs2_unlinked_tag ut;
-	int error;
-
-	gfs2_assert_warn(sdp, test_bit(ULF_LOCKED, &ul->ul_flags));
-	gfs2_assert_warn(sdp, !list_empty(&ul->ul_list));
-
-	memset(&ut, 0, sizeof(struct gfs2_unlinked_tag));
-
-	error = munge_ondisk(sdp, ul->ul_slot, &ut);
-	if (error)
-		return error;
-
-	ul_unhash(sdp, ul);
-
-	return 0;
-}
-
-/**
- * gfs2_unlinked_dealloc - Go through the list of inodes to be deallocated
- * @sdp: the filesystem
- *
- * Returns: errno
- */
-
-int gfs2_unlinked_dealloc(struct gfs2_sbd *sdp)
-{
-	unsigned int hits, strikes;
-	int error;
-
-	for (;;) {
-		hits = 0;
-		strikes = 0;
-
-		for (;;) {
-			struct gfs2_unlinked *ul = ul_fish(sdp);
-			if (!ul)
-				return 0;
-			error = gfs2_inode_dealloc(sdp, ul);
-			gfs2_unlinked_put(sdp, ul);
-
-			if (!error) {
-				hits++;
-				if (strikes)
-					strikes--;
-			} else if (error == 1) {
-				strikes++;
-				if (strikes >=
-				    atomic_read(&sdp->sd_unlinked_count)) {
-					error = 0;
-					break;
-				}
-			} else
-				return error;
-		}
-
-		if (!hits || kthread_should_stop())
-			break;
-
-		cond_resched();
-	}
-
-	return 0;
-}
-
-int gfs2_unlinked_init(struct gfs2_sbd *sdp)
-{
-	struct gfs2_inode *ip = sdp->sd_ut_inode->u.generic_ip;
-	unsigned int blocks = ip->i_di.di_size >> sdp->sd_sb.sb_bsize_shift;
-	unsigned int x, slot = 0;
-	unsigned int found = 0;
-	uint64_t dblock;
-	uint32_t extlen = 0;
-	int error;
-
-	if (!ip->i_di.di_size ||
-	    ip->i_di.di_size > (64 << 20) ||
-	    ip->i_di.di_size & (sdp->sd_sb.sb_bsize - 1)) {
-		gfs2_consist_inode(ip);
-		return -EIO;		
-	}
-	sdp->sd_unlinked_slots = blocks * sdp->sd_ut_per_block;
-	sdp->sd_unlinked_chunks = DIV_ROUND_UP(sdp->sd_unlinked_slots,
-					       8 * PAGE_SIZE);
-
-	error = -ENOMEM;
-
-	sdp->sd_unlinked_bitmap = kcalloc(sdp->sd_unlinked_chunks,
-					  sizeof(unsigned char *),
-					  GFP_KERNEL);
-	if (!sdp->sd_unlinked_bitmap)
-		return error;
-
-	for (x = 0; x < sdp->sd_unlinked_chunks; x++) {
-		sdp->sd_unlinked_bitmap[x] = kzalloc(PAGE_SIZE, GFP_KERNEL);
-		if (!sdp->sd_unlinked_bitmap[x])
-			goto fail;
-	}
-
-	for (x = 0; x < blocks; x++) {
-		struct buffer_head *bh;
-		unsigned int y;
-
-		if (!extlen) {
-			int new = 0;
-			error = gfs2_extent_map(ip->i_vnode, x, &new, &dblock, &extlen);
-			if (error)
-				goto fail;
-		}
-		gfs2_meta_ra(ip->i_gl, dblock, extlen);
-		error = gfs2_meta_read(ip->i_gl, dblock, DIO_START | DIO_WAIT,
-				       &bh);
-		if (error)
-			goto fail;
-		error = -EIO;
-		if (gfs2_metatype_check(sdp, bh, GFS2_METATYPE_UT)) {
-			brelse(bh);
-			goto fail;
-		}
-
-		for (y = 0;
-		     y < sdp->sd_ut_per_block && slot < sdp->sd_unlinked_slots;
-		     y++, slot++) {
-			struct gfs2_unlinked_tag ut;
-			struct gfs2_unlinked *ul;
-
-			gfs2_unlinked_tag_in(&ut, bh->b_data +
-					  sizeof(struct gfs2_meta_header) +
-					  y * sizeof(struct gfs2_unlinked_tag));
-			if (!ut.ut_inum.no_addr)
-				continue;
-
-			error = -ENOMEM;
-			ul = ul_alloc(sdp);
-			if (!ul) {
-				brelse(bh);
-				goto fail;
-			}
-			ul->ul_ut = ut;
-			ul->ul_slot = slot;
-
-			spin_lock(&sdp->sd_unlinked_spin);
-			gfs2_icbit_munge(sdp, sdp->sd_unlinked_bitmap, slot, 1);
-			spin_unlock(&sdp->sd_unlinked_spin);
-			ul_hash(sdp, ul);
-
-			gfs2_unlinked_put(sdp, ul);
-			found++;
-		}
-
-		brelse(bh);
-		dblock++;
-		extlen--;
-	}
-
-	if (found)
-		fs_info(sdp, "found %u unlinked inodes\n", found);
-
-	return 0;
-
-fail:
-	gfs2_unlinked_cleanup(sdp);
-	return error;
-}
-
-/**
- * gfs2_unlinked_cleanup - get rid of any extra struct gfs2_unlinked structures
- * @sdp: the filesystem
- *
- */
-
-void gfs2_unlinked_cleanup(struct gfs2_sbd *sdp)
-{
-	struct list_head *head = &sdp->sd_unlinked_list;
-	struct gfs2_unlinked *ul;
-	unsigned int x;
-
-	spin_lock(&sdp->sd_unlinked_spin);
-	while (!list_empty(head)) {
-		ul = list_entry(head->next, struct gfs2_unlinked, ul_list);
-
-		if (ul->ul_count > 1) {
-			list_move_tail(&ul->ul_list, head);
-			spin_unlock(&sdp->sd_unlinked_spin);
-			schedule();
-			spin_lock(&sdp->sd_unlinked_spin);
-			continue;
-		}
-
-		list_del_init(&ul->ul_list);
-		atomic_dec(&sdp->sd_unlinked_count);
-
-		gfs2_assert_warn(sdp, ul->ul_count == 1);
-		gfs2_assert_warn(sdp, !test_bit(ULF_LOCKED, &ul->ul_flags));
-		kfree(ul);
-	}
-	spin_unlock(&sdp->sd_unlinked_spin);
-
-	gfs2_assert_warn(sdp, !atomic_read(&sdp->sd_unlinked_count));
-
-	if (sdp->sd_unlinked_bitmap) {
-		for (x = 0; x < sdp->sd_unlinked_chunks; x++)
-			kfree(sdp->sd_unlinked_bitmap[x]);
-		kfree(sdp->sd_unlinked_bitmap);
-	}
-}
-
diff --git a/fs/gfs2/unlinked.h b/fs/gfs2/unlinked.h
deleted file mode 100644
index 159cf5f..0000000
--- a/fs/gfs2/unlinked.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
- * Copyright (C) 2004-2006 Red Hat, Inc.  All rights reserved.
- *
- * This copyrighted material is made available to anyone wishing to use,
- * modify, copy, or redistribute it subject to the terms and conditions
- * of the GNU General Public License v.2.
- */
-
-#ifndef __UNLINKED_DOT_H__
-#define __UNLINKED_DOT_H__
-
-int gfs2_unlinked_get(struct gfs2_sbd *sdp, struct gfs2_unlinked **ul);
-void gfs2_unlinked_put(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul);
-
-int gfs2_unlinked_ondisk_add(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul);
-int gfs2_unlinked_ondisk_munge(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul);
-int gfs2_unlinked_ondisk_rm(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul);
-
-int gfs2_unlinked_dealloc(struct gfs2_sbd *sdp);
-
-int gfs2_unlinked_init(struct gfs2_sbd *sdp);
-void gfs2_unlinked_cleanup(struct gfs2_sbd *sdp);
-
-#endif /* __UNLINKED_DOT_H__ */
diff --git a/fs/gfs2/util.c b/fs/gfs2/util.c
index 88974e9..39e67b1 100644
--- a/fs/gfs2/util.c
+++ b/fs/gfs2/util.c
@@ -109,7 +109,7 @@
 int gfs2_consist_inode_i(struct gfs2_inode *ip, int cluster_wide,
 			 const char *function, char *file, unsigned int line)
 {
-	struct gfs2_sbd *sdp = ip->i_sbd;
+	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
 	int rv;
 	rv = gfs2_lm_withdraw(sdp,
 		"GFS2: fsid=%s: fatal: filesystem consistency error\n"