diff options
| author | Anuradha Talur <atalur@redhat.com> | 2016-05-02 00:36:30 +0530 | 
|---|---|---|
| committer | Niels de Vos <ndevos@redhat.com> | 2016-05-01 18:05:31 -0700 | 
| commit | 60e340481ad5496e920722e8267572fa26cf2822 (patch) | |
| tree | 1530ba672669216ee67c6217443a4c1d30afd592 | |
| parent | a15195794c336ed0e272076a128c56b171cae12f (diff) | |
protocol/server: Implementation of compound fopv3.9dev
Change-Id: I981258afa527337dd2ad33eecba7fc8084238e6d
BUG: 1303829
Signed-off-by: Anuradha Talur <atalur@redhat.com>
Reviewed-on: http://review.gluster.org/14137
Smoke: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Niels de Vos <ndevos@redhat.com>
NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
CentOS-regression: Gluster Build System <jenkins@build.gluster.com>
| -rw-r--r-- | xlators/protocol/client/src/client-rpc-fops.c | 2 | ||||
| -rw-r--r-- | xlators/protocol/server/src/Makefile.am | 4 | ||||
| -rw-r--r-- | xlators/protocol/server/src/server-common.c | 472 | ||||
| -rw-r--r-- | xlators/protocol/server/src/server-common.h | 132 | ||||
| -rw-r--r-- | xlators/protocol/server/src/server-helpers.c | 2439 | ||||
| -rw-r--r-- | xlators/protocol/server/src/server-helpers.h | 13 | ||||
| -rw-r--r-- | xlators/protocol/server/src/server-mem-types.h | 1 | ||||
| -rw-r--r-- | xlators/protocol/server/src/server-messages.h | 11 | ||||
| -rw-r--r-- | xlators/protocol/server/src/server-rpc-fops.c | 491 | ||||
| -rw-r--r-- | xlators/protocol/server/src/server.h | 20 | 
10 files changed, 3339 insertions, 246 deletions
diff --git a/xlators/protocol/client/src/client-rpc-fops.c b/xlators/protocol/client/src/client-rpc-fops.c index 8d7da4e0d29..872f7635b11 100644 --- a/xlators/protocol/client/src/client-rpc-fops.c +++ b/xlators/protocol/client/src/client-rpc-fops.c @@ -6403,6 +6403,7 @@ rpc_clnt_procedure_t clnt3_3_fop_actors[GF_FOP_MAXVALUE] = {          [GF_FOP_LEASE]        = { "LEASE",        client3_3_lease },          [GF_FOP_GETACTIVELK]  = { "GETACTIVELK", client3_3_getactivelk},          [GF_FOP_SETACTIVELK]  = { "SETACTIVELK", client3_3_setactivelk}, +        [GF_FOP_COMPOUND]     = { "COMPOUND",     client3_3_compound },  };  /* Used From RPC-CLNT library to log proper name of procedure based on number */ @@ -6459,6 +6460,7 @@ char *clnt3_3_fop_names[GFS3_OP_MAXVALUE] = {          [GFS3_OP_LEASE]       = "LEASE",          [GFS3_OP_GETACTIVELK] = "GETACTIVELK",          [GFS3_OP_SETACTIVELK] = "SETACTIVELK", +        [GFS3_OP_COMPOUND]    = "COMPOUND",  };  rpc_clnt_prog_t clnt3_3_fop_prog = { diff --git a/xlators/protocol/server/src/Makefile.am b/xlators/protocol/server/src/Makefile.am index dbec61d6cad..bb46fda6f08 100644 --- a/xlators/protocol/server/src/Makefile.am +++ b/xlators/protocol/server/src/Makefile.am @@ -8,10 +8,10 @@ server_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \  	$(top_builddir)/rpc/xdr/src/libgfxdr.la  server_la_SOURCES = server.c server-resolve.c server-helpers.c  \ -	server-rpc-fops.c server-handshake.c authenticate.c +	server-rpc-fops.c server-handshake.c authenticate.c server-common.c  server_la_HEADERS = server.h server-helpers.h server-mem-types.h authenticate.h \ -	server-messages.h +	server-messages.h server-common.h  server_ladir = $(includedir)/glusterfs/server diff --git a/xlators/protocol/server/src/server-common.c b/xlators/protocol/server/src/server-common.c new file mode 100644 index 00000000000..fd6749a4df7 --- /dev/null +++ b/xlators/protocol/server/src/server-common.c @@ -0,0 +1,472 @@ +#include "server.h" +#include "defaults.h" +#include "rpc-common-xdr.h" +#include "glusterfs3-xdr.h" +#include "glusterfs3.h" +#include "compat-errno.h" +#include "server-messages.h" +#include "defaults.h" +#include "fd.h" +#include "xdr-nfs3.h" + +void +server_post_stat (gfs3_stat_rsp *rsp, struct iatt *stbuf) +{ +        gf_stat_from_iatt (&rsp->stat, stbuf); +} + +void +server_post_readlink (gfs3_readlink_rsp *rsp, struct iatt *stbuf, +                      const char *buf) +{ +        gf_stat_from_iatt (&rsp->buf, stbuf); +        rsp->path = (char *)buf; + +        if (!rsp->path) +                rsp->path = ""; +} + +void +server_post_mknod (server_state_t *state, gfs3_mknod_rsp *rsp, +                   struct iatt *stbuf, struct iatt *preparent, +                   struct iatt *postparent, inode_t *inode) +{ +        inode_t             *link_inode = NULL; + +        gf_stat_from_iatt (&rsp->stat, stbuf); +        gf_stat_from_iatt (&rsp->preparent, preparent); +        gf_stat_from_iatt (&rsp->postparent, postparent); + +        link_inode = inode_link (inode, state->loc.parent, +                                 state->loc.name, stbuf); +        inode_lookup (link_inode); +        inode_unref  (link_inode); +} + +void +server_post_mkdir (server_state_t *state, gfs3_mkdir_rsp *rsp, +                   inode_t *inode, +                   struct iatt *stbuf, struct iatt *preparent, +                   struct iatt *postparent, dict_t *xdata) +{ +        inode_t             *link_inode = NULL; + +        gf_stat_from_iatt (&rsp->stat, stbuf); +        gf_stat_from_iatt (&rsp->preparent, preparent); +        gf_stat_from_iatt (&rsp->postparent, postparent); + +        link_inode = inode_link (inode, state->loc.parent, +                                 state->loc.name, stbuf); +        inode_lookup (link_inode); +        inode_unref (link_inode); + +} + +void +server_post_unlink (server_state_t *state, gfs3_unlink_rsp *rsp, +                    struct iatt *preparent, struct iatt *postparent) +{ +        inode_unlink (state->loc.inode, state->loc.parent, +                      state->loc.name); + +        forget_inode_if_no_dentry (state->loc.inode); + +        gf_stat_from_iatt (&rsp->preparent, preparent); +        gf_stat_from_iatt (&rsp->postparent, postparent); + +} + +void +server_post_rmdir (server_state_t *state, gfs3_rmdir_rsp *rsp, +                    struct iatt *preparent, struct iatt *postparent) +{ +        inode_unlink (state->loc.inode, state->loc.parent, +                      state->loc.name); +        /* parent should not be found for directories after +         * inode_unlink, since directories cannot have +         * hardlinks. +         */ +        forget_inode_if_no_dentry (state->loc.inode); + +        gf_stat_from_iatt (&rsp->preparent, preparent); +        gf_stat_from_iatt (&rsp->postparent, postparent); +} + +void +server_post_symlink (server_state_t *state, gfs3_symlink_rsp *rsp, +                   inode_t *inode, +                   struct iatt *stbuf, struct iatt *preparent, +                   struct iatt *postparent, dict_t *xdata) +{ +        inode_t             *link_inode = NULL; + +        gf_stat_from_iatt (&rsp->stat, stbuf); +        gf_stat_from_iatt (&rsp->preparent, preparent); +        gf_stat_from_iatt (&rsp->postparent, postparent); + +        link_inode = inode_link (inode, state->loc.parent, +                                 state->loc.name, stbuf); +        inode_lookup (link_inode); +        inode_unref (link_inode); + +} + +void +server_post_link (server_state_t *state, gfs3_link_rsp *rsp, +                   inode_t *inode, +                   struct iatt *stbuf, struct iatt *preparent, +                   struct iatt *postparent, dict_t *xdata) +{ +        inode_t             *link_inode = NULL; + +        gf_stat_from_iatt (&rsp->stat, stbuf); +        gf_stat_from_iatt (&rsp->preparent, preparent); +        gf_stat_from_iatt (&rsp->postparent, postparent); + +        link_inode = inode_link (inode, state->loc2.parent, +                                 state->loc2.name, stbuf); +        inode_lookup (link_inode); +        inode_unref (link_inode); + +} + +void +server_post_truncate (gfs3_truncate_rsp *rsp, struct iatt *prebuf, +                      struct iatt *postbuf) +{ +        gf_stat_from_iatt (&rsp->prestat, prebuf); +        gf_stat_from_iatt (&rsp->poststat, postbuf); +} + +void +server_post_writev (gfs3_write_rsp *rsp, struct iatt *prebuf, +                      struct iatt *postbuf) +{ +        gf_stat_from_iatt (&rsp->prestat, prebuf); +        gf_stat_from_iatt (&rsp->poststat, postbuf); +} + +void +server_post_statfs (gfs3_statfs_rsp *rsp, struct statvfs *stbuf) +{ +        gf_statfs_from_statfs (&rsp->statfs, stbuf); +} + +void +server_post_fsync (gfs3_fsync_rsp *rsp, struct iatt *prebuf, +                   struct iatt *postbuf) +{ +        gf_stat_from_iatt (&rsp->prestat, prebuf); +        gf_stat_from_iatt (&rsp->poststat, postbuf); +} + +void +server_post_ftruncate (gfs3_ftruncate_rsp *rsp, struct iatt *prebuf, +                      struct iatt *postbuf) +{ +        gf_stat_from_iatt (&rsp->prestat, prebuf); +        gf_stat_from_iatt (&rsp->poststat, postbuf); +} + +void +server_post_fstat (gfs3_fstat_rsp *rsp, struct iatt *stbuf) +{ +        gf_stat_from_iatt (&rsp->stat, stbuf); +} + +void +server_post_lk (xlator_t *this, gfs3_lk_rsp *rsp, struct gf_flock *lock) +{ +        switch (lock->l_type) { +        case F_RDLCK: +                lock->l_type = GF_LK_F_RDLCK; +                break; +        case F_WRLCK: +                lock->l_type = GF_LK_F_WRLCK; +                break; +        case F_UNLCK: +                lock->l_type = GF_LK_F_UNLCK; +                break; +        default: +                gf_msg (this->name, GF_LOG_ERROR, 0, PS_MSG_LOCK_ERROR, +                        "Unknown lock type: %"PRId32"!", lock->l_type); +                break; +        } + +        gf_proto_flock_from_flock (&rsp->flock, lock); +} + +int +server_post_readdir (gfs3_readdir_rsp *rsp, gf_dirent_t *entries) +{ +                int     ret = 0; + +                ret = serialize_rsp_dirent (entries, rsp); + +        return ret; +} +void +server_post_zerofill (gfs3_zerofill_rsp *rsp, struct iatt *statpre, +                      struct iatt *statpost) +{ +        gf_stat_from_iatt (&rsp->statpre, statpre); +        gf_stat_from_iatt (&rsp->statpost, statpost); +} + +void +server_post_discard (gfs3_discard_rsp *rsp, struct iatt *statpre, +                      struct iatt *statpost) +{ +        gf_stat_from_iatt (&rsp->statpre, statpre); +        gf_stat_from_iatt (&rsp->statpost, statpost); +} + +void +server_post_fallocate (gfs3_fallocate_rsp *rsp, struct iatt *statpre, +                       struct iatt *statpost) +{ +        gf_stat_from_iatt (&rsp->statpre, statpre); +        gf_stat_from_iatt (&rsp->statpost, statpost); +} + +int +server_post_readdirp (gfs3_readdirp_rsp *rsp, gf_dirent_t *entries) +{ +                int     ret = 0; + +                ret = serialize_rsp_direntp (entries, rsp); + +        return ret; +} + +void +server_post_fsetattr (gfs3_fsetattr_rsp *rsp, struct iatt *statpre, +                       struct iatt *statpost) +{ +        gf_stat_from_iatt (&rsp->statpre, statpre); +        gf_stat_from_iatt (&rsp->statpost, statpost); +} + +void +server_post_setattr (gfs3_setattr_rsp *rsp, struct iatt *statpre, +                     struct iatt *statpost) +{ +        gf_stat_from_iatt (&rsp->statpre, statpre); +        gf_stat_from_iatt (&rsp->statpost, statpost); +} + +void +server_post_rchecksum (gfs3_rchecksum_rsp *rsp, uint32_t weak_checksum, +                       uint8_t *strong_checksum) +{ +        rsp->weak_checksum = weak_checksum; + +        rsp->strong_checksum.strong_checksum_val = (char *)strong_checksum; +        rsp->strong_checksum.strong_checksum_len = MD5_DIGEST_LENGTH; + +} + +void +server_post_rename (call_frame_t *frame, +                    server_state_t *state, gfs3_rename_rsp *rsp, +                    struct iatt *stbuf, +                    struct iatt *preoldparent, +                    struct iatt *postoldparent, +                    struct iatt *prenewparent, +                    struct iatt *postnewparent) +{ +        inode_t             *tmp_inode  = NULL; +        inode_t             *tmp_parent = NULL; + +        stbuf->ia_type = state->loc.inode->ia_type; + +        /* TODO: log gfid of the inodes */ +        gf_msg_trace (frame->root->client->bound_xl->name, 0, "%"PRId64": " +                      "RENAME_CBK %s ==> %s", frame->root->unique, +                      state->loc.name, state->loc2.name); + +        /* Before renaming the inode, we have to get the inode for the +         * destination entry (i.e. inode with state->loc2.parent as +         * parent and state->loc2.name as name). If it exists, then +         * unlink that inode, and send forget on that inode if the +         * unlinked entry is the last entry. In case of fuse client +         * the fuse kernel module itself sends the forget on the +         * unlinked inode. +         */ +        tmp_inode = inode_grep (state->loc.inode->table, +                                state->loc2.parent, state->loc2.name); +        if (tmp_inode) { +                inode_unlink (tmp_inode, state->loc2.parent, +                              state->loc2.name); +                forget_inode_if_no_dentry (tmp_inode); +                inode_unref (tmp_inode); +        } + +        inode_rename (state->itable, +                      state->loc.parent, state->loc.name, +                      state->loc2.parent, state->loc2.name, +                      state->loc.inode, stbuf); +        gf_stat_from_iatt (&rsp->stat, stbuf); + +        gf_stat_from_iatt (&rsp->preoldparent, preoldparent); +        gf_stat_from_iatt (&rsp->postoldparent, postoldparent); + +        gf_stat_from_iatt (&rsp->prenewparent, prenewparent); +        gf_stat_from_iatt (&rsp->postnewparent, postnewparent); + +} + +int +server_post_open (call_frame_t *frame, xlator_t *this, +                  gfs3_open_rsp *rsp, fd_t *fd) +{ +        server_ctx_t        *serv_ctx = NULL; +        uint64_t             fd_no    = 0; +        int                  ret       = 0; + +        serv_ctx = server_ctx_get (frame->root->client, this); +        if (serv_ctx == NULL) { +                gf_msg (this->name, GF_LOG_INFO, 0, +                        PS_MSG_SERVER_CTX_GET_FAILED, "server_ctx_get() " +                        "failed"); +                return -1; +        } + +        fd_bind (fd); +        fd_no = gf_fd_unused_get (serv_ctx->fdtable, fd); +        fd_ref (fd); +        rsp->fd = fd_no; + +        return 0; +} + +void +server_post_readv (gfs3_read_rsp *rsp, struct iatt *stbuf, int op_ret) +{ +        gf_stat_from_iatt (&rsp->stat, stbuf); +        rsp->size = op_ret; +} + +int +server_post_opendir (call_frame_t *frame, xlator_t *this, +                     gfs3_opendir_rsp *rsp, fd_t *fd) +{ +        server_ctx_t        *serv_ctx = NULL; +        uint64_t             fd_no    = 0; +        int                  ret       = 0; + +        serv_ctx = server_ctx_get (frame->root->client, this); +        if (serv_ctx == NULL) { +                gf_msg (this->name, GF_LOG_INFO, 0, +                        PS_MSG_SERVER_CTX_GET_FAILED, "server_ctx_get() " +                        "failed"); +                return -1; +        } + +        fd_bind (fd); +        fd_no = gf_fd_unused_get (serv_ctx->fdtable, fd); +        fd_ref (fd); +        rsp->fd = fd_no; + +        return 0; +} + +int +server_post_create (call_frame_t *frame, gfs3_create_rsp *rsp, +                    server_state_t *state, +                    xlator_t *this, fd_t *fd, inode_t *inode, +                    struct iatt *stbuf, struct iatt *preparent, +                    struct iatt *postparent) +{ +        server_ctx_t        *serv_ctx   = NULL; +        inode_t             *link_inode = NULL; +        uint64_t             fd_no      = 0; +        int                  op_errno   = 0; + +        link_inode = inode_link (inode, state->loc.parent, +                                 state->loc.name, stbuf); + +        if (!link_inode) { +                op_errno = ENOENT; +                goto out; +        } + +        if (link_inode != inode) { +                /* +                  VERY racy code (if used anywhere else) +                  -- don't do this without understanding +                */ + +                inode_ctx_merge (fd, fd->inode, link_inode); +                inode_unref (fd->inode); +                fd->inode = inode_ref (link_inode); +        } + +        inode_lookup (link_inode); +        inode_unref (link_inode); + +        serv_ctx = server_ctx_get (frame->root->client, this); +        if (serv_ctx == NULL) { +                gf_msg (this->name, GF_LOG_INFO, 0, +                        PS_MSG_SERVER_CTX_GET_FAILED, "server_ctx_get() " +                        "failed"); +                goto out; +        } + +        fd_bind (fd); +        fd_no = gf_fd_unused_get (serv_ctx->fdtable, fd); +        fd_ref (fd); + +        if ((fd_no > UINT64_MAX) || (fd == 0)) { +                op_errno = errno; +        } + +        rsp->fd = fd_no; +        gf_stat_from_iatt (&rsp->stat, stbuf); +        gf_stat_from_iatt (&rsp->preparent, preparent); +        gf_stat_from_iatt (&rsp->postparent, postparent); + +        return 0; +out: +        return -op_errno; +} + +/*TODO: Handle revalidate path */ +void +server_post_lookup (gfs3_lookup_rsp *rsp, call_frame_t *frame, +                    server_state_t *state, +                    inode_t *inode, struct iatt *stbuf, +                    struct iatt *postparent) +{ +        inode_t             *root_inode = NULL; +        inode_t             *link_inode = NULL; +        uuid_t               rootgfid   = {0,}; + +        root_inode = frame->root->client->bound_xl->itable->root; + +        if (inode == root_inode) { +                /* we just looked up root ("/") */ +                stbuf->ia_ino = 1; +                rootgfid[15]  = 1; +                gf_uuid_copy (stbuf->ia_gfid, rootgfid); +                if (inode->ia_type == 0) +                        inode->ia_type = stbuf->ia_type; +        } + +        gf_stat_from_iatt (&rsp->stat, stbuf); + +        if (!__is_root_gfid (inode->gfid)) { +                link_inode = inode_link (inode, state->loc.parent, +                                         state->loc.name, stbuf); +                if (link_inode) { +                        inode_lookup (link_inode); +                        inode_unref (link_inode); +                } +        } +} + +void +server_post_lease (gfs3_lease_rsp *rsp, struct gf_lease *lease) +{ +        gf_proto_lease_from_lease (&rsp->lease, lease); +} diff --git a/xlators/protocol/server/src/server-common.h b/xlators/protocol/server/src/server-common.h new file mode 100644 index 00000000000..afd9fb81269 --- /dev/null +++ b/xlators/protocol/server/src/server-common.h @@ -0,0 +1,132 @@ +#include "server.h" +#include "defaults.h" +#include "rpc-common-xdr.h" +#include "glusterfs3-xdr.h" +#include "glusterfs3.h" +#include "compat-errno.h" +#include "server-messages.h" +#include "defaults.h" + +#include "xdr-nfs3.h" +void +server_post_stat (gfs3_stat_rsp *rsp, struct iatt *stbuf); + +void +server_post_readlink (gfs3_readlink_rsp *rsp, struct iatt *stbuf, +                      const char *buf); + +void +server_post_mknod (server_state_t *state, gfs3_mknod_rsp *rsp, +                   struct iatt *stbuf, struct iatt *preparent, +                   struct iatt *postparent, inode_t *inode); +void +server_post_mkdir (server_state_t *state, gfs3_mkdir_rsp *rsp, +                   inode_t *inode, +                   struct iatt *stbuf, struct iatt *preparent, +                   struct iatt *postparent, dict_t *xdata); + +void +server_post_unlink (server_state_t *state, gfs3_unlink_rsp *rsp, +                    struct iatt *preparent, struct iatt *postparent); +void +server_post_rmdir (server_state_t *state, gfs3_rmdir_rsp *rsp, +                    struct iatt *preparent, struct iatt *postparent); + +void +server_post_symlink (server_state_t *state, gfs3_symlink_rsp *rsp, +                   inode_t *inode, +                   struct iatt *stbuf, struct iatt *preparent, +                   struct iatt *postparent, dict_t *xdata); +void +server_post_link (server_state_t *state, gfs3_link_rsp *rsp, +                   inode_t *inode, +                   struct iatt *stbuf, struct iatt *preparent, +                   struct iatt *postparent, dict_t *xdata); +void +server_post_truncate (gfs3_truncate_rsp *rsp, struct iatt *prebuf, +                      struct iatt *postbuf); + +void +server_post_writev (gfs3_write_rsp *rsp, struct iatt *prebuf, +                      struct iatt *postbuf); +void +server_post_statfs (gfs3_statfs_rsp *rsp, struct statvfs *stbuf); + +void +server_post_fsync (gfs3_fsync_rsp *rsp, struct iatt *prebuf, +                   struct iatt *postbuf); + +void +server_post_ftruncate (gfs3_ftruncate_rsp *rsp, struct iatt *prebuf, +                      struct iatt *postbuf); + +void +server_post_fstat (gfs3_fstat_rsp *rsp, struct iatt *stbuf); + +void +server_post_lk (xlator_t *this, gfs3_lk_rsp *rsp, struct gf_flock *lock); + +int +server_post_readdir (gfs3_readdir_rsp *rsp, gf_dirent_t *entries); + +void +server_post_zerofill (gfs3_zerofill_rsp *rsp, struct iatt *statpre, +                      struct iatt *statpost); + +void +server_post_discard (gfs3_discard_rsp *rsp, struct iatt *statpre, +                      struct iatt *statpost); + +void +server_post_fallocate (gfs3_fallocate_rsp *rsp, struct iatt *statpre, +                       struct iatt *statpost); + +int +server_post_readdirp (gfs3_readdirp_rsp *rsp, gf_dirent_t *entries); + +void +server_post_fsetattr (gfs3_fsetattr_rsp *rsp, struct iatt *statpre, +                       struct iatt *statpost); + +void +server_post_setattr (gfs3_setattr_rsp *rsp, struct iatt *statpre, +                     struct iatt *statpost); + +void +server_post_rchecksum (gfs3_rchecksum_rsp *rsp, uint32_t weak_checksum, +                       uint8_t *strong_checksum); + +void +server_post_rename (call_frame_t *frame, server_state_t *state, +                    gfs3_rename_rsp *rsp, +                    struct iatt *stbuf, +                    struct iatt *preoldparent, +                    struct iatt *postoldparent, +                    struct iatt *prenewparent, +                    struct iatt *postnewparent); + +int +server_post_open (call_frame_t *frame, xlator_t *this, +                  gfs3_open_rsp *rsp, fd_t *fd); +void +server_post_readv (gfs3_read_rsp *rsp, struct iatt *stbuf, int op_ret); + +int +server_post_opendir (call_frame_t *frame, xlator_t *this, +                     gfs3_opendir_rsp *rsp, fd_t *fd); + +int +server_post_create (call_frame_t *frame, gfs3_create_rsp *rsp, +                    server_state_t *state, +                    xlator_t *this, fd_t *fd, inode_t *inode, +                    struct iatt *stbuf, struct iatt *preparent, +                    struct iatt *postparent); + +void +server_post_lookup (gfs3_lookup_rsp *rsp, call_frame_t *frame, +                    server_state_t *state, +                    inode_t *inode, struct iatt *stbuf, +                    struct iatt *postparent); + +void +server_post_lease (gfs3_lease_rsp *rsp, struct gf_lease *lease); diff --git a/xlators/protocol/server/src/server-helpers.c b/xlators/protocol/server/src/server-helpers.c index dc127a6cdcd..09183e8a1dd 100644 --- a/xlators/protocol/server/src/server-helpers.c +++ b/xlators/protocol/server/src/server-helpers.c @@ -13,6 +13,9 @@  #include "gidcache.h"  #include "server-messages.h"  #include "syscall.h" +#include "defaults.h" +#include "default-args.h" +#include "server-common.h"  #include <fnmatch.h>  #include <pwd.h> @@ -1345,3 +1348,2439 @@ unserialize_req_locklist (gfs3_setactivelk_req *req,  out:          return ret;  } + +int +server_populate_compound_request (gfs3_compound_req *req, call_frame_t *frame, +                                  default_args_t *this_args, +                                  int index) +{ +        int                     op_errno    = 0; +        int                     ret         = -1; +        struct iovec req_iovec[MAX_IOVEC]   = { {0,} }; +        compound_req            *this_req   = NULL; +        server_state_t          *state      = CALL_STATE (frame); + +        this_req = &req->compound_req_array.compound_req_array_val[index]; + +        switch (this_req->fop_enum) { +        case GF_FOP_STAT: +        { +                gfs3_stat_req *args = NULL; + +                args = &this_req->compound_req_u.compound_stat_req; + +                GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, +                                              this_args->xdata, +                                              args->xdata.xdata_val, +                                              args->xdata.xdata_len, ret, +                                              op_errno, out); +                args_stat_store (this_args, &state->loc, this_args->xdata); +                break; +        } +        case GF_FOP_READLINK: +        { +                gfs3_readlink_req *args = NULL; + +                args = &this_req->compound_req_u.compound_readlink_req; + +                GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, +                                              this_args->xdata, +                                              args->xdata.xdata_val, +                                              args->xdata.xdata_len, ret, +                                              op_errno, out); +                args_readlink_store (this_args, &state->loc, +                                     args->size, this_args->xdata); +                break; +        } +        case GF_FOP_MKNOD: +        { +                gfs3_mknod_req *args = NULL; + +                args = &this_req->compound_req_u.compound_mknod_req; + +                GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, +                                              this_args->xdata, +                                              args->xdata.xdata_val, +                                              args->xdata.xdata_len, ret, +                                              op_errno, out); +                args_mknod_store (this_args, &state->loc, args->mode, +                                  args->dev, args->umask, +                                  this_args->xdata); +                break; +        } +        case GF_FOP_MKDIR: +        { +                gfs3_mkdir_req *args = NULL; + +                args = &this_req->compound_req_u.compound_mkdir_req; + +                GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, +                                              this_args->xdata, +                                              args->xdata.xdata_val, +                                              args->xdata.xdata_len, ret, +                                              op_errno, out); +                args_mkdir_store (this_args, &state->loc, args->mode, +                                  args->umask, this_args->xdata); +                break; +        } +        case GF_FOP_UNLINK: +        { +                gfs3_unlink_req *args = NULL; + +                args = &this_req->compound_req_u.compound_unlink_req; + +                GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, +                                              this_args->xdata, +                                              args->xdata.xdata_val, +                                              args->xdata.xdata_len, ret, +                                              op_errno, out); +                args_unlink_store (this_args, &state->loc, +                                   args->xflags, this_args->xdata); +                break; +        } +        case GF_FOP_RMDIR: +        { +                gfs3_rmdir_req *args = NULL; + +                args = &this_req->compound_req_u.compound_rmdir_req; + +                GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, +                                              this_args->xdata, +                                              args->xdata.xdata_val, +                                              args->xdata.xdata_len, ret, +                                              op_errno, out); +                args_rmdir_store (this_args, &state->loc, +                                  args->xflags, this_args->xdata); +                break; +        } +        case GF_FOP_SYMLINK: +        { +                gfs3_symlink_req *args = NULL; + +                args = &this_req->compound_req_u.compound_symlink_req; + +                GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, +                                              this_args->xdata, +                                              args->xdata.xdata_val, +                                              args->xdata.xdata_len, ret, +                                              op_errno, out); +                args_symlink_store (this_args, args->linkname, +                                    &state->loc, +                                    args->umask, this_args->xdata); + +                this_args->loc.inode = inode_new (state->itable); + +                break; +        } +        case GF_FOP_RENAME: +        { +                gfs3_rename_req *args = NULL; + +                args = &this_req->compound_req_u.compound_rename_req; + +                GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, +                                              this_args->xdata, +                                              args->xdata.xdata_val, +                                              args->xdata.xdata_len, ret, +                                              op_errno, out); + +                args_rename_store (this_args, &state->loc, +                                   &state->loc2, this_args->xdata); +                break; +        } +        case GF_FOP_LINK: +        { +                gfs3_link_req *args = NULL; + +                args = &this_req->compound_req_u.compound_link_req; + +                GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, +                                              this_args->xdata, +                                              args->xdata.xdata_val, +                                              args->xdata.xdata_len, ret, +                                              op_errno, out); +                args_link_store (this_args, &state->loc, +                                 &state->loc2, this_args->xdata); + +                this_args->loc2.inode = inode_ref (this_args->loc.inode); + +                break; +        } +        case GF_FOP_TRUNCATE: +        { +                gfs3_truncate_req *args = NULL; + +                args = &this_req->compound_req_u.compound_truncate_req; + +                GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, +                                              this_args->xdata, +                                              args->xdata.xdata_val, +                                              args->xdata.xdata_len, ret, +                                              op_errno, out); +                args_truncate_store (this_args, &state->loc, +                                     args->offset, this_args->xdata); +                break; +        } +        case GF_FOP_OPEN: +        { +                gfs3_open_req *args = NULL; + +                args = &this_req->compound_req_u.compound_open_req; + +                GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, +                                              this_args->xdata, +                                              args->xdata.xdata_val, +                                              args->xdata.xdata_len, ret, +                                              op_errno, out); +                args_open_store (this_args, &state->loc, +                                 args->flags, state->fd, this_args->xdata); + +                this_args->fd = fd_create (this_args->loc.inode, +                                           frame->root->pid); +                this_args->fd->flags = this_args->flags; + +                break; +        } +        case GF_FOP_READ: +        { +                gfs3_read_req *args = NULL; + +                args = &this_req->compound_req_u.compound_read_req; + +                GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, +                                              this_args->xdata, +                                              args->xdata.xdata_val, +                                              args->xdata.xdata_len, ret, +                                              op_errno, out); +                args_readv_store (this_args, state->fd, args->size, +                                  args->offset, args->flag, +                                  this_args->xdata); +                break; +        } +        case GF_FOP_WRITE: +        { +                gfs3_write_req *args = NULL; + +                args = &this_req->compound_req_u.compound_write_req; + +                /*TODO : What happens when payload count is more than one? */ +                req_iovec[0].iov_base = state->payload_vector[0].iov_base + +                                        state->write_length; +                req_iovec[0].iov_len  = args->size; + +                GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, +                                              this_args->xdata, +                                              args->xdata.xdata_val, +                                              args->xdata.xdata_len, ret, +                                              op_errno, out); +                args_writev_store (this_args, state->fd, +                                   req_iovec, +                                   args->size, args->offset, +                                   args->flag, +                                   this_args->iobref, this_args->xdata); +                state->write_length += args->size; +                break; +        } +        case GF_FOP_STATFS: +        { +                gfs3_statfs_req *args = NULL; + +                args = &this_req->compound_req_u.compound_statfs_req; + +                GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, +                                              this_args->xdata, +                                              args->xdata.xdata_val, +                                              args->xdata.xdata_len, ret, +                                              op_errno, out); +                args_statfs_store (this_args, &state->loc, +                                   this_args->xdata); +                break; +        } +        case GF_FOP_FLUSH: +        { +                gfs3_flush_req *args = NULL; + +                args = &this_req->compound_req_u.compound_flush_req; + +                GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, +                                              this_args->xdata, +                                              args->xdata.xdata_val, +                                              args->xdata.xdata_len, ret, +                                              op_errno, out); +                args_flush_store (this_args, state->fd, this_args->xdata); +                break; +        } +        case GF_FOP_FSYNC: +        { +                gfs3_fsync_req *args = NULL; + +                args = &this_req->compound_req_u.compound_fsync_req; + +                GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, +                                              this_args->xdata, +                                              args->xdata.xdata_val, +                                              args->xdata.xdata_len, ret, +                                              op_errno, out); +                args_fsync_store (this_args, state->fd, +                                  args->data, this_args->xdata); +                break; +        } +        case GF_FOP_SETXATTR: +        { +                gfs3_setxattr_req *args = NULL; + +                args = &this_req->compound_req_u.compound_setxattr_req; + +                GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, +                                              this_args->xdata, +                                              args->xdata.xdata_val, +                                              args->xdata.xdata_len, ret, +                                              op_errno, out); +                GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, +                                              this_args->xattr, +                                              args->dict.dict_val, +                                              args->dict.dict_len, ret, +                                              op_errno, out); +                args_setxattr_store (this_args, &state->loc, +                                     this_args->xattr, args->flags, +                                     this_args->xdata); +                break; +        } +        case GF_FOP_GETXATTR: +        { +                gfs3_getxattr_req *args = NULL; + +                args = &this_req->compound_req_u.compound_getxattr_req; + +                GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, +                                              this_args->xdata, +                                              args->xdata.xdata_val, +                                              args->xdata.xdata_len, ret, +                                              op_errno, out); +                gf_server_check_getxattr_cmd (frame, args->name); + +                args_getxattr_store (this_args, &state->loc, +                                     args->name, this_args->xdata); +                break; +        } +        case GF_FOP_REMOVEXATTR: +        { +                gfs3_removexattr_req *args = NULL; + +                args = &this_req->compound_req_u.compound_removexattr_req; + +                GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, +                                              this_args->xdata, +                                              args->xdata.xdata_val, +                                              args->xdata.xdata_len, ret, +                                              op_errno, out); +                args_removexattr_store (this_args, &state->loc, +                                        args->name, +                                        this_args->xdata); +                break; +        } +        case GF_FOP_OPENDIR: +        { +                gfs3_opendir_req *args = NULL; + +                args = &this_req->compound_req_u.compound_opendir_req; + +                this_args->fd = fd_create (this_args->loc.inode, +                                           frame->root->pid); +                if (!this_args->fd) { +                        gf_msg ("server", GF_LOG_ERROR, 0, +                                PS_MSG_FD_CREATE_FAILED, +                                "could not create the fd"); +                        goto out; +                } +                GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, +                                              this_args->xdata, +                                              args->xdata.xdata_val, +                                              args->xdata.xdata_len, ret, +                                              op_errno, out); +                args_opendir_store (this_args, &state->loc, +                                    state->fd, this_args->xdata); +                break; +        } +        case GF_FOP_FSYNCDIR: +        { +                gfs3_fsyncdir_req *args = NULL; + +                args = &this_req->compound_req_u.compound_fsyncdir_req; + +                GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, +                                              this_args->xdata, +                                              args->xdata.xdata_val, +                                              args->xdata.xdata_len, ret, +                                              op_errno, out); +                args_fsyncdir_store (this_args, state->fd, +                                     args->data, this_args->xdata); +                break; +        } +        case GF_FOP_ACCESS: +        { +                gfs3_access_req *args = NULL; + +                args = &this_req->compound_req_u.compound_access_req; + +                GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, +                                              this_args->xdata, +                                              args->xdata.xdata_val, +                                              args->xdata.xdata_len, ret, +                                              op_errno, out); +                args_access_store (this_args, &state->loc, +                                   args->mask, this_args->xdata); +                break; +        } +        case GF_FOP_CREATE: +        { +                gfs3_create_req *args = NULL; + +                args = &this_req->compound_req_u.compound_create_req; + +                state->loc.inode = inode_new (state->itable); + +                state->fd = fd_create (state->loc.inode, frame->root->pid); +                if (!state->fd) { +                        gf_msg ("server", GF_LOG_ERROR, 0, +                                PS_MSG_FD_CREATE_FAILED, +                                "fd creation for the inode %s failed", +                                state->loc.inode ? +                                uuid_utoa (state->loc.inode->gfid):NULL); +                        goto out; +                } +                state->fd->flags = state->flags; + +                GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, +                                              this_args->xdata, +                                              args->xdata.xdata_val, +                                              args->xdata.xdata_len, ret, +                                              op_errno, out); +                args_create_store (this_args, &state->loc, +                                   args->flags, args->mode, +                                   args->umask, state->fd, +                                   this_args->xdata); +                break; +        } +        case GF_FOP_FTRUNCATE: +        { +                gfs3_ftruncate_req *args = NULL; + +                args = &this_req->compound_req_u.compound_ftruncate_req; + +                GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, +                                              this_args->xdata, +                                              args->xdata.xdata_val, +                                              args->xdata.xdata_len, ret, +                                              op_errno, out); +                args_ftruncate_store (this_args, state->fd, +                                      args->offset, +                                      this_args->xdata); +                break; +        } +        case GF_FOP_FSTAT: +        { +                gfs3_fstat_req *args = NULL; + +                args = &this_req->compound_req_u.compound_fstat_req; + +                GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, +                                              this_args->xdata, +                                              args->xdata.xdata_val, +                                              args->xdata.xdata_len, ret, +                                              op_errno, out); +                args_fstat_store (this_args, state->fd, this_args->xdata); +                break; +        } +        case GF_FOP_LK: +        { +                gfs3_lk_req *args = NULL; + +                args = &this_req->compound_req_u.compound_lk_req; + +                GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, +                                              this_args->xdata, +                                              args->xdata.xdata_val, +                                              args->xdata.xdata_len, ret, +                                              op_errno, out); + +                switch (args->cmd) { +                case GF_LK_GETLK: +                        this_args->cmd = F_GETLK; +                        break; +                case GF_LK_SETLK: +                        this_args->cmd = F_SETLK; +                        break; +                case GF_LK_SETLKW: +                        this_args->cmd = F_SETLKW; +                        break; +                case GF_LK_RESLK_LCK: +                        this_args->cmd = F_RESLK_LCK; +                        break; +                case GF_LK_RESLK_LCKW: +                        this_args->cmd = F_RESLK_LCKW; +                        break; +                case GF_LK_RESLK_UNLCK: +                        this_args->cmd = F_RESLK_UNLCK; +                        break; +                case GF_LK_GETLK_FD: +                        this_args->cmd = F_GETLK_FD; +                        break; +                } + +                gf_proto_flock_to_flock (&args->flock, &this_args->lock); + +                switch (args->type) { +                case GF_LK_F_RDLCK: +                        this_args->lock.l_type = F_RDLCK; +                        break; +                case GF_LK_F_WRLCK: +                        this_args->lock.l_type = F_WRLCK; +                        break; +                case GF_LK_F_UNLCK: +                        this_args->lock.l_type = F_UNLCK; +                        break; +                default: +                        gf_msg (frame->root->client->bound_xl->name, +                                GF_LOG_ERROR, +                                0, PS_MSG_LOCK_ERROR, "fd - %"PRId64" (%s):" +                                " Unknown " +                                "lock type: %"PRId32"!", state->resolve.fd_no, +                                uuid_utoa (state->fd->inode->gfid), +                                args->type); +                        break; +                } +                args_lk_store (this_args, state->fd, this_args->cmd, +                               &this_args->lock, this_args->xdata); +                break; +        } +        case GF_FOP_LOOKUP: +        { +                gfs3_lookup_req *args = NULL; + +                args = &this_req->compound_req_u.compound_lookup_req; + +                if (this_args->loc.inode) +                        this_args->loc.inode = server_inode_new (state->itable, +                                                             state->loc.gfid); +                else +                        state->is_revalidate = 1; + +                GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, +                                              this_args->xdata, +                                              args->xdata.xdata_val, +                                              args->xdata.xdata_len, ret, +                                              op_errno, out); +                args_lookup_store (this_args, &state->loc, this_args->xdata); +                break; +        } +        case GF_FOP_READDIR: +        { +                gfs3_readdir_req *args = NULL; + +                args = &this_req->compound_req_u.compound_readdir_req; + +                GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, +                                              this_args->xdata, +                                              args->xdata.xdata_val, +                                              args->xdata.xdata_len, ret, +                                              op_errno, out); +                args_readdir_store (this_args, state->fd, args->size, +                                    args->offset, this_args->xdata); +                break; +        } +        case GF_FOP_INODELK: +        { +                gfs3_inodelk_req *args = NULL; + +                args = &this_req->compound_req_u.compound_inodelk_req; + +                switch (args->cmd) { +                case GF_LK_GETLK: +                        this_args->cmd = F_GETLK; +                        break; +                case GF_LK_SETLK: +                        this_args->cmd = F_SETLK; +                        break; +                case GF_LK_SETLKW: +                        this_args->cmd = F_SETLKW; +                        break; +                } + +                gf_proto_flock_to_flock (&args->flock, &this_args->lock); + +                switch (args->type) { +                case GF_LK_F_RDLCK: +                        this_args->lock.l_type = F_RDLCK; +                        break; +                case GF_LK_F_WRLCK: +                        this_args->lock.l_type = F_WRLCK; +                        break; +                case GF_LK_F_UNLCK: +                        this_args->lock.l_type = F_UNLCK; +                        break; +                } + +                GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, +                                              this_args->xdata, +                                              args->xdata.xdata_val, +                                              args->xdata.xdata_len, ret, +                                              op_errno, out); +                args_inodelk_store (this_args, args->volume, &state->loc, +                                    this_args->cmd, +                                    &this_args->lock, this_args->xdata); +                break; +        } +        case GF_FOP_FINODELK: +        { +                gfs3_finodelk_req *args = NULL; + +                args = &this_req->compound_req_u.compound_finodelk_req; + +                GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, +                                              this_args->xdata, +                                              args->xdata.xdata_val, +                                              args->xdata.xdata_len, ret, +                                              op_errno, out); + +                switch (args->cmd) { +                case GF_LK_GETLK: +                        this_args->cmd = F_GETLK; +                        break; +                case GF_LK_SETLK: +                        this_args->cmd = F_SETLK; +                        break; +                case GF_LK_SETLKW: +                        this_args->cmd = F_SETLKW; +                        break; +                } + +                gf_proto_flock_to_flock (&args->flock, &this_args->lock); + +                switch (args->type) { +                case GF_LK_F_RDLCK: +                        this_args->lock.l_type = F_RDLCK; +                        break; +                case GF_LK_F_WRLCK: +                        this_args->lock.l_type = F_WRLCK; +                        break; +                case GF_LK_F_UNLCK: +                        this_args->lock.l_type = F_UNLCK; +                        break; +                } +                args_finodelk_store (this_args, args->volume, state->fd, +                                     this_args->cmd, +                                     &this_args->lock, this_args->xdata); +                        break; +        } +        case GF_FOP_ENTRYLK: +        { +                gfs3_entrylk_req *args = NULL; + +                args = &this_req->compound_req_u.compound_entrylk_req; + +                GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, +                                              this_args->xdata, +                                              args->xdata.xdata_val, +                                              args->xdata.xdata_len, ret, +                                              op_errno, out); +                args_entrylk_store (this_args, args->volume, &state->loc, +                                    args->name, args->cmd, args->type, +                                    this_args->xdata); +                break; +        } +        case GF_FOP_FENTRYLK: +        { +                gfs3_fentrylk_req *args = NULL; + +                args = &this_req->compound_req_u.compound_fentrylk_req; + +                GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, +                                              this_args->xdata, +                                              args->xdata.xdata_val, +                                              args->xdata.xdata_len, ret, +                                              op_errno, out); +                args_fentrylk_store (this_args, args->volume, state->fd, +                                     args->name, args->cmd, args->type, +                                     this_args->xdata); +                break; +        } +        case GF_FOP_XATTROP: +        { +                gfs3_xattrop_req *args = NULL; + +                args = &this_req->compound_req_u.compound_xattrop_req; + +                GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, +                                              this_args->xdata, +                                              args->xdata.xdata_val, +                                              args->xdata.xdata_len, ret, +                                              op_errno, out); + +                GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, +                                              this_args->xattr, +                                              (args->dict.dict_val), +                                              (args->dict.dict_len), ret, +                                               op_errno, out); +                args_xattrop_store (this_args, &state->loc, args->flags, +                                    this_args->xattr, this_args->xdata); +                break; +        } +        case GF_FOP_FXATTROP: +        { +                gfs3_fxattrop_req *args = NULL; + +                args = &this_req->compound_req_u.compound_fxattrop_req; + +                GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, +                                              this_args->xattr, +                                              (args->dict.dict_val), +                                              (args->dict.dict_len), ret, +                                              op_errno, out); + +                GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, +                                              this_args->xdata, +                                              args->xdata.xdata_val, +                                              args->xdata.xdata_len, ret, +                                              op_errno, out); + +                args_fxattrop_store (this_args, state->fd, args->flags, +                                     this_args->xattr, this_args->xdata); +                break; +        } +        case GF_FOP_FGETXATTR: +        { +                gfs3_fgetxattr_req *args = NULL; + +                args = &this_req->compound_req_u.compound_fgetxattr_req; + +                GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, +                                              this_args->xdata, +                                              args->xdata.xdata_val, +                                              args->xdata.xdata_len, ret, +                                              op_errno, out); + +                args_fgetxattr_store (this_args, state->fd, +                                      args->name, this_args->xdata); +                break; +        } +        case GF_FOP_FSETXATTR: +        { +                gfs3_fsetxattr_req *args = NULL; + +                args = &this_req->compound_req_u.compound_fsetxattr_req; + +                GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, +                                              this_args->xattr, +                                              (args->dict.dict_val), +                                              (args->dict.dict_len), ret, +                                              op_errno, out); + +                GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, +                                              this_args->xdata, +                                              args->xdata.xdata_val, +                                              args->xdata.xdata_len, ret, +                                              op_errno, out); + +                args_fsetxattr_store (this_args, state->fd, this_args->xattr, +                                      args->flags, this_args->xdata); +                break; +        } +        case GF_FOP_RCHECKSUM: +        { +                gfs3_rchecksum_req *args = NULL; + +                args = &this_req->compound_req_u.compound_rchecksum_req; + +                GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, +                                              this_args->xdata, +                                              args->xdata.xdata_val, +                                              args->xdata.xdata_len, ret, +                                              op_errno, out); + +                args_rchecksum_store (this_args, state->fd, args->offset, +                                      args->len, this_args->xdata); +                break; +        } +        case GF_FOP_SETATTR: +        { +                gfs3_setattr_req *args = NULL; + +                args = &this_req->compound_req_u.compound_setattr_req; + +                GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, +                                              this_args->xdata, +                                              args->xdata.xdata_val, +                                              args->xdata.xdata_len, ret, +                                              op_errno, out); + +                gf_stat_to_iatt (&args->stbuf, &this_args->stat); + +                args_setattr_store (this_args, &state->loc, &this_args->stat, +                                    args->valid, this_args->xdata); +                break; +        } +        case GF_FOP_FSETATTR: +        { +                gfs3_fsetattr_req *args = NULL; + +                args = &this_req->compound_req_u.compound_fsetattr_req; + +                GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, +                                              this_args->xdata, +                                              args->xdata.xdata_val, +                                              args->xdata.xdata_len, ret, +                                              op_errno, out); + +                gf_stat_to_iatt (&args->stbuf, &this_args->stat); + +                args_fsetattr_store (this_args, state->fd, &this_args->stat, +                                     args->valid, this_args->xdata); +                break; +        } +        case GF_FOP_READDIRP: +        { +                gfs3_readdirp_req *args = NULL; + +                args = &this_req->compound_req_u.compound_readdirp_req; + +                GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, +                                              this_args->xattr, +                                              (args->dict.dict_val), +                                              (args->dict.dict_len), ret, +                                              op_errno, out); + +                args_readdirp_store (this_args, state->fd, args->size, +                                     args->offset, this_args->xattr); +                break; +        } +        case GF_FOP_FREMOVEXATTR: +        { +                gfs3_fremovexattr_req *args = NULL; + +                args = &this_req->compound_req_u.compound_fremovexattr_req; + +                GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, +                                              this_args->xdata, +                                              args->xdata.xdata_val, +                                              args->xdata.xdata_len, ret, +                                              op_errno, out); + +                args_fremovexattr_store (this_args, state->fd, args->name, +                                         this_args->xdata); +                break; +        } +	case GF_FOP_FALLOCATE: +        { +                gfs3_fallocate_req *args = NULL; + +                args = &this_req->compound_req_u.compound_fallocate_req; + +                GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, +                                              this_args->xdata, +                                              args->xdata.xdata_val, +                                              args->xdata.xdata_len, ret, +                                              op_errno, out); +                args_fallocate_store (this_args, state->fd, args->flags, +                                      args->offset, args->size, +                                      this_args->xdata); +                break; +        } +	case GF_FOP_DISCARD: +        { +                gfs3_discard_req *args = NULL; + +                args = &this_req->compound_req_u.compound_discard_req; + +                GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, +                                              this_args->xdata, +                                              args->xdata.xdata_val, +                                              args->xdata.xdata_len, ret, +                                              op_errno, out); + +                args_discard_store (this_args, state->fd, args->offset, +                                    args->size, this_args->xdata); +                break; +        } +        case GF_FOP_ZEROFILL: +        { +                gfs3_zerofill_req *args = NULL; + +                args = &this_req->compound_req_u.compound_zerofill_req; + +                GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, +                                              this_args->xdata, +                                              args->xdata.xdata_val, +                                              args->xdata.xdata_len, ret, +                                              op_errno, out); +                args_zerofill_store (this_args, state->fd, args->offset, +                                     args->size, this_args->xdata); +                break; +        } +        case GF_FOP_SEEK: +        { +                gfs3_seek_req *args = NULL; + +                args = &this_req->compound_req_u.compound_seek_req; + +                GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, +                                              this_args->xdata, +                                              args->xdata.xdata_val, +                                              args->xdata.xdata_len, ret, +                                              op_errno, out); +                args_seek_store (this_args, state->fd, args->offset, +                                 args->what, this_args->xdata); +                break; +        } +        case GF_FOP_LEASE: +        { +                gfs3_lease_req *args = NULL; + +                args = &this_req->compound_req_u.compound_lease_req; + +                GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, +                                              this_args->xdata, +                                              args->xdata.xdata_val, +                                              args->xdata.xdata_len, ret, +                                              op_errno, out); + +                gf_proto_lease_to_lease (&args->lease, &state->lease); + +                args_lease_store (this_args, &state->loc, &state->lease, +                                  this_args->xdata); +                break; +        } +        default: +                return ENOTSUP; +        } +out: +        return op_errno; +} + +int +server_populate_compound_response (xlator_t *this, gfs3_compound_rsp *rsp, +                                   call_frame_t *frame, +                                   compound_args_cbk_t *args_cbk, int index) +{ +        int                     op_errno    = ENOMEM; +        int                     op_ret      = -1; +        default_args_cbk_t      *this_args_cbk = NULL; +        compound_rsp            *this_rsp   = NULL; +        server_state_t          *state      = NULL; +        int                     ret         = 0; + +        state = CALL_STATE (frame); +        rsp->compound_rsp_array.compound_rsp_array_val = GF_CALLOC +                                                         (args_cbk->fop_length, +                                                         sizeof (compound_rsp), +                                                  gf_server_mt_compound_rsp_t); + +        rsp->compound_rsp_array.compound_rsp_array_len = args_cbk->fop_length; + +        this_rsp = &rsp->compound_rsp_array.compound_rsp_array_val[index]; + +        this_args_cbk = &args_cbk->rsp_list[index]; +        switch (this_rsp->fop_enum) { +        case GF_FOP_STAT: +        { +                gfs3_stat_rsp *rsp_args = NULL; + +                rsp_args = &this_rsp->compound_rsp_u.compound_stat_rsp; + +                GF_PROTOCOL_DICT_SERIALIZE (this, this_args_cbk->xdata, +                                            &rsp_args->xdata.xdata_val, +                                            rsp_args->xdata.xdata_len, +                                            rsp_args->op_errno, out); +                if (!this_args_cbk->op_ret) { +                        server_post_stat (rsp_args, +                                          &this_args_cbk->stat); +                } +                rsp_args->op_ret = this_args_cbk->op_ret; +                rsp_args->op_errno  = gf_errno_to_error +                                      (this_args_cbk->op_errno); +                break; +        } +        case GF_FOP_READLINK: +        { +                gfs3_readlink_rsp *rsp_args = NULL; + +                rsp_args = &this_rsp->compound_rsp_u.compound_readlink_rsp; + +                GF_PROTOCOL_DICT_SERIALIZE (this, this_args_cbk->xdata, +                                            &rsp_args->xdata.xdata_val, +                                            rsp_args->xdata.xdata_len, +                                            rsp_args->op_errno, out); +                if (this_args_cbk->op_ret >= 0) { +                        server_post_readlink (rsp_args, &this_args_cbk->stat, +                                              this_args_cbk->buf); +                } +                rsp_args->op_ret = this_args_cbk->op_ret; +                rsp_args->op_errno  = gf_errno_to_error +                                      (this_args_cbk->op_errno); +                break; +        } +        case GF_FOP_MKNOD: +        { +                gfs3_mknod_rsp *rsp_args = NULL; + +                rsp_args = &this_rsp->compound_rsp_u.compound_mknod_rsp; + +                GF_PROTOCOL_DICT_SERIALIZE (this, this_args_cbk->xdata, +                                            &rsp_args->xdata.xdata_val, +                                            rsp_args->xdata.xdata_len, +                                            rsp_args->op_errno, out); +                if (!this_args_cbk->op_ret) { +                        server_post_mknod (state, rsp_args, +                                           &this_args_cbk->stat, +                                           &this_args_cbk->preparent, +                                           &this_args_cbk->postparent, +                                           this_args_cbk->inode); +                } +                rsp_args->op_ret = this_args_cbk->op_ret; +                rsp_args->op_errno  = gf_errno_to_error +                                      (this_args_cbk->op_errno); +                break; +        } +        case GF_FOP_MKDIR: +        { +                gfs3_mkdir_rsp *rsp_args = NULL; + +                rsp_args = &this_rsp->compound_rsp_u.compound_mkdir_rsp; + +                GF_PROTOCOL_DICT_SERIALIZE (this, this_args_cbk->xdata, +                                            &rsp_args->xdata.xdata_val, +                                            rsp_args->xdata.xdata_len, +                                            rsp_args->op_errno, out); + +                if (!this_args_cbk->op_ret) { +                        server_post_mkdir (state, rsp_args, +                                           this_args_cbk->inode, +                                           &this_args_cbk->stat, +                                           &this_args_cbk->preparent, +                                           &this_args_cbk->postparent, +                                           this_args_cbk->xdata); +                } +                rsp_args->op_ret = this_args_cbk->op_ret; +                rsp_args->op_errno  = gf_errno_to_error +                                      (this_args_cbk->op_errno); +                break; +        } +        case GF_FOP_UNLINK: +        { +                gfs3_unlink_rsp *rsp_args = NULL; + +                rsp_args = &this_rsp->compound_rsp_u.compound_unlink_rsp; + +                GF_PROTOCOL_DICT_SERIALIZE (this, this_args_cbk->xdata, +                                            &rsp_args->xdata.xdata_val, +                                            rsp_args->xdata.xdata_len, +                                            rsp_args->op_errno, out); +                if (!this_args_cbk->op_ret) { +                        server_post_unlink (state, rsp_args, +                                            &this_args_cbk->preparent, +                                            &this_args_cbk->postparent); +                } +                rsp_args->op_ret = this_args_cbk->op_ret; +                rsp_args->op_errno  = gf_errno_to_error +                                      (this_args_cbk->op_errno); +                break; +        } +        case GF_FOP_RMDIR: +        { +                gfs3_rmdir_rsp *rsp_args = NULL; + +                rsp_args = &this_rsp->compound_rsp_u.compound_rmdir_rsp; + +                GF_PROTOCOL_DICT_SERIALIZE (this, this_args_cbk->xdata, +                                            &rsp_args->xdata.xdata_val, +                                            rsp_args->xdata.xdata_len, +                                            rsp_args->op_errno, out); +                if (!this_args_cbk->op_ret) { +                        server_post_rmdir (state, rsp_args, +                                            &this_args_cbk->preparent, +                                            &this_args_cbk->postparent); +                } +                rsp_args->op_ret = this_args_cbk->op_ret; +                rsp_args->op_errno  = gf_errno_to_error +                                      (this_args_cbk->op_errno); +                break; +        } +        case GF_FOP_SYMLINK: +        { +                gfs3_symlink_rsp *rsp_args = NULL; + +                rsp_args = &this_rsp->compound_rsp_u.compound_symlink_rsp; + +                GF_PROTOCOL_DICT_SERIALIZE (this, this_args_cbk->xdata, +                                            &rsp_args->xdata.xdata_val, +                                            rsp_args->xdata.xdata_len, +                                            rsp_args->op_errno, out); + +                if (!this_args_cbk->op_ret) { +                        server_post_symlink (state, rsp_args, +                                             this_args_cbk->inode, +                                             &this_args_cbk->stat, +                                             &this_args_cbk->preparent, +                                             &this_args_cbk->postparent, +                                             this_args_cbk->xdata); +                } +                rsp_args->op_ret = this_args_cbk->op_ret; +                rsp_args->op_errno  = gf_errno_to_error +                                      (this_args_cbk->op_errno); +                break; +        } +        case GF_FOP_RENAME: +        { +                gfs3_rename_rsp *rsp_args = NULL; + +                rsp_args = &this_rsp->compound_rsp_u.compound_rename_rsp; + +                GF_PROTOCOL_DICT_SERIALIZE (this, this_args_cbk->xdata, +                                            &rsp_args->xdata.xdata_val, +                                            rsp_args->xdata.xdata_len, +                                            rsp_args->op_errno, out); + +                if (!this_args_cbk->op_ret) { +                        server_post_rename (frame, state, rsp_args, +                                            &this_args_cbk->stat, +                                            &this_args_cbk->preparent, +                                            &this_args_cbk->postparent, +                                            &this_args_cbk->preparent2, +                                            &this_args_cbk->postparent2); +                } +                rsp_args->op_ret = this_args_cbk->op_ret; +                rsp_args->op_errno  = gf_errno_to_error +                                      (this_args_cbk->op_errno); +                break; +        } +        case GF_FOP_LINK: +        { +                gfs3_link_rsp *rsp_args = NULL; + +                rsp_args = &this_rsp->compound_rsp_u.compound_link_rsp; + +                GF_PROTOCOL_DICT_SERIALIZE (this, this_args_cbk->xdata, +                                            &rsp_args->xdata.xdata_val, +                                            rsp_args->xdata.xdata_len, +                                            rsp_args->op_errno, out); + +                if (!this_args_cbk->op_ret) { +                        server_post_link (state, rsp_args, +                                          this_args_cbk->inode, +                                          &this_args_cbk->stat, +                                          &this_args_cbk->preparent, +                                          &this_args_cbk->postparent, +                                          this_args_cbk->xdata); +                } +                rsp_args->op_ret = this_args_cbk->op_ret; +                rsp_args->op_errno  = gf_errno_to_error +                                      (this_args_cbk->op_errno); +                break; +        } +        case GF_FOP_TRUNCATE: +        { +                gfs3_truncate_rsp *rsp_args = NULL; + +                rsp_args = &this_rsp->compound_rsp_u.compound_truncate_rsp; + +                GF_PROTOCOL_DICT_SERIALIZE (this, this_args_cbk->xdata, +                                            &rsp_args->xdata.xdata_val, +                                            rsp_args->xdata.xdata_len, +                                            rsp_args->op_errno, out); + +                if (!this_args_cbk->op_ret) { +                        server_post_truncate (rsp_args, +                                              &this_args_cbk->prestat, +                                              &this_args_cbk->poststat); +                } +                rsp_args->op_ret = this_args_cbk->op_ret; +                rsp_args->op_errno  = gf_errno_to_error +                                      (this_args_cbk->op_errno); +                break; +        } +        case GF_FOP_OPEN: +        { +                gfs3_open_rsp *rsp_args = NULL; + +                rsp_args = &this_rsp->compound_rsp_u.compound_open_rsp; + +                GF_PROTOCOL_DICT_SERIALIZE (this, this_args_cbk->xdata, +                                            &rsp_args->xdata.xdata_val, +                                            rsp_args->xdata.xdata_len, +                                            rsp_args->op_errno, out); + +                if (!this_args_cbk->op_ret) { +                        server_post_open (frame, this, rsp_args, +                                          this_args_cbk->fd); + +                } +                rsp_args->op_ret = this_args_cbk->op_ret; +                rsp_args->op_errno = gf_errno_to_error +                                     (this_args_cbk->op_errno); +                break; +        } +        case GF_FOP_READ: +        { +                gfs3_read_rsp *rsp_args = NULL; + +                rsp_args = &this_rsp->compound_rsp_u.compound_read_rsp; + +                GF_PROTOCOL_DICT_SERIALIZE (this, this_args_cbk->xdata, +                                            &rsp_args->xdata.xdata_val, +                                            rsp_args->xdata.xdata_len, +                                            rsp_args->op_errno, out); + +                if (this_args_cbk->op_ret >= 0) { +                        server_post_readv (rsp_args, &this_args_cbk->stat, +                                           this_args_cbk->op_ret); + +                        if (!state->rsp_iobref) { +                                state->rsp_iobref = this_args_cbk->iobref; +                                state->rsp_count = 0; +                        } +                        iobref_merge (state->rsp_iobref, +                                      this_args_cbk->iobref); +                        memcpy (&state->rsp_vector[state->rsp_count], +                                this_args_cbk->vector, +                                (this_args_cbk->count * +                                 sizeof(state->rsp_vector[0]))); +                        state->rsp_count += this_args_cbk->count; +                } +                rsp_args->op_ret = this_args_cbk->op_ret; +                rsp_args->op_errno = gf_errno_to_error +                                     (this_args_cbk->op_errno); +                break; +        } +        case GF_FOP_WRITE: +        { +                gfs3_write_rsp *rsp_args = NULL; + +                rsp_args = &this_rsp->compound_rsp_u.compound_write_rsp; + +                GF_PROTOCOL_DICT_SERIALIZE (this, this_args_cbk->xdata, +                                            &rsp_args->xdata.xdata_val, +                                            rsp_args->xdata.xdata_len, +                                            rsp_args->op_errno, out); + +                if (this_args_cbk->op_ret >= 0) { +                        server_post_writev (rsp_args, +                                              &this_args_cbk->prestat, +                                              &this_args_cbk->poststat); +                } +                rsp_args->op_ret = this_args_cbk->op_ret; +                rsp_args->op_errno  = gf_errno_to_error +                                      (this_args_cbk->op_errno); +                break; +        } +        case GF_FOP_STATFS: +        { +                gfs3_statfs_rsp *rsp_args = NULL; + +                rsp_args = &this_rsp->compound_rsp_u.compound_statfs_rsp; + +                GF_PROTOCOL_DICT_SERIALIZE (this, this_args_cbk->xdata, +                                            &rsp_args->xdata.xdata_val, +                                            rsp_args->xdata.xdata_len, +                                            rsp_args->op_errno, out); +                if (!this_args_cbk->op_ret) { +                        server_post_statfs (rsp_args, +                                            &this_args_cbk->statvfs); +                } +                rsp_args->op_ret = this_args_cbk->op_ret; +                rsp_args->op_errno  = gf_errno_to_error +                                      (this_args_cbk->op_errno); +                break; +        } +        case GF_FOP_FLUSH: +        { +                gf_common_rsp *rsp_args = NULL; + +                rsp_args = &this_rsp->compound_rsp_u.compound_flush_rsp; + +                GF_PROTOCOL_DICT_SERIALIZE (this, this_args_cbk->xdata, +                                            &rsp_args->xdata.xdata_val, +                                            rsp_args->xdata.xdata_len, +                                            rsp_args->op_errno, out); +                rsp_args->op_ret = this_args_cbk->op_ret; +                rsp_args->op_errno  = gf_errno_to_error +                                      (this_args_cbk->op_errno); +                break; +        } +        case GF_FOP_FSYNC: +        { +                gfs3_fsync_rsp *rsp_args = NULL; + +                rsp_args = &this_rsp->compound_rsp_u.compound_fsync_rsp; + +                GF_PROTOCOL_DICT_SERIALIZE (this, this_args_cbk->xdata, +                                            &rsp_args->xdata.xdata_val, +                                            rsp_args->xdata.xdata_len, +                                            rsp_args->op_errno, out); + +                if (!this_args_cbk->op_ret) { +                        server_post_fsync (rsp_args, +                                            &this_args_cbk->prestat, +                                            &this_args_cbk->poststat); +                } +                rsp_args->op_ret = this_args_cbk->op_ret; +                rsp_args->op_errno  = gf_errno_to_error +                                      (this_args_cbk->op_errno); +                break; +        } +        case GF_FOP_SETXATTR: +        { +                gf_common_rsp *rsp_args = NULL; + +                rsp_args = &this_rsp->compound_rsp_u.compound_setxattr_rsp; + +                GF_PROTOCOL_DICT_SERIALIZE (this, this_args_cbk->xdata, +                                            &rsp_args->xdata.xdata_val, +                                            rsp_args->xdata.xdata_len, +                                            rsp_args->op_errno, out); +                rsp_args->op_ret = this_args_cbk->op_ret; +                rsp_args->op_errno  = gf_errno_to_error +                                      (this_args_cbk->op_errno); +                break; +        } +        case GF_FOP_GETXATTR: +        { +                gfs3_getxattr_rsp *rsp_args = NULL; + +                rsp_args = &this_rsp->compound_rsp_u.compound_getxattr_rsp; + +                GF_PROTOCOL_DICT_SERIALIZE (this, this_args_cbk->xdata, +                                            &rsp_args->xdata.xdata_val, +                                            rsp_args->xdata.xdata_len, +                                            rsp_args->op_errno, out); + +                if (-1 != this_args_cbk->op_ret) { +                        GF_PROTOCOL_DICT_SERIALIZE (this, +                                                    this_args_cbk->xattr, +                                                    &rsp_args->dict.dict_val, +                                                    rsp_args->dict.dict_len, +                                                    rsp_args->op_errno, out); +                } +                rsp_args->op_ret = this_args_cbk->op_ret; +                rsp_args->op_errno  = gf_errno_to_error +                                      (this_args_cbk->op_errno); +                break; +        } +        case GF_FOP_REMOVEXATTR: +        { +                gf_common_rsp *rsp_args = NULL; + +                rsp_args = &this_rsp->compound_rsp_u.compound_removexattr_rsp; + +                GF_PROTOCOL_DICT_SERIALIZE (this, this_args_cbk->xdata, +                                            &rsp_args->xdata.xdata_val, +                                            rsp_args->xdata.xdata_len, +                                            rsp_args->op_errno, out); +                rsp_args->op_ret = this_args_cbk->op_ret; +                rsp_args->op_errno  = gf_errno_to_error +                                      (this_args_cbk->op_errno); +                break; +        } +        case GF_FOP_OPENDIR: +        { +                gfs3_opendir_rsp *rsp_args = NULL; + +                rsp_args = &this_rsp->compound_rsp_u.compound_opendir_rsp; + +                GF_PROTOCOL_DICT_SERIALIZE (this, this_args_cbk->xdata, +                                            &rsp_args->xdata.xdata_val, +                                            rsp_args->xdata.xdata_len, +                                            rsp_args->op_errno, out); + +                if (!this_args_cbk->op_ret) { +                        server_post_opendir (frame, this, rsp_args, +                                          this_args_cbk->fd); + +                } +                rsp_args->op_ret = this_args_cbk->op_ret; +                rsp_args->op_errno = gf_errno_to_error +                                     (this_args_cbk->op_errno); +                break; +        } +        case GF_FOP_FSYNCDIR: +        { +                gf_common_rsp *rsp_args = NULL; + +                rsp_args = &this_rsp->compound_rsp_u.compound_fsyncdir_rsp; + +                GF_PROTOCOL_DICT_SERIALIZE (this, this_args_cbk->xdata, +                                            &rsp_args->xdata.xdata_val, +                                            rsp_args->xdata.xdata_len, +                                            rsp_args->op_errno, out); +                rsp_args->op_ret = this_args_cbk->op_ret; +                rsp_args->op_errno  = gf_errno_to_error +                                      (this_args_cbk->op_errno); +                break; +        } +        case GF_FOP_ACCESS: +        { +                gf_common_rsp *rsp_args = NULL; + +                rsp_args = &this_rsp->compound_rsp_u.compound_access_rsp; + +                GF_PROTOCOL_DICT_SERIALIZE (this, this_args_cbk->xdata, +                                            &rsp_args->xdata.xdata_val, +                                            rsp_args->xdata.xdata_len, +                                            rsp_args->op_errno, out); +                rsp_args->op_ret = this_args_cbk->op_ret; +                rsp_args->op_errno  = gf_errno_to_error +                                      (this_args_cbk->op_errno); +                break; +        } +        case GF_FOP_CREATE: +        { +                gfs3_create_rsp *rsp_args = NULL; + +                rsp_args = &this_rsp->compound_rsp_u.compound_create_rsp; + +                GF_PROTOCOL_DICT_SERIALIZE (this, this_args_cbk->xdata, +                                            &rsp_args->xdata.xdata_val, +                                            rsp_args->xdata.xdata_len, +                                            rsp_args->op_errno, out); + +                rsp_args->op_ret = this_args_cbk->op_ret; +                rsp_args->op_errno  = gf_errno_to_error +                                      (this_args_cbk->op_errno); + +                if (!this_args_cbk->op_ret) { +                        rsp_args->op_ret = server_post_create (frame, +                                                rsp_args, state, this, +                                                this_args_cbk->fd, +                                                this_args_cbk->inode, +                                                &this_args_cbk->stat, +                                                &this_args_cbk->preparent, +                                                &this_args_cbk->postparent); +                        if (rsp_args->op_ret) { +                                rsp_args->op_errno = -rsp_args->op_ret; +                                rsp_args->op_ret = -1; +                        } +                } +                break; +        } +        case GF_FOP_FTRUNCATE: +        { +                gfs3_ftruncate_rsp *rsp_args = NULL; + +                rsp_args = &this_rsp->compound_rsp_u.compound_ftruncate_rsp; + +                GF_PROTOCOL_DICT_SERIALIZE (this, this_args_cbk->xdata, +                                            &rsp_args->xdata.xdata_val, +                                            rsp_args->xdata.xdata_len, +                                            rsp_args->op_errno, out); + +                if (!this_args_cbk->op_ret) { +                        server_post_ftruncate (rsp_args, +                                              &this_args_cbk->prestat, +                                              &this_args_cbk->poststat); +                } +                rsp_args->op_ret = this_args_cbk->op_ret; +                rsp_args->op_errno  = gf_errno_to_error +                                      (this_args_cbk->op_errno); +                break; +        } +        case GF_FOP_FSTAT: +        { +                gfs3_fstat_rsp *rsp_args = NULL; + +                rsp_args = &this_rsp->compound_rsp_u.compound_fstat_rsp; + +                GF_PROTOCOL_DICT_SERIALIZE (this, this_args_cbk->xdata, +                                            &rsp_args->xdata.xdata_val, +                                            rsp_args->xdata.xdata_len, +                                            rsp_args->op_errno, out); +                if (!this_args_cbk->op_ret) { +                        server_post_fstat (rsp_args, +                                          &this_args_cbk->stat); +                } +                rsp_args->op_ret = this_args_cbk->op_ret; +                rsp_args->op_errno  = gf_errno_to_error +                                      (this_args_cbk->op_errno); +                break; +        } +        case GF_FOP_LK: +        { +                gfs3_lk_rsp *rsp_args = NULL; + +                rsp_args = &this_rsp->compound_rsp_u.compound_lk_rsp; + +                GF_PROTOCOL_DICT_SERIALIZE (this, this_args_cbk->xdata, +                                            &rsp_args->xdata.xdata_val, +                                            rsp_args->xdata.xdata_len, +                                            rsp_args->op_errno, out); + +                if (!this_args_cbk->op_ret) { +                        server_post_lk (this, rsp_args, &this_args_cbk->lock); +                } + +                rsp_args->op_ret = this_args_cbk->op_ret; +                rsp_args->op_errno  = gf_errno_to_error +                                      (this_args_cbk->op_errno); +                break; +        } +        case GF_FOP_LOOKUP: +        { +                gfs3_lookup_rsp *rsp_args = NULL; + +                rsp_args = &this_rsp->compound_rsp_u.compound_lookup_rsp; + +                GF_PROTOCOL_DICT_SERIALIZE (this, this_args_cbk->xdata, +                                            &rsp_args->xdata.xdata_val, +                                            rsp_args->xdata.xdata_len, +                                            rsp_args->op_errno, out); + +                if (!this_args_cbk->op_ret) { +                        server_post_lookup (rsp_args, frame, state, +                                            this_args_cbk->inode, +                                            &this_args_cbk->stat, +                                            &this_args_cbk->postparent); +                } +                rsp_args->op_ret = this_args_cbk->op_ret; +                rsp_args->op_errno  = gf_errno_to_error +                                      (this_args_cbk->op_errno); +                break; +        } +        case GF_FOP_READDIR: +        { +                gfs3_readdir_rsp *rsp_args = NULL; + +                rsp_args = &this_rsp->compound_rsp_u.compound_readdir_rsp; + +                GF_PROTOCOL_DICT_SERIALIZE (this, this_args_cbk->xdata, +                                            &rsp_args->xdata.xdata_val, +                                            rsp_args->xdata.xdata_len, +                                            rsp_args->op_errno, out); + +                rsp_args->op_ret = this_args_cbk->op_ret; +                rsp_args->op_errno  = gf_errno_to_error +                                      (this_args_cbk->op_errno); + +                if (this_args_cbk->op_ret > 0) { +                        ret = server_post_readdir (rsp_args, +                                                   &this_args_cbk->entries); +                        if (ret < 0) { +                                rsp_args->op_ret = ret; +                                rsp_args->op_errno = ENOMEM; +                        } +                } +                break; +        } +        case GF_FOP_INODELK: +        { +                gf_common_rsp *rsp_args = NULL; + +                rsp_args = &this_rsp->compound_rsp_u.compound_inodelk_rsp; + +                GF_PROTOCOL_DICT_SERIALIZE (this, this_args_cbk->xdata, +                                            &rsp_args->xdata.xdata_val, +                                            rsp_args->xdata.xdata_len, +                                            rsp_args->op_errno, out); +                rsp_args->op_ret = this_args_cbk->op_ret; +                rsp_args->op_errno  = gf_errno_to_error +                                      (this_args_cbk->op_errno); +                break; +        } +        case GF_FOP_FINODELK: +        { +                gf_common_rsp *rsp_args = NULL; + +                rsp_args = &this_rsp->compound_rsp_u.compound_finodelk_rsp; + +                GF_PROTOCOL_DICT_SERIALIZE (this, this_args_cbk->xdata, +                                            &rsp_args->xdata.xdata_val, +                                            rsp_args->xdata.xdata_len, +                                            rsp_args->op_errno, out); +                rsp_args->op_ret = this_args_cbk->op_ret; +                rsp_args->op_errno  = gf_errno_to_error +                                      (this_args_cbk->op_errno); +                break; +        } +        case GF_FOP_ENTRYLK: +        { +                gf_common_rsp *rsp_args = NULL; + +                rsp_args = &this_rsp->compound_rsp_u.compound_entrylk_rsp; + +                GF_PROTOCOL_DICT_SERIALIZE (this, this_args_cbk->xdata, +                                            &rsp_args->xdata.xdata_val, +                                            rsp_args->xdata.xdata_len, +                                            rsp_args->op_errno, out); +                rsp_args->op_ret = this_args_cbk->op_ret; +                rsp_args->op_errno  = gf_errno_to_error +                                      (this_args_cbk->op_errno); +                break; +        } +        case GF_FOP_FENTRYLK: +        { +                gf_common_rsp *rsp_args = NULL; + +                rsp_args = &this_rsp->compound_rsp_u.compound_fentrylk_rsp; + +                GF_PROTOCOL_DICT_SERIALIZE (this, this_args_cbk->xdata, +                                            &rsp_args->xdata.xdata_val, +                                            rsp_args->xdata.xdata_len, +                                            rsp_args->op_errno, out); +                rsp_args->op_ret = this_args_cbk->op_ret; +                rsp_args->op_errno  = gf_errno_to_error +                                      (this_args_cbk->op_errno); +                break; +        } +        case GF_FOP_XATTROP: +        { +                gfs3_xattrop_rsp *rsp_args = NULL; + +                rsp_args = &this_rsp->compound_rsp_u.compound_xattrop_rsp; + +                GF_PROTOCOL_DICT_SERIALIZE (this, this_args_cbk->xdata, +                                            &rsp_args->xdata.xdata_val, +                                            rsp_args->xdata.xdata_len, +                                            rsp_args->op_errno, out); + +                if (!this_args_cbk->op_ret) { +                        GF_PROTOCOL_DICT_SERIALIZE (this, +                                                    this_args_cbk->xattr, +                                                    &rsp_args->dict.dict_val, +                                                    rsp_args->dict.dict_len, +                                                    rsp_args->op_errno, out); +                } +                rsp_args->op_ret = this_args_cbk->op_ret; +                rsp_args->op_errno  = gf_errno_to_error +                                      (this_args_cbk->op_errno); +                break; +        } +        case GF_FOP_FXATTROP: +        { +                gfs3_fxattrop_rsp *rsp_args = NULL; + +                rsp_args = &this_rsp->compound_rsp_u.compound_fxattrop_rsp; + +                GF_PROTOCOL_DICT_SERIALIZE (this, this_args_cbk->xdata, +                                            &rsp_args->xdata.xdata_val, +                                            rsp_args->xdata.xdata_len, +                                            rsp_args->op_errno, out); + +                if (!this_args_cbk->op_ret) { +                        GF_PROTOCOL_DICT_SERIALIZE (this, +                                                    this_args_cbk->xattr, +                                                    &rsp_args->dict.dict_val, +                                                    rsp_args->dict.dict_len, +                                                    rsp_args->op_errno, out); +                } +                rsp_args->op_ret = this_args_cbk->op_ret; +                rsp_args->op_errno  = gf_errno_to_error +                                      (this_args_cbk->op_errno); +                break; +        } +        case GF_FOP_FGETXATTR: +        { +                gfs3_fgetxattr_rsp *rsp_args = NULL; + +                rsp_args = &this_rsp->compound_rsp_u.compound_fgetxattr_rsp; + +                GF_PROTOCOL_DICT_SERIALIZE (this, this_args_cbk->xdata, +                                            &rsp_args->xdata.xdata_val, +                                            rsp_args->xdata.xdata_len, +                                            rsp_args->op_errno, out); + +                if (-1 != this_args_cbk->op_ret) { +                        GF_PROTOCOL_DICT_SERIALIZE (this, this_args_cbk->xattr, +                                                    &rsp_args->dict.dict_val, +                                                    rsp_args->dict.dict_len, +                                                    rsp_args->op_errno, out); +                } +                rsp_args->op_ret = this_args_cbk->op_ret; +                rsp_args->op_errno  = gf_errno_to_error +                                      (this_args_cbk->op_errno); +                break; +        } +        case GF_FOP_FSETXATTR: +        { +                gf_common_rsp *rsp_args = NULL; + +                rsp_args = &this_rsp->compound_rsp_u.compound_setxattr_rsp; + +                GF_PROTOCOL_DICT_SERIALIZE (this, this_args_cbk->xdata, +                                            &rsp_args->xdata.xdata_val, +                                            rsp_args->xdata.xdata_len, +                                            rsp_args->op_errno, out); +                rsp_args->op_ret = this_args_cbk->op_ret; +                rsp_args->op_errno  = gf_errno_to_error +                                      (this_args_cbk->op_errno); +                break; +        } +        case GF_FOP_RCHECKSUM: +        { +                gfs3_rchecksum_rsp *rsp_args = NULL; + +                rsp_args = &this_rsp->compound_rsp_u.compound_rchecksum_rsp; + +                GF_PROTOCOL_DICT_SERIALIZE (this, this_args_cbk->xdata, +                                            &rsp_args->xdata.xdata_val, +                                            rsp_args->xdata.xdata_len, +                                            rsp_args->op_errno, out); + +                if (!this_args_cbk->op_ret) { +                        server_post_rchecksum (rsp_args, +                                               this_args_cbk->weak_checksum, +                                               this_args_cbk->strong_checksum); +                } +                rsp_args->op_ret = this_args_cbk->op_ret; +                rsp_args->op_errno  = gf_errno_to_error +                                      (this_args_cbk->op_errno); +                break; +        } +        case GF_FOP_SETATTR: +        { +                gfs3_setattr_rsp *rsp_args = NULL; + +                rsp_args = &this_rsp->compound_rsp_u.compound_setattr_rsp; + +                GF_PROTOCOL_DICT_SERIALIZE (this, this_args_cbk->xdata, +                                            &rsp_args->xdata.xdata_val, +                                            rsp_args->xdata.xdata_len, +                                            rsp_args->op_errno, out); + +                if (!this_args_cbk->op_ret) { +                        server_post_setattr (rsp_args, +                                             &this_args_cbk->prestat, +                                             &this_args_cbk->poststat); +                } +                rsp_args->op_ret = this_args_cbk->op_ret; +                rsp_args->op_errno  = gf_errno_to_error +                                      (this_args_cbk->op_errno); +                break; +        } +        case GF_FOP_FSETATTR: +        { +                gfs3_fsetattr_rsp *rsp_args = NULL; + +                rsp_args = &this_rsp->compound_rsp_u.compound_fsetattr_rsp; + +                GF_PROTOCOL_DICT_SERIALIZE (this, this_args_cbk->xdata, +                                            &rsp_args->xdata.xdata_val, +                                            rsp_args->xdata.xdata_len, +                                            rsp_args->op_errno, out); + +                if (!this_args_cbk->op_ret) { +                        server_post_fsetattr (rsp_args, &this_args_cbk->prestat, +                                              &this_args_cbk->poststat); +                } +                rsp_args->op_ret = this_args_cbk->op_ret; +                rsp_args->op_errno  = gf_errno_to_error +                                      (this_args_cbk->op_errno); +                break; +        } +        case GF_FOP_READDIRP: +        { +                gfs3_readdirp_rsp *rsp_args = NULL; + +                rsp_args = &this_rsp->compound_rsp_u.compound_readdirp_rsp; + +                GF_PROTOCOL_DICT_SERIALIZE (this, this_args_cbk->xdata, +                                            &rsp_args->xdata.xdata_val, +                                            rsp_args->xdata.xdata_len, +                                            rsp_args->op_errno, out); + +                if (this_args_cbk->op_ret > 0) { +                        ret = server_post_readdirp (rsp_args, +                                                   &this_args_cbk->entries); +                        if (ret < 0) { +                                rsp_args->op_ret = ret; +                                rsp_args->op_errno = ENOMEM; +                                goto out; +                        } +                        gf_link_inodes_from_dirent (this, state->fd->inode, +                                                    &this_args_cbk->entries); +                } +                rsp_args->op_ret = this_args_cbk->op_ret; +                rsp_args->op_errno  = gf_errno_to_error +                                      (this_args_cbk->op_errno); +                break; +        } +        case GF_FOP_FREMOVEXATTR: +        { +                gf_common_rsp *rsp_args = NULL; + +                rsp_args = &this_rsp->compound_rsp_u.compound_fremovexattr_rsp; + +                GF_PROTOCOL_DICT_SERIALIZE (this, this_args_cbk->xdata, +                                            &rsp_args->xdata.xdata_val, +                                            rsp_args->xdata.xdata_len, +                                            rsp_args->op_errno, out); +                rsp_args->op_ret = this_args_cbk->op_ret; +                rsp_args->op_errno  = gf_errno_to_error +                                      (this_args_cbk->op_errno); +                break; +        } +	case GF_FOP_FALLOCATE: +        { +                gfs3_fallocate_rsp *rsp_args = NULL; + +                rsp_args = &this_rsp->compound_rsp_u.compound_fallocate_rsp; + +                GF_PROTOCOL_DICT_SERIALIZE (this, this_args_cbk->xdata, +                                            &rsp_args->xdata.xdata_val, +                                            rsp_args->xdata.xdata_len, +                                            rsp_args->op_errno, out); + +                if (!this_args_cbk->op_ret) { +                        server_post_fallocate (rsp_args, +                                               &this_args_cbk->prestat, +                                               &this_args_cbk->poststat); +                } +                rsp_args->op_ret = this_args_cbk->op_ret; +                rsp_args->op_errno  = gf_errno_to_error +                                      (this_args_cbk->op_errno); +                break; +        } +	case GF_FOP_DISCARD: +        { +                gfs3_discard_rsp *rsp_args = NULL; + +                rsp_args = &this_rsp->compound_rsp_u.compound_discard_rsp; + +                GF_PROTOCOL_DICT_SERIALIZE (this, this_args_cbk->xdata, +                                            &rsp_args->xdata.xdata_val, +                                            rsp_args->xdata.xdata_len, +                                            rsp_args->op_errno, out); + +                if (!this_args_cbk->op_ret) { +                        server_post_discard (rsp_args, +                                             &this_args_cbk->prestat, +                                             &this_args_cbk->poststat); +                } +                rsp_args->op_ret = this_args_cbk->op_ret; +                rsp_args->op_errno  = gf_errno_to_error +                                      (this_args_cbk->op_errno); +                break; +        } +        case GF_FOP_ZEROFILL: +        { +                gfs3_zerofill_rsp *rsp_args = NULL; + +                rsp_args = &this_rsp->compound_rsp_u.compound_zerofill_rsp; + +                GF_PROTOCOL_DICT_SERIALIZE (this, this_args_cbk->xdata, +                                            &rsp_args->xdata.xdata_val, +                                            rsp_args->xdata.xdata_len, +                                            rsp_args->op_errno, out); + +                if (!this_args_cbk->op_ret) { +                        server_post_zerofill (rsp_args, +                                              &this_args_cbk->prestat, +                                              &this_args_cbk->poststat); +                } +                rsp_args->op_ret = this_args_cbk->op_ret; +                rsp_args->op_errno  = gf_errno_to_error +                                      (this_args_cbk->op_errno); +                break; +        } +        case GF_FOP_SEEK: +        { +                gfs3_seek_rsp *rsp_args = NULL; + +                rsp_args = &this_rsp->compound_rsp_u.compound_seek_rsp; + +                GF_PROTOCOL_DICT_SERIALIZE (this, this_args_cbk->xdata, +                                            &rsp_args->xdata.xdata_val, +                                            rsp_args->xdata.xdata_len, +                                            rsp_args->op_errno, out); +                rsp_args->op_ret = this_args_cbk->op_ret; +                rsp_args->op_errno  = gf_errno_to_error +                                      (this_args_cbk->op_errno); +                break; +        } +        case GF_FOP_LEASE: +        { +                gfs3_lease_rsp *rsp_args = NULL; + +                rsp_args = &this_rsp->compound_rsp_u.compound_lease_rsp; + +                GF_PROTOCOL_DICT_SERIALIZE (this, this_args_cbk->xdata, +                                            &rsp_args->xdata.xdata_val, +                                            rsp_args->xdata.xdata_len, +                                            rsp_args->op_errno, out); + +                if (!this_args_cbk->op_ret) { +                        server_post_lease (rsp_args, &this_args_cbk->lease); +                } + +                rsp_args->op_ret = this_args_cbk->op_ret; +                rsp_args->op_errno  = gf_errno_to_error +                                      (this_args_cbk->op_errno); +                break; +        } +        default: +                return ENOTSUP; +        } +out: +        return op_errno; +} +/* This works only when the compound fop acts on one loc/inode/gfid. + * If compound fops on more than one inode is required, multiple + * resolve and resumes will have to be done. This will have to change. + * Right now, multiple unlinks, rmdirs etc is are not supported. + * This can be added for future enhancements. + */ +int +server_get_compound_resolve (server_state_t *state, gfs3_compound_req *req) +{ +        int                      i          = 0; +        compound_req             *array     = &req->compound_req_array.compound_req_array_val[i]; + +        switch (array->fop_enum) { +        case GF_FOP_STAT: +        { +                gfs3_stat_req this_req = { {0,} }; + +                this_req = array[i].compound_req_u.compound_stat_req; + +                state->resolve.type  = RESOLVE_MUST; +                memcpy (state->resolve.gfid, +                        this_req.gfid, 16); +                break; +        } +        case GF_FOP_READLINK: +        { +                gfs3_readlink_req this_req = { {0,} }; + +                this_req = array[i].compound_req_u.compound_readlink_req; + +                state->resolve.type  = RESOLVE_MUST; +                memcpy (state->resolve.gfid, +                        this_req.gfid, 16); +                break; +        } +        case GF_FOP_MKNOD: +        { +                gfs3_mknod_req this_req = { {0,} }; + +                this_req = array[i].compound_req_u.compound_mknod_req; + +                state->resolve.type    = RESOLVE_NOT; +                memcpy (state->resolve.pargfid, this_req.pargfid, 16); +                state->resolve.bname = gf_strdup +                                       (this_req.bname); +                break; +        } +        case GF_FOP_MKDIR: +        { +                gfs3_mkdir_req this_req = { {0,} }; + +                this_req = array[i].compound_req_u.compound_mkdir_req; + +                state->resolve.type    = RESOLVE_NOT; +                memcpy (state->resolve.pargfid, this_req.pargfid, 16); +                state->resolve.bname = gf_strdup +                                       (this_req.bname); +                break; +        } +        case GF_FOP_UNLINK: +        { +                gfs3_unlink_req this_req = { {0,} }; + +                this_req = array[i].compound_req_u.compound_unlink_req; + +                state->resolve.type    = RESOLVE_MUST; +                memcpy (state->resolve.pargfid, this_req.pargfid, 16); +                state->resolve.bname = gf_strdup +                                       (this_req.bname); +                break; +        } +        case GF_FOP_RMDIR: +        { +                gfs3_rmdir_req this_req = { {0,} }; + +                this_req = array[i].compound_req_u.compound_rmdir_req; + +                state->resolve.type    = RESOLVE_MUST; +                memcpy (state->resolve.pargfid, this_req.pargfid, 16); +                state->resolve.bname = gf_strdup +                                       (this_req.bname); +                break; +        } +        case GF_FOP_SYMLINK: +        { +                gfs3_symlink_req this_req = { {0,} }; + +                this_req = array[i].compound_req_u.compound_symlink_req; + +                state->resolve.type   = RESOLVE_NOT; +                memcpy (state->resolve.pargfid, this_req.pargfid, 16); +                state->resolve.bname = gf_strdup +                                       (this_req.bname); +                break; +        } +        case GF_FOP_RENAME: +        { +                gfs3_rename_req this_req = { {0,} }; + +                this_req = array[i].compound_req_u.compound_rename_req; + +                state->resolve.type   = RESOLVE_MUST; +                state->resolve.bname = gf_strdup +                                       (this_req.oldbname); +                memcpy (state->resolve.pargfid, this_req.oldgfid, 16); + +                state->resolve2.type  = RESOLVE_MAY; +                state->resolve2.bname = gf_strdup +                                       (this_req.newbname); +                memcpy (state->resolve2.pargfid, this_req.newgfid, 16); +                break; +        } +        case GF_FOP_LINK: +        { +                gfs3_link_req this_req = { {0,} }; + +                this_req = array[i].compound_req_u.compound_link_req; + +                state->resolve.type    = RESOLVE_MUST; +                memcpy (state->resolve.gfid, this_req.oldgfid, 16); + +                state->resolve2.type   = RESOLVE_NOT; +                state->resolve2.bname = gf_strdup +                                       (this_req.newbname); +                memcpy (state->resolve2.pargfid, this_req.newgfid, 16); +                break; +        } +        case GF_FOP_TRUNCATE: +        { +                gfs3_truncate_req this_req = { {0,} }; + +                this_req = array[i].compound_req_u.compound_truncate_req; + +                state->resolve.type  = RESOLVE_MUST; +                memcpy (state->resolve.gfid, +                        this_req.gfid, 16); +                break; +        } +        case GF_FOP_OPEN: +        { +                gfs3_open_req this_req = { {0,} }; + +                this_req = array[i].compound_req_u.compound_open_req; + +                state->resolve.type  = RESOLVE_MUST; +                memcpy (state->resolve.gfid, +                        this_req.gfid, 16); +                break; +        } +        case GF_FOP_READ: +        { +                gfs3_read_req this_req = { {0,} }; + +                this_req = array[i].compound_req_u.compound_read_req; + +                state->resolve.type  = RESOLVE_MUST; +                memcpy (state->resolve.gfid, +                        this_req.gfid, 16); +                break; +        } +        case GF_FOP_WRITE: +        { +                gfs3_write_req this_req = { {0,} }; + +                this_req = array[i].compound_req_u.compound_write_req; + +                state->resolve.type  = RESOLVE_MUST; +                memcpy (state->resolve.gfid, +                        this_req.gfid, 16); +                break; +        } +        case GF_FOP_STATFS: +        { +                gfs3_statfs_req this_req = { {0,} }; + +                this_req = array[i].compound_req_u.compound_statfs_req; + +                state->resolve.type  = RESOLVE_MUST; +                memcpy (state->resolve.gfid, +                        this_req.gfid, 16); +                break; +        } +        case GF_FOP_FLUSH: +        { +                gfs3_flush_req this_req = { {0,} }; + +                this_req = array[i].compound_req_u.compound_flush_req; + +                state->resolve.type  = RESOLVE_MUST; +                memcpy (state->resolve.gfid, +                        this_req.gfid, 16); +                state->resolve.fd_no = this_req.fd; +                break; +        } +        case GF_FOP_FSYNC: +        { +                gfs3_fsync_req this_req = { {0,} }; + +                this_req = array[i].compound_req_u.compound_fsync_req; + +                state->resolve.type  = RESOLVE_MUST; +                memcpy (state->resolve.gfid, +                        this_req.gfid, 16); +                state->resolve.fd_no = this_req.fd; +                break; +        } +        case GF_FOP_SETXATTR: +        { +                gfs3_setxattr_req this_req = { {0,} }; + +                this_req = array[i].compound_req_u.compound_setxattr_req; + +                state->resolve.type  = RESOLVE_MUST; +                memcpy (state->resolve.gfid, +                        this_req.gfid, 16); +                break; +        } +        case GF_FOP_GETXATTR: +        { +                gfs3_getxattr_req this_req = { {0,} }; + +                this_req = array[i].compound_req_u.compound_getxattr_req; + +                state->resolve.type  = RESOLVE_MUST; +                memcpy (state->resolve.gfid, +                        this_req.gfid, 16); +                break; +        } +        case GF_FOP_REMOVEXATTR: +        { +                gfs3_removexattr_req this_req = { {0,} }; + +                this_req = array[i].compound_req_u.compound_removexattr_req; + +                state->resolve.type  = RESOLVE_MUST; +                memcpy (state->resolve.gfid, +                        this_req.gfid, 16); +                break; +        } +        case GF_FOP_OPENDIR: +        { +                gfs3_opendir_req this_req = { {0,} }; + +                this_req = array[i].compound_req_u.compound_opendir_req; + +                state->resolve.type  = RESOLVE_MUST; +                memcpy (state->resolve.gfid, +                        this_req.gfid, 16); +                break; +        } +        case GF_FOP_FSYNCDIR: +        { +                gfs3_fsyncdir_req this_req = { {0,} }; + +                this_req = array[i].compound_req_u.compound_fsyncdir_req; + +                state->resolve.type  = RESOLVE_MUST; +                memcpy (state->resolve.gfid, +                        this_req.gfid, 16); +                state->resolve.fd_no = this_req.fd; +                break; +        } +        case GF_FOP_ACCESS: +        { +                gfs3_access_req this_req = { {0,} }; + +                this_req = array[i].compound_req_u.compound_access_req; + +                state->resolve.type  = RESOLVE_MUST; +                memcpy (state->resolve.gfid, +                        this_req.gfid, 16); +                break; +        } +        case GF_FOP_CREATE: +        { +                gfs3_create_req this_req = { {0,} }; + +                this_req = array[i].compound_req_u.compound_create_req; + +                state->flags = gf_flags_to_flags (this_req.flags); +                if (state->flags & O_EXCL) { +                        state->resolve.type = RESOLVE_NOT; +                } else { +                        state->resolve.type = RESOLVE_DONTCARE; +                } + +                memcpy (state->resolve.pargfid, this_req.pargfid, 16); +                state->resolve.bname = gf_strdup +                                       (this_req.bname); +                break; +        } +        case GF_FOP_FTRUNCATE: +        { +                gfs3_ftruncate_req this_req = { {0,} }; + +                this_req = array[i].compound_req_u.compound_ftruncate_req; + +                state->resolve.type  = RESOLVE_MUST; +                memcpy (state->resolve.gfid, +                        this_req.gfid, 16); +                state->resolve.fd_no = this_req.fd; +                break; +        } +        case GF_FOP_FSTAT: +        { +                gfs3_fstat_req this_req = { {0,} }; + +                this_req = array[i].compound_req_u.compound_fstat_req; + +                state->resolve.type  = RESOLVE_MUST; +                memcpy (state->resolve.gfid, +                        this_req.gfid, 16); +                state->resolve.fd_no = this_req.fd; +                break; +        } +        case GF_FOP_LK: +        { +                gfs3_lk_req this_req = { {0,} }; + +                this_req = array[i].compound_req_u.compound_lk_req; + +                memcpy (state->resolve.gfid, +                        this_req.gfid, 16); +                state->resolve.fd_no = this_req.fd; +                break; +        } +        case GF_FOP_LOOKUP: +        { +                gfs3_lookup_req this_req = { {0,} }; + +                this_req = array[i].compound_req_u.compound_lookup_req; +                state->resolve.type   = RESOLVE_DONTCARE; + +                if (this_req.bname && strcmp (this_req.bname, "")) { +                        memcpy (state->resolve.pargfid, this_req.pargfid, 16); +                        state->resolve.bname = gf_strdup +                                               (this_req.bname); +                } else { +                        memcpy (state->resolve.gfid, this_req.gfid, 16); +                } +                break; +        } +        case GF_FOP_READDIR: +        { +                gfs3_readdir_req this_req = { {0,} }; + +                this_req = array[i].compound_req_u.compound_readdir_req; + +                state->resolve.type  = RESOLVE_MUST; +                memcpy (state->resolve.gfid, +                        this_req.gfid, 16); +                state->resolve.fd_no = this_req.fd; +                break; +        } +        case GF_FOP_INODELK: +        { +                gfs3_inodelk_req this_req = { {0,} }; + +                this_req = array[i].compound_req_u.compound_inodelk_req; + +                state->resolve.type  = RESOLVE_EXACT; +                memcpy (state->resolve.gfid, +                        this_req.gfid, 16); +                break; +        } +        case GF_FOP_FINODELK: +        { +                gfs3_finodelk_req this_req = { {0,} }; + +                this_req = array[i].compound_req_u.compound_finodelk_req; + +                state->resolve.type  = RESOLVE_EXACT; +                memcpy (state->resolve.gfid, +                        this_req.gfid, 16); +                state->resolve.fd_no = this_req.fd; +                break; +        } +        case GF_FOP_ENTRYLK: +        { +                gfs3_entrylk_req this_req = { {0,} }; + +                this_req = array[i].compound_req_u.compound_entrylk_req; + +                state->resolve.type  = RESOLVE_EXACT; +                memcpy (state->resolve.gfid, +                        this_req.gfid, 16); +                break; +        } +        case GF_FOP_FENTRYLK: +        { +                gfs3_fentrylk_req this_req = { {0,} }; + +                this_req = array[i].compound_req_u.compound_fentrylk_req; + +                state->resolve.type  = RESOLVE_EXACT; +                memcpy (state->resolve.gfid, +                        this_req.gfid, 16); +                state->resolve.fd_no = this_req.fd; +                break; +        } +        case GF_FOP_XATTROP: +        { +                gfs3_xattrop_req this_req = { {0,} }; + +                this_req = array[i].compound_req_u.compound_xattrop_req; + +                state->resolve.type  = RESOLVE_MUST; +                memcpy (state->resolve.gfid, +                        this_req.gfid, 16); +                break; +        } +        case GF_FOP_FXATTROP: +        { +                gfs3_fxattrop_req this_req = { {0,} }; + +                this_req = array[i].compound_req_u.compound_fxattrop_req; + +                state->resolve.type  = RESOLVE_MUST; +                memcpy (state->resolve.gfid, +                        this_req.gfid, 16); +                state->resolve.fd_no = this_req.fd; +                break; +        } +        case GF_FOP_FGETXATTR: +        { +                gfs3_fgetxattr_req this_req = { {0,} }; + +                this_req = array[i].compound_req_u.compound_fgetxattr_req; + +                state->resolve.type  = RESOLVE_MUST; +                memcpy (state->resolve.gfid, +                        this_req.gfid, 16); +                state->resolve.fd_no = this_req.fd; +                break; +        } +        case GF_FOP_FSETXATTR: +        { +                gfs3_fsetxattr_req this_req = { {0,} }; + +                this_req = array[i].compound_req_u.compound_fsetxattr_req; + +                state->resolve.type  = RESOLVE_MUST; +                memcpy (state->resolve.gfid, +                        this_req.gfid, 16); +                state->resolve.fd_no = this_req.fd; +                break; +        } +        case GF_FOP_RCHECKSUM: +        { +                gfs3_rchecksum_req this_req = {0,}; + +                this_req = array[i].compound_req_u.compound_rchecksum_req; + +                state->resolve.type  = RESOLVE_MAY; +                state->resolve.fd_no = this_req.fd; +                break; +        } +        case GF_FOP_SETATTR: +        { +                gfs3_setattr_req this_req = { {0,} }; + +                this_req = array[i].compound_req_u.compound_setattr_req; + +                state->resolve.type  = RESOLVE_MUST; +                memcpy (state->resolve.gfid, +                        this_req.gfid, 16); +                break; +        } +        case GF_FOP_FSETATTR: +        { +                gfs3_fsetattr_req this_req = {0,}; + +                this_req = array[i].compound_req_u.compound_fsetattr_req; + +                state->resolve.type  = RESOLVE_MUST; +                state->resolve.fd_no = this_req.fd; +                break; +        } +        case GF_FOP_READDIRP: +        { +                gfs3_readdirp_req this_req = { {0,} }; + +                this_req = array[i].compound_req_u.compound_readdirp_req; + +                state->resolve.type  = RESOLVE_MUST; +                memcpy (state->resolve.gfid, +                        this_req.gfid, 16); +                state->resolve.fd_no = this_req.fd; +                break; +        } +        case GF_FOP_FREMOVEXATTR: +        { +                gfs3_fremovexattr_req this_req = { {0,} }; + +                this_req = array[i].compound_req_u.compound_fremovexattr_req; + +                state->resolve.type  = RESOLVE_MUST; +                memcpy (state->resolve.gfid, +                        this_req.gfid, 16); +                state->resolve.fd_no = this_req.fd; +                break; +        } +        case GF_FOP_FALLOCATE: +        { +                gfs3_fallocate_req this_req = { {0,} }; + +                this_req = array[i].compound_req_u.compound_fallocate_req; + +                state->resolve.type  = RESOLVE_MUST; +                memcpy (state->resolve.gfid, +                        this_req.gfid, 16); +                state->resolve.fd_no = this_req.fd; +                break; +        } +        case GF_FOP_DISCARD: +        { +                gfs3_discard_req this_req = { {0,} }; + +                this_req = array[i].compound_req_u.compound_discard_req; + +                state->resolve.type  = RESOLVE_MUST; +                memcpy (state->resolve.gfid, +                        this_req.gfid, 16); +                state->resolve.fd_no = this_req.fd; +                break; +        } +        case GF_FOP_ZEROFILL: +        { +                gfs3_zerofill_req this_req = { {0,} }; + +                this_req = array[i].compound_req_u.compound_zerofill_req; + +                state->resolve.type  = RESOLVE_MUST; +                memcpy (state->resolve.gfid, +                        this_req.gfid, 16); +                state->resolve.fd_no = this_req.fd; +                break; +        } +        case GF_FOP_SEEK: +        { +                gfs3_seek_req this_req = { {0,} }; + +                this_req = array[i].compound_req_u.compound_seek_req; + +                state->resolve.type  = RESOLVE_MUST; +                memcpy (state->resolve.gfid, +                        this_req.gfid, 16); +                state->resolve.fd_no = this_req.fd; +                break; +        } +        case GF_FOP_LEASE: +        { +                gfs3_lease_req this_req = { {0,} }; + +                this_req = array[i].compound_req_u.compound_lease_req; + +                state->resolve.type = RESOLVE_MUST; +                memcpy (state->resolve.gfid, this_req.gfid, 16); +                break; +        } +        default: +                return ENOTSUP; +        } +        return 0; +} diff --git a/xlators/protocol/server/src/server-helpers.h b/xlators/protocol/server/src/server-helpers.h index 78b4bf08343..200b383e67e 100644 --- a/xlators/protocol/server/src/server-helpers.h +++ b/xlators/protocol/server/src/server-helpers.h @@ -12,6 +12,7 @@  #define _SERVER_HELPERS_H  #include "server.h" +#include "defaults.h"  #define CALL_STATE(frame)   ((server_state_t *)frame->root->state) @@ -68,4 +69,16 @@ serialize_rsp_locklist (lock_migration_info_t *locklist,  int  getactivelkinfo_rsp_cleanup (gfs3_getactivelk_rsp  *rsp); + +int +server_populate_compound_response (xlator_t *this, gfs3_compound_rsp *rsp, +                                   call_frame_t *frame, +                                   compound_args_cbk_t *args_cbk, int index); +int +server_get_compound_resolve (server_state_t *state, gfs3_compound_req *req); + +int +server_populate_compound_request (gfs3_compound_req *req, call_frame_t *frame, +                                  default_args_t *this_args, +                                  int index);  #endif /* !_SERVER_HELPERS_H */ diff --git a/xlators/protocol/server/src/server-mem-types.h b/xlators/protocol/server/src/server-mem-types.h index 38921884e83..9165249d49a 100644 --- a/xlators/protocol/server/src/server-mem-types.h +++ b/xlators/protocol/server/src/server-mem-types.h @@ -27,6 +27,7 @@ enum gf_server_mem_types_ {          gf_server_mt_timer_data_t,          gf_server_mt_setvolume_rsp_t,          gf_server_mt_lock_mig_t, +        gf_server_mt_compound_rsp_t,          gf_server_mt_end,  };  #endif /* __SERVER_MEM_TYPES_H__ */ diff --git a/xlators/protocol/server/src/server-messages.h b/xlators/protocol/server/src/server-messages.h index 7f560663af8..5593e68d3d4 100644 --- a/xlators/protocol/server/src/server-messages.h +++ b/xlators/protocol/server/src/server-messages.h @@ -40,7 +40,7 @@   */  #define GLFS_PS_BASE                GLFS_MSGID_COMP_PS -#define GLFS_NUM_MESSAGES           89 +#define GLFS_NUM_MESSAGES           90  #define GLFS_MSGID_END              (GLFS_PS_BASE + GLFS_NUM_MESSAGES + 1)  /* Messages with message IDs */  #define glfs_msg_start_x GLFS_PS_BASE, "Invalid: Start of messages" @@ -839,6 +839,15 @@   */  #define PS_MSG_SEEK_INFO                        (GLFS_PS_BASE + 89) + +/*! + * @messageid + * @diagnosis + * @recommendedaction + * + */ + +#define PS_MSG_COMPOUND_INFO                    (GLFS_PS_BASE + 90)  /*------------*/  #define glfs_msg_end_x GLFS_MSGID_END, "Invalid: End of messages" diff --git a/xlators/protocol/server/src/server-rpc-fops.c b/xlators/protocol/server/src/server-rpc-fops.c index 72824781406..64e9f537a1d 100644 --- a/xlators/protocol/server/src/server-rpc-fops.c +++ b/xlators/protocol/server/src/server-rpc-fops.c @@ -18,6 +18,9 @@  #include "glusterfs3.h"  #include "compat-errno.h"  #include "server-messages.h" +#include "defaults.h" +#include "default-args.h" +#include "server-common.h"  #include "xdr-nfs3.h" @@ -56,7 +59,7 @@ server_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                  goto out;          } -        gf_statfs_from_statfs (&rsp.statfs, buf); +        server_post_statfs (&rsp, buf);  out:          rsp.op_ret    = op_ret; @@ -83,7 +86,6 @@ server_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,          inode_t             *link_inode = NULL;          loc_t                fresh_loc  = {0,};          gfs3_lookup_rsp      rsp        = {0,}; -        uuid_t               rootgfid   = {0,};          state = CALL_STATE (frame); @@ -136,27 +138,7 @@ server_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                  goto out;          } -        root_inode = frame->root->client->bound_xl->itable->root; -        if (inode == root_inode) { -                /* we just looked up root ("/") */ -                stbuf->ia_ino = 1; -                rootgfid[15]  = 1; -                gf_uuid_copy (stbuf->ia_gfid, rootgfid); -                if (inode->ia_type == 0) -                        inode->ia_type = stbuf->ia_type; -        } - -        gf_stat_from_iatt (&rsp.stat, stbuf); - -        if (!__is_root_gfid (inode->gfid)) { -                link_inode = inode_link (inode, state->loc.parent, -                                         state->loc.name, stbuf); -                if (link_inode) { -                        inode_lookup (link_inode); -                        inode_unref (link_inode); -                } -        } - +        server_post_lookup (&rsp, frame, state, inode, stbuf, postparent);  out:          rsp.op_ret   = op_ret;          rsp.op_errno = gf_errno_to_error (op_errno); @@ -215,7 +197,7 @@ server_lease_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                          strerror (op_errno));                  goto out;          } -        gf_proto_lease_from_lease (&rsp.lease, lease); +        server_post_lease (&rsp, lease);  out:          rsp.op_ret    = op_ret; @@ -254,24 +236,7 @@ server_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                  goto out;          } -        switch (lock->l_type) { -        case F_RDLCK: -                lock->l_type = GF_LK_F_RDLCK; -                break; -        case F_WRLCK: -                lock->l_type = GF_LK_F_WRLCK; -                break; -        case F_UNLCK: -                lock->l_type = GF_LK_F_UNLCK; -                break; -        default: -                gf_msg (this->name, GF_LOG_ERROR, 0, PS_MSG_LOCK_ERROR, -                        "Unknown lock type: %"PRId32"!", lock->l_type); -                break; -        } - -        gf_proto_flock_from_flock (&rsp.flock, lock); - +        server_post_lk (this, &rsp, lock);  out:          rsp.op_ret    = op_ret;          rsp.op_errno  = gf_errno_to_error (op_errno); @@ -494,16 +459,7 @@ server_rmdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                  goto out;          } -        inode_unlink (state->loc.inode, state->loc.parent, -                      state->loc.name); -        /* parent should not be found for directories after -         * inode_unlink, since directories cannot have -         * hardlinks. -         */ -        forget_inode_if_no_dentry (state->loc.inode); - -        gf_stat_from_iatt (&rsp.preparent, preparent); -        gf_stat_from_iatt (&rsp.postparent, postparent); +        server_post_rmdir (state, &rsp, preparent, postparent);  out:          rsp.op_ret    = op_ret; @@ -526,7 +482,6 @@ server_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,  {          gfs3_mkdir_rsp       rsp        = {0,};          server_state_t      *state      = NULL; -        inode_t             *link_inode = NULL;          rpcsvc_request_t    *req        = NULL;          client_t            *client     = NULL; @@ -548,15 +503,8 @@ server_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                  goto out;          } -        gf_stat_from_iatt (&rsp.stat, stbuf); -        gf_stat_from_iatt (&rsp.preparent, preparent); -        gf_stat_from_iatt (&rsp.postparent, postparent); - -        link_inode = inode_link (inode, state->loc.parent, -                                 state->loc.name, stbuf); -        inode_lookup (link_inode); -        inode_unref (link_inode); - +        server_post_mkdir (state, &rsp, inode, stbuf, preparent, +                           postparent, xdata);  out:          rsp.op_ret    = op_ret;          rsp.op_errno  = gf_errno_to_error (op_errno); @@ -578,7 +526,6 @@ server_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this,  {          gfs3_mknod_rsp       rsp        = {0,};          server_state_t      *state      = NULL; -        inode_t             *link_inode = NULL;          rpcsvc_request_t    *req        = NULL;          GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val, @@ -596,15 +543,8 @@ server_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                  goto out;          } -        gf_stat_from_iatt (&rsp.stat, stbuf); -        gf_stat_from_iatt (&rsp.preparent, preparent); -        gf_stat_from_iatt (&rsp.postparent, postparent); - -        link_inode = inode_link (inode, state->loc.parent, -                                 state->loc.name, stbuf); -        inode_lookup (link_inode); -        inode_unref (link_inode); - +        server_post_mknod (state, &rsp, stbuf, preparent, postparent, +                           inode);  out:          rsp.op_ret    = op_ret;          rsp.op_errno  = gf_errno_to_error (op_errno); @@ -679,7 +619,7 @@ server_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,          /* (op_ret == 0) is valid, and means EOF */          if (op_ret) { -                ret = serialize_rsp_dirent (entries, &rsp); +                ret = server_post_readdir (&rsp, entries);                  if (ret == -1) {                          op_ret   = -1;                          op_errno = ENOMEM; @@ -726,20 +666,13 @@ server_opendir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                  goto out;          } -        serv_ctx = server_ctx_get (frame->root->client, this); -        if (serv_ctx == NULL) { -                gf_msg (this->name, GF_LOG_INFO, 0, -                        PS_MSG_SERVER_CTX_GET_FAILED, "server_ctx_get() " -                        "failed"); -                goto out; -        } - -        fd_bind (fd); -        fd_no = gf_fd_unused_get (serv_ctx->fdtable, fd); -        fd_ref (fd); // on behalf of the client +        op_ret = server_post_opendir (frame, this, &rsp, fd); +        if (op_ret) +                goto out;  out: -        rsp.fd = fd_no; +        if (op_ret) +                rsp.fd = fd_no;          rsp.op_ret    = op_ret;          rsp.op_errno  = gf_errno_to_error (op_errno); @@ -1044,8 +977,6 @@ server_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,          gfs3_rename_rsp      rsp        = {0,};          server_state_t      *state      = NULL;          rpcsvc_request_t    *req        = NULL; -        inode_t             *tmp_inode  = NULL; -        inode_t             *tmp_parent = NULL;          char         oldpar_str[50]     = {0,};          char         newpar_str[50]     = {0,}; @@ -1065,42 +996,9 @@ server_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                  goto out;          } -        stbuf->ia_type = state->loc.inode->ia_type; - -        /* TODO: log gfid of the inodes */ -        gf_msg_trace (frame->root->client->bound_xl->name, 0, "%"PRId64": " -                      "RENAME_CBK %s ==> %s", frame->root->unique, -                      state->loc.name, state->loc2.name); - -        /* Before renaming the inode, we have to get the inode for the -         * destination entry (i.e. inode with state->loc2.parent as -         * parent and state->loc2.name as name). If it exists, then -         * unlink that inode, and send forget on that inode if the -         * unlinked entry is the last entry. In case of fuse client -         * the fuse kernel module itself sends the forget on the -         * unlinked inode. -         */ -        tmp_inode = inode_grep (state->loc.inode->table, -                                state->loc2.parent, state->loc2.name); -        if (tmp_inode) { -                inode_unlink (tmp_inode, state->loc2.parent, -                              state->loc2.name); -                forget_inode_if_no_dentry (tmp_inode); -                inode_unref (tmp_inode); -        } - -        inode_rename (state->itable, -                      state->loc.parent, state->loc.name, -                      state->loc2.parent, state->loc2.name, -                      state->loc.inode, stbuf); -        gf_stat_from_iatt (&rsp.stat, stbuf); - -        gf_stat_from_iatt (&rsp.preoldparent, preoldparent); -        gf_stat_from_iatt (&rsp.postoldparent, postoldparent); - -        gf_stat_from_iatt (&rsp.prenewparent, prenewparent); -        gf_stat_from_iatt (&rsp.postnewparent, postnewparent); - +        server_post_rename (frame, state, &rsp, stbuf, +                            preoldparent, postoldparent, +                            prenewparent, postnewparent);  out:          rsp.op_ret    = op_ret;          rsp.op_errno  = gf_errno_to_error (op_errno); @@ -1142,13 +1040,7 @@ server_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,          gf_msg_trace (frame->root->client->bound_xl->name, 0, "%"PRId64": "                        "UNLINK_CBK %s", frame->root->unique, state->loc.name); -        inode_unlink (state->loc.inode, state->loc.parent, -                      state->loc.name); - -        forget_inode_if_no_dentry (state->loc.inode); - -        gf_stat_from_iatt (&rsp.preparent, preparent); -        gf_stat_from_iatt (&rsp.postparent, postparent); +        server_post_unlink (state, &rsp, preparent, postparent);  out:          rsp.op_ret    = op_ret; @@ -1188,14 +1080,8 @@ server_symlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                  goto out;          } -        gf_stat_from_iatt (&rsp.stat, stbuf); -        gf_stat_from_iatt (&rsp.preparent, preparent); -        gf_stat_from_iatt (&rsp.postparent, postparent); - -        link_inode = inode_link (inode, state->loc.parent, -                                 state->loc.name, stbuf); -        inode_lookup (link_inode); -        inode_unref (link_inode); +        server_post_symlink (state, &rsp, inode, stbuf, preparent, +                           postparent, xdata);  out:          rsp.op_ret    = op_ret; @@ -1241,13 +1127,8 @@ server_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                  goto out;          } -        gf_stat_from_iatt (&rsp.stat, stbuf); -        gf_stat_from_iatt (&rsp.preparent, preparent); -        gf_stat_from_iatt (&rsp.postparent, postparent); - -        link_inode = inode_link (inode, state->loc2.parent, -                                 state->loc2.name, stbuf); -        inode_unref (link_inode); +        server_post_link (state, &rsp, inode, stbuf, preparent, +                          postparent, xdata);  out:          rsp.op_ret    = op_ret; @@ -1284,8 +1165,7 @@ server_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                  goto out;          } -        gf_stat_from_iatt (&rsp.prestat, prebuf); -        gf_stat_from_iatt (&rsp.poststat, postbuf); +        server_post_truncate (&rsp, prebuf, postbuf);  out:          rsp.op_ret    = op_ret; @@ -1322,7 +1202,7 @@ server_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                  goto out;          } -        gf_stat_from_iatt (&rsp.stat, stbuf); +        server_post_fstat (&rsp, stbuf);  out:          rsp.op_ret    = op_ret; @@ -1359,8 +1239,7 @@ server_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                  goto out;          } -        gf_stat_from_iatt (&rsp.prestat, prebuf); -        gf_stat_from_iatt (&rsp.poststat, postbuf); +        server_post_ftruncate (&rsp, prebuf, postbuf);  out:          rsp.op_ret    = op_ret; @@ -1431,8 +1310,7 @@ server_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                  goto out;          } -        gf_stat_from_iatt (&(rsp.prestat), prebuf); -        gf_stat_from_iatt (&(rsp.poststat), postbuf); +        server_post_fsync (&rsp, prebuf, postbuf);  out:          rsp.op_ret    = op_ret; @@ -1469,8 +1347,7 @@ server_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                  goto out;          } -        gf_stat_from_iatt (&rsp.prestat, prebuf); -        gf_stat_from_iatt (&rsp.poststat, postbuf); +        server_post_writev (&rsp, prebuf, postbuf);  out:          rsp.op_ret    = op_ret; @@ -1519,8 +1396,7 @@ server_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                  goto out;          } -        gf_stat_from_iatt (&rsp.stat, stbuf); -        rsp.size = op_ret; +        server_post_readv (&rsp, stbuf, op_ret);  out:          rsp.op_ret    = op_ret; @@ -1558,11 +1434,7 @@ server_rchecksum_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                  goto out;          } -        rsp.weak_checksum = weak_checksum; - -        rsp.strong_checksum.strong_checksum_val = (char *)strong_checksum; -        rsp.strong_checksum.strong_checksum_len = MD5_DIGEST_LENGTH; - +        server_post_rchecksum (&rsp, weak_checksum, strong_checksum);  out:          rsp.op_ret    = op_ret;          rsp.op_errno  = gf_errno_to_error (op_errno); @@ -1601,19 +1473,9 @@ server_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                  goto out;          } -        serv_ctx = server_ctx_get (frame->root->client, this); -        if (serv_ctx == NULL) { -                gf_msg (this->name, GF_LOG_INFO, 0, -                        PS_MSG_SERVER_CTX_GET_FAILED, "server_ctx_get() " -                        "failed"); +        op_ret = server_post_open (frame, this, &rsp, fd); +        if (op_ret)                  goto out; -        } - -        fd_bind (fd); -        fd_no = gf_fd_unused_get (serv_ctx->fdtable, fd); -        fd_ref (fd); -        rsp.fd = fd_no; -  out:          rsp.op_ret    = op_ret;          rsp.op_errno  = gf_errno_to_error (op_errno); @@ -1634,8 +1496,6 @@ server_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                     struct iatt *postparent, dict_t *xdata)  {          server_state_t      *state      = NULL; -        server_ctx_t        *serv_ctx   = NULL; -        inode_t             *link_inode = NULL;          rpcsvc_request_t    *req        = NULL;          uint64_t             fd_no      = 0;          gfs3_create_rsp      rsp        = {0,}; @@ -1659,52 +1519,18 @@ server_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                        "CREATE %s (%s)", frame->root->unique, state->loc.name,                        uuid_utoa (stbuf->ia_gfid)); -        link_inode = inode_link (inode, state->loc.parent, -                                 state->loc.name, stbuf); - -        if (!link_inode) { +        op_ret = server_post_create (frame, &rsp, state, this, fd, inode, +                                     stbuf, +                                     preparent, postparent); +        if (op_ret) { +                op_errno = -op_ret;                  op_ret = -1; -                op_errno = ENOENT;                  goto out;          } -        if (link_inode != inode) { -                /* -                  VERY racy code (if used anywhere else) -                  -- don't do this without understanding -                */ - -                inode_ctx_merge (fd, fd->inode, link_inode); -                inode_unref (fd->inode); -                fd->inode = inode_ref (link_inode); -        } - -        inode_lookup (link_inode); -        inode_unref (link_inode); - -        serv_ctx = server_ctx_get (frame->root->client, this); -        if (serv_ctx == NULL) { -                gf_msg (this->name, GF_LOG_INFO, 0, -                        PS_MSG_SERVER_CTX_GET_FAILED, "server_ctx_get() " -                        "failed"); -                goto out; -        } - -        fd_bind (fd); -        fd_no = gf_fd_unused_get (serv_ctx->fdtable, fd); -        fd_ref (fd); - -        if ((fd_no > UINT64_MAX) || (fd == 0)) { -                op_ret = -1; -                op_errno = errno; -        } - -        gf_stat_from_iatt (&rsp.stat, stbuf); -        gf_stat_from_iatt (&rsp.preparent, preparent); -        gf_stat_from_iatt (&rsp.postparent, postparent); -  out: -        rsp.fd        = fd_no; +        if (op_ret) +                rsp.fd = fd_no;          rsp.op_ret    = op_ret;          rsp.op_errno  = gf_errno_to_error (op_errno); @@ -1739,16 +1565,11 @@ server_readlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                  goto out;          } -        gf_stat_from_iatt (&rsp.buf, stbuf); -        rsp.path = (char *)buf; - +        server_post_readlink (&rsp, stbuf, buf);  out:          rsp.op_ret    = op_ret;          rsp.op_errno  = gf_errno_to_error (op_errno); -        if (!rsp.path) -                rsp.path = ""; -          req = frame->local;          server_submit_reply (frame, req, &rsp, NULL, 0, NULL,                               (xdrproc_t)xdr_gfs3_readlink_rsp); @@ -1781,8 +1602,7 @@ server_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                  goto out;          } -        gf_stat_from_iatt (&rsp.stat, stbuf); - +        server_post_stat (&rsp, stbuf);  out:          rsp.op_ret    = op_ret;          rsp.op_errno  = gf_errno_to_error (op_errno); @@ -1819,12 +1639,7 @@ server_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                  goto out;          } -        if (statpre) { -                gf_stat_from_iatt (&rsp.statpre, statpre); -        } -        if (statpost) { -                gf_stat_from_iatt (&rsp.statpost, statpost); -        } +        server_post_setattr (&rsp, statpre, statpost);  out:          rsp.op_ret    = op_ret; @@ -1862,8 +1677,7 @@ server_fsetattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                  goto out;          } -        gf_stat_from_iatt (&rsp.statpre, statpre); -        gf_stat_from_iatt (&rsp.statpost, statpost); +        server_post_fsetattr (&rsp, statpre, statpost);  out:          rsp.op_ret    = op_ret; @@ -1991,7 +1805,7 @@ server_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this,          /* (op_ret == 0) is valid, and means EOF */          if (op_ret) { -                ret = serialize_rsp_direntp (entries, &rsp); +                ret = server_post_readdirp (&rsp, entries);                  if (ret == -1) {                          op_ret   = -1;                          op_errno = ENOMEM; @@ -2039,8 +1853,7 @@ server_fallocate_cbk(call_frame_t *frame, void *cookie, xlator_t *this,                  goto out;          } -        gf_stat_from_iatt (&rsp.statpre, statpre); -        gf_stat_from_iatt (&rsp.statpost, statpost); +        server_post_fallocate (&rsp, statpre, statpost);  out:          rsp.op_ret    = op_ret; @@ -2078,8 +1891,7 @@ server_discard_cbk(call_frame_t *frame, void *cookie, xlator_t *this,                  goto out;          } -        gf_stat_from_iatt (&rsp.statpre, statpre); -        gf_stat_from_iatt (&rsp.statpost, statpost); +        server_post_discard (&rsp, statpre, statpost);  out:          rsp.op_ret    = op_ret; @@ -2119,8 +1931,7 @@ server_zerofill_cbk(call_frame_t *frame, void *cookie, xlator_t *this,                  goto out;          } -        gf_stat_from_iatt (&rsp.statpre, statpre); -        gf_stat_from_iatt (&rsp.statpost, statpost); +        server_post_zerofill (&rsp, statpre, statpost);  out:          rsp.op_ret    = op_ret; @@ -2195,8 +2006,6 @@ server_seek_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                  goto out;          } -        rsp.offset    = offset; -  out:          rsp.op_ret    = op_ret;          rsp.op_errno  = gf_errno_to_error (op_errno); @@ -2248,6 +2057,61 @@ out:          return 0;  } +int +server_compound_cbk (call_frame_t *frame, void *cookie, xlator_t *this, +                     int32_t op_ret, int32_t op_errno, void *data, +                     dict_t *xdata) +{ +        struct gfs3_compound_rsp   rsp    = {0,}; +        server_state_t             *state  = NULL; +        rpcsvc_request_t           *req    = NULL; +        compound_args_cbk_t        *args_cbk = data; +        int                        i       = 0; + +        req = frame->local; +        state  = CALL_STATE (frame); + +        GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val), +                                    rsp.xdata.xdata_len, op_errno, out); + +        if (op_ret) { +                gf_msg (this->name, fop_log_level (GF_FOP_COMPOUND, op_errno), +                        op_errno, PS_MSG_COMPOUND_INFO, +                        "%"PRId64": COMPOUND%"PRId64" (%s) ==> (%s)", +                        frame->root->unique, state->resolve.fd_no, +                        uuid_utoa (state->resolve.gfid), +                        strerror (op_errno)); +                goto out; +        } + +        for (i = 0; i < args_cbk->fop_length; i++) { +                op_ret = server_populate_compound_response (this, &rsp, +                                                            frame, +                                                            args_cbk, i); + +                if (op_ret) { +                        op_errno = op_ret; +                        op_ret = -1; +                        goto out; +                } +        } +out: +        rsp.op_ret    = op_ret; +        rsp.op_errno  = gf_errno_to_error (op_errno); + +        server_submit_reply (frame, req, &rsp, NULL, 0, NULL, +                             (xdrproc_t) xdr_gfs3_compound_rsp); + +        for (i = 0; i < state->args->fop_length; i++) +                args_wipe (&state->args->req_list[i]); + +        GF_FREE (state->args->req_list); +        GF_FREE (state->args); +        GF_FREE (rsp.xdata.xdata_val); + +        return 0; +} +  /* Resume function section */  int @@ -3435,6 +3299,67 @@ err:  } +int +server_compound_resume (call_frame_t *frame, xlator_t *bound_xl) +{ +        server_state_t          *state  = NULL; +        gfs3_compound_req       *req    = NULL; +        compound_args_t         *args   = NULL; +        int                     i       = 0; +        int                     ret     = -1; +        int                     length  = 0; +        int                     op_errno = ENOMEM; + +        state = CALL_STATE (frame); +        if (state->resolve.op_ret != 0) { +                ret = state->resolve.op_ret; +                op_errno = state->resolve.op_errno; +                goto err; +        } + +        req = state->req; + +        args = GF_CALLOC (1, sizeof (*args), gf_mt_compound_req_t); +        state->args = args; +        if (!args) +                goto err; + +        length = req->compound_req_array.compound_req_array_len; + +        args->req_list = GF_CALLOC (length, +                                    sizeof (*args->req_list), +                                    gf_mt_default_args_t); +        if (!args->req_list) +                goto err; + +        for (i = 0; i < length; i++) { +                ret = server_populate_compound_request (req, frame, +                                                        &args->req_list[i], +                                                        i); + +                if (ret) { +                        op_errno = ret; +                        ret = -1; +                        goto err; +                } +        } + +        STACK_WIND (frame, server_compound_cbk, +                    bound_xl, bound_xl->fops->compound, +                    args, state->xdata); + +        return 0; +err: +        server_compound_cbk (frame, NULL, frame->this, ret, op_errno, +                             NULL, NULL); + +        for (i = 0; i < length; i++) +                args_wipe (&args->req_list[i]); + +        GF_FREE (args->req_list); +        GF_FREE (args); +        return ret; +}  /* Fop section */  int @@ -6769,6 +6694,85 @@ out:          return ret;  } +int +server3_3_compound (rpcsvc_request_t *req) +{ +        server_state_t      *state = NULL; +        call_frame_t        *frame = NULL; +        gfs3_compound_req    args  = {0,}; +        ssize_t              len    = 0; +        int                  i      = 0; +        int                  ret   = -1; +        int                  op_errno = 0; + +        if (!req) +                return ret; + +        ret = xdr_to_generic (req->msg[0], &args, +                              (xdrproc_t)xdr_gfs3_compound_req); +        if (ret < 0) { +                SERVER_REQ_SET_ERROR (req, ret); +                goto out; +        } + +        frame = get_frame_from_request (req); +        if (!frame) { +                SERVER_REQ_SET_ERROR (req, ret); +                goto out; +        } +        frame->root->op = GF_FOP_COMPOUND; + +        state = CALL_STATE (frame); +        if (!frame->root->client->bound_xl) { +                /* auth failure, request on subvolume without setvolume */ +                SERVER_REQ_SET_ERROR (req, ret); +                goto out; +        } + +        state->req           = &args; +        state->iobref        = iobref_ref (req->iobref); + +        if (len < req->msg[0].iov_len) { +                state->payload_vector[0].iov_base +                        = (req->msg[0].iov_base + len); +                state->payload_vector[0].iov_len +                        = req->msg[0].iov_len - len; +                state->payload_count = 1; +        } + +        for (i = 1; i < req->count; i++) { +                state->payload_vector[state->payload_count++] +                        = req->msg[i]; +        } + +        for (i = 0; i < state->payload_count; i++) { +                state->size += state->payload_vector[i].iov_len; +        } + +        ret = server_get_compound_resolve (state, &args); + +        if (ret) { +                SERVER_REQ_SET_ERROR (req, ret); +                goto out; +        } + +        GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, +                                      state->xdata, +                                      args.xdata.xdata_val, +                                      args.xdata.xdata_len, ret, +                                      op_errno, out); + +        ret = 0; +        resolve_and_resume (frame, server_compound_resume); +out: +        free (args.xdata.xdata_val); + +        if (op_errno) +                SERVER_REQ_SET_ERROR (req, ret); + +        return ret; +} +  rpcsvc_actor_t glusterfs3_3_fop_actors[GLUSTER_FOP_PROCCNT] = {          [GFS3_OP_NULL]         = {"NULL",         GFS3_OP_NULL,         server_null,            NULL, 0, DRC_NA},          [GFS3_OP_STAT]         = {"STAT",         GFS3_OP_STAT,         server3_3_stat,         NULL, 0, DRC_NA}, @@ -6820,8 +6824,9 @@ rpcsvc_actor_t glusterfs3_3_fop_actors[GLUSTER_FOP_PROCCNT] = {          [GFS3_OP_IPC]          = {"IPC",          GFS3_OP_IPC,          server3_3_ipc,          NULL, 0, DRC_NA},          [GFS3_OP_SEEK]         = {"SEEK",         GFS3_OP_SEEK,         server3_3_seek,         NULL, 0, DRC_NA},          [GFS3_OP_LEASE]       =  {"LEASE",        GFS3_OP_LEASE,        server3_3_lease,        NULL, 0, DRC_NA}, -        [GFS3_OP_GETACTIVELK]  = {"GETACTIVELK", GFS3_OP_GETACTIVELK, server3_3_getactivelk, NULL, 0, DRC_NA}, -        [GFS3_OP_SETACTIVELK]  = {"SETACTIVELK", GFS3_OP_SETACTIVELK, server3_3_setactivelk, NULL, 0, DRC_NA}, +        [GFS3_OP_GETACTIVELK]  = {"GETACTIVELK",  GFS3_OP_GETACTIVELK,  server3_3_getactivelk,  NULL, 0, DRC_NA}, +        [GFS3_OP_SETACTIVELK]  = {"SETACTIVELK",  GFS3_OP_SETACTIVELK,  server3_3_setactivelk,  NULL, 0, DRC_NA}, +        [GFS3_OP_COMPOUND]     = {"COMPOUND",     GFS3_OP_COMPOUND,     server3_3_compound,     NULL, 0, DRC_NA},  }; diff --git a/xlators/protocol/server/src/server.h b/xlators/protocol/server/src/server.h index 163cf2b9918..fb9cd45db8a 100644 --- a/xlators/protocol/server/src/server.h +++ b/xlators/protocol/server/src/server.h @@ -23,6 +23,7 @@  #include "timer.h"  #include "client_t.h"  #include "gidcache.h" +#include "defaults.h"  #define DEFAULT_BLOCK_SIZE         4194304   /* 4MB */  #define DEFAULT_VOLUME_FILE_PATH   CONFDIR "/glusterfs.vol" @@ -161,6 +162,16 @@ struct _server_state {          mode_t            umask;          struct gf_lease   lease;          lock_migration_info_t locklist; +        /* required for compound fops */ +        gfs3_compound_req *req; +        /* last length till which iovec for compound +         * writes was processed */ +        int               write_length; +        struct iovec      rsp_vector[MAX_IOVEC]; +        int               rsp_count; +        struct iobuf     *rsp_iobuf; +        struct iobref    *rsp_iobref; +        compound_args_t  *args;  }; @@ -189,4 +200,13 @@ forget_inode_if_no_dentry (inode_t *inode);  int  unserialize_req_locklist (gfs3_setactivelk_req *req,                            lock_migration_info_t *lmi); + +int +serialize_rsp_dirent (gf_dirent_t *entries, gfs3_readdir_rsp *rsp); + +int +serialize_rsp_direntp (gf_dirent_t *entries, gfs3_readdirp_rsp *rsp); + +server_ctx_t* +server_ctx_get (client_t *client, xlator_t *xlator);  #endif /* !_SERVER_H */  | 
