3604df
From ecc54b50659398a76a14aa33d866f1eb5dcc1019 Mon Sep 17 00:00:00 2001
3604df
From: Anuradha Talur <atalur@redhat.com>
3604df
Date: Mon, 29 Aug 2016 16:41:09 +0530
3604df
Subject: [PATCH 78/86] compound fops: Some fixes to compound fops framework
3604df
3604df
	Backport of: http://review.gluster.org/15010
3604df
3604df
Change-Id: Ia0a87d71a9761d9caf6ad466bbb750925f88bb95
3604df
BUG: 1360978
3604df
Signed-off-by: Anuradha Talur <atalur@redhat.com>
3604df
Reviewed-on: https://code.engineering.redhat.com/gerrit/84815
3604df
Reviewed-by: Pranith Kumar Karampuri <pkarampu@redhat.com>
3604df
Tested-by: Pranith Kumar Karampuri <pkarampu@redhat.com>
3604df
---
3604df
 libglusterfs/src/Makefile.am                       |    2 +-
3604df
 libglusterfs/src/compound-fop-utils.c              |  104 ++++-
3604df
 libglusterfs/src/compound-fop-utils.h              |   35 ++
3604df
 libglusterfs/src/default-args.c                    |   12 +-
3604df
 libglusterfs/src/default-args.h                    |    2 +
3604df
 .../performance/decompounder/src/decompounder.c    |  179 ++++----
3604df
 .../performance/decompounder/src/decompounder.h    |    1 +
3604df
 xlators/protocol/client/src/client-common.c        |    1 +
3604df
 xlators/protocol/client/src/client-helpers.c       |  298 +++++++++--
3604df
 xlators/protocol/client/src/client-rpc-fops.c      |   56 +--
3604df
 xlators/protocol/client/src/client.h               |   25 +-
3604df
 xlators/protocol/server/src/server-helpers.c       |  528 +++++++++++++++++++-
3604df
 xlators/protocol/server/src/server-helpers.h       |    5 +
3604df
 xlators/protocol/server/src/server-rpc-fops.c      |   64 ++-
3604df
 xlators/protocol/server/src/server.h               |   28 +
3604df
 15 files changed, 1093 insertions(+), 247 deletions(-)
3604df
 create mode 100644 libglusterfs/src/compound-fop-utils.h
3604df
3604df
diff --git a/libglusterfs/src/Makefile.am b/libglusterfs/src/Makefile.am
3604df
index 93403db..849cb97 100644
3604df
--- a/libglusterfs/src/Makefile.am
3604df
+++ b/libglusterfs/src/Makefile.am
3604df
@@ -52,7 +52,7 @@ libglusterfs_la_HEADERS = common-utils.h defaults.h default-args.h \
3604df
 	glfs-message-id.h template-component-messages.h strfd.h \
3604df
 	syncop-utils.h parse-utils.h libglusterfs-messages.h tw.h \
3604df
 	lvm-defaults.h quota-common-utils.h rot-buffs.h \
3604df
-	compat-uuid.h upcall-utils.h events.h
3604df
+	compat-uuid.h upcall-utils.h events.h compound-fop-utils.h
3604df
 
3604df
 libglusterfs_ladir = $(includedir)/glusterfs
3604df
 
3604df
diff --git a/libglusterfs/src/compound-fop-utils.c b/libglusterfs/src/compound-fop-utils.c
3604df
index 16cd5c6..03d7b5b 100644
3604df
--- a/libglusterfs/src/compound-fop-utils.c
3604df
+++ b/libglusterfs/src/compound-fop-utils.c
3604df
@@ -13,12 +13,94 @@
3604df
 #include "mem-types.h"
3604df
 #include "dict.h"
3604df
 
3604df
+void
3604df
+compound_args_cleanup (compound_args_t *args)
3604df
+{
3604df
+        int i;
3604df
+
3604df
+        if (!args)
3604df
+                return;
3604df
+
3604df
+        if (args->xdata)
3604df
+                dict_unref (args->xdata);
3604df
+
3604df
+        if (args->req_list) {
3604df
+                for (i = 0; i < args->fop_length; i++) {
3604df
+                        args_wipe (&args->req_list[i]);
3604df
+                }
3604df
+        }
3604df
+
3604df
+        GF_FREE (args->enum_list);
3604df
+        GF_FREE (args->req_list);
3604df
+        GF_FREE (args);
3604df
+}
3604df
+
3604df
+void
3604df
+compound_args_cbk_cleanup (compound_args_cbk_t *args_cbk)
3604df
+{
3604df
+        int i;
3604df
+
3604df
+        if (!args_cbk)
3604df
+                return;
3604df
+
3604df
+        if (args_cbk->xdata)
3604df
+                dict_unref (args_cbk->xdata);
3604df
+
3604df
+        if (args_cbk->rsp_list) {
3604df
+                for (i = 0; i < args_cbk->fop_length; i++) {
3604df
+                        args_cbk_wipe (&args_cbk->rsp_list[i]);
3604df
+                }
3604df
+        }
3604df
+
3604df
+        GF_FREE (args_cbk->rsp_list);
3604df
+        GF_FREE (args_cbk->enum_list);
3604df
+        GF_FREE (args_cbk);
3604df
+}
3604df
+
3604df
+compound_args_cbk_t*
3604df
+compound_args_cbk_alloc (int length, dict_t *xdata)
3604df
+{
3604df
+        int                 i             = 0;
3604df
+        compound_args_cbk_t *args_cbk     = NULL;
3604df
+
3604df
+        args_cbk = GF_CALLOC (1, sizeof (*args_cbk), gf_mt_compound_rsp_t);
3604df
+        if (!args_cbk)
3604df
+                return NULL;
3604df
+
3604df
+        args_cbk->fop_length = length;
3604df
+
3604df
+        args_cbk->rsp_list = GF_CALLOC (length, sizeof (*args_cbk->rsp_list),
3604df
+                                        gf_mt_default_args_cbk_t);
3604df
+        if (!args_cbk->rsp_list)
3604df
+                goto out;
3604df
+
3604df
+        for (i = 0; i < length; i++) {
3604df
+                args_cbk_init (&args_cbk->rsp_list[i]);
3604df
+        }
3604df
+
3604df
+        args_cbk->enum_list = GF_CALLOC (length, sizeof (*args_cbk->enum_list),
3604df
+                                        gf_common_mt_int);
3604df
+        if (!args_cbk->enum_list)
3604df
+                goto out;
3604df
+
3604df
+        if (xdata) {
3604df
+                args_cbk->xdata = dict_copy_with_ref (xdata, NULL);
3604df
+                if (!args_cbk->xdata)
3604df
+                        goto out;
3604df
+        }
3604df
+
3604df
+        return args_cbk;
3604df
+out:
3604df
+        compound_args_cbk_cleanup (args_cbk);
3604df
+        return NULL;
3604df
+}
3604df
+
3604df
 compound_args_t*
3604df
 compound_fop_alloc (int length, glusterfs_compound_fop_t fop, dict_t *xdata)
3604df
 {
3604df
         compound_args_t *args     = NULL;
3604df
 
3604df
-        args = GF_CALLOC (1, sizeof (args), gf_mt_compound_req_t);
3604df
+        args = GF_CALLOC (1, sizeof (*args), gf_mt_compound_req_t);
3604df
 
3604df
         if (!args)
3604df
                 return NULL;
3604df
@@ -29,7 +111,7 @@ compound_fop_alloc (int length, glusterfs_compound_fop_t fop, dict_t *xdata)
3604df
          * fop list packed.
3604df
          */
3604df
         args->fop_enum = fop;
3604df
-        args->fop_length   = length;
3604df
+        args->fop_length = length;
3604df
 
3604df
         args->enum_list = GF_CALLOC (length, sizeof (*args->enum_list),
3604df
                                      gf_common_mt_int);
3604df
@@ -51,22 +133,6 @@ compound_fop_alloc (int length, glusterfs_compound_fop_t fop, dict_t *xdata)
3604df
 
3604df
         return args;
3604df
 out:
3604df
-        if (args->xdata)
3604df
-                dict_unref (args->xdata);
3604df
-
3604df
-        if (args->req_list)
3604df
-                GF_FREE (args->req_list);
3604df
-
3604df
-        if (args->enum_list)
3604df
-                GF_FREE (args->enum_list);
3604df
-
3604df
-        if (args)
3604df
-                GF_FREE (args);
3604df
-
3604df
+        compound_args_cleanup (args);
3604df
         return NULL;
3604df
 }
3604df
-
3604df
-#define COMPOUND_PACK_ARGS(fop, fop_enum, args, counter, params ...) do {    \
3604df
-        args->enum_list[counter] = fop_enum;                                 \
3604df
-        args_##fop##_store (&args->req_list[counter], params);               \
3604df
-} while (0)
3604df
diff --git a/libglusterfs/src/compound-fop-utils.h b/libglusterfs/src/compound-fop-utils.h
3604df
new file mode 100644
3604df
index 0000000..bfd0649
3604df
--- /dev/null
3604df
+++ b/libglusterfs/src/compound-fop-utils.h
3604df
@@ -0,0 +1,35 @@
3604df
+/*
3604df
+  Copyright (c) 2016 Red Hat, Inc. <http://www.redhat.com>
3604df
+  This file is part of GlusterFS.
3604df
+
3604df
+  This file is licensed to you under your choice of the GNU Lesser
3604df
+  General Public License, version 3 or any later version (LGPLv3 or
3604df
+  later), or the GNU General Public License, version 2 (GPLv2), in all
3604df
+  cases as published by the Free Software Foundation.
3604df
+*/
3604df
+
3604df
+#ifndef __COMPOUND_FOP_UTILS_H__
3604df
+#define __COMPOUND_FOP_UTILS_H__
3604df
+
3604df
+#include "defaults.h"
3604df
+#include "default-args.h"
3604df
+#include "mem-types.h"
3604df
+#include "dict.h"
3604df
+
3604df
+#define COMPOUND_PACK_ARGS(fop, fop_enum, args, counter, params ...) do {    \
3604df
+        args->enum_list[counter] = fop_enum;                                 \
3604df
+        args_##fop##_store (&args->req_list[counter], params);               \
3604df
+} while (0)
3604df
+
3604df
+compound_args_t*
3604df
+compound_fop_alloc (int length, glusterfs_compound_fop_t fop, dict_t *xdata);
3604df
+
3604df
+void
3604df
+compound_args_cleanup (compound_args_t *args);
3604df
+
3604df
+void
3604df
+compound_args_cbk_cleanup (compound_args_cbk_t *args_cbk);
3604df
+
3604df
+compound_args_cbk_t*
3604df
+compound_args_cbk_alloc (int length, dict_t *xdata);
3604df
+#endif /* __COMPOUND_FOP_UTILS_H__ */
3604df
diff --git a/libglusterfs/src/default-args.c b/libglusterfs/src/default-args.c
3604df
index 2e51bf2..f40de2d 100644
3604df
--- a/libglusterfs/src/default-args.c
3604df
+++ b/libglusterfs/src/default-args.c
3604df
@@ -1576,11 +1576,9 @@ args_wipe (default_args_t *args)
3604df
         if (!args)
3604df
                 return;
3604df
 
3604df
-        if (&args->loc)
3604df
-                loc_wipe (&args->loc);
3604df
+        loc_wipe (&args->loc);
3604df
 
3604df
-        if (&args->loc2)
3604df
-                loc_wipe (&args->loc2);
3604df
+        loc_wipe (&args->loc2);
3604df
 
3604df
         if (args->fd)
3604df
                 fd_unref (args->fd);
3604df
@@ -1603,3 +1601,9 @@ args_wipe (default_args_t *args)
3604df
 	GF_FREE ((char *)args->volume);
3604df
 
3604df
 }
3604df
+
3604df
+void
3604df
+args_cbk_init (default_args_cbk_t *args_cbk)
3604df
+{
3604df
+        INIT_LIST_HEAD (&args_cbk->entries);
3604df
+}
3604df
diff --git a/libglusterfs/src/default-args.h b/libglusterfs/src/default-args.h
3604df
index 93426ca..a2201dd 100644
3604df
--- a/libglusterfs/src/default-args.h
3604df
+++ b/libglusterfs/src/default-args.h
3604df
@@ -479,4 +479,6 @@ args_getactivelk_cbk_store (default_args_cbk_t *args,
3604df
 int
3604df
 args_setactivelk_store (default_args_t *args, loc_t *loc,
3604df
                           lock_migration_info_t *locklist, dict_t *xdata);
3604df
+void
3604df
+args_cbk_init (default_args_cbk_t *args_cbk);
3604df
 #endif /* _DEFAULT_ARGS_H */
3604df
diff --git a/xlators/performance/decompounder/src/decompounder.c b/xlators/performance/decompounder/src/decompounder.c
3604df
index 3009fcd..cd353b7 100644
3604df
--- a/xlators/performance/decompounder/src/decompounder.c
3604df
+++ b/xlators/performance/decompounder/src/decompounder.c
3604df
@@ -10,17 +10,14 @@
3604df
 
3604df
 #include "decompounder.h"
3604df
 #include "mem-types.h"
3604df
+#include "compound-fop-utils.h"
3604df
 
3604df
 void
3604df
 dc_local_cleanup (dc_local_t *local)
3604df
 {
3604df
         int i = 0;
3604df
 
3604df
-        for (i = 0; i < local->length; i++)
3604df
-                args_cbk_wipe (&local->compound_rsp->rsp_list[i]);
3604df
-
3604df
-        GF_FREE (local->compound_rsp->rsp_list);
3604df
-        GF_FREE (local->compound_rsp);
3604df
+        compound_args_cbk_cleanup (local->compound_rsp);
3604df
         return;
3604df
 }
3604df
 
3604df
@@ -551,290 +548,292 @@ dc_compound_fop_wind (call_frame_t *frame, xlator_t *this)
3604df
         compound_args_t         *c_req          = local->compound_req;
3604df
         compound_args_cbk_t     *c_rsp          = local->compound_rsp;
3604df
         int                     counter         = local->counter;
3604df
-        default_args_t          curr_fop        = c_req->req_list[counter];
3604df
+        default_args_t          *curr_fop       = &c_req->req_list[counter];
3604df
         int                     op_ret          = 0;
3604df
         int                     op_errno        = ENOMEM;
3604df
 
3604df
         if (local->counter == local->length)
3604df
                 goto done;
3604df
 
3604df
+        c_rsp->enum_list[counter] = c_req->enum_list[counter];
3604df
+
3604df
         switch (c_req->enum_list[counter]) {
3604df
         case GF_FOP_STAT:
3604df
                 STACK_WIND (frame, dc_stat_cbk,
3604df
                             FIRST_CHILD(this), FIRST_CHILD(this)->fops->stat,
3604df
-                            &curr_fop.loc, curr_fop.xdata);
3604df
+                            &curr_fop->loc, curr_fop->xdata);
3604df
                 break;
3604df
         case GF_FOP_READLINK:
3604df
                 STACK_WIND (frame, dc_readlink_cbk,
3604df
                             FIRST_CHILD(this),
3604df
                             FIRST_CHILD(this)->fops->readlink,
3604df
-                            &curr_fop.loc, curr_fop.size,
3604df
-                            curr_fop.xdata);
3604df
+                            &curr_fop->loc, curr_fop->size,
3604df
+                            curr_fop->xdata);
3604df
                 break;
