From 60e340481ad5496e920722e8267572fa26cf2822 Mon Sep 17 00:00:00 2001 From: Anuradha Talur Date: Mon, 2 May 2016 00:36:30 +0530 Subject: protocol/server: Implementation of compound fop Change-Id: I981258afa527337dd2ad33eecba7fc8084238e6d BUG: 1303829 Signed-off-by: Anuradha Talur Reviewed-on: http://review.gluster.org/14137 Smoke: Gluster Build System Reviewed-by: Niels de Vos NetBSD-regression: NetBSD Build System CentOS-regression: Gluster Build System --- xlators/protocol/server/src/Makefile.am | 4 +- xlators/protocol/server/src/server-common.c | 472 +++++ xlators/protocol/server/src/server-common.h | 132 ++ xlators/protocol/server/src/server-helpers.c | 2439 ++++++++++++++++++++++++ xlators/protocol/server/src/server-helpers.h | 13 + xlators/protocol/server/src/server-mem-types.h | 1 + xlators/protocol/server/src/server-messages.h | 11 +- xlators/protocol/server/src/server-rpc-fops.c | 491 ++--- xlators/protocol/server/src/server.h | 20 + 9 files changed, 3337 insertions(+), 246 deletions(-) create mode 100644 xlators/protocol/server/src/server-common.c create mode 100644 xlators/protocol/server/src/server-common.h (limited to 'xlators/protocol/server') 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 #include @@ -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 */ -- cgit