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

Halevy, Benny bhalevy at panasas.com
Sat Jun 7 03:08:40 EDT 2008


David, this looks great over all.
 
One minor suggestion though, as-per Trond's advice:
gfs2_pnfs_{init,destroy}_layout_cache can be defined
as no-ops in the !defined(CONFIG_PNFSD) case
and the they can be used without the surrounding #ifdef's
 
Benny

________________________________

From: David M. Richter [mailto:richterd at citi.umich.edu]
Sent: Sat 2008-06-07 02:08
To: Halevy, Benny
Cc: pnfs at linux-nfs.org; David M. Richter
Subject: [PATCH] pnfs-gfs2: allocate layouts on a slab



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