3604df
         case GF_FOP_MKNOD:
3604df
                 STACK_WIND (frame, dc_mknod_cbk,
3604df
                             FIRST_CHILD(this), FIRST_CHILD(this)->fops->mknod,
3604df
-                            &curr_fop.loc, curr_fop.mode, curr_fop.rdev,
3604df
-                            curr_fop.umask, curr_fop.xdata);
3604df
+                            &curr_fop->loc, curr_fop->mode, curr_fop->rdev,
3604df
+                            curr_fop->umask, curr_fop->xdata);
3604df
                 break;
3604df
         case GF_FOP_MKDIR:
3604df
                 STACK_WIND (frame, dc_mkdir_cbk,
3604df
                             FIRST_CHILD(this), FIRST_CHILD(this)->fops->mkdir,
3604df
-                            &curr_fop.loc, curr_fop.mode,
3604df
-                            curr_fop.umask, curr_fop.xdata);
3604df
+                            &curr_fop->loc, curr_fop->mode,
3604df
+                            curr_fop->umask, curr_fop->xdata);
3604df
                 break;
3604df
         case GF_FOP_UNLINK:
3604df
                 STACK_WIND (frame, dc_unlink_cbk,
3604df
                             FIRST_CHILD(this), FIRST_CHILD(this)->fops->unlink,
3604df
-                            &curr_fop.loc, curr_fop.xflag, curr_fop.xdata);
3604df
+                            &curr_fop->loc, curr_fop->xflag, curr_fop->xdata);
3604df
                 break;
3604df
         case GF_FOP_RMDIR:
3604df
                 STACK_WIND (frame, dc_rmdir_cbk,
3604df
                             FIRST_CHILD(this), FIRST_CHILD(this)->fops->rmdir,
3604df
-                            &curr_fop.loc, curr_fop.flags, curr_fop.xdata);
3604df
+                            &curr_fop->loc, curr_fop->flags, curr_fop->xdata);
3604df
                 break;
3604df
         case GF_FOP_SYMLINK:
3604df
                 STACK_WIND (frame, dc_symlink_cbk,
3604df
                             FIRST_CHILD(this), FIRST_CHILD(this)->fops->symlink,
3604df
-                            curr_fop.linkname, &curr_fop.loc,
3604df
-                            curr_fop.umask, curr_fop.xdata);
3604df
+                            curr_fop->linkname, &curr_fop->loc,
3604df
+                            curr_fop->umask, curr_fop->xdata);
3604df
                 break;
3604df
         case GF_FOP_RENAME:
3604df
                 STACK_WIND (frame, dc_rename_cbk,
3604df
                             FIRST_CHILD(this), FIRST_CHILD(this)->fops->rename,
3604df
-                            &curr_fop.loc, &curr_fop.loc2, curr_fop.xdata);
3604df
+                            &curr_fop->loc, &curr_fop->loc2, curr_fop->xdata);
3604df
                 break;
3604df
         case GF_FOP_LINK:
3604df
                 STACK_WIND (frame, dc_link_cbk,
3604df
                             FIRST_CHILD(this), FIRST_CHILD(this)->fops->link,
3604df
-                            &curr_fop.loc, &curr_fop.loc2, curr_fop.xdata);
3604df
+                            &curr_fop->loc, &curr_fop->loc2, curr_fop->xdata);
3604df
                 break;
3604df
         case GF_FOP_TRUNCATE:
3604df
                 STACK_WIND (frame, dc_truncate_cbk,
3604df
                             FIRST_CHILD(this),
3604df
                             FIRST_CHILD(this)->fops->truncate,
3604df
-                            &curr_fop.loc, curr_fop.offset, curr_fop.xdata);
3604df
+                            &curr_fop->loc, curr_fop->offset, curr_fop->xdata);
3604df
                 break;
3604df
         case GF_FOP_OPEN:
3604df
                 STACK_WIND (frame, dc_open_cbk,
3604df
                             FIRST_CHILD(this), FIRST_CHILD(this)->fops->open,
3604df
-                            &curr_fop.loc, curr_fop.flags, curr_fop.fd,
3604df
-                            curr_fop.xdata);
3604df
+                            &curr_fop->loc, curr_fop->flags, curr_fop->fd,
3604df
+                            curr_fop->xdata);
3604df
                 break;
3604df
         case GF_FOP_READ:
3604df
                 STACK_WIND (frame, dc_readv_cbk,
3604df
                             FIRST_CHILD(this), FIRST_CHILD(this)->fops->readv,
3604df
-                            curr_fop.fd, curr_fop.size, curr_fop.offset,
3604df
-                            curr_fop.flags, curr_fop.xdata);
3604df
+                            curr_fop->fd, curr_fop->size, curr_fop->offset,
3604df
+                            curr_fop->flags, curr_fop->xdata);
3604df
                 break;
3604df
         case GF_FOP_WRITE:
3604df
                 STACK_WIND (frame, dc_writev_cbk,
3604df
                             FIRST_CHILD(this), FIRST_CHILD(this)->fops->writev,
3604df
-                            curr_fop.fd, curr_fop.vector, curr_fop.count,
3604df
-                            curr_fop.offset, curr_fop.flags, curr_fop.iobref,
3604df
-                            curr_fop.xdata);
3604df
+                            curr_fop->fd, curr_fop->vector, curr_fop->count,
3604df
+                            curr_fop->offset, curr_fop->flags, curr_fop->iobref,
3604df
+                            curr_fop->xdata);
3604df
                 break;
3604df
         case GF_FOP_STATFS:
3604df
                 STACK_WIND (frame, dc_statfs_cbk,
3604df
                             FIRST_CHILD(this), FIRST_CHILD(this)->fops->statfs,
3604df
-                            &curr_fop.loc, curr_fop.xdata);
3604df
+                            &curr_fop->loc, curr_fop->xdata);
3604df
                 break;
3604df
         case GF_FOP_FLUSH:
3604df
                 STACK_WIND (frame, dc_flush_cbk,
3604df
                             FIRST_CHILD(this), FIRST_CHILD(this)->fops->flush,
3604df
-                            curr_fop.fd, curr_fop.xdata);
3604df
+                            curr_fop->fd, curr_fop->xdata);
3604df
                 break;
3604df
         case GF_FOP_FSYNC:
3604df
                 STACK_WIND (frame, dc_fsync_cbk,
3604df
                             FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsync,
3604df
-                            curr_fop.fd, curr_fop.datasync, curr_fop.xdata);
3604df
+                            curr_fop->fd, curr_fop->datasync, curr_fop->xdata);
3604df
                 break;
3604df
         case GF_FOP_SETXATTR:
3604df
                 STACK_WIND (frame, dc_setxattr_cbk,
3604df
                             FIRST_CHILD(this),
3604df
                             FIRST_CHILD(this)->fops->setxattr,
3604df
-                            &curr_fop.loc, curr_fop.xattr, curr_fop.flags,
3604df
-                            curr_fop.xdata);
3604df
+                            &curr_fop->loc, curr_fop->xattr, curr_fop->flags,
3604df
+                            curr_fop->xdata);
3604df
                 break;
3604df
         case GF_FOP_GETXATTR:
3604df
                 STACK_WIND (frame, dc_getxattr_cbk,
3604df
                             FIRST_CHILD(this),
3604df
                             FIRST_CHILD(this)->fops->getxattr,
3604df
-                            &curr_fop.loc, curr_fop.name, curr_fop.xdata);
3604df
+                            &curr_fop->loc, curr_fop->name, curr_fop->xdata);
3604df
                 break;
3604df
         case GF_FOP_REMOVEXATTR:
3604df
                 STACK_WIND (frame, dc_removexattr_cbk,
3604df
                             FIRST_CHILD(this),
3604df
                             FIRST_CHILD(this)->fops->removexattr,
3604df
-                            &curr_fop.loc, curr_fop.name, curr_fop.xdata);
3604df
+                            &curr_fop->loc, curr_fop->name, curr_fop->xdata);
3604df
                 break;
3604df
         case GF_FOP_OPENDIR:
3604df
                 STACK_WIND (frame, dc_opendir_cbk,
3604df
                             FIRST_CHILD(this),
3604df
                             FIRST_CHILD(this)->fops->opendir,
3604df
-                            &curr_fop.loc, curr_fop.fd, curr_fop.xdata);
3604df
+                            &curr_fop->loc, curr_fop->fd, curr_fop->xdata);
3604df
                 break;
3604df
         case GF_FOP_FSYNCDIR:
3604df
                 STACK_WIND (frame, dc_fsyncdir_cbk,
3604df
                             FIRST_CHILD(this),
3604df
                             FIRST_CHILD(this)->fops->fsyncdir,
3604df
-                            curr_fop.fd, curr_fop.datasync, curr_fop.xdata);
3604df
+                            curr_fop->fd, curr_fop->datasync, curr_fop->xdata);
3604df
                 break;
3604df
         case GF_FOP_ACCESS:
3604df
                 STACK_WIND (frame, dc_access_cbk,
3604df
                             FIRST_CHILD(this), FIRST_CHILD(this)->fops->access,
3604df
-                            &curr_fop.loc, curr_fop.mask, curr_fop.xdata);
3604df
+                            &curr_fop->loc, curr_fop->mask, curr_fop->xdata);
3604df
                 break;
3604df
         case GF_FOP_CREATE:
3604df
                 STACK_WIND (frame, dc_create_cbk,
3604df
                             FIRST_CHILD(this), FIRST_CHILD(this)->fops->create,
3604df
-                            &curr_fop.loc, curr_fop.flags, curr_fop.mode,
3604df
-                            curr_fop.umask, curr_fop.fd, curr_fop.xdata);
3604df
+                            &curr_fop->loc, curr_fop->flags, curr_fop->mode,
3604df
+                            curr_fop->umask, curr_fop->fd, curr_fop->xdata);
3604df
                 break;
3604df
         case GF_FOP_FTRUNCATE:
3604df
                 STACK_WIND (frame, dc_ftruncate_cbk,
3604df
                             FIRST_CHILD(this),
3604df
                             FIRST_CHILD(this)->fops->ftruncate,
3604df
-                            curr_fop.fd, curr_fop.offset, curr_fop.xdata);
3604df
+                            curr_fop->fd, curr_fop->offset, curr_fop->xdata);
3604df
                 break;
3604df
         case GF_FOP_FSTAT:
3604df
                 STACK_WIND (frame, dc_fstat_cbk,
3604df
                             FIRST_CHILD(this), FIRST_CHILD(this)->fops->fstat,
3604df
-                            curr_fop.fd, curr_fop.xdata);
3604df
+                            curr_fop->fd, curr_fop->xdata);
3604df
                 break;
3604df
         case GF_FOP_LK:
3604df
                 STACK_WIND (frame, dc_lk_cbk,
3604df
                             FIRST_CHILD(this), FIRST_CHILD(this)->fops->lk,
3604df
-                            curr_fop.fd,
3604df
-                            curr_fop.cmd, &curr_fop.lock, curr_fop.xdata);
3604df
+                            curr_fop->fd,
3604df
+                            curr_fop->cmd, &curr_fop->lock, curr_fop->xdata);
3604df
                 break;
3604df
         case GF_FOP_LOOKUP:
3604df
                 STACK_WIND (frame, dc_lookup_cbk,
3604df
                             FIRST_CHILD(this), FIRST_CHILD(this)->fops->lookup,
3604df
-                            &curr_fop.loc, curr_fop.xdata);
3604df
+                            &curr_fop->loc, curr_fop->xdata);
3604df
                 break;
3604df
         case GF_FOP_READDIR:
3604df
                 STACK_WIND (frame, dc_readdir_cbk,
3604df
                             FIRST_CHILD(this), FIRST_CHILD(this)->fops->readdir,
3604df
-                            curr_fop.fd, curr_fop.size, curr_fop.offset,
3604df
-                            curr_fop.xdata);
3604df
+                            curr_fop->fd, curr_fop->size, curr_fop->offset,
3604df
+                            curr_fop->xdata);
3604df
                 break;
3604df
         case GF_FOP_INODELK:
3604df
                 STACK_WIND (frame, dc_inodelk_cbk,
3604df
                             FIRST_CHILD(this), FIRST_CHILD(this)->fops->inodelk,
3604df
-                            curr_fop.volume, &curr_fop.loc,
3604df
-                            curr_fop.cmd, &curr_fop.lock, curr_fop.xdata);
3604df
+                            curr_fop->volume, &curr_fop->loc,
3604df
+                            curr_fop->cmd, &curr_fop->lock, curr_fop->xdata);
3604df
                 break;
3604df
         case GF_FOP_FINODELK:
3604df
                 STACK_WIND (frame, dc_finodelk_cbk,
3604df
                             FIRST_CHILD(this),
3604df
                             FIRST_CHILD(this)->fops->finodelk,
3604df
-                            curr_fop.volume, curr_fop.fd,
3604df
-                            curr_fop.cmd, &curr_fop.lock, curr_fop.xdata);
3604df
+                            curr_fop->volume, curr_fop->fd,
3604df
+                            curr_fop->cmd, &curr_fop->lock, curr_fop->xdata);
3604df
                 break;
3604df
         case GF_FOP_ENTRYLK:
3604df
                 STACK_WIND (frame, dc_entrylk_cbk,
3604df
                             FIRST_CHILD(this), FIRST_CHILD(this)->fops->entrylk,
3604df
-                            curr_fop.volume, &curr_fop.loc,
3604df
-                            curr_fop.name, curr_fop.entrylkcmd,
3604df
-                            curr_fop.entrylktype, curr_fop.xdata);
3604df
+                            curr_fop->volume, &curr_fop->loc,
3604df
+                            curr_fop->name, curr_fop->entrylkcmd,
3604df
+                            curr_fop->entrylktype, curr_fop->xdata);
3604df
                 break;
3604df
         case GF_FOP_FENTRYLK:
3604df
                 STACK_WIND (frame, dc_fentrylk_cbk,
3604df
                             FIRST_CHILD(this),
3604df
                             FIRST_CHILD(this)->fops->fentrylk,
3604df
-                            curr_fop.volume, curr_fop.fd,
3604df
-                            curr_fop.name, curr_fop.entrylkcmd,
3604df
-                            curr_fop.entrylktype, curr_fop.xdata);
3604df
+                            curr_fop->volume, curr_fop->fd,
3604df
+                            curr_fop->name, curr_fop->entrylkcmd,
3604df
+                            curr_fop->entrylktype, curr_fop->xdata);
3604df
                 break;
3604df
         case GF_FOP_XATTROP:
3604df
                 STACK_WIND (frame, dc_xattrop_cbk,
3604df
                             FIRST_CHILD(this),
3604df
                             FIRST_CHILD(this)->fops->xattrop,
3604df
-                            &curr_fop.loc, curr_fop.optype, curr_fop.xattr,
3604df
-                            curr_fop.xdata);
3604df
+                            &curr_fop->loc, curr_fop->optype, curr_fop->xattr,
3604df
+                            curr_fop->xdata);
3604df
                 break;
3604df
         case GF_FOP_FXATTROP:
3604df
                 STACK_WIND (frame, dc_fxattrop_cbk,
3604df
                             FIRST_CHILD(this),
3604df
                             FIRST_CHILD(this)->fops->fxattrop,
3604df
-                            curr_fop.fd, curr_fop.optype, curr_fop.xattr,
3604df
-                            curr_fop.xdata);
3604df
+                            curr_fop->fd, curr_fop->optype, curr_fop->xattr,
3604df
+                            curr_fop->xdata);
3604df
                 break;
3604df
         case GF_FOP_FGETXATTR:
3604df
                 STACK_WIND (frame, dc_fgetxattr_cbk,
3604df
                             FIRST_CHILD(this),
3604df
                             FIRST_CHILD(this)->fops->fgetxattr,
3604df
-                            curr_fop.fd, curr_fop.name, curr_fop.xdata);
3604df
+                            curr_fop->fd, curr_fop->name, curr_fop->xdata);
3604df
                 break;
3604df
         case GF_FOP_FSETXATTR:
3604df
                 STACK_WIND (frame, dc_fsetxattr_cbk,
3604df
                             FIRST_CHILD(this),
3604df
                             FIRST_CHILD(this)->fops->fsetxattr,
3604df
-                            curr_fop.fd, curr_fop.xattr, curr_fop.flags,
3604df
-                            curr_fop.xdata);
3604df
+                            curr_fop->fd, curr_fop->xattr, curr_fop->flags,
3604df
+                            curr_fop->xdata);
3604df
                 break;
3604df
         case GF_FOP_RCHECKSUM:
3604df
                 STACK_WIND (frame, dc_rchecksum_cbk,
3604df
                             FIRST_CHILD(this),
3604df
                             FIRST_CHILD(this)->fops->rchecksum,
3604df
-                            curr_fop.fd, curr_fop.offset, curr_fop.size,
3604df
-                            curr_fop.xdata);
3604df
+                            curr_fop->fd, curr_fop->offset, curr_fop->size,
3604df
+                            curr_fop->xdata);
3604df
                 break;
3604df
         case GF_FOP_SETATTR:
3604df
                 STACK_WIND (frame, dc_setattr_cbk,
3604df
                             FIRST_CHILD(this), FIRST_CHILD(this)->fops->setattr,
3604df
-                            &curr_fop.loc, &curr_fop.stat, curr_fop.valid,
3604df
-                            curr_fop.xdata);
3604df
+                            &curr_fop->loc, &curr_fop->stat, curr_fop->valid,
3604df
+                            curr_fop->xdata);
3604df
                 break;
3604df
         case GF_FOP_FSETATTR:
3604df
                 STACK_WIND (frame, dc_fsetattr_cbk,
3604df
                             FIRST_CHILD(this),
3604df
                             FIRST_CHILD(this)->fops->fsetattr,
3604df
-                            curr_fop.fd, &curr_fop.stat, curr_fop.valid,
3604df
-                            curr_fop.xdata);
3604df
+                            curr_fop->fd, &curr_fop->stat, curr_fop->valid,
3604df
+                            curr_fop->xdata);
3604df
                 break;
3604df
         case GF_FOP_READDIRP:
3604df
                 STACK_WIND (frame, dc_readdirp_cbk,
3604df
                             FIRST_CHILD(this),
3604df
                             FIRST_CHILD(this)->fops->readdirp,
3604df
-                            curr_fop.fd, curr_fop.size, curr_fop.offset,
3604df
-                            curr_fop.xdata);
3604df
+                            curr_fop->fd, curr_fop->size, curr_fop->offset,
3604df
+                            curr_fop->xdata);
3604df
                 break;
3604df
         case GF_FOP_FREMOVEXATTR:
3604df
                 STACK_WIND (frame, dc_fremovexattr_cbk,
3604df
                             FIRST_CHILD(this),
3604df
                             FIRST_CHILD(this)->fops->fremovexattr,
3604df
-                            curr_fop.fd, curr_fop.name, curr_fop.xdata);
3604df
+                            curr_fop->fd, curr_fop->name, curr_fop->xdata);
3604df
                 break;
3604df
         case GF_FOP_FALLOCATE:
3604df
                 STACK_WIND (frame, dc_fallocate_cbk,
3604df
                             FIRST_CHILD(this), FIRST_CHILD(this)->fops->fallocate,
3604df
-                            curr_fop.fd, curr_fop.flags, curr_fop.offset,
3604df
-                            curr_fop.size, curr_fop.xdata);
3604df
+                            curr_fop->fd, curr_fop->flags, curr_fop->offset,
3604df
+                            curr_fop->size, curr_fop->xdata);
3604df
                 break;
3604df
         case GF_FOP_DISCARD:
3604df
                 STACK_WIND (frame, dc_discard_cbk,
3604df
                             FIRST_CHILD(this), FIRST_CHILD(this)->fops->discard,
3604df
-                            curr_fop.fd, curr_fop.offset, curr_fop.size,
3604df
-                            curr_fop.xdata);
3604df
+                            curr_fop->fd, curr_fop->offset, curr_fop->size,
3604df
+                            curr_fop->xdata);
3604df
                 break;
3604df
         case GF_FOP_ZEROFILL:
3604df
                 STACK_WIND (frame, dc_zerofill_cbk,
3604df
                             FIRST_CHILD(this), FIRST_CHILD(this)->fops->zerofill,
3604df
-                            curr_fop.fd, curr_fop.offset, curr_fop.size,
3604df
-                            curr_fop.xdata);
3604df
+                            curr_fop->fd, curr_fop->offset, curr_fop->size,
3604df
+                            curr_fop->xdata);
3604df
                 break;
3604df
         case GF_FOP_IPC:
3604df
                 STACK_WIND (frame, dc_ipc_cbk,
3604df
                             FIRST_CHILD(this), FIRST_CHILD(this)->fops->ipc,
3604df
-                            curr_fop.cmd, curr_fop.xdata);
3604df
+                            curr_fop->cmd, curr_fop->xdata);
3604df
                 break;
3604df
         case GF_FOP_SEEK:
3604df
                 STACK_WIND (frame, dc_seek_cbk,
3604df
                             FIRST_CHILD(this), FIRST_CHILD(this)->fops->seek,
3604df
-                            curr_fop.fd, curr_fop.offset, curr_fop.what,
3604df
-                            curr_fop.xdata);
3604df
+                            curr_fop->fd, curr_fop->offset, curr_fop->what,
3604df
+                            curr_fop->xdata);
3604df
                 break;
3604df
         default:
3604df
                 return -ENOTSUP;
3604df
@@ -865,20 +864,13 @@ dc_compound (call_frame_t *frame, xlator_t *this, void *data, dict_t *xdata)
3604df
 
3604df
         frame->local = local;
3604df
 
3604df
-        local->compound_rsp = GF_CALLOC (1, sizeof (local->compound_rsp),
3604df
-                                         gf_dc_mt_rsp_t);
3604df
+        local->compound_rsp = compound_args_cbk_alloc (compound_req->fop_length,
3604df
+                                                       NULL);
3604df
         if (!local->compound_rsp)
3604df
                 goto out;
3604df
 
3604df
         compound_rsp = local->compound_rsp;
3604df
 
3604df
-        compound_rsp->fop_length = compound_req->fop_length;
3604df
-        compound_rsp->rsp_list = GF_CALLOC (compound_rsp->fop_length,
3604df
-                                            sizeof (default_args_cbk_t),
3604df
-                                            gf_mt_default_args_cbk_t);
3604df
-        if (!compound_rsp->rsp_list)
3604df
-                goto out;
3604df
-
3604df
         local->length =  compound_req->fop_length;
3604df
         local->counter = 0;
3604df
         local->compound_req = compound_req;
3604df
@@ -941,6 +933,13 @@ init (xlator_t *this)
3604df
                 ret = -1;
3604df
                 goto out;
3604df
         }
3604df
+
3604df
+        this->local_pool = mem_pool_new (dc_local_t, 128);
3604df
+        if (!this->local_pool) {
3604df
+                ret = -1;
3604df
+                goto out;
3604df
+        }
3604df
+
3604df
 out:
3604df
         return ret;
3604df
 }
3604df
diff --git a/xlators/performance/decompounder/src/decompounder.h b/xlators/performance/decompounder/src/decompounder.h
3604df
index 1b8c1d6..59fb908 100644
3604df
--- a/xlators/performance/decompounder/src/decompounder.h
3604df
+++ b/xlators/performance/decompounder/src/decompounder.h
3604df
@@ -26,6 +26,7 @@ typedef struct {
3604df
 
3604df
 #define DC_STACK_UNWIND(frame, op_ret, op_errno, rsp, xdata) do {\
3604df
                 dc_local_t      *__local = NULL;                      \
3604df
+                                                                      \
3604df
                 if (frame) {                                          \
3604df
                         __local = frame->local;                       \
3604df
                         frame->local = NULL;                          \
3604df
diff --git a/xlators/protocol/client/src/client-common.c b/xlators/protocol/client/src/client-common.c
3604df
index 05939b8..4fff7e6 100644
3604df
--- a/xlators/protocol/client/src/client-common.c
3604df
+++ b/xlators/protocol/client/src/client-common.c
3604df
@@ -1402,6 +1402,7 @@ client_post_readlink (xlator_t *this, gfs3_readlink_rsp *rsp,
3604df
                                       rsp->op_errno, out);
3604df
 
3604df
 out:
3604df
+
3604df
         return ret;
3604df
 }
3604df
 
3604df
diff --git a/xlators/protocol/client/src/client-helpers.c b/xlators/protocol/client/src/client-helpers.c
3604df
index 4bdb364..a7e46b5 100644
3604df
--- a/xlators/protocol/client/src/client-helpers.c
3604df
+++ b/xlators/protocol/client/src/client-helpers.c
3604df
@@ -135,10 +135,6 @@ client_local_wipe (clnt_local_t *local)
3604df
                         iobref_unref (local->iobref);
3604df
                 }
3604df
 
3604df
-                if (local->iobref2) {
3604df
-                        iobref_unref (local->iobref2);
3604df
-                }
3604df
-
3604df
                 GF_FREE (local->name);
3604df
 
3604df
                 local->compound_args = NULL;
