Selaa lähdekoodia

[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>
Steven Whitehouse 19 vuotta sitten
vanhempi
commit
fe1bdedc6c
8 muutettua tiedostoa jossa 12 lisäystä ja 10 poistoa
  1. 3 2
      fs/gfs2/dir.c
  2. 3 0
      fs/gfs2/glock.c
  3. 1 0
      fs/gfs2/glock.h
  4. 1 1
      fs/gfs2/incore.h
  5. 1 1
      fs/gfs2/meta_io.c
  6. 2 2
      fs/gfs2/ops_address.c
  7. 1 2
      fs/gfs2/ops_inode.c
  8. 0 2
      fs/gfs2/ops_super.c

+ 3 - 2
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 @@ static int gfs2_dir_read_leaf(struct inode *inode, u64 *offset, void *opaque,
 		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 @@ static int gfs2_dir_read_leaf(struct inode *inode, u64 *offset, void *opaque,
 out_kfree:
 	for(i = 0; i < leaf; i++)
 		brelse(larr[i]);
-	kfree(larr);
+	vfree(larr);
 out:
 	return error;
 }

+ 3 - 0
fs/gfs2/glock.c

@@ -461,6 +461,9 @@ static void handle_recurse(struct gfs2_holder *gh)
 	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;
 

+ 1 - 0
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

+ 1 - 1
fs/gfs2/incore.h

@@ -156,7 +156,7 @@ struct gfs2_holder {
 	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;

+ 1 - 1
fs/gfs2/meta_io.c

@@ -881,7 +881,7 @@ void gfs2_meta_syncfs(struct gfs2_sbd *sdp)
 		gfs2_ail1_start(sdp, DIO_ALL);
 		if (gfs2_ail1_empty(sdp, DIO_ALL))
 			break;
-		msleep(100);
+		msleep(10);
 	}
 }
 

+ 2 - 2
fs/gfs2/ops_address.c

@@ -216,7 +216,7 @@ static int gfs2_readpage(struct file *file, struct page *page)
 	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 @@ static int gfs2_prepare_write(struct file *file, struct page *page,
 	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;

+ 1 - 2
fs/gfs2/ops_inode.c

@@ -742,8 +742,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
 		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 +

+ 0 - 2
fs/gfs2/ops_super.c

@@ -132,9 +132,7 @@ static void gfs2_put_super(struct super_block *sb)
 	/*  At this point, we're through participating in the lockspace  */
 
 	gfs2_sys_fs_del(sdp);
-
 	vfree(sdp);
-
 	sb->s_fs_info = NULL;
 }