diff options
| author | Anuradha Talur <atalur@redhat.com> | 2016-04-29 16:12:10 +0530 | 
|---|---|---|
| committer | Pranith Kumar Karampuri <pkarampu@redhat.com> | 2016-04-30 17:47:47 -0700 | 
| commit | 45fa52d798298623757867c1936045231f0d0af7 (patch) | |
| tree | b216ac267dc21339fac8a40f49a5db4e89a3f19d | |
| parent | 93eaeb9c93be3232f24e840044d560f9f0e66f71 (diff) | |
protocol/client : Implementation of compound fop
Change-Id: Iade71daf3bc70e60833d693ac55151c9cf691381
BUG: 1303829
Signed-off-by: Anuradha Talur <atalur@redhat.com>
Reviewed-on: http://review.gluster.org/14114
Smoke: Gluster Build System <jenkins@build.gluster.com>
NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
CentOS-regression: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Pranith Kumar Karampuri <pkarampu@redhat.com>
| -rw-r--r-- | libglusterfs/src/defaults.h | 4 | ||||
| -rw-r--r-- | rpc/xdr/src/glusterfs3-xdr.x | 2 | ||||
| -rw-r--r-- | xlators/protocol/client/src/client-common.c | 8 | ||||
| -rw-r--r-- | xlators/protocol/client/src/client-helpers.c | 1391 | ||||
| -rw-r--r-- | xlators/protocol/client/src/client-mem-types.h | 2 | ||||
| -rw-r--r-- | xlators/protocol/client/src/client-rpc-fops.c | 228 | ||||
| -rw-r--r-- | xlators/protocol/client/src/client.c | 144 | ||||
| -rw-r--r-- | xlators/protocol/client/src/client.h | 77 | 
8 files changed, 1852 insertions, 4 deletions
diff --git a/libglusterfs/src/defaults.h b/libglusterfs/src/defaults.h index cae69a536a3..bcaac49b7af 100644 --- a/libglusterfs/src/defaults.h +++ b/libglusterfs/src/defaults.h @@ -80,7 +80,7 @@ typedef struct {  typedef struct {          int             fop_enum; -        int             fop_length; +        unsigned int    fop_length;          int             *enum_list;          default_args_t  *req_list;          dict_t          *xdata; @@ -88,7 +88,7 @@ typedef struct {  typedef struct {          int                fop_enum; -        int                fop_length; +        unsigned int       fop_length;          int                *enum_list;          default_args_cbk_t *rsp_list;          dict_t             *xdata; diff --git a/rpc/xdr/src/glusterfs3-xdr.x b/rpc/xdr/src/glusterfs3-xdr.x index 99e88fbffdf..33f1a9357cf 100644 --- a/rpc/xdr/src/glusterfs3-xdr.x +++ b/rpc/xdr/src/glusterfs3-xdr.x @@ -892,6 +892,7 @@ union compound_req switch (glusterfs_fop_t fop_enum) {          case GF_FOP_ZEROFILL:     gfs3_zerofill_req compound_zerofill_req;          case GF_FOP_IPC:          gfs3_ipc_req compound_ipc_req;          case GF_FOP_SEEK:         gfs3_seek_req compound_seek_req; +        case GF_FOP_LEASE:         gfs3_lease_req compound_lease_req;          default:                  void;  }; @@ -951,6 +952,7 @@ union compound_rsp switch (glusterfs_fop_t fop_enum) {          case GF_FOP_ZEROFILL:     gfs3_zerofill_rsp compound_zerofill_rsp;          case GF_FOP_IPC:          gfs3_ipc_rsp compound_ipc_rsp;          case GF_FOP_SEEK:         gfs3_seek_rsp compound_seek_rsp; +        case GF_FOP_LEASE:         gfs3_lease_rsp compound_lease_rsp;          default:                  void;  }; diff --git a/xlators/protocol/client/src/client-common.c b/xlators/protocol/client/src/client-common.c index 3d83bc94f59..51c2d95ea2b 100644 --- a/xlators/protocol/client/src/client-common.c +++ b/xlators/protocol/client/src/client-common.c @@ -1829,8 +1829,12 @@ int  client_post_lookup (xlator_t *this, gfs3_lookup_rsp *rsp, struct iatt *stbuf,                      struct iatt *postparent, dict_t **xdata)  { -        gf_stat_to_iatt (&rsp->postparent, postparent); -        gf_stat_to_iatt (&rsp->stat, stbuf); + +        if (-1 != rsp->op_ret) { +                gf_stat_to_iatt (&rsp->postparent, postparent); +                gf_stat_to_iatt (&rsp->stat, stbuf); +        } +          GF_PROTOCOL_DICT_UNSERIALIZE (this, *xdata, (rsp->xdata.xdata_val),                                        (rsp->xdata.xdata_len), rsp->op_ret,                                        rsp->op_errno, out); diff --git a/xlators/protocol/client/src/client-helpers.c b/xlators/protocol/client/src/client-helpers.c index 804b4028803..e78242ffe65 100644 --- a/xlators/protocol/client/src/client-helpers.c +++ b/xlators/protocol/client/src/client-helpers.c @@ -11,6 +11,9 @@  #include "client.h"  #include "fd.h"  #include "client-messages.h" +#include "client-common.h" +#include "compat-errno.h" +#include "common-utils.h"  int  client_fd_lk_list_empty (fd_lk_ctx_t *lk_ctx, gf_boolean_t try_lock) @@ -132,8 +135,14 @@ client_local_wipe (clnt_local_t *local)                          iobref_unref (local->iobref);                  } +                if (local->iobref2) { +                        iobref_unref (local->iobref2); +                } +                  GF_FREE (local->name); +                local->compound_args = NULL; +                  mem_put (local);          } @@ -359,3 +368,1385 @@ client_fd_fop_prepare_local (call_frame_t *frame, fd_t *fd, int64_t remote_fd)  out:          return ret;  } + +int +client_process_response (call_frame_t *frame, xlator_t *this, +                         struct rpc_req *req, gfs3_compound_rsp *rsp, +                         compound_args_cbk_t *args_cbk, +                         int index) +{ +        int                      ret            = 0; +        default_args_cbk_t      *this_args_cbk  = &args_cbk->rsp_list[index]; +        clnt_local_t            *local          = frame->local; +        compound_rsp            *this_rsp       = NULL; +        compound_args_t         *args           = local->compound_args; +        void                    *data           = NULL; + +        this_rsp = &rsp->compound_rsp_array.compound_rsp_array_val[index]; +        args_cbk->enum_list[index] = this_rsp->fop_enum; + +        switch (args_cbk->enum_list[index]) { + +        case GF_FOP_STAT: +        { +                gfs3_stat_rsp *tmp_rsp = NULL; +                tmp_rsp = &this_rsp->compound_rsp_u.compound_stat_rsp; + +                client_post_stat (this, tmp_rsp, +                                  &this_args_cbk->stat, &this_args_cbk->xdata); + +                CLIENT_POST_FOP_TYPE (stat, this_rsp, this_args_cbk, +                                      &this_args_cbk->stat, +                                      this_args_cbk->xdata); +                break; +        } +        case GF_FOP_READLINK: +        { +                gfs3_readlink_rsp *tmp_rsp = NULL; +                tmp_rsp = &this_rsp->compound_rsp_u.compound_readlink_rsp; + +                client_post_readlink (this, tmp_rsp, +                                      &this_args_cbk->stat, &this_args_cbk->xdata); +                CLIENT_POST_FOP_TYPE (readlink, this_rsp, this_args_cbk, +                                      tmp_rsp->path, +                                      &this_args_cbk->stat, +                                      this_args_cbk->xdata); +                break; +        } +        case GF_FOP_MKNOD: +        { +                gfs3_mknod_rsp *tmp_rsp = NULL; +                tmp_rsp = &this_rsp->compound_rsp_u.compound_mknod_rsp; + +                client_post_mknod (this, tmp_rsp, +                                   &this_args_cbk->stat, +                                   &this_args_cbk->preparent, +                                   &this_args_cbk->postparent, +                                   &this_args_cbk->xdata); +                CLIENT_POST_FOP_TYPE (mknod, this_rsp, this_args_cbk, +                                      local->loc.inode, +                                      &this_args_cbk->stat, +                                      &this_args_cbk->preparent, +                                      &this_args_cbk->postparent, +                                      this_args_cbk->xdata); +                break; +        } +        case GF_FOP_MKDIR: +        { +                gfs3_mkdir_rsp *tmp_rsp = NULL; +                tmp_rsp = &this_rsp->compound_rsp_u.compound_mkdir_rsp; + +                client_post_mkdir (this, +                                   tmp_rsp, +                                   &this_args_cbk->stat, +                                   &this_args_cbk->preparent, +                                   &this_args_cbk->postparent, +                                   &this_args_cbk->xdata); +                CLIENT_POST_FOP_TYPE (mkdir, this_rsp, this_args_cbk, +                                      local->loc.inode, +                                      &this_args_cbk->stat, +                                      &this_args_cbk->preparent, +                                      &this_args_cbk->postparent, +                                      this_args_cbk->xdata); +                break; +        } +        case GF_FOP_UNLINK: +        { +                gfs3_unlink_rsp *tmp_rsp = NULL; +                tmp_rsp = &this_rsp->compound_rsp_u.compound_unlink_rsp; + +                client_post_unlink (this, +                                    tmp_rsp, +                                    &this_args_cbk->preparent, +                                    &this_args_cbk->postparent, +                                    &this_args_cbk->xdata); +                CLIENT_POST_FOP_TYPE (unlink, this_rsp, this_args_cbk, +                                      &this_args_cbk->preparent, +                                      &this_args_cbk->postparent, +                                      this_args_cbk->xdata); +                break; +        } +        case GF_FOP_RMDIR: +        { +                gfs3_rmdir_rsp *tmp_rsp = NULL; +                tmp_rsp = &this_rsp->compound_rsp_u.compound_rmdir_rsp; + +                client_post_rmdir (this, tmp_rsp, +                                   &this_args_cbk->preparent, +                                   &this_args_cbk->postparent, +                                   &this_args_cbk->xdata); +                CLIENT_POST_FOP_TYPE (rmdir, this_rsp, this_args_cbk, +                                      &this_args_cbk->preparent, +                                      &this_args_cbk->postparent, +                                      this_args_cbk->xdata); +                break; +        } +        case GF_FOP_SYMLINK: +        { +                gfs3_symlink_rsp *tmp_rsp = NULL; +                tmp_rsp = &this_rsp->compound_rsp_u.compound_symlink_rsp; + +                client_post_symlink (this, tmp_rsp, +                                     &this_args_cbk->stat, +                                     &this_args_cbk->preparent, +                                     &this_args_cbk->postparent, +                                     &this_args_cbk->xdata); +                CLIENT_POST_FOP_TYPE (symlink, this_rsp, this_args_cbk, NULL, +                                      &this_args_cbk->stat, +                                      &this_args_cbk->preparent, +                                      &this_args_cbk->postparent, +                                      this_args_cbk->xdata); +                break; +        } +        case GF_FOP_RENAME: +        { +                gfs3_rename_rsp *tmp_rsp = NULL; +                tmp_rsp = &this_rsp->compound_rsp_u.compound_rename_rsp; + +                client_post_rename (this, tmp_rsp, +                                    &this_args_cbk->stat, +                                    &this_args_cbk->preparent, +                                    &this_args_cbk->postparent, +                                    &this_args_cbk->preparent2, +                                    &this_args_cbk->postparent2, +                                    &this_args_cbk->xdata); +                CLIENT_POST_FOP_TYPE (rename, this_rsp, this_args_cbk, +                                      &this_args_cbk->stat, +                                      &this_args_cbk->preparent, +                                      &this_args_cbk->postparent, +                                      &this_args_cbk->preparent2, +                                      &this_args_cbk->postparent2, +                                      this_args_cbk->xdata); +                break; +        } +        case GF_FOP_LINK: +        { +                gfs3_link_rsp *tmp_rsp = NULL; +                tmp_rsp = &this_rsp->compound_rsp_u.compound_link_rsp; + +                client_post_link (this, tmp_rsp, +                                  &this_args_cbk->stat, +                                  &this_args_cbk->preparent, +                                  &this_args_cbk->postparent, +                                  &this_args_cbk->xdata); +                CLIENT_POST_FOP_TYPE (link, this_rsp, this_args_cbk, NULL, +                                      &this_args_cbk->stat, +                                      &this_args_cbk->preparent, +                                      &this_args_cbk->postparent, +                                      this_args_cbk->xdata); +                break; +        } +        case GF_FOP_TRUNCATE: +        { +                gfs3_truncate_rsp *tmp_rsp = NULL; +                tmp_rsp = &this_rsp->compound_rsp_u.compound_truncate_rsp; + +                client_post_truncate (this, tmp_rsp, +                                      &this_args_cbk->prestat, +                                      &this_args_cbk->poststat, +                                      &this_args_cbk->xdata); +                CLIENT_POST_FOP_TYPE (truncate, this_rsp, this_args_cbk, +                                      &this_args_cbk->prestat, +                                      &this_args_cbk->poststat, +                                      this_args_cbk->xdata); +                break; +        } +        case GF_FOP_OPEN: +        { +                gfs3_open_rsp *tmp_rsp = NULL; +                tmp_rsp = &this_rsp->compound_rsp_u.compound_open_rsp; + +                client_post_open (this, tmp_rsp, +                                  &this_args_cbk->xdata); +                CLIENT_POST_FOP_TYPE (open, this_rsp, this_args_cbk, +                                      local->fd, +                                      this_args_cbk->xdata); +                if (-1 != this_args_cbk->op_ret) +                        ret = client_add_fd_to_saved_fds (this, local->fd, +                                                          &local->loc, +                                                          args->req_list[index].flags, +                                                          tmp_rsp->fd, +                                                          0); +                break; +        } +        case GF_FOP_READ: +        { +                gfs3_read_rsp *tmp_rsp = NULL; +                tmp_rsp = &this_rsp->compound_rsp_u.compound_read_rsp; + +                client_post_readv (this, tmp_rsp, &this_args_cbk->iobref, +                                  req->rsp_iobref, +                                  &this_args_cbk->stat, +                                  this_args_cbk->vector, &req->rsp[1], +                                  &this_args_cbk->count, +                                  &this_args_cbk->xdata); + +                /* Each read should be given read response that only +                 * corresponds to its request. +                 * Modify the iovecs accordingly. +                 * After each read, store the length of data already read +                 * so that the next ones can continue from there. +                 */ +                if (local->read_length) { +                        this_args_cbk->vector[0].iov_base += local->read_length; +                        local->read_length += tmp_rsp->op_ret; +                } else { +                        local->read_length = tmp_rsp->op_ret; +                } + +                args_readv_cbk_store (this_args_cbk, tmp_rsp->op_ret, +                                      gf_error_to_errno (tmp_rsp->op_errno), +                                      this_args_cbk->vector, +                                      this_args_cbk->count, +                                      &this_args_cbk->stat, +                                      this_args_cbk->iobref, +                                      this_args_cbk->xdata); + +                if (tmp_rsp->op_ret >= 0) +                        if (local->attempt_reopen) +                                client_attempt_reopen (local->fd, this); + +                break; +        } +        case GF_FOP_WRITE: +        { +                gfs3_write_rsp *tmp_rsp = NULL; +                tmp_rsp = &this_rsp->compound_rsp_u.compound_write_rsp; + +                client_post_writev (this, tmp_rsp, &this_args_cbk->prestat, +                                   &this_args_cbk->poststat, +                                   &this_args_cbk->xdata); +                args_writev_cbk_store (this_args_cbk, tmp_rsp->op_ret, +                                       gf_error_to_errno (tmp_rsp->op_errno), +                                       &this_args_cbk->prestat, +                                       &this_args_cbk->poststat, +                                       this_args_cbk->xdata); + +                if (tmp_rsp->op_ret == 0) +                        if (local->attempt_reopen) +                                client_attempt_reopen (local->fd, this); +                break; +        } +        case GF_FOP_STATFS: +        { +                gfs3_statfs_rsp *tmp_rsp = NULL; +                tmp_rsp = &this_rsp->compound_rsp_u.compound_statfs_rsp; + +                client_post_statfs (this, tmp_rsp, +                                    &this_args_cbk->statvfs, +                                    &this_args_cbk->xdata); + +                CLIENT_POST_FOP_TYPE (statfs, this_rsp, this_args_cbk, +                                      &this_args_cbk->statvfs, +                                      this_args_cbk->xdata); +                break; +         } +        case GF_FOP_FLUSH: +        { +                gf_common_rsp *tmp_rsp = NULL; +                tmp_rsp = &this_rsp->compound_rsp_u.compound_flush_rsp; + +                client_post_flush (this, tmp_rsp, +                                    &this_args_cbk->xdata); + +                CLIENT_POST_FOP (flush, this_rsp, this_args_cbk, +                                 this_args_cbk->xdata); +                if (this_args_cbk->op_ret >= 0 && !fd_is_anonymous (local->fd)) { +                        /* Delete all saved locks of the owner issuing flush */ +                        ret = delete_granted_locks_owner (local->fd, &local->owner); +                        gf_msg_trace (this->name, 0, +                                      "deleting locks of owner (%s) returned %d", +                                      lkowner_utoa (&local->owner), ret); +                } +                break; +         } +        case GF_FOP_FSYNC: +        { +                gfs3_fsync_rsp *tmp_rsp = NULL; +                tmp_rsp = &this_rsp->compound_rsp_u.compound_fsync_rsp; + +                client_post_fsync (this, tmp_rsp, +                                   &this_args_cbk->prestat, +                                   &this_args_cbk->poststat, +                                   &this_args_cbk->xdata); + +                CLIENT_POST_FOP_TYPE (fsync, this_rsp, this_args_cbk, +                                      &this_args_cbk->prestat, +                                      &this_args_cbk->poststat, +                                      this_args_cbk->xdata); +                break; +        } +        case GF_FOP_SETXATTR: +        { +                gf_common_rsp *tmp_rsp = NULL; +                tmp_rsp = &this_rsp->compound_rsp_u.compound_setxattr_rsp; + +                client_post_setxattr (this, tmp_rsp, +                                      &this_args_cbk->xdata); + +                CLIENT_POST_FOP (setxattr, this_rsp, this_args_cbk, +                                 this_args_cbk->xdata); +                break; +        } +        case GF_FOP_GETXATTR: +        { +                gfs3_getxattr_rsp *tmp_rsp = NULL; +                tmp_rsp = &this_rsp->compound_rsp_u.compound_getxattr_rsp; + +                client_post_getxattr (this, tmp_rsp, +                                      &this_args_cbk->xattr, +                                      &this_args_cbk->xdata); + +                CLIENT_POST_FOP_TYPE (getxattr, this_rsp, this_args_cbk, +                                      this_args_cbk->xattr, +                                      this_args_cbk->xdata); +                break; +        } +        case GF_FOP_REMOVEXATTR: +         { +                gf_common_rsp *tmp_rsp = NULL; +                tmp_rsp = &this_rsp->compound_rsp_u.compound_removexattr_rsp; + +                client_post_removexattr (this, tmp_rsp, +                                         &this_args_cbk->xdata); + +                CLIENT_POST_FOP (removexattr, this_rsp, this_args_cbk, +                                 this_args_cbk->xdata); +                break; +        } +        case GF_FOP_OPENDIR: +        { +                gfs3_opendir_rsp *tmp_rsp = NULL; +                tmp_rsp = &this_rsp->compound_rsp_u.compound_opendir_rsp; + +                client_post_opendir (this, tmp_rsp, +                                     &this_args_cbk->xdata); + +                CLIENT_POST_FOP_TYPE (opendir, this_rsp, this_args_cbk, +                                      local->fd, +                                      this_args_cbk->xdata); +                if (-1 != this_args_cbk->op_ret) +                        ret = client_add_fd_to_saved_fds (this, local->fd, +                                                          &local->loc, +                                                          args->req_list[index].flags, +                                                          tmp_rsp->fd, 0); +                break; +        } +        case GF_FOP_FSYNCDIR: +        { +                gf_common_rsp *tmp_rsp = NULL; +                tmp_rsp = &this_rsp->compound_rsp_u.compound_fsyncdir_rsp; + +                client_post_fsyncdir (this, tmp_rsp, +                                      &this_args_cbk->xdata); + +                CLIENT_POST_FOP (fsyncdir, this_rsp, this_args_cbk, +                                 this_args_cbk->xdata); +                break; +        } +        case GF_FOP_ACCESS: +        { +                gf_common_rsp *tmp_rsp = NULL; +                tmp_rsp = &this_rsp->compound_rsp_u.compound_access_rsp; + +                client_post_access (this, tmp_rsp, +                                      &this_args_cbk->xdata); + +                CLIENT_POST_FOP (access, this_rsp, this_args_cbk, +                                 this_args_cbk->xdata); +                break; +        } +        case GF_FOP_CREATE: +        { +                gfs3_create_rsp *tmp_rsp = NULL; +                tmp_rsp = &this_rsp->compound_rsp_u.compound_create_rsp; + +                client_post_create (this, tmp_rsp, +                                   &this_args_cbk->stat, +                                   &this_args_cbk->preparent, +                                   &this_args_cbk->postparent, +                                   local, +                                   &this_args_cbk->xdata); +                CLIENT_POST_FOP_TYPE (create, this_rsp, this_args_cbk, +                                      local->fd, +                                      local->loc.inode, +                                      &this_args_cbk->stat, +                                      &this_args_cbk->preparent, +                                      &this_args_cbk->postparent, +                                      this_args_cbk->xdata); +                if (-1 != this_args_cbk->op_ret) +                        ret = client_add_fd_to_saved_fds (this, local->fd, +                                                          &local->loc, +                                                          args->req_list[index].flags, +                                                          tmp_rsp->fd, 0); +                break; +        } +        case GF_FOP_FTRUNCATE: +        { +                gfs3_ftruncate_rsp *tmp_rsp = NULL; +                tmp_rsp = &this_rsp->compound_rsp_u.compound_ftruncate_rsp; + +                client_post_ftruncate (this, tmp_rsp, +                                      &this_args_cbk->prestat, +                                      &this_args_cbk->poststat, +                                      &this_args_cbk->xdata); +                CLIENT_POST_FOP_TYPE (ftruncate, this_rsp, this_args_cbk, +                                      &this_args_cbk->prestat, +                                      &this_args_cbk->poststat, +                                      this_args_cbk->xdata); +                break; +        } +        case GF_FOP_FSTAT: +        { +                gfs3_fstat_rsp *tmp_rsp = NULL; +                tmp_rsp = &this_rsp->compound_rsp_u.compound_fstat_rsp; + +                client_post_fstat (this, tmp_rsp, +                                  &this_args_cbk->stat, &this_args_cbk->xdata); + +                CLIENT_POST_FOP_TYPE (fstat, this_rsp, this_args_cbk, +                                      &this_args_cbk->stat, +                                      this_args_cbk->xdata); +                break; +        } +        case GF_FOP_LK: +        { +                gfs3_lk_rsp *tmp_rsp = NULL; +                tmp_rsp = &this_rsp->compound_rsp_u.compound_lk_rsp; + +                client_post_lk (this, tmp_rsp, +                               &this_args_cbk->lock, +                               &this_args_cbk->xdata); + +                CLIENT_POST_FOP_TYPE (lk, this_rsp, this_args_cbk, +                                      &this_args_cbk->lock, +                                      this_args_cbk->xdata); +                break; +        } +        case GF_FOP_LOOKUP: +        { +                gfs3_lookup_rsp *tmp_rsp = NULL; +                tmp_rsp = &this_rsp->compound_rsp_u.compound_lookup_rsp; + +                client_post_lookup (this, tmp_rsp, +                                   &this_args_cbk->stat, +                                   &this_args_cbk->postparent, +                                   &this_args_cbk->xdata); +                CLIENT_POST_FOP_TYPE (lookup, this_rsp, this_args_cbk, +                                      local->loc.inode, +                                      &this_args_cbk->stat, +                                      this_args_cbk->xdata, +                                      &this_args_cbk->postparent); +                break; +        } +        case GF_FOP_READDIR: +        { +                gfs3_readdir_rsp *tmp_rsp = NULL; +                tmp_rsp = &this_rsp->compound_rsp_u.compound_readdir_rsp; + +                client_post_readdir (this, tmp_rsp, +                                   &this_args_cbk->entries, &this_args_cbk->xdata); + +                CLIENT_POST_FOP_TYPE (readdir, this_rsp, this_args_cbk, +                                   &this_args_cbk->entries, this_args_cbk->xdata); +                break; +        } +        case GF_FOP_INODELK: +        { +                gf_common_rsp *tmp_rsp = NULL; +                tmp_rsp = &this_rsp->compound_rsp_u.compound_inodelk_rsp; + +                client_post_inodelk (this, tmp_rsp, +                                      &this_args_cbk->xdata); + +                CLIENT_POST_FOP (inodelk, this_rsp, this_args_cbk, +                                 this_args_cbk->xdata); +                break; +        } +        case GF_FOP_FINODELK: +        { +                gf_common_rsp *tmp_rsp = NULL; +                tmp_rsp = &this_rsp->compound_rsp_u.compound_finodelk_rsp; + +                client_post_finodelk (this, tmp_rsp, +                                      &this_args_cbk->xdata); + +                CLIENT_POST_FOP (finodelk, this_rsp, this_args_cbk, +                                 this_args_cbk->xdata); +                if (tmp_rsp->op_ret == 0) +                        if (local->attempt_reopen) +                                client_attempt_reopen (local->fd, this); +                break; +        } +        case GF_FOP_ENTRYLK: +        { +                gf_common_rsp *tmp_rsp = NULL; +                tmp_rsp = &this_rsp->compound_rsp_u.compound_entrylk_rsp; + +                client_post_entrylk (this, tmp_rsp, +                                      &this_args_cbk->xdata); + +                CLIENT_POST_FOP (entrylk, this_rsp, this_args_cbk, +                                 this_args_cbk->xdata); +                break; +        } +        case GF_FOP_FENTRYLK: +        { +                gf_common_rsp *tmp_rsp = NULL; +                tmp_rsp = &this_rsp->compound_rsp_u.compound_fentrylk_rsp; + +                client_post_fentrylk (this, tmp_rsp, +                                      &this_args_cbk->xdata); + +                CLIENT_POST_FOP (fentrylk, this_rsp, this_args_cbk, +                                 this_args_cbk->xdata); +                break; +        } +        case GF_FOP_XATTROP: +        { +                gfs3_xattrop_rsp *tmp_rsp = NULL; +                tmp_rsp = &this_rsp->compound_rsp_u.compound_xattrop_rsp; + +                client_post_xattrop (this, tmp_rsp, +                                     &this_args_cbk->xattr, +                                     &this_args_cbk->xdata); + +                CLIENT_POST_FOP_TYPE (xattrop, this_rsp, this_args_cbk, +                                      this_args_cbk->xattr, +                                      this_args_cbk->xdata); +                break; +        } +        case GF_FOP_FXATTROP: +        { +                gfs3_fxattrop_rsp *tmp_rsp = NULL; +                tmp_rsp = &this_rsp->compound_rsp_u.compound_fxattrop_rsp; + +                client_post_fxattrop (this, tmp_rsp, +                                      &this_args_cbk->xattr, +                                      &this_args_cbk->xdata); + +                CLIENT_POST_FOP_TYPE (fxattrop, this_rsp, this_args_cbk, +                                      this_args_cbk->xattr, +                                      this_args_cbk->xdata); +                if (rsp->op_ret == 0) +                        if (local->attempt_reopen) +                                client_attempt_reopen (local->fd, this); +                break; +        } +        case GF_FOP_FGETXATTR: +        { +                gfs3_fgetxattr_rsp *tmp_rsp = NULL; +                tmp_rsp = &this_rsp->compound_rsp_u.compound_fgetxattr_rsp; + +                client_post_fgetxattr (this, tmp_rsp, +                                      &this_args_cbk->xattr, +                                      &this_args_cbk->xdata); + +                CLIENT_POST_FOP_TYPE (fgetxattr, this_rsp, this_args_cbk, +                                      this_args_cbk->xattr, +                                      this_args_cbk->xdata); +                break; +        } +        case GF_FOP_FSETXATTR: +        { +                gf_common_rsp *tmp_rsp = NULL; +                tmp_rsp = &this_rsp->compound_rsp_u.compound_fsetxattr_rsp; + +                client_post_fsetxattr (this, tmp_rsp, +                                      &this_args_cbk->xdata); + +                CLIENT_POST_FOP (fsetxattr, this_rsp, this_args_cbk, +                                 this_args_cbk->xdata); +                break; +        } +        case GF_FOP_RCHECKSUM: +        { +                gfs3_rchecksum_rsp *tmp_rsp = NULL; +                tmp_rsp = &this_rsp->compound_rsp_u.compound_rchecksum_rsp; + +                client_post_rchecksum (this, tmp_rsp, +                                      &this_args_cbk->xdata); + +                break; +                CLIENT_POST_FOP_TYPE (rchecksum, this_rsp, this_args_cbk, +                                      tmp_rsp->weak_checksum, +                                      (uint8_t*)tmp_rsp->strong_checksum.strong_checksum_val, +                                      this_args_cbk->xdata); +                break; +        } +        case GF_FOP_SETATTR: +        { +                gfs3_setattr_rsp *tmp_rsp = NULL; +                tmp_rsp = &this_rsp->compound_rsp_u.compound_setattr_rsp; + +                client_post_setattr (this, tmp_rsp, +                                    &this_args_cbk->prestat, +                                    &this_args_cbk->poststat, +                                    &this_args_cbk->xdata); + +                CLIENT_POST_FOP_TYPE (setattr, this_rsp, this_args_cbk, +                                      &this_args_cbk->prestat, +                                      &this_args_cbk->poststat, +                                      this_args_cbk->xdata); +                break; +        } +        case GF_FOP_FSETATTR: +        { +                gfs3_fsetattr_rsp *tmp_rsp = NULL; +                tmp_rsp = &this_rsp->compound_rsp_u.compound_fsetattr_rsp; + +                client_post_fsetattr (this, tmp_rsp, +                                    &this_args_cbk->prestat, +                                    &this_args_cbk->poststat, +                                    &this_args_cbk->xdata); + +                CLIENT_POST_FOP_TYPE (fsetattr, this_rsp, this_args_cbk, +                                      &this_args_cbk->prestat, +                                      &this_args_cbk->poststat, +                                      this_args_cbk->xdata); +                break; +        } +        case GF_FOP_READDIRP: +        { +                gfs3_readdirp_rsp *tmp_rsp = NULL; +                tmp_rsp = &this_rsp->compound_rsp_u.compound_readdirp_rsp; + +                client_post_readdirp (this, tmp_rsp, local->fd, +                                      &this_args_cbk->entries, +                                      &this_args_cbk->xdata); + +                CLIENT_POST_FOP_TYPE (readdirp, this_rsp, this_args_cbk, +                                      &this_args_cbk->entries, +                                      this_args_cbk->xdata); +                break; +        } +        case GF_FOP_FREMOVEXATTR: +        { +                gf_common_rsp *tmp_rsp = NULL; +                tmp_rsp = &this_rsp->compound_rsp_u.compound_fremovexattr_rsp; + +                client_post_fremovexattr (this, tmp_rsp, +                                         &this_args_cbk->xdata); + +                CLIENT_POST_FOP (fremovexattr, this_rsp, this_args_cbk, +                                 this_args_cbk->xdata); +                break; +        } +        case GF_FOP_FALLOCATE: +        { +                gfs3_fallocate_rsp *tmp_rsp = NULL; +                tmp_rsp = &this_rsp->compound_rsp_u.compound_fallocate_rsp; + +                client_post_fallocate (this, tmp_rsp, +                                    &this_args_cbk->prestat, +                                    &this_args_cbk->poststat, +                                    &this_args_cbk->xdata); + +                CLIENT_POST_FOP_TYPE (fallocate, this_rsp, this_args_cbk, +                                      &this_args_cbk->prestat, +                                      &this_args_cbk->poststat, +                                      this_args_cbk->xdata); +                break; +        } +        case GF_FOP_DISCARD: +        { +                gfs3_discard_rsp *tmp_rsp = NULL; +                tmp_rsp = &this_rsp->compound_rsp_u.compound_discard_rsp; + +                client_post_discard (this, tmp_rsp, +                                    &this_args_cbk->prestat, +                                    &this_args_cbk->poststat, +                                    &this_args_cbk->xdata); + +                CLIENT_POST_FOP_TYPE (discard, this_rsp, this_args_cbk, +                                      &this_args_cbk->prestat, +                                      &this_args_cbk->poststat, +                                      this_args_cbk->xdata); +                break; +        } +        case GF_FOP_ZEROFILL: +        { +                gfs3_zerofill_rsp *tmp_rsp = NULL; +                tmp_rsp = &this_rsp->compound_rsp_u.compound_zerofill_rsp; + +                client_post_zerofill (this, tmp_rsp, +                                    &this_args_cbk->prestat, +                                    &this_args_cbk->poststat, +                                    &this_args_cbk->xdata); + +                CLIENT_POST_FOP_TYPE (zerofill, this_rsp, this_args_cbk, +                                      &this_args_cbk->prestat, +                                      &this_args_cbk->poststat, +                                      this_args_cbk->xdata); +                break; +        } +        case GF_FOP_IPC: +        { +                gfs3_ipc_rsp *tmp_rsp = NULL; +                tmp_rsp = &this_rsp->compound_rsp_u.compound_ipc_rsp; + +                client_post_ipc (this, tmp_rsp, &this_args_cbk->xdata); + +                CLIENT_POST_FOP_TYPE (ipc, this_rsp, this_args_cbk, +                                 this_args_cbk->xdata); +                break; +        } +        case GF_FOP_SEEK: +        { +                gfs3_seek_rsp *tmp_rsp = NULL; +                tmp_rsp = &this_rsp->compound_rsp_u.compound_seek_rsp; + +                client_post_seek (this, tmp_rsp, &this_args_cbk->xdata); + +                CLIENT_POST_FOP_TYPE (seek, this_rsp, this_args_cbk, +                                 tmp_rsp->offset, +                                 this_args_cbk->xdata); +                break; +        } +        case GF_FOP_LEASE: +        { +                gfs3_lease_rsp *tmp_rsp = NULL; +                tmp_rsp = &this_rsp->compound_rsp_u.compound_lease_rsp; + +                client_post_lease (this, tmp_rsp, &this_args_cbk->lease, +                                   &this_args_cbk->xdata); + +                CLIENT_POST_FOP_TYPE (lease, this_rsp, this_args_cbk, +                                      &this_args_cbk->lease, +                                      this_args_cbk->xdata); +                break; +        } +        default: +                return -ENOTSUP; +        } +        return 0; +} + +int +client_handle_fop_requirements (xlator_t *this, call_frame_t *frame, +                                gfs3_compound_req *req, +                                clnt_local_t *local, +                                struct iobref *req_iobref, +                                struct iobref *rsp_iobref, +                                struct iovec *req_vector, +                                struct iovec *rsp_vector, int *req_count, +                                int *rsp_count, default_args_t *args, +                                int fop_enum, int index) +{ +        int             ret           = 0; +        int             op_errno      = ENOMEM; +        struct iobuf   *rsp_iobuf     = NULL; +        int64_t         remote_fd     = -1; +        compound_req    *this_req     = &req->compound_req_array.compound_req_array_val[index]; + +        this_req->fop_enum = fop_enum; + +        switch (fop_enum) { +        case GF_FOP_STAT: +                CLIENT_PRE_FOP (stat, this, +                                &this_req->compound_req_u.compound_stat_req, +                                op_errno, out, +                                &args->loc, args->xdata); +                break; +        case GF_FOP_READLINK: +                CLIENT_PRE_FOP (readlink, this, +                                &this_req->compound_req_u.compound_readlink_req, +                                op_errno, out, +                                &args->loc, args->size, args->xdata); +                break; +        case GF_FOP_MKNOD: +                CLIENT_PRE_FOP (mknod, this, +                                &this_req->compound_req_u.compound_mknod_req, +                                op_errno, out, +                                &args->loc, args->mode, args->rdev, +                                args->umask, args->xdata); +                if (!&local->loc) { +                        loc_copy (&local->loc, &args->loc); +                        loc_path (&local->loc, NULL); +                } +                break; +        case GF_FOP_MKDIR: +                CLIENT_PRE_FOP (mkdir, this, +                                &this_req->compound_req_u.compound_mkdir_req, +                                op_errno, out, +                                &args->loc, args->mode, +                                args->umask, args->xdata); +                if (!&local->loc) { +                        loc_copy (&local->loc, &args->loc); +                        loc_path (&local->loc, NULL); +                } +                break; +        case GF_FOP_UNLINK: +                CLIENT_PRE_FOP (unlink, this, +                                &this_req->compound_req_u.compound_unlink_req, +                                op_errno, out, +                                &args->loc, args->xflag, args->xdata); +                break; +        case GF_FOP_RMDIR: +                CLIENT_PRE_FOP (rmdir, this, +                                &this_req->compound_req_u.compound_rmdir_req, +                                op_errno, out, +                                &args->loc, args->flags, args->xdata); +                break; +        case GF_FOP_SYMLINK: +                CLIENT_PRE_FOP (symlink, this, +                                &this_req->compound_req_u.compound_symlink_req, +                                op_errno, out, +                                &args->loc, args->linkname, args->umask, +                                args->xdata); +                if (!&local->loc) { +                        loc_copy (&local->loc, &args->loc); +                        loc_path (&local->loc, NULL); +                } +                break; +        case GF_FOP_RENAME: +                CLIENT_PRE_FOP (rename, this, +                                &this_req->compound_req_u.compound_rename_req, +                                op_errno, out, +                                &args->loc, &args->loc2, args->xdata); +                break; +        case GF_FOP_LINK: +                CLIENT_PRE_FOP (link, this, +                                &this_req->compound_req_u.compound_link_req, +                                op_errno, out, +                                &args->loc, &args->loc2, args->xdata); +                break; +        case GF_FOP_TRUNCATE: +                CLIENT_PRE_FOP (truncate, this, +                                &this_req->compound_req_u.compound_truncate_req, +                                op_errno, out, +                                &args->loc, args->offset, args->xdata); +                break; +        case GF_FOP_OPEN: +                CLIENT_PRE_FOP (open, this, +                                &this_req->compound_req_u.compound_open_req, +                                op_errno, out, +                                &args->loc, args->fd, args->flags, +                                args->xdata); +                if (!local->fd) +                        local->fd = fd_ref (args->fd); +                break; +        case GF_FOP_READ: +                op_errno = client_pre_readv (this, +                                  &this_req->compound_req_u.compound_read_req, +                                  args->fd, args->size, args->offset, +                                  args->flags, args->xdata); + +                if (op_errno) { +                        op_errno = -op_errno; +                        goto out; +                } +                if (!local->fd) +                        local->fd = fd_ref (args->fd); +                local->attempt_reopen = client_is_reopen_needed +                                        (args->fd, this, remote_fd); +                rsp_iobuf = iobuf_get2 (this->ctx->iobuf_pool, args->size); +                if (rsp_iobuf == NULL) { +                        op_errno = ENOMEM; +                        goto out; +                } + +                if (!rsp_iobref) { +                        rsp_iobref = iobref_new (); +                        if (rsp_iobref == NULL) { +                                op_errno = ENOMEM; +                                goto out; +                        } +                } + +                iobref_add (rsp_iobref, rsp_iobuf); +                iobuf_unref (rsp_iobuf); + +                if (*rsp_count + 1 >= MAX_IOVEC) { +                        op_errno = ENOMEM; +                        goto out; +                } +                rsp_vector[*rsp_count].iov_base = iobuf_ptr (rsp_iobuf); +                rsp_vector[*rsp_count].iov_len = iobuf_pagesize (rsp_iobuf); +                rsp_iobuf = NULL; +                if (args->size > rsp_vector[*rsp_count].iov_len) { +                        gf_msg (this->name, GF_LOG_WARNING, ENOMEM, +                                PC_MSG_NO_MEMORY, +                                "read-size (%lu) is bigger than iobuf size " +                                "(%lu)", +                                (unsigned long)args->size, +                                (unsigned long)rsp_vector[*rsp_count].iov_len); +                        op_errno = EINVAL; +                        goto out; +                } +                *rsp_count += 1; + +                break; +        case GF_FOP_WRITE: +                op_errno = client_pre_writev (this, +                           &this_req->compound_req_u.compound_write_req, +                           args->fd, args->count, args->offset, +                           args->flags, args->xdata); + +                if (op_errno) { +                        op_errno = -op_errno; +                        goto out; +                } +                if (!local->fd) +                        local->fd = fd_ref (args->fd); +                local->attempt_reopen = client_is_reopen_needed +                                        (args->fd, this, remote_fd); + +                if (*req_count + 1 >= MAX_IOVEC) { +                        op_errno = ENOMEM; +                        goto out; +                } +                memcpy (&req_vector[*req_count], args->vector, +                        (args->count * sizeof(req_vector[0]))); +                *req_count += args->count; + +                if (!req_iobref) +                        req_iobref = args->iobref; +                else +                        if (iobref_merge (req_iobref, args->iobref)) +                                goto out; +                break; +        case GF_FOP_STATFS: +                CLIENT_PRE_FOP (statfs, this, +                                &this_req->compound_req_u.compound_statfs_req, +                                op_errno, out, +                                &args->loc, args->xdata); +                break; +        case GF_FOP_FLUSH: +                CLIENT_PRE_FOP (flush, this, +                                &this_req->compound_req_u.compound_flush_req, +                                op_errno, out, +                                args->fd, args->xdata); +                if (!local->fd) +                        local->fd = fd_ref (args->fd); +                local->owner = frame->root->lk_owner; +                break; +        case GF_FOP_FSYNC: +                CLIENT_PRE_FOP (fsync, this, +                                &this_req->compound_req_u.compound_fsync_req, +                                op_errno, out, +                                args->fd, args->datasync, args->xdata); +                break; +        case GF_FOP_SETXATTR: +                CLIENT_PRE_FOP (setxattr, this, +                                &this_req->compound_req_u.compound_setxattr_req, +                                op_errno, out, +                                &args->loc, args->xattr, args->flags, +                                args->xdata); +                break; +        case GF_FOP_GETXATTR: +                CLIENT_PRE_FOP (getxattr, this, +                                &this_req->compound_req_u.compound_getxattr_req, +                                op_errno, out, +                                &args->loc, args->name, args->xdata); +                if (!&local->loc) { +                        loc_copy (&local->loc, &args->loc); +                        loc_path (&local->loc, NULL); +                } +                break; +        case GF_FOP_REMOVEXATTR: +                CLIENT_PRE_FOP (removexattr, this, +                                &this_req->compound_req_u.compound_removexattr_req, +                                op_errno, out, +                                &args->loc, args->name, args->xdata); +                break; +        case GF_FOP_OPENDIR: +                CLIENT_PRE_FOP (opendir, this, +                                &this_req->compound_req_u.compound_opendir_req, +                                op_errno, out, +                                &args->loc, args->fd, args->xdata); +                if (!local->fd) +                        local->fd = fd_ref (args->fd); +                if (!&local->loc) { +                        loc_copy (&local->loc, &args->loc); +                        loc_path (&local->loc, NULL); +                } +                break; +        case GF_FOP_FSYNCDIR: +                CLIENT_PRE_FOP (fsyncdir, this, +                                &this_req->compound_req_u.compound_fsyncdir_req, +                                op_errno, out, +                                args->fd, args->datasync, args->xdata); +                break; +        case GF_FOP_ACCESS: +                CLIENT_PRE_FOP (access, this, +                                &this_req->compound_req_u.compound_access_req, +                                op_errno, out, +                                &args->loc, args->mask, args->xdata); +                break; +        case GF_FOP_CREATE: +                CLIENT_PRE_FOP (create, this, +                                &this_req->compound_req_u.compound_create_req, +                                op_errno, out, +                                &args->loc, args->fd, args->mode, args->flags, +                                args->umask, args->xdata); +                if (!local->fd) +                        local->fd = fd_ref (args->fd); + +                if (!&local->loc) { +                        loc_copy (&local->loc, &args->loc); +                        loc_path (&local->loc, NULL); +                } +                break; +        case GF_FOP_FTRUNCATE: +                CLIENT_PRE_FOP (ftruncate, this, +                                &this_req->compound_req_u.compound_ftruncate_req, +                                op_errno, out, +                                args->fd, args->offset, args->xdata); +                break; +        case GF_FOP_FSTAT: +                CLIENT_PRE_FOP (fstat, this, +                                &this_req->compound_req_u.compound_fstat_req, +                                op_errno, out, +                                args->fd, args->xdata); +                break; +        case GF_FOP_LK: +                CLIENT_PRE_FOP (lk, this, +                                &this_req->compound_req_u.compound_lk_req, +                                op_errno, out, +                                args->cmd, &args->lock, args->fd, args->xdata); +                if (!local->fd) +                        local->fd    = fd_ref (args->fd); +                local->owner = frame->root->lk_owner; +                break; +        case GF_FOP_LOOKUP: +                CLIENT_PRE_FOP (lookup, this, +                                &this_req->compound_req_u.compound_lookup_req, +                                op_errno, out, +                                &args->loc, args->xdata); +                if (!&local->loc) { +                        loc_copy (&local->loc, &args->loc); +                        loc_path (&local->loc, NULL); +                } +                break; +        case GF_FOP_READDIR: +                CLIENT_PRE_FOP (readdir, this, +                                &this_req->compound_req_u.compound_readdir_req, +                                op_errno, out, +                                args->fd, args->size, args->offset, +                                args->xdata); +                break; +        case GF_FOP_INODELK: +                CLIENT_PRE_FOP (inodelk, this, +                                &this_req->compound_req_u.compound_inodelk_req, +                                op_errno, out, +                                &args->loc, args->cmd, &args->lock, +                                args->volume, args->xdata); +                break; +        case GF_FOP_FINODELK: +                CLIENT_PRE_FOP (finodelk, this, +                                &this_req->compound_req_u.compound_finodelk_req, +                                op_errno, out, +                                args->fd, args->cmd, &args->lock, +                                args->volume, args->xdata); +                if (!local->fd) +                        local->fd = fd_ref (args->fd); +                local->attempt_reopen = client_is_reopen_needed +                                        (args->fd, this, remote_fd); +                break; +        case GF_FOP_ENTRYLK: +                CLIENT_PRE_FOP (entrylk, this, +                                &this_req->compound_req_u.compound_entrylk_req, +                                op_errno, out, +                                &args->loc, args->entrylkcmd, +                                args->entrylktype, args->volume, +                                args->name, args->xdata); +                break; +        case GF_FOP_FENTRYLK: +                CLIENT_PRE_FOP (fentrylk, this, +                                &this_req->compound_req_u.compound_fentrylk_req, +                                op_errno, out, +                                args->fd, args->entrylkcmd, +                                args->entrylktype, args->volume, +                                args->name, args->xdata); +                break; +        case GF_FOP_XATTROP: +                CLIENT_PRE_FOP (xattrop, this, +                                &this_req->compound_req_u.compound_xattrop_req, +                                op_errno, out, +                                &args->loc, args->xattr, args->optype, +                                args->xdata); +                break; +        case GF_FOP_FXATTROP: +                CLIENT_PRE_FOP (fxattrop, this, +                                &this_req->compound_req_u.compound_fxattrop_req, +                                op_errno, out, +                                args->fd, args->xattr, args->optype, +                                args->xdata); +                if (!local->fd) +                        local->fd = fd_ref (args->fd); +                local->attempt_reopen = client_is_reopen_needed +                                        (args->fd, this, remote_fd); +                break; +        case GF_FOP_FGETXATTR: +                CLIENT_PRE_FOP (fgetxattr, this, +                                &this_req->compound_req_u.compound_fgetxattr_req, +                                op_errno, out, +                                args->fd, args->name, args->xdata); +                break; +        case GF_FOP_FSETXATTR: +                CLIENT_PRE_FOP (fsetxattr, this, +                                &this_req->compound_req_u.compound_fsetxattr_req, +                                op_errno, out, +                                args->fd, args->flags, args->xattr, +                                args->xdata); +                break; +        case GF_FOP_RCHECKSUM: +                CLIENT_PRE_FOP (rchecksum, this, +                                &this_req->compound_req_u.compound_rchecksum_req, +                                op_errno, out, +                                args->fd, args->size, args->offset, +                                args->xdata); +                break; +        case GF_FOP_SETATTR: +                CLIENT_PRE_FOP (setattr, this, +                                &this_req->compound_req_u.compound_setattr_req, +                                op_errno, out, +                                &args->loc, args->valid, &args->stat, +                                args->xdata); +                break; +        case GF_FOP_FSETATTR: +                CLIENT_PRE_FOP (fsetattr, this, +                                &this_req->compound_req_u.compound_fsetattr_req, +                                op_errno, out, +                                args->fd, args->valid, &args->stat, +                                args->xdata); +                break; +        case GF_FOP_READDIRP: +                CLIENT_PRE_FOP (readdirp, this, +                                &this_req->compound_req_u.compound_readdirp_req, +                                op_errno, out, +                                args->fd, args->size, args->offset, +                                args->xdata); +                if (!local->fd) +                        local->fd = fd_ref (args->fd); +                break; +        case GF_FOP_FREMOVEXATTR: +                CLIENT_PRE_FOP (fremovexattr, this, +                                &this_req->compound_req_u.compound_fremovexattr_req, +                                op_errno, out, +                                args->fd, args->name, args->xdata); +                break; +	case GF_FOP_FALLOCATE: +                CLIENT_PRE_FOP (fallocate, this, +                                &this_req->compound_req_u.compound_fallocate_req, +                                op_errno, out, +                                args->fd, args->flags, args->offset, +                                args->size, args->xdata); +                break; +	case GF_FOP_DISCARD: +                CLIENT_PRE_FOP (discard, this, +                                &this_req->compound_req_u.compound_discard_req, +                                op_errno, out, +                                args->fd, args->offset, args->size, +                                args->xdata); +                break; +        case GF_FOP_ZEROFILL: +                CLIENT_PRE_FOP (zerofill, this, +                                &this_req->compound_req_u.compound_zerofill_req, +                                op_errno, out, +                                args->fd, args->offset, args->size, +                                args->xdata); +                break; +        case GF_FOP_IPC: +                CLIENT_PRE_FOP (ipc, this, +                                &this_req->compound_req_u.compound_ipc_req, +                                op_errno, out, +                                args->cmd, args->xdata); +                break; +        case GF_FOP_SEEK: +                CLIENT_PRE_FOP (seek, this, +                                &this_req->compound_req_u.compound_seek_req, +                                op_errno, out, +                                args->fd, args->offset, args->what, +                                args->xdata); +                break; +        case GF_FOP_LEASE: +                CLIENT_PRE_FOP (lease, this, +                                &this_req->compound_req_u.compound_lease_req, +                                op_errno, out, &args->loc, &args->lease, +                                args->xdata); +        default: +                return ENOTSUP; +        } +        return 0; +out: +        return op_errno; +} + +void +compound_request_cleanup (gfs3_compound_req *req) +{ +        int i       = 0; +        int length  = req->compound_req_array.compound_req_array_len; +        compound_req   *curr_req = NULL; + + +        for (i = 0; i < length; i++) { +                curr_req = &req->compound_req_array.compound_req_array_val[i]; + +                switch (curr_req->fop_enum) { +                case GF_FOP_STAT: +                        CLIENT_COMPOUND_FOP_CLEANUP (curr_req, stat); +                        break; +                case GF_FOP_READLINK: +                        CLIENT_COMPOUND_FOP_CLEANUP (curr_req, readlink); +                        break; +                case GF_FOP_MKNOD: +                        CLIENT_COMPOUND_FOP_CLEANUP (curr_req, mknod); +                        break; +                case GF_FOP_MKDIR: +                        CLIENT_COMPOUND_FOP_CLEANUP (curr_req, mkdir); +                        break; +                case GF_FOP_UNLINK: +                        CLIENT_COMPOUND_FOP_CLEANUP (curr_req, unlink); +                        break; +                case GF_FOP_RMDIR: +                        CLIENT_COMPOUND_FOP_CLEANUP (curr_req, rmdir); +                        break; +                case GF_FOP_SYMLINK: +                        CLIENT_COMPOUND_FOP_CLEANUP (curr_req, symlink); +                        break; +                case GF_FOP_RENAME: +                        CLIENT_COMPOUND_FOP_CLEANUP (curr_req, rename); +                        break; +                case GF_FOP_LINK: +                        CLIENT_COMPOUND_FOP_CLEANUP (curr_req, link); +                        break; +                case GF_FOP_TRUNCATE: +                        CLIENT_COMPOUND_FOP_CLEANUP (curr_req, truncate); +                        break; +                case GF_FOP_OPEN: +                        CLIENT_COMPOUND_FOP_CLEANUP (curr_req, open); +                        break; +                case GF_FOP_READ: +                        CLIENT_COMPOUND_FOP_CLEANUP (curr_req, read); +                        break; +                case GF_FOP_WRITE: +                        CLIENT_COMPOUND_FOP_CLEANUP (curr_req, write); +                        break; +                case GF_FOP_STATFS: +                        CLIENT_COMPOUND_FOP_CLEANUP (curr_req, statfs); +                        break; +                case GF_FOP_FLUSH: +                        CLIENT_COMPOUND_FOP_CLEANUP (curr_req, flush); +                        break; +                case GF_FOP_FSYNC: +                        CLIENT_COMPOUND_FOP_CLEANUP (curr_req, fsync); +                        break; +                case GF_FOP_SETXATTR: +                { +                        gfs3_setxattr_req args = curr_req->compound_req_u.compound_setxattr_req; +                        GF_FREE (args.dict.dict_val); +                        CLIENT_COMPOUND_FOP_CLEANUP (curr_req, setxattr); +                        break; +                } +                case GF_FOP_GETXATTR: +                        CLIENT_COMPOUND_FOP_CLEANUP (curr_req, getxattr); +                        break; +                case GF_FOP_REMOVEXATTR: +                        CLIENT_COMPOUND_FOP_CLEANUP (curr_req, removexattr); +                        break; +                case GF_FOP_OPENDIR: +                        CLIENT_COMPOUND_FOP_CLEANUP (curr_req, opendir); +                        break; +                case GF_FOP_FSYNCDIR: +                        CLIENT_COMPOUND_FOP_CLEANUP (curr_req, fsyncdir); +                        break; +                case GF_FOP_ACCESS: +                        CLIENT_COMPOUND_FOP_CLEANUP (curr_req, access); +                        break; +                case GF_FOP_CREATE: +                        CLIENT_COMPOUND_FOP_CLEANUP (curr_req, create); +                        break; +                case GF_FOP_FTRUNCATE: +                        CLIENT_COMPOUND_FOP_CLEANUP (curr_req, ftruncate); +                        break; +                case GF_FOP_FSTAT: +                        CLIENT_COMPOUND_FOP_CLEANUP (curr_req, fstat); +                        break; +                case GF_FOP_LK: +                        CLIENT_COMPOUND_FOP_CLEANUP (curr_req, lk); +                        break; +                case GF_FOP_LOOKUP: +                        CLIENT_COMPOUND_FOP_CLEANUP (curr_req, lookup); +                        break; +                case GF_FOP_READDIR: +                        CLIENT_COMPOUND_FOP_CLEANUP (curr_req, readdir); +                        break; +                case GF_FOP_INODELK: +                        CLIENT_COMPOUND_FOP_CLEANUP (curr_req, inodelk); +                        break; +                case GF_FOP_FINODELK: +                        CLIENT_COMPOUND_FOP_CLEANUP (curr_req, finodelk); +                        break; +                case GF_FOP_ENTRYLK: +                        CLIENT_COMPOUND_FOP_CLEANUP (curr_req, entrylk); +                        break; +                case GF_FOP_FENTRYLK: +                        CLIENT_COMPOUND_FOP_CLEANUP (curr_req, fentrylk); +                        break; +                case GF_FOP_XATTROP: +                { +                        gfs3_xattrop_req args = curr_req->compound_req_u.compound_xattrop_req; +                        GF_FREE (args.dict.dict_val); +                        CLIENT_COMPOUND_FOP_CLEANUP (curr_req, xattrop); +                        break; +                } +                case GF_FOP_FXATTROP: +                { +                        gfs3_fxattrop_req args = curr_req->compound_req_u.compound_fxattrop_req; +                        GF_FREE (args.dict.dict_val); +                        CLIENT_COMPOUND_FOP_CLEANUP (curr_req, fxattrop); +                        break; +                } +                case GF_FOP_FGETXATTR: +                        CLIENT_COMPOUND_FOP_CLEANUP (curr_req, fgetxattr); +                        break; +                case GF_FOP_FSETXATTR: +                { +                        gfs3_fsetxattr_req args = curr_req->compound_req_u.compound_fsetxattr_req; +                        GF_FREE (args.dict.dict_val); +                        CLIENT_COMPOUND_FOP_CLEANUP (curr_req, fsetxattr); +                        break; +                } +                case GF_FOP_RCHECKSUM: +                        CLIENT_COMPOUND_FOP_CLEANUP (curr_req, rchecksum); +                        break; +                case GF_FOP_SETATTR: +                        CLIENT_COMPOUND_FOP_CLEANUP (curr_req, setattr); +                        break; +                case GF_FOP_FSETATTR: +                        CLIENT_COMPOUND_FOP_CLEANUP (curr_req, fsetattr); +                        break; +                case GF_FOP_READDIRP: +                { +                        gfs3_readdirp_req args = curr_req->compound_req_u.compound_readdirp_req; +                        GF_FREE (args.dict.dict_val); +                        break; +                } +                case GF_FOP_FREMOVEXATTR: +                        CLIENT_COMPOUND_FOP_CLEANUP (curr_req, fremovexattr); +                        break; +                case GF_FOP_FALLOCATE: +                        CLIENT_COMPOUND_FOP_CLEANUP (curr_req, fallocate); +                        break; +                case GF_FOP_DISCARD: +                        CLIENT_COMPOUND_FOP_CLEANUP (curr_req, discard); +                        break; +                case GF_FOP_ZEROFILL: +                        CLIENT_COMPOUND_FOP_CLEANUP (curr_req, zerofill); +                        break; +                case GF_FOP_IPC: +                        CLIENT_COMPOUND_FOP_CLEANUP (curr_req, ipc); +                        break; +                case GF_FOP_SEEK: +                        CLIENT_COMPOUND_FOP_CLEANUP (curr_req, seek); +                        break; +                default: +                        break; +                } +        } + +        return; +} diff --git a/xlators/protocol/client/src/client-mem-types.h b/xlators/protocol/client/src/client-mem-types.h index f6573da2ddd..e6cb9a2e0f4 100644 --- a/xlators/protocol/client/src/client-mem-types.h +++ b/xlators/protocol/client/src/client-mem-types.h @@ -20,6 +20,8 @@ enum gf_client_mem_types_ {          gf_client_mt_clnt_fdctx_t,          gf_client_mt_clnt_lock_t,          gf_client_mt_clnt_fd_lk_local_t, +        gf_client_mt_clnt_args_t, +        gf_client_mt_compound_req_t,          gf_client_mt_end,  };  #endif /* __CLIENT_MEM_TYPES_H__ */ diff --git a/xlators/protocol/client/src/client-rpc-fops.c b/xlators/protocol/client/src/client-rpc-fops.c index b09c169b806..a80c9e610d8 100644 --- a/xlators/protocol/client/src/client-rpc-fops.c +++ b/xlators/protocol/client/src/client-rpc-fops.c @@ -3030,6 +3030,90 @@ client3_3_releasedir_cbk (struct rpc_req *req, struct iovec *iov, int count,  }  int +client3_3_compound_cbk (struct rpc_req *req, struct iovec *iov, int count, +                        void *myframe) +{ +        gfs3_compound_rsp       rsp              = {0,}; +        compound_args_cbk_t     *args_cbk        = NULL; +        call_frame_t            *frame           = NULL; +        int                     ret              = -1; +        xlator_t                *this            = NULL; +        dict_t                  *xdata           = NULL; +        clnt_local_t            *local           = NULL; +        int                     op_errno         = 0; +        int                     i,length         = 0; + +        this = THIS; + +        frame = myframe; +        local = frame->local; + +        if (-1 == req->rpc_status) { +                op_errno = ENOTCONN; +                goto out; +        } + +        ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_compound_rsp); +        if (ret < 0) { +                gf_msg (this->name, GF_LOG_ERROR, EINVAL, +                        PC_MSG_XDR_DECODING_FAILED, "XDR decoding failed"); +                op_errno = EINVAL; +                goto out; +        } + +        args_cbk = GF_CALLOC (1, sizeof (compound_args_cbk_t), gf_mt_compound_rsp_t); +        if (!args_cbk) { +                op_errno = ENOMEM; +                goto out; +        } + +        length = args_cbk->fop_length = local->length; + +        args_cbk->rsp_list = GF_CALLOC (length, sizeof (default_args_cbk_t), +                                        gf_mt_default_args_cbk_t); +        if (!args_cbk->rsp_list) { +                op_errno = ENOMEM; +                goto out; +        } + +        op_errno = rsp.op_errno; + +        for (i = 0; i < args_cbk->fop_length; i++) { +                ret = client_process_response (frame, this, req, &rsp, +                                               args_cbk, i); +                if (ret) { +                        op_errno = -ret; +                        ret = -1; +                        goto out; +                } + +        } + +        GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val), +                                      (rsp.xdata.xdata_len), ret, +                                       rsp.op_errno, out); + +        ret = 0; +out: +        CLIENT_STACK_UNWIND (compound, frame, ret, +                             gf_error_to_errno (op_errno), args_cbk, xdata); + +        free (rsp.xdata.xdata_val); + +        if (xdata) +                dict_unref (xdata); + +        if (args_cbk->rsp_list) { +                for (i = 0; i < length; i++) { +                        args_cbk_wipe (&args_cbk->rsp_list[i]); +                } +        } +        GF_FREE (args_cbk->rsp_list); +        GF_FREE (args_cbk); +        return 0; +} + +int  client_fdctx_destroy (xlator_t *this, clnt_fd_ctx_t *fdctx)  {          clnt_conf_t  *conf        = NULL; @@ -5889,6 +5973,150 @@ unwind:          return 0;  } +/* Brief explanation of gfs3_compound_req structure : + * 1) It consists of version of compounding. + * 2) A compound-fop enum, new enum for compound fops + * 3) A 'compound_req_arrray' structure that has + *      a) array len - based on the number of fops compounded + *      b) compound_req_array_val - pointer to an array of compound_req's + * 4) compound_req - structure that contains: + *      a) fop enum of type glusterfs_fop_t + *      b) union of structures of xdr requests of all fops. + */ + +int32_t +client3_3_compound (call_frame_t *frame, xlator_t *this, void *data) +{ +        clnt_conf_t             *conf              = NULL; +        compound_args_t         *c_args            = data; +        default_args_t          *args              = NULL; +        gfs3_compound_req       req                = {0,}; +        clnt_local_t            *local             = NULL; +        int                     op_errno           = ENOMEM; +        int                     ret                = 0; +        int                     i                  = 0; +        int                     rsp_count          = 0; +        struct iovec            rsp_vector[MAX_IOVEC] = {{0}, }; +        struct iovec            req_vector[MAX_IOVEC] = {{0}, }; +        struct iovec            vector[MAX_IOVEC] = {{0}, }; +        struct iovec            *rsphdr             = NULL; +        struct iobref           *req_iobref         = NULL; +        struct iobref           *rsp_iobref         = NULL; +        struct iobref           *rsphdr_iobref      = NULL; +        struct iobuf            *rsphdr_iobuf       = NULL; +        int                     rsphdr_count        = 0; +        int                     req_count           = 0; +        int                     index               = 0; +        dict_t                  *xdata              = c_args->xdata; + +        GF_ASSERT (frame); + +        if (!this || !data) +                goto unwind; + +        memset (req_vector, 0, sizeof (req_vector)); +        memset (rsp_vector, 0, sizeof (rsp_vector)); + +        conf = this->private; + +        local = mem_get0 (this->local_pool); +        if (!local) { +                op_errno = ENOMEM; +                goto unwind; +        } +        frame->local = local; + +        local->length = c_args->fop_length; +        local->compound_args = c_args; + +        rsphdr_iobref = iobref_new (); +        if (rsphdr_iobref == NULL) { +                goto unwind; +        } + +        /* TODO: what is the size we should send ? */ +        rsphdr_iobuf = iobuf_get (this->ctx->iobuf_pool); +        if (rsphdr_iobuf == NULL) { +                goto unwind; +        } + +        iobref_add (rsphdr_iobref, rsphdr_iobuf); +        iobuf_unref (rsphdr_iobuf); +        rsphdr = &vector[0]; +        rsphdr->iov_base = iobuf_ptr (rsphdr_iobuf); +        rsphdr->iov_len = iobuf_pagesize (rsphdr_iobuf); +        rsphdr_count = 1; +        local->iobref = rsp_iobref; +        rsphdr_iobuf = NULL; +        rsphdr_iobref = NULL; + +        req.compound_fop_enum = c_args->fop_enum; +        req.compound_req_array.compound_req_array_len = c_args->fop_length; +        /*TODO : Talk to Sowmya about this */ +        req.compound_version = 0; +        if (xdata) { +                GF_PROTOCOL_DICT_SERIALIZE (this, xdata, +                                            (&req.xdata.xdata_val), +                                            req.xdata.xdata_len, +                                            op_errno, unwind); +        } + +        req.compound_req_array.compound_req_array_val = GF_CALLOC (local->length, +                                                        sizeof (compound_req), +                                                        gf_client_mt_compound_req_t); + +        if (!req.compound_req_array.compound_req_array_val) { +                op_errno = ENOMEM; +                goto unwind; +        } + +        for (i = 0; i < local->length; i++) { +                ret = client_handle_fop_requirements (this, frame, +                                                      &req, local, +                                                      req_iobref, rsp_iobref, +                                                      req_vector, +                                                      rsp_vector, &req_count, +                                                      &rsp_count, +                                                      &c_args->req_list[i], +                                                      c_args->enum_list[i], +                                                      index); +                if (ret) { +                        op_errno = ret; +                        goto unwind; +                } +                index++; +        } + +        local->iobref2 = rsp_iobref; +        rsp_iobref     = NULL; + +        ret = client_submit_compound_request (this, &req, frame, conf->fops, +                                     GFS3_OP_COMPOUND, client3_3_compound_cbk, +                                     req_vector, req_count, local->iobref, +                                     rsphdr, rsphdr_count, +                                     rsp_vector, rsp_count, +                                     local->iobref2, +                                     (xdrproc_t) xdr_gfs3_compound_req); + +        GF_FREE (req.xdata.xdata_val); + +        compound_request_cleanup (&req); +        return 0; +unwind: +        CLIENT_STACK_UNWIND (compound, frame, -1, op_errno, NULL, NULL); + +        if (rsp_iobref) +                iobref_unref (rsp_iobref); + +        if (rsphdr_iobref) +                iobref_unref (rsphdr_iobref); + +        GF_FREE (req.xdata.xdata_val); + +        compound_request_cleanup (&req); +        return 0; +} +  /* Table Specific to FOPS */ diff --git a/xlators/protocol/client/src/client.c b/xlators/protocol/client/src/client.c index aae712acd4b..c37c1e25b44 100644 --- a/xlators/protocol/client/src/client.c +++ b/xlators/protocol/client/src/client.c @@ -339,6 +339,123 @@ out:  } +int +client_submit_compound_request (xlator_t *this, void *req, call_frame_t *frame, +                       rpc_clnt_prog_t *prog, int procnum, fop_cbk_fn_t cbkfn, +                       struct iovec *req_payload, int req_count, +                       struct iobref *iobref,  struct iovec *rsphdr, +                       int rsphdr_count, struct iovec *rsp_payload, +                       int rsp_payload_count, struct iobref *rsp_iobref, +                       xdrproc_t xdrproc) +{ +        int             ret        = -1; +        clnt_conf_t    *conf       = NULL; +        struct iovec    iov        = {0, }; +        struct iobuf   *iobuf      = NULL; +        int             count      = 0; +        struct iobref  *new_iobref = NULL; +        ssize_t         xdr_size   = 0; +        struct rpc_req  rpcreq     = {0, }; + +        GF_VALIDATE_OR_GOTO ("client", this, out); +        GF_VALIDATE_OR_GOTO (this->name, prog, out); +        GF_VALIDATE_OR_GOTO (this->name, frame, out); + +        conf = this->private; + +        /* If 'setvolume' is not successful, we should not send frames to +         * server +         */ + +        if (!conf->connected) { +                gf_msg_debug (this->name, 0, +                              "connection in disconnected state"); +                goto out; +        } + +        if (req && xdrproc) { +                xdr_size = xdr_sizeof (xdrproc, req); +                iobuf = iobuf_get2 (this->ctx->iobuf_pool, xdr_size); +                if (!iobuf) { +                        goto out; +                }; + +                new_iobref = iobref_new (); +                if (!new_iobref) { +                        goto out; +                } + +                if (iobref != NULL) { +                        ret = iobref_merge (new_iobref, iobref); +                        if (ret != 0) { +                                goto out; +                        } +                } + +                ret = iobref_add (new_iobref, iobuf); +                if (ret != 0) { +                        goto out; +                } + +                iov.iov_base = iobuf->ptr; +                iov.iov_len  = iobuf_size (iobuf); + +                /* Create the xdr payload */ +                ret = xdr_serialize_generic (iov, req, xdrproc); +                if (ret == -1) { +                        /* callingfn so that, we can get to know which xdr +                           function was called */ +                        gf_log_callingfn (this->name, GF_LOG_WARNING, +                                          "XDR payload creation failed"); +                        goto out; +                } +                iov.iov_len = ret; +                count = 1; +        } + +        /* do not send all groups if they are resolved server-side */ +        if (!conf->send_gids) { +                if (frame->root->ngrps <= SMALL_GROUP_COUNT) { +                        frame->root->groups_small[0] = frame->root->gid; +                        frame->root->groups = frame->root->groups_small; +                } +                frame->root->ngrps = 1; +        } + +        /* Send the msg */ +        ret = rpc_clnt_submit (conf->rpc, prog, procnum, cbkfn, &iov, count, +                               req_payload, req_count, new_iobref, frame, +                               rsphdr, rsphdr_count, +                               rsp_payload, rsp_payload_count, rsp_iobref); + +        if (ret < 0) { +                gf_msg_debug (this->name, 0, "rpc_clnt_submit failed"); +        } + +        ret = 0; + +        if (new_iobref) +                iobref_unref (new_iobref); + +        if (iobuf) +                iobuf_unref (iobuf); + +        return ret; + +out: +        rpcreq.rpc_status = -1; + +        cbkfn (&rpcreq, NULL, 0, frame); + +        if (new_iobref) +                iobref_unref (new_iobref); + +        if (iobuf) +                iobuf_unref (iobuf); + +        return 0; +} +  int32_t  client_forget (xlator_t *this, inode_t *inode)  { @@ -1980,6 +2097,32 @@ out:  } +int32_t +client_compound (call_frame_t *frame, xlator_t *this, +                 void *data, dict_t *xdata) +{ +        int          ret  = -1; +        clnt_conf_t *conf = NULL; +        compound_args_t *args = data; +        rpc_clnt_procedure_t *proc = NULL; + +        conf = this->private; +        if (!conf || !conf->fops) +                goto out; + +        args->xdata = xdata; + +        proc = &conf->fops->proctable[GF_FOP_COMPOUND]; +        if (proc->fn) +                ret = proc->fn (frame, this, args); +out: +        if (ret) +                STACK_UNWIND_STRICT (compound, frame, -1, ENOTCONN, +                                     NULL, NULL); + +	return 0; +} +  int  client_mark_fd_bad (xlator_t *this)  { @@ -2749,6 +2892,7 @@ struct xlator_fops fops = {          .ipc         = client_ipc,          .seek        = client_seek,          .lease       = client_lease, +        .compound    = client_compound,  }; diff --git a/xlators/protocol/client/src/client.h b/xlators/protocol/client/src/client.h index e27b1dbca21..efa9d21437a 100644 --- a/xlators/protocol/client/src/client.h +++ b/xlators/protocol/client/src/client.h @@ -20,6 +20,7 @@  #include "client-mem-types.h"  #include "protocol-common.h"  #include "glusterfs3.h" +#include "glusterfs3-xdr.h"  #include "fd-lk.h"  #include "defaults.h"  #include "default-args.h" @@ -42,6 +43,47 @@ typedef enum {          FALLBACK_TO_ANON_FD = 1  } clnt_remote_fd_flags_t; +#define CLIENT_POST_FOP(fop, this_rsp_u, this_args_cbk,  params ...)                     \ +        do {                                                                             \ +                gf_common_rsp  *_this_rsp = &this_rsp_u->compound_rsp_u.compound_##fop##_rsp;           \ +                int              _op_ret    = 0;                                         \ +                int              _op_errno  = 0;                                         \ +                                                                                         \ +                _op_ret = _this_rsp->op_ret;                                             \ +                _op_errno = gf_error_to_errno (_this_rsp->op_errno);                     \ +                args_##fop##_cbk_store (this_args_cbk, _op_ret, _op_errno, params);      \ +        } while (0) + +#define CLIENT_POST_FOP_TYPE(fop, this_rsp_u, this_args_cbk, params ...)                \ +        do {                                                                             \ +                gfs3_##fop##_rsp  *_this_rsp = &this_rsp_u->compound_rsp_u.compound_##fop##_rsp;          \ +                int              _op_ret    = 0;                                         \ +                int              _op_errno  = 0;                                         \ +                                                                                         \ +                _op_ret = _this_rsp->op_ret;                                             \ +                _op_errno = gf_error_to_errno (_this_rsp->op_errno);                     \ +                args_##fop##_cbk_store (this_args_cbk, _op_ret, _op_errno, params);      \ +        } while (0) + +#define CLIENT_PRE_FOP(fop, xl, compound_req, op_errno, label, params ...) \ +        do {                                                               \ +                gfs3_##fop##_req  *_req = (gfs3_##fop##_req *) compound_req;  \ +                int              _ret = 0;                                 \ +                                                                           \ +                _ret = client_pre_##fop (xl, _req, params);              \ +                if (_ret < 0) {                                            \ +                        op_errno = -ret;                                  \ +                        goto label;                                        \ +                }                                                          \ +        } while (0) + +#define CLIENT_COMPOUND_FOP_CLEANUP(curr_req, fop)                                      \ +        do {                                                                            \ +                gfs3_##fop##_req *_req = &curr_req->compound_req_u.compound_##fop##_req;\ +                                                                                        \ +                GF_FREE (_req->xdata.xdata_val);                                        \ +        } while (0) +  #define CLIENT_GET_REMOTE_FD(xl, fd, flags, remote_fd, op_errno, label) \          do {                                                            \                  int     _ret    = 0;                                    \ @@ -185,6 +227,11 @@ typedef struct client_local {          pthread_mutex_t      mutex;          char                *name;          gf_boolean_t         attempt_reopen; +        /* required for compound fops */ +        struct iobref       *iobref2; +        compound_args_t     *compound_args; +        unsigned int         length; /* length of a compound fop */ +        unsigned int         read_length; /* defines the last processed length for a compound read */  } clnt_local_t;  typedef struct client_args { @@ -238,6 +285,15 @@ int client_submit_request (xlator_t *this, void *req,                             struct iovec *rsp_payload, int rsp_count,                             struct iobref *rsp_iobref, xdrproc_t xdrproc); +int +client_submit_compound_request (xlator_t *this, void *req, call_frame_t *frame, +                       rpc_clnt_prog_t *prog, int procnum, fop_cbk_fn_t cbkfn, +                       struct iovec *req_vector, int req_count, +                       struct iobref *iobref,  struct iovec *rsphdr, +                       int rsphdr_count, struct iovec *rsp_payload, +                       int rsp_payload_count, struct iobref *rsp_iobref, +                       xdrproc_t xdrproc); +  int unserialize_rsp_dirent (xlator_t *this, struct gfs3_readdir_rsp *rsp,                              gf_dirent_t *entries);  int unserialize_rsp_direntp (xlator_t *this, fd_t *fd, @@ -283,4 +339,25 @@ client_notify_dispatch_uniq (xlator_t *this, int32_t event, void *data, ...);  gf_boolean_t  client_is_reopen_needed (fd_t *fd, xlator_t *this, int64_t remote_fd); + +int +client_add_fd_to_saved_fds (xlator_t *this, fd_t *fd, loc_t *loc, int32_t flags, +                            int64_t remote_fd, int is_dir); +int +client_handle_fop_requirements (xlator_t *this, call_frame_t *frame, +                                gfs3_compound_req *req, +                                clnt_local_t *local, +                                struct iobref *req_iobref, +                                struct iobref *rsp_iobref, +                                struct iovec *req_vector, +                                struct iovec *rsp_vector, int *req_count, +                                int *rsp_count, default_args_t *args, +                                int fop_enum, int index); +int +client_process_response (call_frame_t *frame, xlator_t *this, +                         struct rpc_req *req, +                         gfs3_compound_rsp *rsp, compound_args_cbk_t *args_cbk, +                         int index); +void +compound_request_cleanup (gfs3_compound_req *req);  #endif /* !_CLIENT_H */  | 
