[GFS2] Readpages support

This adds readpages support (and also corrects a small bug in
the readpage error path at the same time). Hopefully this will
improve performance by allowing GFS to submit larger lumps of
I/O at a time.

In order to simplify the setting of BH_Boundary, it currently gets
set when we hit the end of a indirect pointer block. There is
always a boundary at this point with the current allocation code.
It doesn't get all the boundaries right though, so there is still
room for improvement in this.

See comments in fs/gfs2/ops_address.c for further information about
readpages with GFS2.

Signed-off-by: Steven Whitehouse
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c
index cfe1a42..474b9a1 100644
--- a/fs/gfs2/bmap.c
+++ b/fs/gfs2/bmap.c
@@ -314,13 +314,17 @@
  * metadata tree.
  */
 
-static inline uint64_t *metapointer(struct buffer_head *bh,
-				    unsigned int height, struct metapath *mp)
+static inline u64 *metapointer(struct buffer_head *bh, int *boundary,
+			       unsigned int height, const struct metapath *mp)
 {
 	unsigned int head_size = (height > 0) ?
 		sizeof(struct gfs2_meta_header) : sizeof(struct gfs2_dinode);
-
-	return ((uint64_t *)(bh->b_data + head_size)) + mp->mp_list[height];
+	u64 *ptr;
+	*boundary = 0;
+	ptr = ((u64 *)(bh->b_data + head_size)) + mp->mp_list[height];
+	if (ptr + 1 == (u64*)(bh->b_data + bh->b_size))
+		*boundary = 1;
+	return ptr;
 }
 
 /**
@@ -339,24 +343,24 @@
  *
  */
 
-static void lookup_block(struct gfs2_inode *ip, struct buffer_head *bh,
-			 unsigned int height, struct metapath *mp, int create,
-			 int *new, uint64_t *block)
+static int lookup_block(struct gfs2_inode *ip, struct buffer_head *bh,
+			unsigned int height, struct metapath *mp, int create,
+			int *new, uint64_t *block)
 {
-	uint64_t *ptr = metapointer(bh, height, mp);
+	int boundary;
+	uint64_t *ptr = metapointer(bh, &boundary, height, mp);
 
 	if (*ptr) {
 		*block = be64_to_cpu(*ptr);
-		return;
+		return boundary;
 	}
 
 	*block = 0;
 
 	if (!create)
-		return;
+		return 0;
 
-	if (height == ip->i_di.di_height - 1 &&
-	    !gfs2_is_dir(ip))
+	if (height == ip->i_di.di_height - 1 && !gfs2_is_dir(ip))
 		*block = gfs2_alloc_data(ip);
 	else
 		*block = gfs2_alloc_meta(ip);
@@ -367,15 +371,16 @@
 	ip->i_di.di_blocks++;
 
 	*new = 1;
+	return 0;
 }
 
 /**
- * gfs2_block_map - Map a block from an inode to a disk block
- * @ip: The GFS2 inode
+ * gfs2_block_pointers - Map a block from an inode to a disk block
+ * @inode: The inode
  * @lblock: The logical block number
  * @new: Value/Result argument (1 = may create/did create new blocks)
- * @dblock: the disk block number of the start of an extent
- * @extlen: the size of the extent
+ * @boundary: gets set if we've hit a block boundary
+ * @mp: metapath to use
  *
  * Find the block number on the current device which corresponds to an
  * inode's block. If the block had to be created, "new" will be set.
@@ -383,12 +388,14 @@
  * Returns: errno
  */
 
-int gfs2_block_map(struct gfs2_inode *ip, uint64_t lblock, int *new,
-		   uint64_t *dblock, uint32_t *extlen)
+static struct buffer_head *gfs2_block_pointers(struct inode *inode, u64 lblock,
+					       int *new, u64 *dblock,
+					       int *boundary,
+					       struct metapath *mp)
 {
+	struct gfs2_inode *ip = inode->u.generic_ip;
 	struct gfs2_sbd *sdp = ip->i_sbd;
 	struct buffer_head *bh;
-	struct metapath mp;
 	int create = *new;
 	unsigned int bsize;
 	unsigned int height;
@@ -398,13 +405,6 @@
 
 	*new = 0;
 	*dblock = 0;
-	if (extlen)
-		*extlen = 0;
-
-	if (create)
-		down_write(&ip->i_rw_mutex);
-	else
-		down_read(&ip->i_rw_mutex);
 
 	if (gfs2_assert_warn(sdp, !gfs2_is_stuffed(ip)))
 		goto out;
@@ -421,7 +421,7 @@
 			goto out;
 	}
 