3604df
@@ -1126,8 +1122,8 @@ int
3604df
 client_handle_fop_requirements (xlator_t *this, call_frame_t *frame,
3604df
                                 gfs3_compound_req *req,
3604df
                                 clnt_local_t *local,
3604df
-                                struct iobref *req_iobref,
3604df
-                                struct iobref *rsp_iobref,
3604df
+                                struct iobref **req_iobref,
3604df
+                                struct iobref **rsp_iobref,
3604df
                                 struct iovec *req_vector,
3604df
                                 struct iovec *rsp_vector, int *req_count,
3604df
                                 int *rsp_count, default_args_t *args,
3604df
@@ -1160,10 +1156,8 @@ client_handle_fop_requirements (xlator_t *this, call_frame_t *frame,
3604df
                                 op_errno, out,
3604df
                                 &args->loc, args->mode, args->rdev,
3604df
                                 args->umask, args->xdata);
3604df
-                if (!&local->loc) {
3604df
-                        loc_copy (&local->loc, &args->loc);
3604df
-                        loc_path (&local->loc, NULL);
3604df
-                }
3604df
+                loc_copy (&local->loc, &args->loc);
3604df
+                loc_path (&local->loc, NULL);
3604df
                 break;
3604df
         case GF_FOP_MKDIR:
3604df
                 CLIENT_PRE_FOP (mkdir, this,
3604df
@@ -1171,10 +1165,8 @@ client_handle_fop_requirements (xlator_t *this, call_frame_t *frame,
3604df
                                 op_errno, out,
3604df
                                 &args->loc, args->mode,
3604df
                                 args->umask, args->xdata);
3604df
-                if (!&local->loc) {
3604df
-                        loc_copy (&local->loc, &args->loc);
3604df
-                        loc_path (&local->loc, NULL);
3604df
-                }
3604df
+                loc_copy (&local->loc, &args->loc);
3604df
+                loc_path (&local->loc, NULL);
3604df
                 break;
3604df
         case GF_FOP_UNLINK:
3604df
                 CLIENT_PRE_FOP (unlink, this,
3604df
@@ -1194,10 +1186,8 @@ client_handle_fop_requirements (xlator_t *this, call_frame_t *frame,
3604df
                                 op_errno, out,
3604df
                                 &args->loc, args->linkname, args->umask,
3604df
                                 args->xdata);
3604df
-                if (!&local->loc) {
3604df
-                        loc_copy (&local->loc, &args->loc);
3604df
-                        loc_path (&local->loc, NULL);
3604df
-                }
3604df
+                loc_copy (&local->loc, &args->loc);
3604df
+                loc_path (&local->loc, NULL);
3604df
                 break;
3604df
         case GF_FOP_RENAME:
3604df
                 CLIENT_PRE_FOP (rename, this,
3604df
@@ -1246,15 +1236,15 @@ client_handle_fop_requirements (xlator_t *this, call_frame_t *frame,
3604df
                         goto out;
3604df
                 }
3604df
 
3604df
-                if (!rsp_iobref) {
3604df
-                        rsp_iobref = iobref_new ();
3604df
-                        if (rsp_iobref == NULL) {
3604df
+                if (!*rsp_iobref) {
3604df
+                        *rsp_iobref = iobref_new ();
3604df
+                        if (*rsp_iobref == NULL) {
3604df
                                 op_errno = ENOMEM;
3604df
                                 goto out;
3604df
                         }
3604df
                 }
3604df
 
3604df
-                iobref_add (rsp_iobref, rsp_iobuf);
3604df
+                iobref_add (*rsp_iobref, rsp_iobuf);
3604df
                 iobuf_unref (rsp_iobuf);
3604df
 
3604df
                 if (*rsp_count + 1 >= MAX_IOVEC) {
3604df
@@ -1280,7 +1270,8 @@ client_handle_fop_requirements (xlator_t *this, call_frame_t *frame,
3604df
         case GF_FOP_WRITE:
3604df
                 op_errno = client_pre_writev (this,
3604df
                            &this_req->compound_req_u.compound_write_req,
3604df
-                           args->fd, args->count, args->offset,
3604df
+                           args->fd, iov_length (args->vector, args->count),
3604df
+                           args->offset,
3604df
                            args->flags, args->xdata);
3604df
 
3604df
                 if (op_errno) {
3604df
@@ -1292,7 +1283,7 @@ client_handle_fop_requirements (xlator_t *this, call_frame_t *frame,
3604df
                 local->attempt_reopen = client_is_reopen_needed
3604df
                                         (args->fd, this, remote_fd);
3604df
 
3604df
-                if (*req_count + 1 >= MAX_IOVEC) {
3604df
+                if (*req_count + args->count >= MAX_IOVEC) {
3604df
                         op_errno = ENOMEM;
3604df
                         goto out;
3604df
                 }
3604df
@@ -1300,10 +1291,10 @@ client_handle_fop_requirements (xlator_t *this, call_frame_t *frame,
3604df
                         (args->count * sizeof(req_vector[0])));
3604df
                 *req_count += args->count;
3604df
 
3604df
-                if (!req_iobref)
3604df
-                        req_iobref = args->iobref;
3604df
+                if (!*req_iobref)
3604df
+                        *req_iobref = args->iobref;
3604df
                 else
3604df
-                        if (iobref_merge (req_iobref, args->iobref))
3604df
+                        if (iobref_merge (*req_iobref, args->iobref))
3604df
                                 goto out;
3604df
                 break;
3604df
         case GF_FOP_STATFS:
3604df
@@ -1339,10 +1330,8 @@ client_handle_fop_requirements (xlator_t *this, call_frame_t *frame,
3604df
                                 &this_req->compound_req_u.compound_getxattr_req,
3604df
                                 op_errno, out,
3604df
                                 &args->loc, args->name, args->xdata);
3604df
-                if (!&local->loc) {
3604df
-                        loc_copy (&local->loc, &args->loc);
3604df
-                        loc_path (&local->loc, NULL);
3604df
-                }
3604df
+                loc_copy (&local->loc, &args->loc);
3604df
+                loc_path (&local->loc, NULL);
3604df
                 break;
3604df
         case GF_FOP_REMOVEXATTR:
3604df
                 CLIENT_PRE_FOP (removexattr, this,
3604df
@@ -1357,10 +1346,8 @@ client_handle_fop_requirements (xlator_t *this, call_frame_t *frame,
3604df
                                 &args->loc, args->fd, args->xdata);
3604df
                 if (!local->fd)
3604df
                         local->fd = fd_ref (args->fd);
3604df
-                if (!&local->loc) {
3604df
-                        loc_copy (&local->loc, &args->loc);
3604df
-                        loc_path (&local->loc, NULL);
3604df
-                }
3604df
+                loc_copy (&local->loc, &args->loc);
3604df
+                loc_path (&local->loc, NULL);
3604df
                 break;
3604df
         case GF_FOP_FSYNCDIR:
3604df
                 CLIENT_PRE_FOP (fsyncdir, this,
3604df
@@ -1383,10 +1370,8 @@ client_handle_fop_requirements (xlator_t *this, call_frame_t *frame,
3604df
                 if (!local->fd)
3604df
                         local->fd = fd_ref (args->fd);
3604df
 
3604df
-                if (!&local->loc) {
3604df
-                        loc_copy (&local->loc, &args->loc);
3604df
-                        loc_path (&local->loc, NULL);
3604df
-                }
3604df
+                loc_copy (&local->loc, &args->loc);
3604df
+                loc_path (&local->loc, NULL);
3604df
                 break;
3604df
         case GF_FOP_FTRUNCATE:
3604df
                 CLIENT_PRE_FOP (ftruncate, this,
3604df
@@ -1414,10 +1399,8 @@ client_handle_fop_requirements (xlator_t *this, call_frame_t *frame,
3604df
                                 &this_req->compound_req_u.compound_lookup_req,
3604df
                                 op_errno, out,
3604df
                                 &args->loc, args->xdata);
3604df
-                if (!&local->loc) {
3604df
-                        loc_copy (&local->loc, &args->loc);
3604df
-                        loc_path (&local->loc, NULL);
3604df
-                }
3604df
+                loc_copy (&local->loc, &args->loc);
3604df
+                loc_path (&local->loc, NULL);
3604df
                 break;
3604df
         case GF_FOP_READDIR:
3604df
                 CLIENT_PRE_FOP (readdir, this,
3604df
@@ -1582,6 +1565,9 @@ compound_request_cleanup (gfs3_compound_req *req)
3604df
         compound_req   *curr_req = NULL;
3604df
 
3604df
 
3604df
+        if (!req->compound_req_array.compound_req_array_val)
3604df
+                return;
3604df
+
3604df
         for (i = 0; i < length; i++) {
3604df
                 curr_req = &req->compound_req_array.compound_req_array_val[i];
3604df
 
3604df
@@ -1636,8 +1622,9 @@ compound_request_cleanup (gfs3_compound_req *req)
3604df
                         break;
3604df
                 case GF_FOP_SETXATTR:
3604df
                 {
3604df
-                        gfs3_setxattr_req args = curr_req->compound_req_u.compound_setxattr_req;
3604df
-                        GF_FREE (args.dict.dict_val);
3604df
+                        gfs3_setxattr_req *args = &CPD_REQ_FIELD (curr_req,
3604df
+                                                  setxattr);
3604df
+                        GF_FREE (args->dict.dict_val);
3604df
                         CLIENT_COMPOUND_FOP_CLEANUP (curr_req, setxattr);
3604df
                         break;
3604df
                 }
3604df
@@ -1688,15 +1675,17 @@ compound_request_cleanup (gfs3_compound_req *req)
3604df
                         break;
3604df
                 case GF_FOP_XATTROP:
3604df
                 {
3604df
-                        gfs3_xattrop_req args = curr_req->compound_req_u.compound_xattrop_req;
3604df
-                        GF_FREE (args.dict.dict_val);
3604df
+                        gfs3_xattrop_req *args = &CPD_REQ_FIELD (curr_req,
3604df
+                                                 xattrop);
3604df
+                        GF_FREE (args->dict.dict_val);
3604df
                         CLIENT_COMPOUND_FOP_CLEANUP (curr_req, xattrop);
3604df
                         break;
3604df
                 }
3604df
                 case GF_FOP_FXATTROP:
3604df
                 {
3604df
-                        gfs3_fxattrop_req args = curr_req->compound_req_u.compound_fxattrop_req;
3604df
-                        GF_FREE (args.dict.dict_val);
3604df
+                        gfs3_fxattrop_req *args = &CPD_REQ_FIELD (curr_req,
3604df
+                                                  fxattrop);
3604df
+                        GF_FREE (args->dict.dict_val);
3604df
                         CLIENT_COMPOUND_FOP_CLEANUP (curr_req, fxattrop);
3604df
                         break;
3604df
                 }
3604df
@@ -1705,8 +1694,9 @@ compound_request_cleanup (gfs3_compound_req *req)
3604df
                         break;
3604df
                 case GF_FOP_FSETXATTR:
3604df
                 {
3604df
-                        gfs3_fsetxattr_req args = curr_req->compound_req_u.compound_fsetxattr_req;
3604df
-                        GF_FREE (args.dict.dict_val);
3604df
+                        gfs3_fsetxattr_req *args = &CPD_REQ_FIELD(curr_req,
3604df
+                                                   fsetxattr);
3604df
+                        GF_FREE (args->dict.dict_val);
3604df
                         CLIENT_COMPOUND_FOP_CLEANUP (curr_req, fsetxattr);
3604df
                         break;
3604df
                 }
3604df
@@ -1721,8 +1711,9 @@ compound_request_cleanup (gfs3_compound_req *req)
3604df
                         break;
3604df
                 case GF_FOP_READDIRP:
3604df
                 {
3604df
-                        gfs3_readdirp_req args = curr_req->compound_req_u.compound_readdirp_req;
3604df
-                        GF_FREE (args.dict.dict_val);
3604df
+                        gfs3_readdirp_req *args = &CPD_REQ_FIELD(curr_req,
3604df
+                                                  readdirp);
3604df
+                        GF_FREE (args->dict.dict_val);
3604df
                         break;
3604df
                 }
3604df
                 case GF_FOP_FREMOVEXATTR:
3604df
@@ -1888,3 +1879,204 @@ out:
3604df
 
3604df
         return ret;
3604df
 }
3604df
+
3604df
+void
3604df
+client_compound_rsp_cleanup (gfs3_compound_rsp *rsp, int len)
3604df
+{
3604df
+        int i = 0;
3604df
+        compound_rsp            *this_rsp       = NULL;
3604df
+
3604df
+        for (i = 0; i < len; i++) {
3604df
+                this_rsp = &rsp->compound_rsp_array.compound_rsp_array_val[i];
3604df
+                switch (this_rsp->fop_enum) {
3604df
+                case GF_FOP_STAT:
3604df
+                        CLIENT_FOP_RSP_CLEANUP (rsp, stat, i);
3604df
+                        break;
3604df
+                case GF_FOP_MKNOD:
3604df
+                        CLIENT_FOP_RSP_CLEANUP (rsp, mknod, i);
3604df
+                        break;
3604df
+                case GF_FOP_MKDIR:
3604df
+                        CLIENT_FOP_RSP_CLEANUP (rsp, mkdir, i);
3604df
+                        break;
3604df
+                case GF_FOP_UNLINK:
3604df
+                        CLIENT_FOP_RSP_CLEANUP (rsp, unlink, i);
3604df
+                        break;
3604df
+                case GF_FOP_RMDIR:
3604df
+                        CLIENT_FOP_RSP_CLEANUP (rsp, rmdir, i);
3604df
+                        break;
3604df
+                case GF_FOP_SYMLINK:
3604df
+                        CLIENT_FOP_RSP_CLEANUP (rsp, symlink, i);
3604df
+                        break;
3604df
+                case GF_FOP_RENAME:
3604df
+                        CLIENT_FOP_RSP_CLEANUP (rsp, rename, i);
3604df
+                        break;
3604df
+                case GF_FOP_LINK:
3604df
+                        CLIENT_FOP_RSP_CLEANUP (rsp, link, i);
3604df
+                        break;
3604df
+                case GF_FOP_TRUNCATE:
3604df
+                        CLIENT_FOP_RSP_CLEANUP (rsp, truncate, i);
3604df
+                        break;
3604df
+                case GF_FOP_OPEN:
3604df
+                        CLIENT_FOP_RSP_CLEANUP (rsp, open, i);
3604df
+                        break;
3604df
+                case GF_FOP_READ:
3604df
+                        CLIENT_FOP_RSP_CLEANUP (rsp, read, i);
3604df
+                        break;
3604df
+                case GF_FOP_WRITE:
3604df
+                        CLIENT_FOP_RSP_CLEANUP (rsp, write, i);
3604df
+                        break;
3604df
+                case GF_FOP_STATFS:
3604df
+                        CLIENT_FOP_RSP_CLEANUP (rsp, statfs, i);
3604df
+                        break;
3604df
+                case GF_FOP_FSYNC:
3604df
+                        CLIENT_FOP_RSP_CLEANUP (rsp, fsync, i);
3604df
+                        break;
3604df
+                case GF_FOP_OPENDIR:
3604df
+                        CLIENT_FOP_RSP_CLEANUP (rsp, opendir, i);
3604df
+                        break;
3604df
+                case GF_FOP_CREATE:
3604df
+                        CLIENT_FOP_RSP_CLEANUP (rsp, create, i);
3604df
+                        break;
3604df
+                case GF_FOP_FTRUNCATE:
3604df
+                        CLIENT_FOP_RSP_CLEANUP (rsp, ftruncate, i);
3604df
+                        break;
3604df
+                case GF_FOP_FSTAT:
3604df
+                        CLIENT_FOP_RSP_CLEANUP (rsp, fstat, i);
3604df
+                        break;
3604df
+                case GF_FOP_LK:
3604df
+                        CLIENT_FOP_RSP_CLEANUP (rsp, lk, i);
3604df
+                        break;
3604df
+                case GF_FOP_LOOKUP:
3604df
+                        CLIENT_FOP_RSP_CLEANUP (rsp, lookup, i);
3604df
+                        break;
3604df
+                case GF_FOP_SETATTR:
3604df
+                        CLIENT_FOP_RSP_CLEANUP (rsp, setattr, i);
3604df
+                        break;
3604df
+                case GF_FOP_FSETATTR:
3604df
+                        CLIENT_FOP_RSP_CLEANUP (rsp, fsetattr, i);
3604df
+                        break;
3604df
+                case GF_FOP_FALLOCATE:
3604df
+                        CLIENT_FOP_RSP_CLEANUP (rsp, fallocate, i);
3604df
+                        break;
3604df
+                case GF_FOP_DISCARD:
3604df
+                        CLIENT_FOP_RSP_CLEANUP (rsp, discard, i);
3604df
+                        break;
3604df
+                case GF_FOP_ZEROFILL:
3604df
+                        CLIENT_FOP_RSP_CLEANUP (rsp, zerofill, i);
3604df
+                        break;
3604df
+                case GF_FOP_IPC:
3604df
+                        CLIENT_FOP_RSP_CLEANUP (rsp, ipc, i);
3604df
+                        break;
3604df
+                case GF_FOP_SEEK:
3604df
+                        CLIENT_FOP_RSP_CLEANUP (rsp, seek, i);
3604df
+                        break;
3604df
+                case GF_FOP_LEASE:
3604df
+                        CLIENT_FOP_RSP_CLEANUP (rsp, lease, i);
3604df
+                        break;
3604df
+                /* fops that use gf_common_rsp */
3604df
+                case GF_FOP_FLUSH:
3604df
+                        CLIENT_COMMON_RSP_CLEANUP (rsp, flush, i);
3604df
+                        break;
3604df
+                case GF_FOP_SETXATTR:
3604df
+                        CLIENT_COMMON_RSP_CLEANUP (rsp, setxattr, i);
3604df
+                        break;
3604df
+                case GF_FOP_REMOVEXATTR:
3604df
+                        CLIENT_COMMON_RSP_CLEANUP (rsp, removexattr, i);
3604df
+                        break;
3604df
+                case GF_FOP_FSETXATTR:
3604df
+                        CLIENT_COMMON_RSP_CLEANUP (rsp, fsetxattr, i);
3604df
+                        break;
3604df
+                case GF_FOP_FREMOVEXATTR:
3604df
+                        CLIENT_COMMON_RSP_CLEANUP (rsp, fremovexattr, i);
3604df
+                        break;
3604df
+                case GF_FOP_FSYNCDIR:
3604df
+                        CLIENT_COMMON_RSP_CLEANUP (rsp, fsyncdir, i);
3604df
+                        break;
3604df
+                case GF_FOP_ACCESS:
3604df
+                        CLIENT_COMMON_RSP_CLEANUP (rsp, access, i);
3604df
+                        break;
3604df
+                case GF_FOP_INODELK:
3604df
+                        CLIENT_COMMON_RSP_CLEANUP (rsp, inodelk, i);
3604df
+                        break;
3604df
+                case GF_FOP_FINODELK:
3604df
+                        CLIENT_COMMON_RSP_CLEANUP (rsp, finodelk, i);
3604df
+                        break;
3604df
+                case GF_FOP_ENTRYLK:
3604df
+                        CLIENT_COMMON_RSP_CLEANUP (rsp, entrylk, i);
3604df
+                        break;
3604df
+                case GF_FOP_FENTRYLK:
3604df
+                        CLIENT_COMMON_RSP_CLEANUP (rsp, fentrylk, i);
3604df
+                        break;
3604df
+                /* fops that need extra cleanup */
3604df
+                case GF_FOP_READLINK:
3604df
+                {
3604df
+                        CLIENT_FOP_RSP_CLEANUP (rsp, readlink, i);
3604df
+                        gfs3_readlink_rsp *tmp_rsp = &CPD_RSP_FIELD(this_rsp,
3604df
+                                                     readlink);
3604df
+                        free (tmp_rsp->path);
3604df
+                        break;
3604df
+                }
3604df
+                case GF_FOP_XATTROP:
3604df
+                {
3604df
+                        gfs3_xattrop_rsp *tmp_rsp = &CPD_RSP_FIELD(this_rsp,
3604df
+                                                    xattrop);
3604df
+                        CLIENT_FOP_RSP_CLEANUP (rsp, xattrop, i);
3604df
+                        free (tmp_rsp->dict.dict_val);
3604df
+                        break;
3604df
+                }
3604df
+                case GF_FOP_FXATTROP:
3604df
+                {
3604df
+                        gfs3_fxattrop_rsp *tmp_rsp = &CPD_RSP_FIELD(this_rsp,
3604df
+                                                     fxattrop);
3604df
+                        CLIENT_FOP_RSP_CLEANUP (rsp, fxattrop, i);
3604df
+                        free (tmp_rsp->dict.dict_val);
3604df
+                        break;
3604df
+                }
3604df
+                case GF_FOP_READDIR:
3604df
+                {
3604df
+                        CLIENT_FOP_RSP_CLEANUP (rsp, readdir, i);
3604df
+                        gfs3_readdir_rsp *tmp_rsp = &CPD_RSP_FIELD(this_rsp,
3604df
+                                                    readdir);
3604df
+                        clnt_readdir_rsp_cleanup (tmp_rsp);
3604df
+                        break;
3604df
+                }
3604df
+                case GF_FOP_READDIRP:
3604df
+                {
3604df
+                        CLIENT_FOP_RSP_CLEANUP (rsp, readdirp, i);
3604df
+                        gfs3_readdirp_rsp *tmp_rsp = &CPD_RSP_FIELD(this_rsp,
3604df
+                                                     readdirp);
3604df
+                        clnt_readdirp_rsp_cleanup (tmp_rsp);
3604df
+                        break;
3604df
+                }
3604df
+                case GF_FOP_GETXATTR:
3604df
+                {
3604df
+                        gfs3_getxattr_rsp *tmp_rsp = &CPD_RSP_FIELD(this_rsp,
3604df
+                                                     getxattr);
3604df
+                        CLIENT_FOP_RSP_CLEANUP (rsp, getxattr, i);
3604df
+                        free (tmp_rsp->dict.dict_val);
3604df
+                        break;
3604df
+                }
3604df
+                case GF_FOP_FGETXATTR:
3604df
+                {
3604df
+                        gfs3_fgetxattr_rsp *tmp_rsp = &CPD_RSP_FIELD(this_rsp,
3604df
+                                                      fgetxattr);
3604df
+                        CLIENT_FOP_RSP_CLEANUP (rsp, fgetxattr, i);
3604df
+                        free (tmp_rsp->dict.dict_val);
3604df
+                        break;
3604df
+                }
3604df
+                case GF_FOP_RCHECKSUM:
3604df
+                {
3604df
+                        gfs3_rchecksum_rsp *rck = &CPD_RSP_FIELD(this_rsp,
3604df
+                                                  rchecksum);
3604df
+                        CLIENT_FOP_RSP_CLEANUP (rsp, rchecksum, i);
3604df
+                        if (rck->strong_checksum.strong_checksum_val) {
3604df
+                                free (rck->strong_checksum.strong_checksum_val);
3604df
+                        }
3604df
+                        break;
3604df
+                }
3604df
+                default:
3604df
+                        break;
3604df
+                }
3604df
+        }
3604df
+        return;
3604df
+}
3604df
diff --git a/xlators/protocol/client/src/client-rpc-fops.c b/xlators/protocol/client/src/client-rpc-fops.c
3604df
index b26c494..c122941 100644
3604df
--- a/xlators/protocol/client/src/client-rpc-fops.c
3604df
+++ b/xlators/protocol/client/src/client-rpc-fops.c
3604df
@@ -16,6 +16,7 @@
3604df
 #include "client-messages.h"
3604df
 #include "defaults.h"
3604df
 #include "client-common.h"
3604df
+#include "compound-fop-utils.h"
3604df
 
3604df
 int32_t client3_getspec (call_frame_t *frame, xlator_t *this, void *data);
3604df
 rpc_clnt_prog_t clnt3_3_fop_prog;
3604df
@@ -3161,12 +3162,12 @@ client3_3_compound_cbk (struct rpc_req *req, struct iovec *iov, int count,
3604df
         gfs3_compound_rsp       rsp              = {0,};
3604df
         compound_args_cbk_t     *args_cbk        = NULL;
3604df
         call_frame_t            *frame           = NULL;
3604df
-        int                     ret              = -1;
3604df
         xlator_t                *this            = NULL;
3604df
         dict_t                  *xdata           = NULL;
3604df
         clnt_local_t            *local           = NULL;
3604df
         int                     op_errno         = 0;
3604df
         int                     i,length         = 0;
3604df
+        int                     ret              = -1;
3604df
 
3604df
         this = THIS;
3604df
 
3604df
@@ -3186,55 +3187,40 @@ client3_3_compound_cbk (struct rpc_req *req, struct iovec *iov, int count,
3604df
                 goto out;
3604df
         }
3604df
 
3604df
-        args_cbk = GF_CALLOC (1, sizeof (compound_args_cbk_t), gf_mt_compound_rsp_t);
3604df
-        if (!args_cbk) {
3604df
-                op_errno = ENOMEM;
3604df
-                goto out;
3604df
-        }
3604df
+        GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
3604df
+                                      (rsp.xdata.xdata_len), rsp.op_ret,
3604df
+                                       rsp.op_errno, out);
3604df
 
3604df
-        length = args_cbk->fop_length = local->length;
3604df
+        length =  local->length;
3604df
 
3604df
-        args_cbk->rsp_list = GF_CALLOC (length, sizeof (default_args_cbk_t),
3604df
-                                        gf_mt_default_args_cbk_t);
3604df
-        if (!args_cbk->rsp_list) {
3604df
+        args_cbk = compound_args_cbk_alloc (length, xdata);
3604df
+        if (!args_cbk) {
3604df
                 op_errno = ENOMEM;
3604df
                 goto out;
3604df
         }
3604df
 
3604df
-        op_errno = rsp.op_errno;
3604df
-
3604df
         for (i = 0; i < args_cbk->fop_length; i++) {
3604df
                 ret = client_process_response (frame, this, req, &rsp,
3604df
                                                args_cbk, i);
3604df
                 if (ret) {
3604df
                         op_errno = -ret;
3604df
-                        ret = -1;
3604df
                         goto out;
3604df
                 }
3604df
 
3604df
         }
3604df
-
3604df
-        GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
3604df
-                                      (rsp.xdata.xdata_len), ret,
3604df
-                                       rsp.op_errno, out);
3604df
-
3604df
-        ret = 0;
3604df
+        rsp.op_ret = 0;
3604df
 out:
3604df
-        CLIENT_STACK_UNWIND (compound, frame, ret,
3604df
-                             gf_error_to_errno (op_errno), args_cbk, xdata);
3604df
+        CLIENT_STACK_UNWIND (compound, frame, rsp.op_ret,
3604df
+                             gf_error_to_errno (rsp.op_errno), args_cbk, xdata);
3604df
 
3604df
         free (rsp.xdata.xdata_val);
3604df
 
3604df
+        client_compound_rsp_cleanup (&rsp, local->length);
3604df
+
3604df
         if (xdata)
3604df
                 dict_unref (xdata);
3604df
 
3604df
-        if (args_cbk->rsp_list) {
3604df
-                for (i = 0; i < length; i++) {
3604df
-                        args_cbk_wipe (&args_cbk->rsp_list[i]);
3604df
-                }
3604df
-        }
3604df
-        GF_FREE (args_cbk->rsp_list);
3604df
-        GF_FREE (args_cbk);
3604df
+        compound_args_cbk_cleanup (args_cbk);
3604df
         return 0;
3604df
 }
3604df
 
3604df
@@ -6131,7 +6117,6 @@ client3_3_compound (call_frame_t *frame, xlator_t *this, void *data)
3604df
         struct iobuf            *rsphdr_iobuf       = NULL;
3604df
         int                     rsphdr_count        = 0;
3604df
         int                     req_count           = 0;
3604df
-        int                     index               = 0;
3604df
         dict_t                  *xdata              = c_args->xdata;
3604df
 
3604df
         GF_ASSERT (frame);
3604df
@@ -6171,13 +6156,11 @@ client3_3_compound (call_frame_t *frame, xlator_t *this, void *data)
3604df
         rsphdr->iov_base = iobuf_ptr (rsphdr_iobuf);
3604df
         rsphdr->iov_len = iobuf_pagesize (rsphdr_iobuf);
3604df
         rsphdr_count = 1;
3604df
-        local->iobref = rsp_iobref;
3604df
         rsphdr_iobuf = NULL;
3604df
         rsphdr_iobref = NULL;
3604df
 
3604df
         req.compound_fop_enum = c_args->fop_enum;
3604df
         req.compound_req_array.compound_req_array_len = c_args->fop_length;
3604df
-        /*TODO : Talk to Sowmya about this */
3604df
         req.compound_version = 0;
3604df
         if (xdata) {
3604df
                 GF_PROTOCOL_DICT_SERIALIZE (this, xdata,
3604df
@@ -6198,29 +6181,28 @@ client3_3_compound (call_frame_t *frame, xlator_t *this, void *data)
3604df
         for (i = 0; i < local->length; i++) {
3604df
                 ret = client_handle_fop_requirements (this, frame,
3604df
                                                       &req, local,
3604df
-                                                      req_iobref, rsp_iobref,
3604df
+                                                      &req_iobref, &rsp_iobref,
3604df
                                                       req_vector,
3604df
                                                       rsp_vector, &req_count,
3604df
                                                       &rsp_count,
3604df
                                                       &c_args->req_list[i],
3604df
                                                       c_args->enum_list[i],
3604df
-                                                      index);
3604df
+                                                      i);
3604df
                 if (ret) {
3604df
                         op_errno = ret;
3604df
                         goto unwind;
3604df
                 }
3604df
-                index++;
3604df
         }
3604df
 
3604df
-        local->iobref2 = rsp_iobref;
3604df
+        local->iobref = rsp_iobref;
3604df
         rsp_iobref     = NULL;
3604df
 
3604df
         ret = client_submit_compound_request (this, &req, frame, conf->fops,
3604df
                                      GFS3_OP_COMPOUND, client3_3_compound_cbk,
3604df
-                                     req_vector, req_count, local->iobref,
3604df
+                                     req_vector, req_count, req_iobref,
3604df
                                      rsphdr, rsphdr_count,
3604df
                                      rsp_vector, rsp_count,
3604df
-                                     local->iobref2,
3604df
+                                     local->iobref,
3604df
                                      (xdrproc_t) xdr_gfs3_compound_req);
3604df
 
3604df
         GF_FREE (req.xdata.xdata_val);
3604df
diff --git a/xlators/protocol/client/src/client.h b/xlators/protocol/client/src/client.h
3604df
index c2b8d54..8854b82 100644
3604df
--- a/xlators/protocol/client/src/client.h
3604df
+++ b/xlators/protocol/client/src/client.h
3604df
@@ -89,6 +89,24 @@ typedef enum {
3604df
                 GF_FREE (_req->xdata.xdata_val);                              \
3604df
         } while (0)
3604df
 
3604df
+#define CLIENT_COMMON_RSP_CLEANUP(rsp, fop, i)                                \
3604df
+        do {                                                                  \
3604df
+                compound_rsp            *this_rsp       = NULL;               \
3604df
+                this_rsp = &rsp->compound_rsp_array.compound_rsp_array_val[i];\
3604df
+                gf_common_rsp *_this_rsp = &CPD_RSP_FIELD (this_rsp, fop);    \
3604df
+                                                                              \
3604df
+                free (_this_rsp->xdata.xdata_val);                            \
3604df
+        } while (0)
3604df
+
3604df
+#define CLIENT_FOP_RSP_CLEANUP(rsp, fop, i)                                   \
3604df
+        do {                                                                  \
3604df
+                compound_rsp            *this_rsp       = NULL;               \
3604df
+                this_rsp = &rsp->compound_rsp_array.compound_rsp_array_val[i];\
3604df
+                gfs3_##fop##_rsp * _this_rsp = &CPD_RSP_FIELD (this_rsp, fop); \
3604df
+                                                                              \
3604df
+                free (_this_rsp->xdata.xdata_val);                            \
3604df
+        } while (0)
3604df
+
3604df
 #define CLIENT_GET_REMOTE_FD(xl, fd, flags, remote_fd, op_errno, label) \
3604df
         do {                                                            \
3604df
                 int     _ret    = 0;                                    \
3604df
@@ -233,7 +251,6 @@ typedef struct client_local {
3604df
         char                *name;
3604df
         gf_boolean_t         attempt_reopen;
3604df
         /* required for compound fops */
3604df
-        struct iobref       *iobref2;
3604df
         compound_args_t     *compound_args;
3604df
         unsigned int         length; /* length of a compound fop */
3604df
         unsigned int         read_length; /* defines the last processed length for a compound read */
3604df
@@ -353,8 +370,8 @@ int
3604df
 client_handle_fop_requirements (xlator_t *this, call_frame_t *frame,
3604df
                                 gfs3_compound_req *req,
3604df
                                 clnt_local_t *local,
3604df
-                                struct iobref *req_iobref,
3604df
-                                struct iobref *rsp_iobref,
3604df
+                                struct iobref **req_iobref,
3604df
+                                struct iobref **rsp_iobref,
3604df
                                 struct iovec *req_vector,
3604df
                                 struct iovec *rsp_vector, int *req_count,
3604df
                                 int *rsp_count, default_args_t *args,
3604df
@@ -380,4 +397,6 @@ int
3604df
 serialize_req_locklist (lock_migration_info_t *locklist,
3604df
                         gfs3_setactivelk_req *req);
3604df
 
3604df
+void
3604df
+client_compound_rsp_cleanup (gfs3_compound_rsp *rsp, int len);
3604df
 #endif /* !_CLIENT_H */
3604df
diff --git a/xlators/protocol/server/src/server-helpers.c b/xlators/protocol/server/src/server-helpers.c
3604df
index 474db92..1fe44dd 100644
3604df
--- a/xlators/protocol/server/src/server-helpers.c
3604df
+++ b/xlators/protocol/server/src/server-helpers.c
3604df
@@ -20,6 +20,7 @@
3604df
 #include <fnmatch.h>
3604df
 #include <pwd.h>
3604df
 #include <grp.h>
3604df
+#include "compound-fop-utils.h"
3604df
 
3604df
 /* based on nfs_fix_aux_groups() */
3604df
 int
3604df
@@ -230,6 +231,8 @@ free_state (server_state_t *state)
3604df
         server_resolve_wipe (&state->resolve);
3604df
         server_resolve_wipe (&state->resolve2);
3604df
 
3604df
+        compound_args_cleanup (state->args);
3604df
+
3604df
         GF_FREE (state);
3604df
 }
3604df
 
3604df
@@ -1577,12 +1580,23 @@ server_populate_compound_request (gfs3_compound_req *req, call_frame_t *frame,
3604df
                                               args->xdata.xdata_val,
3604df
                                               args->xdata.xdata_len, ret,
3604df
                                               op_errno, out);
3604df
+                /* The way writev fop works :
3604df
+                 * xdr args of write along with other args contains
3604df
+                 * write length not count. But when the call is wound to posix,
3604df
+                 * this length is not used. It is taken from the request
3604df
+                 * write vector that is passed down. Posix needs the vector
3604df
+                 * count to determine the amount of write to be done.
3604df
+                 * This count for writes that come as part of compound fops
3604df
+                 * will be 1. The vectors are merged into one under
3604df
+                 * GF_FOP_WRITE section of client_handle_fop_requirements()
3604df
+                 * in protocol client.
3604df
+                 */
3604df
                 args_writev_store (this_args, state->fd,
3604df
                                    req_iovec,
3604df
-                                   args->size, args->offset,
3604df
+                                   1, args->offset,
3604df
                                    args->flag,
3604df
-                                   this_args->iobref, this_args->xdata);
3604df
-                state->write_length += args->size;
3604df
+                                   state->iobref, this_args->xdata);
3604df
+                state->write_length += req_iovec[0].iov_len;
3604df
                 break;
3604df
         }
3604df
         case GF_FOP_STATFS:
3604df
@@ -2266,24 +2280,18 @@ server_populate_compound_response (xlator_t *this, gfs3_compound_rsp *rsp,
3604df
                                    call_frame_t *frame,
3604df
                                    compound_args_cbk_t *args_cbk, int index)
3604df
 {
3604df
-        int                     op_errno    = ENOMEM;
3604df
-        int                     op_ret      = -1;
3604df
+        int                     op_errno    = EINVAL;
3604df
         default_args_cbk_t      *this_args_cbk = NULL;
3604df
         compound_rsp            *this_rsp   = NULL;
3604df
         server_state_t          *state      = NULL;
3604df
         int                     ret         = 0;
3604df
 
3604df
         state = CALL_STATE (frame);
3604df
-        rsp->compound_rsp_array.compound_rsp_array_val = GF_CALLOC
3604df
-                                                         (args_cbk->fop_length,
3604df
-                                                         sizeof (compound_rsp),
3604df
-                                                  gf_server_mt_compound_rsp_t);
3604df
-
3604df
-        rsp->compound_rsp_array.compound_rsp_array_len = args_cbk->fop_length;
3604df
 
3604df
         this_rsp = &rsp->compound_rsp_array.compound_rsp_array_val[index];
3604df
-
3604df
         this_args_cbk = &args_cbk->rsp_list[index];
3604df
+        this_rsp->fop_enum = args_cbk->enum_list[index];
3604df
+
3604df
         switch (this_rsp->fop_enum) {
3604df
         case GF_FOP_STAT:
3604df
         {
3604df
@@ -3222,6 +3230,7 @@ server_populate_compound_response (xlator_t *this, gfs3_compound_rsp *rsp,
3604df
         default:
3604df
                 return ENOTSUP;
3604df
         }
3604df
+        op_errno = 0;
3604df
 out:
3604df
         return op_errno;
3604df
 }
3604df
@@ -3234,8 +3243,8 @@ out:
3604df
 int
3604df
 server_get_compound_resolve (server_state_t *state, gfs3_compound_req *req)
3604df
 {
3604df
-        int                      i          = 0;
3604df
-        compound_req             *array     = &req->compound_req_array.compound_req_array_val[i];
3604df
+        int           i     = 0;
3604df
+        compound_req *array = &req->compound_req_array.compound_req_array_val[i];
3604df
 
3604df
         switch (array->fop_enum) {
3604df
         case GF_FOP_STAT:
3604df
@@ -3790,3 +3799,494 @@ server_get_compound_resolve (server_state_t *state, gfs3_compound_req *req)
3604df
         }
3604df
         return 0;
3604df
 }
3604df
+
3604df
+void
3604df
+server_compound_rsp_cleanup (gfs3_compound_rsp *rsp, compound_args_cbk_t *args)
3604df
+{
3604df
+        int                     i, len          = 0;
3604df
+        compound_rsp            *this_rsp       = NULL;
3604df
+
3604df
+        if (!rsp->compound_rsp_array.compound_rsp_array_val)
3604df
+                return;
3604df
+
3604df
+        len = rsp->compound_rsp_array.compound_rsp_array_len;
3604df
+        return;
3604df
+
3604df
+        for (i = 0; i < len; i++) {
3604df
+                this_rsp = &rsp->compound_rsp_array.compound_rsp_array_val[i];
3604df
+                switch (args->enum_list[i]) {
3604df
+                case GF_FOP_STAT:
3604df
+                        SERVER_FOP_RSP_CLEANUP (rsp, stat, i);
3604df
+                        break;
3604df
+                case GF_FOP_MKNOD:
3604df
+                        SERVER_FOP_RSP_CLEANUP (rsp, mknod, i);
3604df
+                        break;
3604df
+                case GF_FOP_MKDIR:
3604df
+                        SERVER_FOP_RSP_CLEANUP (rsp, mkdir, i);
3604df
+                        break;
3604df
+                case GF_FOP_UNLINK:
3604df
+                        SERVER_FOP_RSP_CLEANUP (rsp, unlink, i);
3604df
+                        break;
3604df
+                case GF_FOP_RMDIR:
3604df
+                        SERVER_FOP_RSP_CLEANUP (rsp, rmdir, i);
3604df
+                        break;
3604df
+                case GF_FOP_SYMLINK:
3604df
+                        SERVER_FOP_RSP_CLEANUP (rsp, symlink, i);
3604df
+                        break;
3604df
+                case GF_FOP_RENAME:
3604df
+                        SERVER_FOP_RSP_CLEANUP (rsp, rename, i);
3604df
+                        break;
3604df
+                case GF_FOP_LINK:
3604df
+                        SERVER_FOP_RSP_CLEANUP (rsp, link, i);
3604df
+                        break;
3604df
+                case GF_FOP_TRUNCATE:
3604df
+                        SERVER_FOP_RSP_CLEANUP (rsp, truncate, i);
3604df
+                        break;
3604df
+                case GF_FOP_OPEN:
3604df
+                        SERVER_FOP_RSP_CLEANUP (rsp, open, i);
3604df
+                        break;
3604df
+                case GF_FOP_READ:
3604df
+                        SERVER_FOP_RSP_CLEANUP (rsp, read, i);
3604df
+                        break;
3604df
+                case GF_FOP_WRITE:
3604df
+                        SERVER_FOP_RSP_CLEANUP (rsp, write, i);
3604df
+                        break;
3604df
+                case GF_FOP_STATFS:
3604df
+                        SERVER_FOP_RSP_CLEANUP (rsp, statfs, i);
3604df
+                        break;
3604df
+                case GF_FOP_FSYNC:
3604df
+                        SERVER_FOP_RSP_CLEANUP (rsp, fsync, i);
3604df
+                        break;
3604df
+                case GF_FOP_OPENDIR:
3604df
+                        SERVER_FOP_RSP_CLEANUP (rsp, opendir, i);
3604df
+                        break;
3604df
+                case GF_FOP_CREATE:
3604df
+                        SERVER_FOP_RSP_CLEANUP (rsp, create, i);
3604df
+                        break;
3604df
+                case GF_FOP_FTRUNCATE:
3604df
+                        SERVER_FOP_RSP_CLEANUP (rsp, ftruncate, i);
3604df
+                        break;
3604df
+                case GF_FOP_FSTAT:
3604df
+                        SERVER_FOP_RSP_CLEANUP (rsp, fstat, i);
3604df
+                        break;
3604df
+                case GF_FOP_LK:
3604df
+                        SERVER_FOP_RSP_CLEANUP (rsp, lk, i);
3604df
+                        break;
3604df
+                case GF_FOP_LOOKUP:
3604df
+                        SERVER_FOP_RSP_CLEANUP (rsp, lookup, i);
3604df
+                        break;
3604df
+                case GF_FOP_SETATTR:
3604df
+                        SERVER_FOP_RSP_CLEANUP (rsp, setattr, i);
3604df
+                        break;
3604df
+                case GF_FOP_FSETATTR:
3604df
+                        SERVER_FOP_RSP_CLEANUP (rsp, fsetattr, i);
3604df
+                        break;
3604df
+                case GF_FOP_FALLOCATE:
3604df
+                        SERVER_FOP_RSP_CLEANUP (rsp, fallocate, i);
3604df
+                        break;
3604df
+                case GF_FOP_DISCARD:
3604df
+                        SERVER_FOP_RSP_CLEANUP (rsp, discard, i);
3604df
+                        break;
3604df
+                case GF_FOP_ZEROFILL:
3604df
+                        SERVER_FOP_RSP_CLEANUP (rsp, zerofill, i);
3604df
+                        break;
3604df
+                case GF_FOP_IPC:
3604df
+                        SERVER_FOP_RSP_CLEANUP (rsp, ipc, i);
3604df
+                        break;
3604df
+                case GF_FOP_SEEK:
3604df
+                        SERVER_FOP_RSP_CLEANUP (rsp, seek, i);
3604df
+                        break;
3604df
+                case GF_FOP_LEASE:
3604df
+                        SERVER_FOP_RSP_CLEANUP (rsp, lease, i);
3604df
+                        break;
3604df
+                /* fops that use gf_common_rsp */
3604df
+                case GF_FOP_FLUSH:
3604df
+                        SERVER_COMMON_RSP_CLEANUP (rsp, flush, i);
3604df
+                        break;
3604df
+                case GF_FOP_SETXATTR:
3604df
+                        SERVER_COMMON_RSP_CLEANUP (rsp, setxattr, i);
3604df
+                        break;
3604df
+                case GF_FOP_REMOVEXATTR:
3604df
+                        SERVER_COMMON_RSP_CLEANUP (rsp, removexattr, i);
3604df
+                        break;
3604df
+                case GF_FOP_FSETXATTR:
3604df
+                        SERVER_COMMON_RSP_CLEANUP (rsp, fsetxattr, i);
3604df
+                        break;
3604df
+                case GF_FOP_FREMOVEXATTR:
3604df
+                        SERVER_COMMON_RSP_CLEANUP (rsp, fremovexattr, i);
3604df
+                        break;
3604df
+                case GF_FOP_FSYNCDIR:
3604df
+                        SERVER_COMMON_RSP_CLEANUP (rsp, fsyncdir, i);
3604df
+                        break;
3604df
+                case GF_FOP_ACCESS:
3604df
+                        SERVER_COMMON_RSP_CLEANUP (rsp, access, i);
3604df
+                        break;
3604df
+                case GF_FOP_INODELK:
3604df
+                        SERVER_COMMON_RSP_CLEANUP (rsp, inodelk, i);
3604df
+                        break;
3604df
+                case GF_FOP_FINODELK:
3604df
+                        SERVER_COMMON_RSP_CLEANUP (rsp, finodelk, i);
3604df
+                        break;
3604df
+                case GF_FOP_ENTRYLK:
3604df
+                        SERVER_COMMON_RSP_CLEANUP (rsp, entrylk, i);
3604df
+                        break;
3604df
+                case GF_FOP_FENTRYLK:
3604df
+                        SERVER_COMMON_RSP_CLEANUP (rsp, fentrylk, i);
3604df
+                        break;
3604df
+                case GF_FOP_READLINK:
3604df
+                        SERVER_FOP_RSP_CLEANUP (rsp, readlink, i);
3604df
+                        break;
3604df
+                case GF_FOP_RCHECKSUM:
3604df
+                        SERVER_FOP_RSP_CLEANUP (rsp, rchecksum, i);
3604df
+                        break;
3604df
+                /* fops that need extra cleanup */
3604df
+                case GF_FOP_XATTROP:
3604df
+                {
3604df
+                        gfs3_xattrop_rsp *tmp_rsp = &CPD_RSP_FIELD(this_rsp,
3604df
+                                                    xattrop);
3604df
+                        SERVER_FOP_RSP_CLEANUP (rsp, xattrop, i);
3604df
+                        GF_FREE (tmp_rsp->dict.dict_val);
3604df
+                        break;
3604df
+                }
3604df
+                case GF_FOP_FXATTROP:
3604df
+                {
3604df
+                        gfs3_fxattrop_rsp *tmp_rsp = &CPD_RSP_FIELD(this_rsp,
3604df
+                                                     fxattrop);
3604df
+                        SERVER_FOP_RSP_CLEANUP (rsp, fxattrop, i);
3604df
+                        GF_FREE (tmp_rsp->dict.dict_val);
3604df
+                        break;
3604df
+                }
3604df
+                case GF_FOP_READDIR:
3604df
+                {
3604df
+                        gfs3_readdir_rsp *tmp_rsp = &CPD_RSP_FIELD(this_rsp,
3604df
+                                                    readdir);
3604df
+                        SERVER_FOP_RSP_CLEANUP (rsp, readdir, i);
3604df
+                        readdir_rsp_cleanup (tmp_rsp);
3604df
+                        break;
3604df
+                }
3604df
+                case GF_FOP_READDIRP:
3604df
+                {
3604df
+                        gfs3_readdirp_rsp *tmp_rsp = &CPD_RSP_FIELD(this_rsp,
3604df
+                                                     readdirp);
3604df
+                        SERVER_FOP_RSP_CLEANUP (rsp, readdir, i);
3604df
+                        readdirp_rsp_cleanup (tmp_rsp);
3604df
+                        break;
3604df
+                }
3604df
+                case GF_FOP_GETXATTR:
3604df
+                {
3604df
+                        gfs3_getxattr_rsp *tmp_rsp = &CPD_RSP_FIELD(this_rsp,
3604df
+                                                     getxattr);
3604df
+                        SERVER_FOP_RSP_CLEANUP (rsp, getxattr, i);
3604df
+                        GF_FREE (tmp_rsp->dict.dict_val);
3604df
+                        break;
3604df
+                }
3604df
+                case GF_FOP_FGETXATTR:
3604df
+                {
3604df
+                        gfs3_fgetxattr_rsp *tmp_rsp = &CPD_RSP_FIELD(this_rsp,
3604df
+                                                      fgetxattr);
3604df
+                        SERVER_FOP_RSP_CLEANUP (rsp, fgetxattr, i);
3604df
+                        GF_FREE (tmp_rsp->dict.dict_val);
3604df
+                        break;
3604df
+                }
3604df
+                default:
3604df
+                        break;
3604df
+                }
3604df
+        }
3604df
+        return;
3604df
+}
3604df
+
3604df
+void
3604df
+server_compound_req_cleanup (gfs3_compound_req *req, int len)
3604df
+{
3604df
+        int             i        = 0;
3604df
+        compound_req   *curr_req = NULL;
3604df
+
3604df
+
3604df
+        if (!req->compound_req_array.compound_req_array_val)
3604df
+                return;
3604df
+
3604df
+        for (i = 0; i < len; i++) {
3604df
+                curr_req = &req->compound_req_array.compound_req_array_val[i];
3604df
+
3604df
+                switch (curr_req->fop_enum) {
3604df
+                case GF_FOP_STAT:
3604df
+                        SERVER_COMPOUND_FOP_CLEANUP (curr_req, stat);
3604df
+                        break;
3604df
+                case GF_FOP_READLINK:
3604df
+                        SERVER_COMPOUND_FOP_CLEANUP (curr_req, readlink);
3604df
+                        break;
3604df
+                case GF_FOP_MKNOD:
3604df
+                        SERVER_COMPOUND_FOP_CLEANUP (curr_req, mknod);
3604df
+                        break;
3604df
+                case GF_FOP_MKDIR:
3604df
+                {
3604df
+                        gfs3_mkdir_req *args = &CPD_REQ_FIELD (curr_req, mkdir);
3604df
+
3604df
+                        SERVER_COMPOUND_FOP_CLEANUP (curr_req, mkdir);
3604df
+                        free (args->bname);
3604df
+                        break;
3604df
+                }
3604df
+                case GF_FOP_UNLINK:
3604df
+                {
3604df
+                        gfs3_unlink_req *args = &CPD_REQ_FIELD (curr_req,
3604df
+                                                unlink);
3604df
+
3604df
+                        SERVER_COMPOUND_FOP_CLEANUP (curr_req, unlink);
3604df
+                        free (args->bname);
3604df
+                        break;
3604df
+                }
3604df
+                case GF_FOP_RMDIR:
3604df
+                {
3604df
+                        gfs3_rmdir_req *args = &CPD_REQ_FIELD (curr_req,
3604df
+                                               rmdir);
3604df
+
3604df
+                        SERVER_COMPOUND_FOP_CLEANUP (curr_req, rmdir);
3604df
+                        free (args->bname);
3604df
+                        break;
3604df
+                }
3604df
+                case GF_FOP_SYMLINK:
3604df
+                {
3604df
+                        gfs3_symlink_req *args = &CPD_REQ_FIELD (curr_req,
3604df
+                                                 symlink);
3604df
+
3604df
+                        SERVER_COMPOUND_FOP_CLEANUP (curr_req, symlink);
3604df
+                        free (args->bname);
3604df
+                        free (args->linkname);
3604df
+                        break;
3604df
+                }
3604df
+                case GF_FOP_RENAME:
3604df
+                {
3604df
+                        gfs3_rename_req *args = &CPD_REQ_FIELD (curr_req,
3604df
+                                                rename);
3604df
+
3604df
+                        SERVER_COMPOUND_FOP_CLEANUP (curr_req, rename);
3604df
+                        free (args->oldbname);
3604df
+                        free (args->newbname);
3604df
+                        break;
3604df
+                }
3604df
+                case GF_FOP_LINK:
3604df
+                {
3604df
+                        gfs3_link_req *args = &CPD_REQ_FIELD (curr_req,
3604df
+                                              link);
3604df
+
3604df
+                        SERVER_COMPOUND_FOP_CLEANUP (curr_req, link);
3604df
+                        free (args->newbname);
3604df
+                        break;
3604df
+                }
3604df
+                case GF_FOP_TRUNCATE:
3604df
+                        SERVER_COMPOUND_FOP_CLEANUP (curr_req, truncate);
3604df
+                        break;
3604df
+                case GF_FOP_OPEN:
3604df
+                        SERVER_COMPOUND_FOP_CLEANUP (curr_req, open);
3604df
+                        break;
3604df
+                case GF_FOP_READ:
3604df
+                        SERVER_COMPOUND_FOP_CLEANUP (curr_req, read);
3604df
+                        break;
3604df
+                case GF_FOP_WRITE:
3604df
+                        SERVER_COMPOUND_FOP_CLEANUP (curr_req, write);
3604df
+                        break;
3604df
+                case GF_FOP_STATFS:
3604df
+                        SERVER_COMPOUND_FOP_CLEANUP (curr_req, statfs);
3604df
+                        break;
3604df
+                case GF_FOP_FLUSH:
3604df
+                        SERVER_COMPOUND_FOP_CLEANUP (curr_req, flush);
3604df
+                        break;
3604df
+                case GF_FOP_FSYNC:
3604df
+                        SERVER_COMPOUND_FOP_CLEANUP (curr_req, fsync);
3604df
+                        break;
3604df
+                case GF_FOP_SETXATTR:
3604df
+                {
3604df
+                        gfs3_setxattr_req *args = &CPD_REQ_FIELD (curr_req,
3604df
+                                                  setxattr);
3604df
+
3604df
+                        free (args->dict.dict_val);
3604df
+                        SERVER_COMPOUND_FOP_CLEANUP (curr_req, setxattr);
3604df
+                        break;
3604df
+                }
3604df
+                case GF_FOP_GETXATTR:
3604df
+                {
3604df
+                        gfs3_getxattr_req *args = &CPD_REQ_FIELD (curr_req,
3604df
+                                                  getxattr);
3604df
+
3604df
+                        SERVER_COMPOUND_FOP_CLEANUP (curr_req, getxattr);
3604df
+                        free (args->name);
3604df
+                        break;
3604df
+                }
3604df
+                case GF_FOP_REMOVEXATTR:
3604df
+                {
3604df
+                        gfs3_removexattr_req *args = &CPD_REQ_FIELD (curr_req,
3604df
+                                                     removexattr);
3604df
+
3604df
+                        SERVER_COMPOUND_FOP_CLEANUP (curr_req, removexattr);
3604df
+                        free (args->name);
3604df
+                        break;
3604df
+                }
3604df
+                case GF_FOP_OPENDIR:
3604df
+                        SERVER_COMPOUND_FOP_CLEANUP (curr_req, opendir);
3604df
+                        break;
3604df
+                case GF_FOP_FSYNCDIR:
3604df
+                        SERVER_COMPOUND_FOP_CLEANUP (curr_req, fsyncdir);
3604df
+                        break;
3604df
+                case GF_FOP_ACCESS:
3604df
+                        SERVER_COMPOUND_FOP_CLEANUP (curr_req, access);
3604df
+                        break;
3604df
+                case GF_FOP_CREATE:
3604df
+                {
3604df
+                        gfs3_create_req *args = &CPD_REQ_FIELD (curr_req,
3604df
+                                                create);
3604df
+
3604df
+                        SERVER_COMPOUND_FOP_CLEANUP (curr_req, create);
3604df
+                        free (args->bname);
3604df
+                        break;
3604df
+                }
3604df
+                case GF_FOP_FTRUNCATE:
3604df
+                        SERVER_COMPOUND_FOP_CLEANUP (curr_req, ftruncate);
3604df
+                        break;
3604df
+                case GF_FOP_FSTAT:
3604df
+                        SERVER_COMPOUND_FOP_CLEANUP (curr_req, fstat);
3604df
+                        break;
3604df
+                case GF_FOP_LK:
3604df
+                {
3604df
+                        gfs3_lk_req *args = &CPD_REQ_FIELD (curr_req, lk);
3604df
+
3604df
+                        SERVER_COMPOUND_FOP_CLEANUP (curr_req, lk);
3604df
+                        free (args->flock.lk_owner.lk_owner_val);
3604df
+                        break;
3604df
+                }
3604df
+                case GF_FOP_LOOKUP:
3604df
+                {
3604df
+                        gfs3_lookup_req *args = &CPD_REQ_FIELD (curr_req,
3604df
+                                                                lookup);
3604df
+
3604df
+                        SERVER_COMPOUND_FOP_CLEANUP (curr_req, lookup);
3604df
+                        free (args->bname);
3604df
+                        break;
3604df
+                }
3604df
+                case GF_FOP_READDIR:
3604df
+                        SERVER_COMPOUND_FOP_CLEANUP (curr_req, readdir);
3604df
+                        break;
3604df
+                case GF_FOP_INODELK:
3604df
+                {
3604df
+                        gfs3_inodelk_req *args = &CPD_REQ_FIELD (curr_req,
3604df
+                                                                 inodelk);
3604df
+
3604df
+                        SERVER_COMPOUND_FOP_CLEANUP (curr_req, inodelk);
3604df
+                        free (args->volume);
3604df
+                        free (args->flock.lk_owner.lk_owner_val);
3604df
+                        break;
3604df
+                }
3604df
+                case GF_FOP_FINODELK:
3604df
+                {
3604df
+                        gfs3_finodelk_req *args = &CPD_REQ_FIELD (curr_req,
3604df
+                                                                  finodelk);
3604df
+
3604df
+                        SERVER_COMPOUND_FOP_CLEANUP (curr_req, finodelk);
3604df
+                        free (args->volume);
3604df
+                        free (args->flock.lk_owner.lk_owner_val);
3604df
+                        break;
3604df
+                }
3604df
+                case GF_FOP_ENTRYLK:
3604df
+                {
3604df
+                        gfs3_entrylk_req *args = &CPD_REQ_FIELD (curr_req,
3604df
+                                                                 entrylk);
3604df
+
3604df
+                        SERVER_COMPOUND_FOP_CLEANUP (curr_req, entrylk);
3604df
+                        free (args->volume);
3604df
+                        free (args->name);
3604df
+                        break;
3604df
+                }
3604df
+                case GF_FOP_FENTRYLK:
3604df
+                {
3604df
+                        gfs3_fentrylk_req *args = &CPD_REQ_FIELD (curr_req,
3604df
+                                                                  fentrylk);
3604df
+
3604df
+                        SERVER_COMPOUND_FOP_CLEANUP (curr_req, fentrylk);
3604df
+                        free (args->volume);
3604df
+                        free (args->name);
3604df
+                        break;
3604df
+                }
3604df
+                case GF_FOP_XATTROP:
3604df
+                {
3604df
+                        gfs3_xattrop_req *args = &CPD_REQ_FIELD (curr_req,
3604df
+                                                                 xattrop);
3604df
+
3604df
+                        free (args->dict.dict_val);
3604df
+                        SERVER_COMPOUND_FOP_CLEANUP (curr_req, xattrop);
3604df
+                        break;
3604df
+                }
3604df
+                case GF_FOP_FXATTROP:
3604df
+                {
3604df
+                        gfs3_fxattrop_req *args = &CPD_REQ_FIELD (curr_req,
3604df
+                                                                  fxattrop);
3604df
+
3604df
+                        free (args->dict.dict_val);
3604df
+                        SERVER_COMPOUND_FOP_CLEANUP (curr_req, fxattrop);
3604df
+                        break;
3604df
+                }
3604df
+                case GF_FOP_FGETXATTR:
3604df
+                {
3604df
+                        gfs3_fgetxattr_req *args = &CPD_REQ_FIELD (curr_req,
3604df
+                                                   fgetxattr);
3604df
+
3604df
+                        SERVER_COMPOUND_FOP_CLEANUP (curr_req, fgetxattr);
3604df
+                        free (args->name);
3604df
+                        break;
3604df
+                }
3604df
+                case GF_FOP_FSETXATTR:
3604df
+                {
3604df
+                        gfs3_fsetxattr_req *args = &CPD_REQ_FIELD(curr_req,
3604df
+                                                   fsetxattr);
3604df
+
3604df
+                        free (args->dict.dict_val);
3604df
+                        SERVER_COMPOUND_FOP_CLEANUP (curr_req, fsetxattr);
3604df
+                        break;
3604df
+                }
3604df
+                case GF_FOP_RCHECKSUM:
3604df
+                        SERVER_COMPOUND_FOP_CLEANUP (curr_req, rchecksum);
3604df
+                        break;
3604df
+                case GF_FOP_SETATTR:
3604df
+                        SERVER_COMPOUND_FOP_CLEANUP (curr_req, setattr);
3604df
+                        break;
3604df
+                case GF_FOP_FSETATTR:
3604df
+                        SERVER_COMPOUND_FOP_CLEANUP (curr_req, fsetattr);
3604df
+                        break;
3604df
+                case GF_FOP_READDIRP:
3604df
+                {
3604df
+                        gfs3_readdirp_req *args = &CPD_REQ_FIELD (curr_req,
3604df
+                                                  readdirp);
3604df
+
3604df
+                        SERVER_COMPOUND_FOP_CLEANUP (curr_req, fremovexattr);
3604df
+                        free (args->dict.dict_val);
3604df
+                        break;
3604df
+                }
3604df
+                case GF_FOP_FREMOVEXATTR:
3604df
+                {
3604df
+                        gfs3_fremovexattr_req *args = &CPD_REQ_FIELD(curr_req,
3604df
+                                                      fremovexattr);
3604df
+
3604df
+                        SERVER_COMPOUND_FOP_CLEANUP (curr_req, fremovexattr);
3604df
+                        free (args->name);
3604df
+                        break;
3604df
+                }
3604df
+                case GF_FOP_FALLOCATE:
3604df
+                        SERVER_COMPOUND_FOP_CLEANUP (curr_req, fallocate);
3604df
+                        break;
3604df
+                case GF_FOP_DISCARD:
3604df
+                        SERVER_COMPOUND_FOP_CLEANUP (curr_req, discard);
3604df
+                        break;
3604df
+                case GF_FOP_ZEROFILL:
3604df
+                        SERVER_COMPOUND_FOP_CLEANUP (curr_req, zerofill);
3604df
+                        break;
3604df
+                case GF_FOP_IPC:
3604df
+                        SERVER_COMPOUND_FOP_CLEANUP (curr_req, ipc);
3604df
+                        break;
3604df
+                case GF_FOP_SEEK:
3604df
+                        SERVER_COMPOUND_FOP_CLEANUP (curr_req, seek);
3604df
+                        break;
3604df
+                default:
3604df
+                        break;
3604df
+                }
3604df
+        }
3604df
+
3604df
+        return;
3604df
+}
3604df
diff --git a/xlators/protocol/server/src/server-helpers.h b/xlators/protocol/server/src/server-helpers.h
3604df
index 200b383..02e092b 100644
3604df
--- a/xlators/protocol/server/src/server-helpers.h
3604df
+++ b/xlators/protocol/server/src/server-helpers.h
3604df
@@ -81,4 +81,9 @@ int
3604df
 server_populate_compound_request (gfs3_compound_req *req, call_frame_t *frame,
3604df
                                   default_args_t *this_args,
3604df
                                   int index);
3604df
+void
3604df
+server_compound_rsp_cleanup (gfs3_compound_rsp *rsp, compound_args_cbk_t *args);
3604df
+
3604df
+void
3604df
+server_compound_req_cleanup (gfs3_compound_req *req, int len);
3604df
 #endif /* !_SERVER_HELPERS_H */
3604df
diff --git a/xlators/protocol/server/src/server-rpc-fops.c b/xlators/protocol/server/src/server-rpc-fops.c
3604df
index fa160a5..756275e 100644
3604df
--- a/xlators/protocol/server/src/server-rpc-fops.c
3604df
+++ b/xlators/protocol/server/src/server-rpc-fops.c
3604df
@@ -21,6 +21,8 @@
3604df
 #include "defaults.h"
3604df
 #include "default-args.h"
3604df
 #include "server-common.h"
3604df
+#include "xlator.h"
3604df
+#include "compound-fop-utils.h"
3604df
 
3604df
 #include "xdr-nfs3.h"
3604df
 
3604df
@@ -2083,8 +2085,19 @@ server_compound_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
3604df
                         frame->root->unique, state->resolve.fd_no,
3604df
                         uuid_utoa (state->resolve.gfid),
3604df
                         strerror (op_errno));
3604df
+        }
3604df
+
3604df
+        rsp.compound_rsp_array.compound_rsp_array_val = GF_CALLOC
3604df
+                                                        (args_cbk->fop_length,
3604df
+                                                         sizeof (compound_rsp),
3604df
+                                                  gf_server_mt_compound_rsp_t);
3604df
+
3604df
+        if (!rsp.compound_rsp_array.compound_rsp_array_val) {
3604df
+                op_ret = -1;
3604df
+                op_errno = ENOMEM;
3604df
                 goto out;
3604df
         }
3604df
+        rsp.compound_rsp_array.compound_rsp_array_len = args_cbk->fop_length;
3604df
 
3604df
         for (i = 0; i < args_cbk->fop_length; i++) {
3604df
                 op_ret = server_populate_compound_response (this, &rsp,
3604df
@@ -2104,11 +2117,7 @@ out:
3604df
         server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
3604df
                              (xdrproc_t) xdr_gfs3_compound_rsp);
3604df
 
3604df
-        for (i = 0; i < state->args->fop_length; i++)
3604df
-                args_wipe (&state->args->req_list[i]);
3604df
-
3604df
-        GF_FREE (state->args->req_list);
3604df
-        GF_FREE (state->args);
3604df
+        server_compound_rsp_cleanup (&rsp, args_cbk);
3604df
         GF_FREE (rsp.xdata.xdata_val);
3604df
 
3604df
         return 0;
3604df
@@ -3311,8 +3320,12 @@ server_compound_resume (call_frame_t *frame, xlator_t *bound_xl)
3604df
         int                     ret     = -1;
3604df
         int                     length  = 0;
3604df
         int                     op_errno = ENOMEM;
3604df
+        compound_req            *c_req  = NULL;
3604df
+        xlator_t                *this   = NULL;
3604df
 
3604df
         state = CALL_STATE (frame);
3604df
+        this = frame->this;
3604df
+
3604df
         if (state->resolve.op_ret != 0) {
3604df
                 ret = state->resolve.op_ret;
3604df
                 op_errno = state->resolve.op_errno;
3604df
@@ -3321,20 +3334,18 @@ server_compound_resume (call_frame_t *frame, xlator_t *bound_xl)
3604df
 
3604df
         req = state->req;
3604df
 
3604df
-        args = GF_CALLOC (1, sizeof (*args), gf_mt_compound_req_t);
3604df
-        state->args = args;
3604df
-        if (!args)
3604df
-                goto err;
3604df
-
3604df
         length = req->compound_req_array.compound_req_array_len;
3604df
+        state->args = compound_fop_alloc (length, req->compound_fop_enum,
3604df
+                                          state->xdata);
3604df
+        args = state->args;
3604df
 
3604df
-        args->req_list = GF_CALLOC (length,
3604df
-                                    sizeof (*args->req_list),
3604df
-                                    gf_mt_default_args_t);
3604df
-        if (!args->req_list)
3604df
+        if (!args)
3604df
                 goto err;
3604df
 
3604df
         for (i = 0; i < length; i++) {
3604df
+                c_req = &req->compound_req_array.compound_req_array_val[i];
3604df
+                args->enum_list[i] = c_req->fop_enum;
3604df
+
3604df
                 ret = server_populate_compound_request (req, frame,
3604df
                                                         &args->req_list[i],
3604df
                                                         i);
3604df
@@ -3347,7 +3358,8 @@ server_compound_resume (call_frame_t *frame, xlator_t *bound_xl)
3604df
         }
3604df
 
3604df
         STACK_WIND (frame, server_compound_cbk,
3604df
-                    bound_xl, bound_xl->fops->compound,
3604df
+                    FIRST_CHILD(this),
3604df
+                    FIRST_CHILD(this)->fops->compound,
3604df
                     args, state->xdata);
3604df
 
3604df
         return 0;
3604df
@@ -3355,11 +3367,6 @@ err:
3604df
         server_compound_cbk (frame, NULL, frame->this, ret, op_errno,
3604df
                              NULL, NULL);
3604df
 
3604df
-        for (i = 0; i < length; i++)
3604df
-                args_wipe (&args->req_list[i]);
3604df
-
3604df
-        GF_FREE (args->req_list);
3604df
-        GF_FREE (args);
3604df
         return ret;
3604df
 }
3604df
 /* Fop section */
3604df
@@ -6695,12 +6702,13 @@ out:
3604df
 int
3604df
 server3_3_compound (rpcsvc_request_t *req)
3604df
 {
3604df
-        server_state_t      *state = NULL;
3604df
-        call_frame_t        *frame = NULL;
3604df
-        gfs3_compound_req    args  = {0,};
3604df
-        ssize_t              len    = 0;
3604df
-        int                  i      = 0;
3604df
-        int                  ret   = -1;
3604df
+        server_state_t      *state    = NULL;
3604df
+        call_frame_t        *frame    = NULL;
3604df
+        gfs3_compound_req    args     = {0,};
3604df
+        ssize_t              len      = 0;
3604df
+        int                  length   = 0;
3604df
+        int                  i        = 0;
3604df
+        int                  ret      = -1;
3604df
         int                  op_errno = 0;
3604df
 
3604df
         if (!req)
3604df
@@ -6713,6 +6721,7 @@ server3_3_compound (rpcsvc_request_t *req)
3604df
                 goto out;
3604df
         }
3604df
 
3604df
+        len = ret;
3604df
         frame = get_frame_from_request (req);
3604df
         if (!frame) {
3604df
                 SERVER_REQ_SET_ERROR (req, ret);
3604df
@@ -6765,6 +6774,9 @@ server3_3_compound (rpcsvc_request_t *req)
3604df
 out:
3604df
         free (args.xdata.xdata_val);
3604df
 
3604df
+        length = args.compound_req_array.compound_req_array_len;
3604df
+        server_compound_req_cleanup (&args, length);
3604df
+
3604df
         if (op_errno)
3604df
                 SERVER_REQ_SET_ERROR (req, ret);
3604df
 
3604df
diff --git a/xlators/protocol/server/src/server.h b/xlators/protocol/server/src/server.h
3604df
index fb9cd45..f50e9ab 100644
3604df
--- a/xlators/protocol/server/src/server.h
3604df
+++ b/xlators/protocol/server/src/server.h
3604df
@@ -30,6 +30,34 @@
3604df
 #define GF_MAX_SOCKET_WINDOW_SIZE  (1 * GF_UNIT_MB)
3604df
 #define GF_MIN_SOCKET_WINDOW_SIZE  (0)
3604df
 
3604df
+#define CPD_REQ_FIELD(v, f)  ((v)->compound_req_u.compound_##f##_req)
3604df
+#define CPD_RSP_FIELD(v, f)  ((v)->compound_rsp_u.compound_##f##_rsp)
3604df
+
3604df
+#define SERVER_COMMON_RSP_CLEANUP(rsp, fop, i)                                \
3604df
+        do {                                                                  \
3604df
+                compound_rsp            *this_rsp       = NULL;               \
3604df
+                this_rsp = &rsp->compound_rsp_array.compound_rsp_array_val[i];\
3604df
+                gf_common_rsp  *_this_rsp = &CPD_RSP_FIELD(this_rsp, fop);    \
3604df
+                                                                              \
3604df
+                GF_FREE (_this_rsp->xdata.xdata_val);                         \
3604df
+        } while (0)
3604df
+
3604df
+#define SERVER_FOP_RSP_CLEANUP(rsp, fop, i)                                   \
3604df
+        do {                                                                  \
3604df
+                compound_rsp            *this_rsp       = NULL;               \
3604df
+                this_rsp = &rsp->compound_rsp_array.compound_rsp_array_val[i];\
3604df
+                gfs3_##fop##_rsp  * _this_rsp = &CPD_RSP_FIELD(this_rsp, fop); \
3604df
+                                                                              \
3604df
+                GF_FREE (_this_rsp->xdata.xdata_val);                         \
3604df
+        } while (0)
3604df
+
3604df
+#define SERVER_COMPOUND_FOP_CLEANUP(curr_req, fop)                            \
3604df
+        do {                                                                  \
3604df
+                gfs3_##fop##_req * _req = &CPD_REQ_FIELD(curr_req, fop);       \
3604df
+                                                                              \
3604df
+                free (_req->xdata.xdata_val);                                 \
3604df
+        } while (0)
3604df
+
3604df
 typedef enum {
3604df
         INTERNAL_LOCKS = 1,
3604df
         POSIX_LOCKS = 2,
3604df
-- 
3604df
1.7.1
3604df