[GFS2] Use vmalloc() in dir code

When allocating memory to sort directory entries, use vmalloc()
rather than kmalloc() since for larger directories, the required
size can easily be graeter than the 128k maximum of kmalloc().

Also adding the first steps towards getting the AOP_TRUNCATED_PAGE
return code get in the glock code by flagging all places where we
request a glock and we are holding a page lock.

Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c
index fe6c5ad..eb68cdd 100644
--- a/fs/gfs2/dir.c
+++ b/fs/gfs2/dir.c
@@ -61,6 +61,7 @@
 #include <linux/sort.h>
 #include <linux/gfs2_ondisk.h>
 #include <linux/crc32.h>
+#include <linux/vmalloc.h>
 #include <asm/semaphore.h>
 
 #include "gfs2.h"
@@ -1290,7 +1291,7 @@
 		return 0;
 
 	error = -ENOMEM;
-	larr = kmalloc((leaves + entries) * sizeof(void*), GFP_KERNEL);
+	larr = vmalloc((leaves + entries) * sizeof(void*));
 	if (!larr)
 		goto out;
 	darr = (const struct gfs2_dirent **)(larr + leaves);
@@ -1323,7 +1324,7 @@
 out_kfree:
 	for(i = 0; i < leaf; i++)
 		brelse(larr[i]);
-	kfree(larr);
+	vfree(larr);
 out:
 	return error;
 }
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 6a1b42c..4ed1378 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -461,6 +461,9 @@
 	struct gfs2_holder *tmp_gh, *safe;
 	int found = 0;
 
+	printk(KERN_INFO "recursion %016llx, %u\n", gl->gl_name.ln_number,
+		gl->gl_name.ln_type);
+
 	if (gfs2_assert_warn(sdp, gh->gh_owner))
 		return;
 
diff --git a/fs/gfs2/glock.h b/fs/gfs2/glock.h
index 560029d..b6646e7 100644
--- a/fs/gfs2/glock.h
+++ b/fs/gfs2/glock.h
@@ -27,6 +27,7 @@
 #define GL_SYNC			0x00000800
 #define GL_NOCANCEL		0x00001000
 #define GL_NEVER_RECURSE	0x00002000
+#define GL_AOP			0x00004000
 
 #define GLR_TRYFAILED		13
 #define GLR_CANCELED		14
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index dfed83b..761f001 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
@@ -156,7 +156,7 @@
 	struct gfs2_glock *gh_gl;
 	struct task_struct *gh_owner;
 	unsigned int gh_state;
-	int gh_flags;
+	unsigned gh_flags;
 
 	int gh_error;
 	unsigned long gh_iflags;
diff --git a/fs/gfs2/meta_io.c b/fs/gfs2/meta_io.c
index 4a6aacf..74cf28e 100644
--- a/fs/gfs2/meta_io.c
+++ b/fs/gfs2/meta_io.c
@@ -881,7 +881,7 @@
 		gfs2_ail1_start(sdp, DIO_ALL);
 		if (gfs2_ail1_empty(sdp, DIO_ALL))
 			break;
-		msleep(100);
+		msleep(10);
 	}
 }
 
diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c
index 3fd8c6e..005c252 100644
--- a/fs/gfs2/ops_address.c
+++ b/fs/gfs2/ops_address.c
@@ -216,7 +216,7 @@
 	int error;
 
 	if (file != &gfs2_internal_file_sentinal) {
-		gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &gh);
+		gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME|GL_AOP, &gh);
 		error = gfs2_glock_nq_m_atime(1, &gh);
 		if (error)
 			goto out_unlock;
@@ -267,7 +267,7 @@
 	loff_t end = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
 	struct gfs2_alloc *al;
 
-	gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_ATIME, &ip->i_gh);
+	gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_ATIME|GL_AOP, &ip->i_gh);
 	error = gfs2_glock_nq_m_atime(1, &ip->i_gh);
 	if (error)
 		goto out_uninit;
diff --git a/fs/gfs2/ops_inode.c b/fs/gfs2/ops_inode.c
index 1e2b709..62a12a5 100644
--- a/fs/gfs2/ops_inode.c
+++ b/fs/gfs2/ops_inode.c
@@ -742,8 +742,7 @@
 		if (error)
 			goto out_gunlock_q;
 
-		error = gfs2_trans_begin(sdp,
-					 sdp->sd_max_dirres +
+		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 +
diff --git a/fs/gfs2/ops_super.c b/fs/gfs2/ops_super.c
index 80ce40c..60bf256 100644
--- a/fs/gfs2/ops_super.c
+++ b/fs/gfs2/ops_super.c
@@ -132,9 +132,7 @@
 	/*  At this point, we're through participating in the lockspace  */
 
 	gfs2_sys_fs_del(sdp);
-
 	vfree(sdp);
-
 	sb->s_fs_info = NULL;
 }