-	find_metapath(ip, lblock, &mp);
+	find_metapath(ip, lblock, mp);
 	end_of_metadata = ip->i_di.di_height - 1;
 
 	error = gfs2_meta_inode_buffer(ip, &bh);
@@ -429,7 +429,7 @@
 		goto out;
 
 	for (x = 0; x < end_of_metadata; x++) {
-		lookup_block(ip, bh, x, &mp, create, new, dblock);
+		lookup_block(ip, bh, x, mp, create, new, dblock);
 		brelse(bh);
 		if (!*dblock)
 			goto out;
@@ -439,49 +439,95 @@
 			goto out;
 	}
 
-	lookup_block(ip, bh, end_of_metadata, &mp, create, new, dblock);
-
-	if (extlen && *dblock) {
-		*extlen = 1;
-
-		if (!*new) {
-			uint64_t tmp_dblock;
-			int tmp_new;
-			unsigned int nptrs;
-
-			nptrs = (end_of_metadata) ? sdp->sd_inptrs :
-						    sdp->sd_diptrs;
-
-			while (++mp.mp_list[end_of_metadata] < nptrs) {
-				lookup_block(ip, bh, end_of_metadata, &mp,
-					     0, &tmp_new, &tmp_dblock);
-
-				if (*dblock + *extlen != tmp_dblock)
-					break;
-
-				(*extlen)++;
-			}
-		}
-	}
-
-	brelse(bh);
-
+	*boundary = lookup_block(ip, bh, end_of_metadata, mp, create, new, dblock);
 	if (*new) {
-		error = gfs2_meta_inode_buffer(ip, &bh);
+		struct buffer_head *dibh;
+		error = gfs2_meta_inode_buffer(ip, &dibh);
 		if (!error) {
-			gfs2_trans_add_bh(ip->i_gl, bh, 1);
-			gfs2_dinode_out(&ip->i_di, bh->b_data);
-			brelse(bh);
+			gfs2_trans_add_bh(ip->i_gl, dibh, 1);
+			gfs2_dinode_out(&ip->i_di, dibh->b_data);
+			brelse(dibh);
 		}
 	}
+	return bh;
+out:
+	return ERR_PTR(error);
+}
 
- out:
+
+static inline void bmap_lock(struct inode *inode, int create)
+{
+	struct gfs2_inode *ip = inode->u.generic_ip;
+	if (create)
+		down_write(&ip->i_rw_mutex);
+	else
+		down_read(&ip->i_rw_mutex);
+}
+
+static inline void bmap_unlock(struct inode *inode, int create)
+{
+	struct gfs2_inode *ip = inode->u.generic_ip;
 	if (create)
 		up_write(&ip->i_rw_mutex);
 	else
 		up_read(&ip->i_rw_mutex);
+}
 
