[pnfs] [PATCH] pnfs-gfs2: allocate layouts on a slab

David M. Richter richterd at citi.umich.edu
Fri Jun 6 19:08:06 EDT 2008


Since LAYOUTGET is permitted to return a single file handle for sparse layouts,
allocate the layout and the filehandle together from a slab cache.

Signed-off-by: David M. Richter <richterd at citi.umich.edu>
---
 fs/gfs2/gfs2.h       |    3 +++
 fs/gfs2/main.c       |   14 ++++++++++++++
 fs/gfs2/ops_export.c |   37 ++++++++++++++++++++++++-------------
 3 files changed, 41 insertions(+), 13 deletions(-)

diff --git a/fs/gfs2/gfs2.h b/fs/gfs2/gfs2.h
index 8669d7e..aff5543 100644
--- a/fs/gfs2/gfs2.h
+++ b/fs/gfs2/gfs2.h
@@ -28,6 +28,9 @@ enum {
 #define GFS2_FAST_NAME_SIZE 8
 
 #if defined(CONFIG_PNFSD)
+extern int gfs2_pnfs_init_layout_cache(void);
+extern void gfs2_pnfs_destroy_layout_cache(void);
+
 /* XXX: revisit; surely there's a better place for this? */
 #define XXX_PNFS_DS_LISTSZ 256
 extern char pnfs_ds_list[XXX_PNFS_DS_LISTSZ];
diff --git a/fs/gfs2/main.c b/fs/gfs2/main.c
index caebe75..a894bc2 100644
--- a/fs/gfs2/main.c
+++ b/fs/gfs2/main.c
@@ -153,6 +153,12 @@ static int __init init_gfs2_fs(void)
 	if (!gfs2_bufdata_cachep)
 		goto fail;
 
+#if defined(CONFIG_PNFSD)
+	error = gfs2_pnfs_init_layout_cache();
+	if (error)
+		goto fail;
+#endif /* CONFIG_PNFSD */
+
 	error = register_filesystem(&gfs2_fs_type);
 	if (error)
 		goto fail;
@@ -176,6 +182,10 @@ fail_unregister:
 fail:
 	gfs2_glock_exit();
 
+#if defined(CONFIG_PNFSD)
+	gfs2_pnfs_destroy_layout_cache();
+#endif /* CONFIG_PNFSD */
+
 	if (gfs2_bufdata_cachep)
 		kmem_cache_destroy(gfs2_bufdata_cachep);
 
@@ -202,6 +212,10 @@ static void __exit exit_gfs2_fs(void)
 	unregister_filesystem(&gfs2_fs_type);
 	unregister_filesystem(&gfs2meta_fs_type);
 
+#if defined(CONFIG_PNFSD)
+	gfs2_pnfs_destroy_layout_cache();
+#endif /* CONFIG_PNFSD */
+
 	kmem_cache_destroy(gfs2_bufdata_cachep);
 	kmem_cache_destroy(gfs2_inode_cachep);
 	kmem_cache_destroy(gfs2_glock_cachep);
diff --git a/fs/gfs2/ops_export.c b/fs/gfs2/ops_export.c
index 20491d6..09405a0 100644
--- a/fs/gfs2/ops_export.c
+++ b/fs/gfs2/ops_export.c
@@ -35,6 +35,8 @@
 #include <linux/nfsd/pnfsd.h>
 #include <linux/nfsd/nfs4layoutxdr.h>
 #include <linux/nfs4_pnfs.h>
+
+static struct kmem_cache *gfs2_pnfs_layout_cachep;
 #endif /* CONFIG_PNFSD */
 
 #define GFS2_SMALL_FH_SIZE 4
@@ -305,6 +307,23 @@ static struct dentry *gfs2_fh_to_parent(struct super_block *sb, struct fid *fid,
 }
 
 #if defined(CONFIG_PNFSD)
+int gfs2_pnfs_init_layout_cache(void)
+{
+	gfs2_pnfs_layout_cachep = kmem_cache_create("gfs2_pnfs_layout",
+				    sizeof(struct pnfs_filelayout_layout) +
+				    sizeof(struct knfsd_fh),
+				    0, 0, NULL);
+	if (!gfs2_pnfs_layout_cachep)
+		return -ENOMEM;
+	return 0;
+}
+
+void gfs2_pnfs_destroy_layout_cache(void)
+{
+	if (gfs2_pnfs_layout_cachep)
+		kmem_cache_destroy(gfs2_pnfs_layout_cachep);
+}
+
 static int gfs2_layout_type(void)
 {
 	return LAYOUT_NFSV4_FILES;
@@ -328,7 +347,6 @@ static int gfs2_layout_get(struct inode *inode, struct pnfs_layoutget_arg *arg)
 {
 	int rc = 0;
 	struct pnfs_filelayout_layout *layout = NULL;
-	struct knfsd_fh *fhp = NULL;
 
 	printk(KERN_DEBUG "%s: LAYOUT_GET\n", __func__);
 
@@ -337,7 +355,7 @@ static int gfs2_layout_get(struct inode *inode, struct pnfs_layoutget_arg *arg)
 	arg->seg.offset = 0;
 	arg->seg.length = inode->i_sb->s_maxbytes; /* The maximum file size */
 
-	layout = kzalloc(sizeof(*layout), GFP_KERNEL);
+	layout = kmem_cache_alloc(gfs2_pnfs_layout_cachep, GFP_KERNEL);
 	if (layout == NULL) {
 		rc = -ENOMEM;
 		goto error;
@@ -353,22 +371,15 @@ static int gfs2_layout_get(struct inode *inode, struct pnfs_layoutget_arg *arg)
 	layout->device_id.pnfs_devid = 1;			/*FSFTEMP*/
 	layout->lg_first_stripe_index = 0;			/*FSFTEMP*/
 	layout->lg_pattern_offset = 0;
+	layout->lg_fh_list = (void *)(layout + 1);
 
-	fhp = kmalloc(sizeof(*fhp), GFP_KERNEL);
-	if (fhp == NULL) {
-		rc = -ENOMEM;
-		goto error;
-	}
-
-	memcpy(fhp, arg->fh, sizeof(*fhp));
-	pnfs_fh_mark_ds(fhp);
-	layout->lg_fh_list = fhp;
+	memcpy(layout->lg_fh_list, arg->fh, sizeof(struct knfsd_fh));
+	pnfs_fh_mark_ds(layout->lg_fh_list);
 
 	/* Call nfsd to encode layout */
 	rc = arg->func(&arg->xdr, layout);
 exit:
-	kfree(layout);
-	kfree(fhp);
+	kmem_cache_free(gfs2_pnfs_layout_cachep, layout);
 	return rc;
 
 error:
-- 
1.5.3



More information about the pNFS mailing list