-	return error;
+int gfs2_block_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, int *boundary)
+{
+	struct metapath mp;
+	struct buffer_head *bh;
+	int create = *new;
+
+	bmap_lock(inode, create);
+	bh = gfs2_block_pointers(inode, lblock, new, dblock, boundary, &mp);
+	bmap_unlock(inode, create);
+	if (!bh)
+		return 0;
+	if (IS_ERR(bh))
+		return PTR_ERR(bh);
+	brelse(bh);
+	return 0;
+}
+
+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 metapath mp;
+	struct buffer_head *bh;
+	int boundary;
+	int create = *new;
+
+	BUG_ON(!extlen);
+	BUG_ON(!dblock);
+	BUG_ON(!new);
+
+	bmap_lock(inode, create);
+	bh = gfs2_block_pointers(inode, lblock, new, dblock, &boundary, &mp);
+	*extlen = 1;
+
+	if (bh && !IS_ERR(bh) && *dblock && !*new) {
+		u64 tmp_dblock;
+		int tmp_new;
+		unsigned int nptrs;
+		unsigned end_of_metadata = ip->i_di.di_height - 1;
+		
+		nptrs = (end_of_metadata) ? sdp->sd_inptrs : sdp->sd_diptrs;
+		while (++mp.mp_list[end_of_metadata] < nptrs) {
+			lookup_block(ip, bh, end_of_metadata, &mp, 0, &tmp_new, &tmp_dblock);
+			if (*dblock + *extlen != tmp_dblock)
+				break;
+			(*extlen)++;
+		}
+	}
+	bmap_unlock(inode, create);
+	if (!bh)
+		return 0;
+	if (IS_ERR(bh))
+		return PTR_ERR(bh);
+	brelse(bh);
+	return 0;
 }
 
 /**
@@ -1053,7 +1099,7 @@
 	}
 
 	for (; lblock < lblock_stop; lblock += extlen) {
-		error = gfs2_block_map(ip, lblock, &new, &dblock, &extlen);
+		error = gfs2_extent_map(ip->i_vnode, lblock, &new, &dblock, &extlen);
 		if (error)
 			return error;
 
diff --git a/fs/gfs2/bmap.h b/fs/gfs2/bmap.h
index 23fb658..bc46c11 100644
--- a/fs/gfs2/bmap.h
+++ b/fs/gfs2/bmap.h
@@ -16,9 +16,8 @@
 int gfs2_unstuff_dinode(struct gfs2_inode *ip, gfs2_unstuffer_t unstuffer,
 			void *private);
 
-int gfs2_block_map(struct gfs2_inode *ip,
-		   uint64_t lblock, int *new,
-		   uint64_t *dblock, uint32_t *extlen);
+int gfs2_block_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, int *boundary);
+int gfs2_extent_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, unsigned *extlen);
 
 int gfs2_truncatei(struct gfs2_inode *ip, uint64_t size);
 int gfs2_truncatei_resume(struct gfs2_inode *ip);
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c
index 0404783..7f8b27e 100644
--- a/fs/gfs2/dir.c
+++ b/fs/gfs2/dir.c
@@ -197,8 +197,8 @@
 
 		if (!extlen) {
 			new = 1;
-			error = gfs2_block_map(ip, lblock, &new, &dblock,
-					       &extlen);
+			error = gfs2_extent_map(ip->i_vnode, lblock, &new,
+						&dblock, &extlen);
 			if (error)
 				goto fail;
 			error = -EIO;
@@ -314,8 +314,8 @@
 
 		if (!extlen) {
 			new = 0;
-			error = gfs2_block_map(ip, lblock, &new, &dblock,
-					       &extlen);
+			error = gfs2_extent_map(ip->i_vnode, lblock, &new,
+						&dblock, &extlen);
 			if (error)
 				goto fail;
 		}
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 4fb8066..9d4ae09 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -2125,7 +2125,7 @@
 		mutex_lock(&sdp->sd_invalidate_inodes_mutex);
 		invalidate_inodes(sdp->sd_vfs);
 		mutex_unlock(&sdp->sd_invalidate_inodes_mutex);
-		yield();
+		msleep(10);
 	}
 }
 
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index 9084d60..0817f6e 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -1606,9 +1606,8 @@
 	curtime = get_seconds();
 	if (curtime - ip->i_di.di_atime >= quantum) {
 		gfs2_glock_dq(gh);
-		gfs2_holder_reinit(LM_ST_EXCLUSIVE,
-				  gh->gh_flags & ~LM_FLAG_ANY,
-				  gh);
+		gfs2_holder_reinit(LM_ST_EXCLUSIVE, gh->gh_flags & ~LM_FLAG_ANY,
+				   gh);
 		error = gfs2_glock_nq(gh);
 		if (error)
 			return error;
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c
index 134fc57..02d31e3 100644
--- a/fs/gfs2/log.c
+++ b/fs/gfs2/log.c
@@ -211,9 +211,9 @@
 	int new = 0;
 	uint64_t dbn;
 	int error;
+	int bdy;
 
-	error = gfs2_block_map(sdp->sd_jdesc->jd_inode->u.generic_ip,
-			       lbn, &new, &dbn, NULL);
+	error = gfs2_block_map(sdp->sd_jdesc->jd_inode, lbn, &new, &dbn, &bdy);
 	gfs2_assert_withdraw(sdp, !error && dbn);
 
 	return dbn;
diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c
index afcc12a..d89179b 100644
--- a/fs/gfs2/ops_address.c
+++ b/fs/gfs2/ops_address.c
@@ -13,6 +13,7 @@
 #include <linux/completion.h>
 #include <linux/buffer_head.h>
 #include <linux/pagemap.h>
+#include <linux/pagevec.h>
 #include <linux/mpage.h>
 #include <linux/fs.h>
 #include <linux/gfs2_ondisk.h>
@@ -47,12 +48,12 @@
 int gfs2_get_block(struct inode *inode, sector_t lblock,
 	           struct buffer_head *bh_result, int create)
 {
-	struct gfs2_inode *ip = inode->u.generic_ip;
 	int new = create;
 	uint64_t dblock;
 	int error;
+	int boundary;
 
-	error = gfs2_block_map(ip, lblock, &new, &dblock, NULL);
+	error = gfs2_block_map(inode, lblock, &new, &dblock, &boundary);
 	if (error)
 		return error;
 
@@ -62,6 +63,8 @@
 	map_bh(bh_result, inode->i_sb, dblock);
 	if (new)
 		set_buffer_new(bh_result);
+	if (boundary)
+		set_buffer_boundary(bh_result);
 
 	return 0;
 }
@@ -83,8 +86,9 @@
 	int new = 0;
 	uint64_t dblock;
 	int error;
+	int boundary;
 
-	error = gfs2_block_map(ip, lblock, &new, &dblock, NULL);
+	error = gfs2_block_map(inode, lblock, &new, &dblock, &boundary);
 	if (error)
 		return error;
 
@@ -92,6 +96,8 @@
 		map_bh(bh_result, inode->i_sb, dblock);
 	else if (gfs2_assert_withdraw(ip->i_sbd, !create))
 		error = -EIO;
+	if (boundary)
+		set_buffer_boundary(bh_result);
 
 	return error;
 }
@@ -151,6 +157,19 @@
 	return 0;
 }
 
+static int zero_readpage(struct page *page)
+{
+	void *kaddr;
+
+	kaddr = kmap_atomic(page, KM_USER0);
+	memset(kaddr, 0, PAGE_CACHE_SIZE);
+	kunmap_atomic(page, KM_USER0);
+
+	SetPageUptodate(page);
+
+	return 0;
+}
+
 /**
  * stuffed_readpage - Fill in a Linux page with stuffed file data
  * @ip: the inode
@@ -165,17 +184,18 @@
 	void *kaddr;
 	int error;
 
+	/* Only the first page of a stuffed file might contain data */
+	if (unlikely(page->index))
+		return zero_readpage(page);
+
 	error = gfs2_meta_inode_buffer(ip, &dibh);
 	if (error)
 		return error;
 
 	kaddr = kmap_atomic(page, KM_USER0);
-	memcpy((char *)kaddr,
-	       dibh->b_data + sizeof(struct gfs2_dinode),
+	memcpy(kaddr, dibh->b_data + sizeof(struct gfs2_dinode),
 	       ip->i_di.di_size);
-	memset((char *)kaddr + ip->i_di.di_size,
-	       0,
-	       PAGE_CACHE_SIZE - ip->i_di.di_size);
+	memset(kaddr + ip->i_di.di_size, 0, PAGE_CACHE_SIZE - ip->i_di.di_size);
 	kunmap_atomic(page, KM_USER0);
 
 	brelse(dibh);
@@ -185,19 +205,6 @@
 	return 0;
 }
 
-static int zero_readpage(struct page *page)
-{
-	void *kaddr;
-
-	kaddr = kmap_atomic(page, KM_USER0);
-	memset(kaddr, 0, PAGE_CACHE_SIZE);
-	kunmap_atomic(page, KM_USER0);
-
-	SetPageUptodate(page);
-	unlock_page(page);
-
-	return 0;
-}
 
 /**
  * gfs2_readpage - readpage with locking
@@ -215,19 +222,16 @@
 	struct gfs2_holder gh;
 	int error;
 
-	if (file != &gfs2_internal_file_sentinal) {
+	if (likely(file != &gfs2_internal_file_sentinal)) {
 		gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME|GL_AOP, &gh);
 		error = gfs2_glock_nq_m_atime(1, &gh);
-		if (error)
+		if (unlikely(error))
 			goto out_unlock;
 	}
 
 	if (gfs2_is_stuffed(ip)) {
-		if (!page->index) {
-			error = stuffed_readpage(ip, page);
-			unlock_page(page);
-		} else
-			error = zero_readpage(page);
+		error = stuffed_readpage(ip, page);
+		unlock_page(page);
 	} else
 		error = mpage_readpage(page, gfs2_get_block);
 
@@ -242,6 +246,90 @@
 	return error;
 out_unlock:
 	unlock_page(page);
+	if (file != &gfs2_internal_file_sentinal)
+		gfs2_holder_uninit(&gh);
+	goto out;
+}
+
+#define list_to_page(head) (list_entry((head)->prev, struct page, lru))
+
+/**
+ * gfs2_readpages - Read a bunch of pages at once
+ *
+ * Some notes:
+ * 1. This is only for readahead, so we can simply ignore any things
+ *    which are slightly inconvenient (such as locking conflicts between
+ *    the page lock and the glock) and return having done no I/O. Its
+ *    obviously not something we'd want to do on too regular a basis.
+ *    Any I/O we ignore at this time will be done via readpage later.
+ * 2. We have to handle stuffed files here too.
+ * 3. mpage_readpages() does most of the heavy lifting in the common case.
+ * 4. gfs2_get_block() is relied upon to set BH_Boundary in the right places.
+ * 5. We use LM_FLAG_TRY_1CB here, effectively we then have lock-ahead as
+ *    well as read-ahead.
+ */
+static int gfs2_readpages(struct file *file, struct address_space *mapping,
+			  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_holder gh;
+	unsigned page_idx;
+	int ret;
+
+	if (likely(file != &gfs2_internal_file_sentinal)) {
+		gfs2_holder_init(ip->i_gl, LM_ST_SHARED,
+				 LM_FLAG_TRY_1CB|GL_ATIME|GL_AOP, &gh);
+		ret = gfs2_glock_nq_m_atime(1, &gh);
+		if (ret == GLR_TRYFAILED) 
+			goto out_noerror;
+		if (unlikely(ret))
+			goto out_unlock;
+	}
+
+	if (gfs2_is_stuffed(ip)) {
+		struct pagevec lru_pvec;
+		pagevec_init(&lru_pvec, 0);
+		for (page_idx = 0; page_idx < nr_pages; page_idx++) {
+			struct page *page = list_to_page(pages);
+			list_del(&page->lru);
+			if (!add_to_page_cache(page, mapping,
+					       page->index, GFP_KERNEL)) {
+				ret = stuffed_readpage(ip, page);
+				unlock_page(page);
+				if (!pagevec_add(&lru_pvec, page))
+					 __pagevec_lru_add(&lru_pvec);
+			}
+			page_cache_release(page);
+		}
+		pagevec_lru_add(&lru_pvec);
+		ret = 0;
+	} else {
+		/* What we really want to do .... */
+		ret = mpage_readpages(mapping, pages, nr_pages, gfs2_get_block);
+	}
+
+	if (likely(file != &gfs2_internal_file_sentinal)) {
+		gfs2_glock_dq_m(1, &gh);
+		gfs2_holder_uninit(&gh);
+	}
+out:
+	if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags)))
+		ret = -EIO;
+	return ret;
+out_noerror:
+	ret = 0;
+out_unlock:
+	/* unlock all pages, we can't do any I/O right now */
+	for (page_idx = 0; page_idx < nr_pages; page_idx++) {
+		struct page *page = list_to_page(pages);
+		list_del(&page->lru);
+		unlock_page(page);
+		page_cache_release(page);
+	}
+	if (likely(file != &gfs2_internal_file_sentinal))
+		gfs2_holder_uninit(&gh);
 	goto out;
 }
 
@@ -572,6 +660,7 @@
 struct address_space_operations gfs2_file_aops = {
 	.writepage = gfs2_writepage,
 	.readpage = gfs2_readpage,
+	.readpages = gfs2_readpages,
 	.sync_page = block_sync_page,
 	.prepare_write = gfs2_prepare_write,
 	.commit_write = gfs2_commit_write,
diff --git a/fs/gfs2/ops_super.c b/fs/gfs2/ops_super.c
index 60bf256..5910c7b 100644
--- a/fs/gfs2/ops_super.c
+++ b/fs/gfs2/ops_super.c
@@ -92,7 +92,6 @@
 		if (error)
 			gfs2_io_error(sdp);
 	}
-
 	/*  At this point, we're through modifying the disk  */
 
 	/*  Release stuff  */
@@ -125,12 +124,10 @@
 	gfs2_jindex_free(sdp);
 	/*  Take apart glock structures and buffer lists  */
 	gfs2_gl_hash_clear(sdp, WAIT);
-
 	/*  Unmount the locking protocol  */
 	gfs2_lm_unmount(sdp);
 
 	/*  At this point, we're through participating in the lockspace  */
-
 	gfs2_sys_fs_del(sdp);
 	vfree(sdp);
 	sb->s_fs_info = NULL;
diff --git a/fs/gfs2/ops_vm.c b/fs/gfs2/ops_vm.c
index dbc5707..d67248c 100644
--- a/fs/gfs2/ops_vm.c
+++ b/fs/gfs2/ops_vm.c
@@ -90,8 +90,7 @@
 	if (error)
 		goto out_gunlock_q;
 
-	gfs2_write_calc_reserv(ip, PAGE_CACHE_SIZE,
-			      &data_blocks, &ind_blocks);
+	gfs2_write_calc_reserv(ip, PAGE_CACHE_SIZE, &data_blocks, &ind_blocks);
 
 	al->al_requested = data_blocks + ind_blocks;
 
@@ -99,8 +98,7 @@
 	if (error)
 		goto out_gunlock_q;
 
-	error = gfs2_trans_begin(sdp,
-				 al->al_rgd->rd_ri.ri_length +
+	error = gfs2_trans_begin(sdp, al->al_rgd->rd_ri.ri_length +
 				 ind_blocks + RES_DINODE +
 				 RES_STATFS + RES_QUOTA, 0);
 	if (error)
@@ -117,7 +115,7 @@
 		unsigned int extlen;
 		int new = 1;
 
-		error = gfs2_block_map(ip, lblock, &new, &dblock, &extlen);
+		error = gfs2_extent_map(ip->i_vnode, lblock, &new, &dblock, &extlen);
 		if (error)
 			goto out_trans;
 
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
index 942c4c8..d49ff43 100644
--- a/fs/gfs2/quota.c
+++ b/fs/gfs2/quota.c
@@ -255,6 +255,7 @@
 	int new = 0;
 	struct buffer_head *bh;
 	int error;
+	int boundary;
 
 	mutex_lock(&sdp->sd_quota_mutex);
 
@@ -266,7 +267,7 @@
 	block = qd->qd_slot / sdp->sd_qc_per_block;
 	offset = qd->qd_slot % sdp->sd_qc_per_block;;
 
-	error = gfs2_block_map(ip, block, &new, &dblock, NULL);
+	error = gfs2_block_map(ip->i_vnode, block, &new, &dblock, &boundary);
 	if (error)
 		goto fail;
 	error = gfs2_meta_read(ip->i_gl, dblock, DIO_START | DIO_WAIT, &bh);
@@ -1162,7 +1163,7 @@
 
 		if (!extlen) {
 			int new = 0;
-			error = gfs2_block_map(ip, x, &new, &dblock, &extlen);
+			error = gfs2_extent_map(ip->i_vnode, x, &new, &dblock, &extlen);
 			if (error)
 				goto fail;
 		}
diff --git a/fs/gfs2/recovery.c b/fs/gfs2/recovery.c
index d916817..87adebe 100644
--- a/fs/gfs2/recovery.c
+++ b/fs/gfs2/recovery.c
@@ -40,8 +40,7 @@
 	uint32_t extlen;
 	int error;
 
-	error = gfs2_block_map(ip, blk, &new, &dblock,
-			       &extlen);
+	error = gfs2_extent_map(ip->i_vnode, blk, &new, &dblock, &extlen);
 	if (error)
 		return error;
 	if (!dblock) {
@@ -378,10 +377,11 @@
 	uint32_t hash;
 	struct buffer_head *bh;
 	int error;
-	
+	int boundary;
+
 	lblock = head->lh_blkno;
 	gfs2_replay_incr_blk(sdp, &lblock);
-	error = gfs2_block_map(ip, lblock, &new, &dblock, NULL);
+	error = gfs2_block_map(ip->i_vnode, lblock, &new, &dblock, &boundary);
 	if (error)
 		return error;
 	if (!dblock) {
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index 4ae5596..15c326c 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -956,8 +956,7 @@
 	   search in the first part of our first-searched bit block.  */
 	for (x = 0; x <= length; x++) {
 		if (bi->bi_clone)
-			blk = gfs2_bitfit(rgd,
-					  bi->bi_clone + bi->bi_offset,
+			blk = gfs2_bitfit(rgd, bi->bi_clone + bi->bi_offset,
 					  bi->bi_len, goal, old_state);
 		else
 			blk = gfs2_bitfit(rgd,
@@ -976,12 +975,10 @@
 		blk = 0;
 
 	gfs2_trans_add_bh(rgd->rd_gl, bi->bi_bh, 1);
-	gfs2_setbit(rgd,
-		    bi->bi_bh->b_data + bi->bi_offset,
+	gfs2_setbit(rgd, bi->bi_bh->b_data + bi->bi_offset,
 		    bi->bi_len, blk, new_state);
 	if (bi->bi_clone)
-		gfs2_setbit(rgd,
-			    bi->bi_clone + bi->bi_offset,
+		gfs2_setbit(rgd, bi->bi_clone + bi->bi_offset,
 			    bi->bi_len, blk, new_state);
 
 	return bi->bi_start * GFS2_NBBY + blk;
@@ -1064,8 +1061,7 @@
 	else
 		goal = rgd->rd_last_alloc_data;
 
-	blk = rgblk_search(rgd, goal,
-			   GFS2_BLKST_FREE, GFS2_BLKST_USED);
+	blk = rgblk_search(rgd, goal, GFS2_BLKST_FREE, GFS2_BLKST_USED);
 	rgd->rd_last_alloc_data = blk;
 
 	block = rgd->rd_ri.ri_data0 + blk;
@@ -1109,8 +1105,7 @@
 	else
 		goal = rgd->rd_last_alloc_meta;
 
-	blk = rgblk_search(rgd, goal,
-			   GFS2_BLKST_FREE, GFS2_BLKST_USED);
+	blk = rgblk_search(rgd, goal, GFS2_BLKST_FREE, GFS2_BLKST_USED);
 	rgd->rd_last_alloc_meta = blk;
 
 	block = rgd->rd_ri.ri_data0 + blk;
diff --git a/fs/gfs2/unlinked.c b/fs/gfs2/unlinked.c
index 24b91c2..0d2314a 100644
--- a/fs/gfs2/unlinked.c
+++ b/fs/gfs2/unlinked.c
@@ -35,11 +35,12 @@
 	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, block, &new, &dblock, NULL);
+	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);
@@ -354,7 +355,7 @@
 
 		if (!extlen) {
 			int new = 0;
-			error = gfs2_block_map(ip, x, &new, &dblock, &extlen);
+			error = gfs2_extent_map(ip->i_vnode, x, &new, &dblock, &extlen);
 			if (error)
 				goto fail;
 		}