diff options
Diffstat (limited to 'xlators/protocol/client/src/client-helpers.c')
-rw-r--r-- | xlators/protocol/client/src/client-helpers.c | 1391 |
1 files changed, 1391 insertions, 0 deletions
diff --git a/xlators/protocol/client/src/client-helpers.c b/xlators/protocol/client/src/client-helpers.c index 804b4028803..e78242ffe65 100644 --- a/xlators/protocol/client/src/client-helpers.c +++ b/xlators/protocol/client/src/client-helpers.c @@ -11,6 +11,9 @@ #include "client.h" #include "fd.h" #include "client-messages.h" +#include "client-common.h" +#include "compat-errno.h" +#include "common-utils.h" int client_fd_lk_list_empty (fd_lk_ctx_t *lk_ctx, gf_boolean_t try_lock) @@ -132,8 +135,14 @@ client_local_wipe (clnt_local_t *local) iobref_unref (local->iobref); } + if (local->iobref2) { + iobref_unref (local->iobref2); + } + GF_FREE (local->name); + local->compound_args = NULL; + mem_put (local); } @@ -359,3 +368,1385 @@ client_fd_fop_prepare_local (call_frame_t *frame, fd_t *fd, int64_t remote_fd) out: return ret; } + +int +client_process_response (call_frame_t *frame, xlator_t *this, + struct rpc_req *req, gfs3_compound_rsp *rsp, + compound_args_cbk_t *args_cbk, + int index) +{ + int ret = 0; + default_args_cbk_t *this_args_cbk = &args_cbk->rsp_list[index]; + clnt_local_t *local = frame->local; + compound_rsp *this_rsp = NULL; + compound_args_t *args = local->compound_args; + void *data = NULL; + + this_rsp = &rsp->compound_rsp_array.compound_rsp_array_val[index]; + args_cbk->enum_list[index] = this_rsp->fop_enum; + + switch (args_cbk->enum_list[index]) { + + case GF_FOP_STAT: + { + gfs3_stat_rsp *tmp_rsp = NULL; + tmp_rsp = &this_rsp->compound_rsp_u.compound_stat_rsp; + + client_post_stat (this, tmp_rsp, + &this_args_cbk->stat, &this_args_cbk->xdata); + + CLIENT_POST_FOP_TYPE (stat, this_rsp, this_args_cbk, + &this_args_cbk->stat, + this_args_cbk->xdata); + break; + } + case GF_FOP_READLINK: + { + gfs3_readlink_rsp *tmp_rsp = NULL; + tmp_rsp = &this_rsp->compound_rsp_u.compound_readlink_rsp; + + client_post_readlink (this, tmp_rsp, + &this_args_cbk->stat, &this_args_cbk->xdata); + CLIENT_POST_FOP_TYPE (readlink, this_rsp, this_args_cbk, + tmp_rsp->path, + &this_args_cbk->stat, + this_args_cbk->xdata); + break; + } + case GF_FOP_MKNOD: + { + gfs3_mknod_rsp *tmp_rsp = NULL; + tmp_rsp = &this_rsp->compound_rsp_u.compound_mknod_rsp; + + client_post_mknod (this, tmp_rsp, + &this_args_cbk->stat, + &this_args_cbk->preparent, + &this_args_cbk->postparent, + &this_args_cbk->xdata); + CLIENT_POST_FOP_TYPE (mknod, this_rsp, this_args_cbk, + local->loc.inode, + &this_args_cbk->stat, + &this_args_cbk->preparent, + &this_args_cbk->postparent, + this_args_cbk->xdata); + break; + } + case GF_FOP_MKDIR: + { + gfs3_mkdir_rsp *tmp_rsp = NULL; + tmp_rsp = &this_rsp->compound_rsp_u.compound_mkdir_rsp; + + client_post_mkdir (this, + tmp_rsp, + &this_args_cbk->stat, + &this_args_cbk->preparent, + &this_args_cbk->postparent, + &this_args_cbk->xdata); + CLIENT_POST_FOP_TYPE (mkdir, this_rsp, this_args_cbk, + local->loc.inode, + &this_args_cbk->stat, + &this_args_cbk->preparent, + &this_args_cbk->postparent, + this_args_cbk->xdata); + break; + } + case GF_FOP_UNLINK: + { + gfs3_unlink_rsp *tmp_rsp = NULL; + tmp_rsp = &this_rsp->compound_rsp_u.compound_unlink_rsp; + + client_post_unlink (this, + tmp_rsp, + &this_args_cbk->preparent, + &this_args_cbk->postparent, + &this_args_cbk->xdata); + CLIENT_POST_FOP_TYPE (unlink, this_rsp, this_args_cbk, + &this_args_cbk->preparent, + &this_args_cbk->postparent, + this_args_cbk->xdata); + break; + } + case GF_FOP_RMDIR: + { + gfs3_rmdir_rsp *tmp_rsp = NULL; + tmp_rsp = &this_rsp->compound_rsp_u.compound_rmdir_rsp; + + client_post_rmdir (this, tmp_rsp, + &this_args_cbk->preparent, + &this_args_cbk->postparent, + &this_args_cbk->xdata); + CLIENT_POST_FOP_TYPE (rmdir, this_rsp, this_args_cbk, + &this_args_cbk->preparent, + &this_args_cbk->postparent, + this_args_cbk->xdata); + break; + } + case GF_FOP_SYMLINK: + { + gfs3_symlink_rsp *tmp_rsp = NULL; + tmp_rsp = &this_rsp->compound_rsp_u.compound_symlink_rsp; + + client_post_symlink (this, tmp_rsp, + &this_args_cbk->stat, + &this_args_cbk->preparent, + &this_args_cbk->postparent, + &this_args_cbk->xdata); + CLIENT_POST_FOP_TYPE (symlink, this_rsp, this_args_cbk, NULL, + &this_args_cbk->stat, + &this_args_cbk->preparent, + &this_args_cbk->postparent, + this_args_cbk->xdata); + break; + } + case GF_FOP_RENAME: + { + gfs3_rename_rsp *tmp_rsp = NULL; + tmp_rsp = &this_rsp->compound_rsp_u.compound_rename_rsp; + + client_post_rename (this, tmp_rsp, + &this_args_cbk->stat, + &this_args_cbk->preparent, + &this_args_cbk->postparent, + &this_args_cbk->preparent2, + &this_args_cbk->postparent2, + &this_args_cbk->xdata); + CLIENT_POST_FOP_TYPE (rename, this_rsp, this_args_cbk, + &this_args_cbk->stat, + &this_args_cbk->preparent, + &this_args_cbk->postparent, + &this_args_cbk->preparent2, + &this_args_cbk->postparent2, + this_args_cbk->xdata); + break; + } + case GF_FOP_LINK: + { + gfs3_link_rsp *tmp_rsp = NULL; + tmp_rsp = &this_rsp->compound_rsp_u.compound_link_rsp; + + client_post_link (this, tmp_rsp, + &this_args_cbk->stat, + &this_args_cbk->preparent, + &this_args_cbk->postparent, + &this_args_cbk->xdata); + CLIENT_POST_FOP_TYPE (link, this_rsp, this_args_cbk, NULL, + &this_args_cbk->stat, + &this_args_cbk->preparent, + &this_args_cbk->postparent, + this_args_cbk->xdata); + break; + } + case GF_FOP_TRUNCATE: + { + gfs3_truncate_rsp *tmp_rsp = NULL; + tmp_rsp = &this_rsp->compound_rsp_u.compound_truncate_rsp; + + client_post_truncate (this, tmp_rsp, + &this_args_cbk->prestat, + &this_args_cbk->poststat, + &this_args_cbk->xdata); + CLIENT_POST_FOP_TYPE (truncate, this_rsp, this_args_cbk, + &this_args_cbk->prestat, + &this_args_cbk->poststat, + this_args_cbk->xdata); + break; + } + case GF_FOP_OPEN: + { + gfs3_open_rsp *tmp_rsp = NULL; + tmp_rsp = &this_rsp->compound_rsp_u.compound_open_rsp; + + client_post_open (this, tmp_rsp, + &this_args_cbk->xdata); + CLIENT_POST_FOP_TYPE (open, this_rsp, this_args_cbk, + local->fd, + this_args_cbk->xdata); + if (-1 != this_args_cbk->op_ret) + ret = client_add_fd_to_saved_fds (this, local->fd, + &local->loc, + args->req_list[index].flags, + tmp_rsp->fd, + 0); + break; + } + case GF_FOP_READ: + { + gfs3_read_rsp *tmp_rsp = NULL; + tmp_rsp = &this_rsp->compound_rsp_u.compound_read_rsp; + + client_post_readv (this, tmp_rsp, &this_args_cbk->iobref, + req->rsp_iobref, + &this_args_cbk->stat, + this_args_cbk->vector, &req->rsp[1], + &this_args_cbk->count, + &this_args_cbk->xdata); + + /* Each read should be given read response that only + * corresponds to its request. + * Modify the iovecs accordingly. + * After each read, store the length of data already read + * so that the next ones can continue from there. + */ + if (local->read_length) { + this_args_cbk->vector[0].iov_base += local->read_length; + local->read_length += tmp_rsp->op_ret; + } else { + local->read_length = tmp_rsp->op_ret; + } + + args_readv_cbk_store (this_args_cbk, tmp_rsp->op_ret, + gf_error_to_errno (tmp_rsp->op_errno), + this_args_cbk->vector, + this_args_cbk->count, + &this_args_cbk->stat, + this_args_cbk->iobref, + this_args_cbk->xdata); + + if (tmp_rsp->op_ret >= 0) + if (local->attempt_reopen) + client_attempt_reopen (local->fd, this); + + break; + } + case GF_FOP_WRITE: + { + gfs3_write_rsp *tmp_rsp = NULL; + tmp_rsp = &this_rsp->compound_rsp_u.compound_write_rsp; + + client_post_writev (this, tmp_rsp, &this_args_cbk->prestat, + &this_args_cbk->poststat, + &this_args_cbk->xdata); + args_writev_cbk_store (this_args_cbk, tmp_rsp->op_ret, + gf_error_to_errno (tmp_rsp->op_errno), + &this_args_cbk->prestat, + &this_args_cbk->poststat, + this_args_cbk->xdata); + + if (tmp_rsp->op_ret == 0) + if (local->attempt_reopen) + client_attempt_reopen (local->fd, this); + break; + } + case GF_FOP_STATFS: + { + gfs3_statfs_rsp *tmp_rsp = NULL; + tmp_rsp = &this_rsp->compound_rsp_u.compound_statfs_rsp; + + client_post_statfs (this, tmp_rsp, + &this_args_cbk->statvfs, + &this_args_cbk->xdata); + + CLIENT_POST_FOP_TYPE (statfs, this_rsp, this_args_cbk, + &this_args_cbk->statvfs, + this_args_cbk->xdata); + break; + } + case GF_FOP_FLUSH: + { + gf_common_rsp *tmp_rsp = NULL; + tmp_rsp = &this_rsp->compound_rsp_u.compound_flush_rsp; + + client_post_flush (this, tmp_rsp, + &this_args_cbk->xdata); + + CLIENT_POST_FOP (flush, this_rsp, this_args_cbk, + this_args_cbk->xdata); + if (this_args_cbk->op_ret >= 0 && !fd_is_anonymous (local->fd)) { + /* Delete all saved locks of the owner issuing flush */ + ret = delete_granted_locks_owner (local->fd, &local->owner); + gf_msg_trace (this->name, 0, + "deleting locks of owner (%s) returned %d", + lkowner_utoa (&local->owner), ret); + } + break; + } + case GF_FOP_FSYNC: + { + gfs3_fsync_rsp *tmp_rsp = NULL; + tmp_rsp = &this_rsp->compound_rsp_u.compound_fsync_rsp; + + client_post_fsync (this, tmp_rsp, + &this_args_cbk->prestat, + &this_args_cbk->poststat, + &this_args_cbk->xdata); + + CLIENT_POST_FOP_TYPE (fsync, this_rsp, this_args_cbk, + &this_args_cbk->prestat, + &this_args_cbk->poststat, + this_args_cbk->xdata); + break; + } + case GF_FOP_SETXATTR: + { + gf_common_rsp *tmp_rsp = NULL; + tmp_rsp = &this_rsp->compound_rsp_u.compound_setxattr_rsp; + + client_post_setxattr (this, tmp_rsp, + &this_args_cbk->xdata); + + CLIENT_POST_FOP (setxattr, this_rsp, this_args_cbk, + this_args_cbk->xdata); + break; + } + case GF_FOP_GETXATTR: + { + gfs3_getxattr_rsp *tmp_rsp = NULL; + tmp_rsp = &this_rsp->compound_rsp_u.compound_getxattr_rsp; + + client_post_getxattr (this, tmp_rsp, + &this_args_cbk->xattr, + &this_args_cbk->xdata); + + CLIENT_POST_FOP_TYPE (getxattr, this_rsp, this_args_cbk, + this_args_cbk->xattr, + this_args_cbk->xdata); + break; + } + case GF_FOP_REMOVEXATTR: + { + gf_common_rsp *tmp_rsp = NULL; + tmp_rsp = &this_rsp->compound_rsp_u.compound_removexattr_rsp; + + client_post_removexattr (this, tmp_rsp, + &this_args_cbk->xdata); + + CLIENT_POST_FOP (removexattr, this_rsp, this_args_cbk, + this_args_cbk->xdata); + break; + } + case GF_FOP_OPENDIR: + { + gfs3_opendir_rsp *tmp_rsp = NULL; + tmp_rsp = &this_rsp->compound_rsp_u.compound_opendir_rsp; + + client_post_opendir (this, tmp_rsp, + &this_args_cbk->xdata); + + CLIENT_POST_FOP_TYPE (opendir, this_rsp, this_args_cbk, + local->fd, + this_args_cbk->xdata); + if (-1 != this_args_cbk->op_ret) + ret = client_add_fd_to_saved_fds (this, local->fd, + &local->loc, + args->req_list[index].flags, + tmp_rsp->fd, 0); + break; + } + case GF_FOP_FSYNCDIR: + { + gf_common_rsp *tmp_rsp = NULL; + tmp_rsp = &this_rsp->compound_rsp_u.compound_fsyncdir_rsp; + + client_post_fsyncdir (this, tmp_rsp, + &this_args_cbk->xdata); + + CLIENT_POST_FOP (fsyncdir, this_rsp, this_args_cbk, + this_args_cbk->xdata); + break; + } + case GF_FOP_ACCESS: + { + gf_common_rsp *tmp_rsp = NULL; + tmp_rsp = &this_rsp->compound_rsp_u.compound_access_rsp; + + client_post_access (this, tmp_rsp, + &this_args_cbk->xdata); + + CLIENT_POST_FOP (access, this_rsp, this_args_cbk, + this_args_cbk->xdata); + break; + } + case GF_FOP_CREATE: + { + gfs3_create_rsp *tmp_rsp = NULL; + tmp_rsp = &this_rsp->compound_rsp_u.compound_create_rsp; + + client_post_create (this, tmp_rsp, + &this_args_cbk->stat, + &this_args_cbk->preparent, + &this_args_cbk->postparent, + local, + &this_args_cbk->xdata); + CLIENT_POST_FOP_TYPE (create, this_rsp, this_args_cbk, + local->fd, + local->loc.inode, + &this_args_cbk->stat, + &this_args_cbk->preparent, + &this_args_cbk->postparent, + this_args_cbk->xdata); + if (-1 != this_args_cbk->op_ret) + ret = client_add_fd_to_saved_fds (this, local->fd, + &local->loc, + args->req_list[index].flags, + tmp_rsp->fd, 0); + break; + } + case GF_FOP_FTRUNCATE: + { + gfs3_ftruncate_rsp *tmp_rsp = NULL; + tmp_rsp = &this_rsp->compound_rsp_u.compound_ftruncate_rsp; + + client_post_ftruncate (this, tmp_rsp, + &this_args_cbk->prestat, + &this_args_cbk->poststat, + &this_args_cbk->xdata); + CLIENT_POST_FOP_TYPE (ftruncate, this_rsp, this_args_cbk, + &this_args_cbk->prestat, + &this_args_cbk->poststat, + this_args_cbk->xdata); + break; + } + case GF_FOP_FSTAT: + { + gfs3_fstat_rsp *tmp_rsp = NULL; + tmp_rsp = &this_rsp->compound_rsp_u.compound_fstat_rsp; + + client_post_fstat (this, tmp_rsp, + &this_args_cbk->stat, &this_args_cbk->xdata); + + CLIENT_POST_FOP_TYPE (fstat, this_rsp, this_args_cbk, + &this_args_cbk->stat, + this_args_cbk->xdata); + break; + } + case GF_FOP_LK: + { + gfs3_lk_rsp *tmp_rsp = NULL; + tmp_rsp = &this_rsp->compound_rsp_u.compound_lk_rsp; + + client_post_lk (this, tmp_rsp, + &this_args_cbk->lock, + &this_args_cbk->xdata); + + CLIENT_POST_FOP_TYPE (lk, this_rsp, this_args_cbk, + &this_args_cbk->lock, + this_args_cbk->xdata); + break; + } + case GF_FOP_LOOKUP: + { + gfs3_lookup_rsp *tmp_rsp = NULL; + tmp_rsp = &this_rsp->compound_rsp_u.compound_lookup_rsp; + + client_post_lookup (this, tmp_rsp, + &this_args_cbk->stat, + &this_args_cbk->postparent, + &this_args_cbk->xdata); + CLIENT_POST_FOP_TYPE (lookup, this_rsp, this_args_cbk, + local->loc.inode, + &this_args_cbk->stat, + this_args_cbk->xdata, + &this_args_cbk->postparent); + break; + } + case GF_FOP_READDIR: + { + gfs3_readdir_rsp *tmp_rsp = NULL; + tmp_rsp = &this_rsp->compound_rsp_u.compound_readdir_rsp; + + client_post_readdir (this, tmp_rsp, + &this_args_cbk->entries, &this_args_cbk->xdata); + + CLIENT_POST_FOP_TYPE (readdir, this_rsp, this_args_cbk, + &this_args_cbk->entries, this_args_cbk->xdata); + break; + } + case GF_FOP_INODELK: + { + gf_common_rsp *tmp_rsp = NULL; + tmp_rsp = &this_rsp->compound_rsp_u.compound_inodelk_rsp; + + client_post_inodelk (this, tmp_rsp, + &this_args_cbk->xdata); + + CLIENT_POST_FOP (inodelk, this_rsp, this_args_cbk, + this_args_cbk->xdata); + break; + } + case GF_FOP_FINODELK: + { + gf_common_rsp *tmp_rsp = NULL; + tmp_rsp = &this_rsp->compound_rsp_u.compound_finodelk_rsp; + + client_post_finodelk (this, tmp_rsp, + &this_args_cbk->xdata); + + CLIENT_POST_FOP (finodelk, this_rsp, this_args_cbk, + this_args_cbk->xdata); + if (tmp_rsp->op_ret == 0) + if (local->attempt_reopen) + client_attempt_reopen (local->fd, this); + break; + } + case GF_FOP_ENTRYLK: + { + gf_common_rsp *tmp_rsp = NULL; + tmp_rsp = &this_rsp->compound_rsp_u.compound_entrylk_rsp; + + client_post_entrylk (this, tmp_rsp, + &this_args_cbk->xdata); + + CLIENT_POST_FOP (entrylk, this_rsp, this_args_cbk, + this_args_cbk->xdata); + break; + } + case GF_FOP_FENTRYLK: + { + gf_common_rsp *tmp_rsp = NULL; + tmp_rsp = &this_rsp->compound_rsp_u.compound_fentrylk_rsp; + + client_post_fentrylk (this, tmp_rsp, + &this_args_cbk->xdata); + + CLIENT_POST_FOP (fentrylk, this_rsp, this_args_cbk, + this_args_cbk->xdata); + break; + } + case GF_FOP_XATTROP: + { + gfs3_xattrop_rsp *tmp_rsp = NULL; + tmp_rsp = &this_rsp->compound_rsp_u.compound_xattrop_rsp; + + client_post_xattrop (this, tmp_rsp, + &this_args_cbk->xattr, + &this_args_cbk->xdata); + + CLIENT_POST_FOP_TYPE (xattrop, this_rsp, this_args_cbk, + this_args_cbk->xattr, + this_args_cbk->xdata); + break; + } + case GF_FOP_FXATTROP: + { + gfs3_fxattrop_rsp *tmp_rsp = NULL; + tmp_rsp = &this_rsp->compound_rsp_u.compound_fxattrop_rsp; + + client_post_fxattrop (this, tmp_rsp, + &this_args_cbk->xattr, + &this_args_cbk->xdata); + + CLIENT_POST_FOP_TYPE (fxattrop, this_rsp, this_args_cbk, + this_args_cbk->xattr, + this_args_cbk->xdata); + if (rsp->op_ret == 0) + if (local->attempt_reopen) + client_attempt_reopen (local->fd, this); + break; + } + case GF_FOP_FGETXATTR: + { + gfs3_fgetxattr_rsp *tmp_rsp = NULL; + tmp_rsp = &this_rsp->compound_rsp_u.compound_fgetxattr_rsp; + + client_post_fgetxattr (this, tmp_rsp, + &this_args_cbk->xattr, + &this_args_cbk->xdata); + + CLIENT_POST_FOP_TYPE (fgetxattr, this_rsp, this_args_cbk, + this_args_cbk->xattr, + this_args_cbk->xdata); + break; + } + case GF_FOP_FSETXATTR: + { + gf_common_rsp *tmp_rsp = NULL; + tmp_rsp = &this_rsp->compound_rsp_u.compound_fsetxattr_rsp; + + client_post_fsetxattr (this, tmp_rsp, + &this_args_cbk->xdata); + + CLIENT_POST_FOP (fsetxattr, this_rsp, this_args_cbk, + this_args_cbk->xdata); + break; + } + case GF_FOP_RCHECKSUM: + { + gfs3_rchecksum_rsp *tmp_rsp = NULL; + tmp_rsp = &this_rsp->compound_rsp_u.compound_rchecksum_rsp; + + client_post_rchecksum (this, tmp_rsp, + &this_args_cbk->xdata); + + break; + CLIENT_POST_FOP_TYPE (rchecksum, this_rsp, this_args_cbk, + tmp_rsp->weak_checksum, + (uint8_t*)tmp_rsp->strong_checksum.strong_checksum_val, + this_args_cbk->xdata); + break; + } + case GF_FOP_SETATTR: + { + gfs3_setattr_rsp *tmp_rsp = NULL; + tmp_rsp = &this_rsp->compound_rsp_u.compound_setattr_rsp; + + client_post_setattr (this, tmp_rsp, + &this_args_cbk->prestat, + &this_args_cbk->poststat, + &this_args_cbk->xdata); + + CLIENT_POST_FOP_TYPE (setattr, this_rsp, this_args_cbk, + &this_args_cbk->prestat, + &this_args_cbk->poststat, + this_args_cbk->xdata); + break; + } + case GF_FOP_FSETATTR: + { + gfs3_fsetattr_rsp *tmp_rsp = NULL; + tmp_rsp = &this_rsp->compound_rsp_u.compound_fsetattr_rsp; + + client_post_fsetattr (this, tmp_rsp, + &this_args_cbk->prestat, + &this_args_cbk->poststat, + &this_args_cbk->xdata); + + CLIENT_POST_FOP_TYPE (fsetattr, this_rsp, this_args_cbk, + &this_args_cbk->prestat, + &this_args_cbk->poststat, + this_args_cbk->xdata); + break; + } + case GF_FOP_READDIRP: + { + gfs3_readdirp_rsp *tmp_rsp = NULL; + tmp_rsp = &this_rsp->compound_rsp_u.compound_readdirp_rsp; + + client_post_readdirp (this, tmp_rsp, local->fd, + &this_args_cbk->entries, + &this_args_cbk->xdata); + + CLIENT_POST_FOP_TYPE (readdirp, this_rsp, this_args_cbk, + &this_args_cbk->entries, + this_args_cbk->xdata); + break; + } + case GF_FOP_FREMOVEXATTR: + { + gf_common_rsp *tmp_rsp = NULL; + tmp_rsp = &this_rsp->compound_rsp_u.compound_fremovexattr_rsp; + + client_post_fremovexattr (this, tmp_rsp, + &this_args_cbk->xdata); + + CLIENT_POST_FOP (fremovexattr, this_rsp, this_args_cbk, + this_args_cbk->xdata); + break; + } + case GF_FOP_FALLOCATE: + { + gfs3_fallocate_rsp *tmp_rsp = NULL; + tmp_rsp = &this_rsp->compound_rsp_u.compound_fallocate_rsp; + + client_post_fallocate (this, tmp_rsp, + &this_args_cbk->prestat, + &this_args_cbk->poststat, + &this_args_cbk->xdata); + + CLIENT_POST_FOP_TYPE (fallocate, this_rsp, this_args_cbk, + &this_args_cbk->prestat, + &this_args_cbk->poststat, + this_args_cbk->xdata); + break; + } + case GF_FOP_DISCARD: + { + gfs3_discard_rsp *tmp_rsp = NULL; + tmp_rsp = &this_rsp->compound_rsp_u.compound_discard_rsp; + + client_post_discard (this, tmp_rsp, + &this_args_cbk->prestat, + &this_args_cbk->poststat, + &this_args_cbk->xdata); + + CLIENT_POST_FOP_TYPE (discard, this_rsp, this_args_cbk, + &this_args_cbk->prestat, + &this_args_cbk->poststat, + this_args_cbk->xdata); + break; + } + case GF_FOP_ZEROFILL: + { + gfs3_zerofill_rsp *tmp_rsp = NULL; + tmp_rsp = &this_rsp->compound_rsp_u.compound_zerofill_rsp; + + client_post_zerofill (this, tmp_rsp, + &this_args_cbk->prestat, + &this_args_cbk->poststat, + &this_args_cbk->xdata); + + CLIENT_POST_FOP_TYPE (zerofill, this_rsp, this_args_cbk, + &this_args_cbk->prestat, + &this_args_cbk->poststat, + this_args_cbk->xdata); + break; + } + case GF_FOP_IPC: + { + gfs3_ipc_rsp *tmp_rsp = NULL; + tmp_rsp = &this_rsp->compound_rsp_u.compound_ipc_rsp; + + client_post_ipc (this, tmp_rsp, &this_args_cbk->xdata); + + CLIENT_POST_FOP_TYPE (ipc, this_rsp, this_args_cbk, + this_args_cbk->xdata); + break; + } + case GF_FOP_SEEK: + { + gfs3_seek_rsp *tmp_rsp = NULL; + tmp_rsp = &this_rsp->compound_rsp_u.compound_seek_rsp; + + client_post_seek (this, tmp_rsp, &this_args_cbk->xdata); + + CLIENT_POST_FOP_TYPE (seek, this_rsp, this_args_cbk, + tmp_rsp->offset, + this_args_cbk->xdata); + break; + } + case GF_FOP_LEASE: + { + gfs3_lease_rsp *tmp_rsp = NULL; + tmp_rsp = &this_rsp->compound_rsp_u.compound_lease_rsp; + + client_post_lease (this, tmp_rsp, &this_args_cbk->lease, + &this_args_cbk->xdata); + + CLIENT_POST_FOP_TYPE (lease, this_rsp, this_args_cbk, + &this_args_cbk->lease, + this_args_cbk->xdata); + break; + } + default: + return -ENOTSUP; + } + return 0; +} + +int +client_handle_fop_requirements (xlator_t *this, call_frame_t *frame, + gfs3_compound_req *req, + clnt_local_t *local, + struct iobref *req_iobref, + struct iobref *rsp_iobref, + struct iovec *req_vector, + struct iovec *rsp_vector, int *req_count, + int *rsp_count, default_args_t *args, + int fop_enum, int index) +{ + int ret = 0; + int op_errno = ENOMEM; + struct iobuf *rsp_iobuf = NULL; + int64_t remote_fd = -1; + compound_req *this_req = &req->compound_req_array.compound_req_array_val[index]; + + this_req->fop_enum = fop_enum; + + switch (fop_enum) { + case GF_FOP_STAT: + CLIENT_PRE_FOP (stat, this, + &this_req->compound_req_u.compound_stat_req, + op_errno, out, + &args->loc, args->xdata); + break; + case GF_FOP_READLINK: + CLIENT_PRE_FOP (readlink, this, + &this_req->compound_req_u.compound_readlink_req, + op_errno, out, + &args->loc, args->size, args->xdata); + break; + case GF_FOP_MKNOD: + CLIENT_PRE_FOP (mknod, this, + &this_req->compound_req_u.compound_mknod_req, + op_errno, out, + &args->loc, args->mode, args->rdev, + args->umask, args->xdata); + if (!&local->loc) { + loc_copy (&local->loc, &args->loc); + loc_path (&local->loc, NULL); + } + break; + case GF_FOP_MKDIR: + CLIENT_PRE_FOP (mkdir, this, + &this_req->compound_req_u.compound_mkdir_req, + op_errno, out, + &args->loc, args->mode, + args->umask, args->xdata); + if (!&local->loc) { + loc_copy (&local->loc, &args->loc); + loc_path (&local->loc, NULL); + } + break; + case GF_FOP_UNLINK: + CLIENT_PRE_FOP (unlink, this, + &this_req->compound_req_u.compound_unlink_req, + op_errno, out, + &args->loc, args->xflag, args->xdata); + break; + case GF_FOP_RMDIR: + CLIENT_PRE_FOP (rmdir, this, + &this_req->compound_req_u.compound_rmdir_req, + op_errno, out, + &args->loc, args->flags, args->xdata); + break; + case GF_FOP_SYMLINK: + CLIENT_PRE_FOP (symlink, this, + &this_req->compound_req_u.compound_symlink_req, + op_errno, out, + &args->loc, args->linkname, args->umask, + args->xdata); + if (!&local->loc) { + loc_copy (&local->loc, &args->loc); + loc_path (&local->loc, NULL); + } + break; + case GF_FOP_RENAME: + CLIENT_PRE_FOP (rename, this, + &this_req->compound_req_u.compound_rename_req, + op_errno, out, + &args->loc, &args->loc2, args->xdata); + break; + case GF_FOP_LINK: + CLIENT_PRE_FOP (link, this, + &this_req->compound_req_u.compound_link_req, + op_errno, out, + &args->loc, &args->loc2, args->xdata); + break; + case GF_FOP_TRUNCATE: + CLIENT_PRE_FOP (truncate, this, + &this_req->compound_req_u.compound_truncate_req, + op_errno, out, + &args->loc, args->offset, args->xdata); + break; + case GF_FOP_OPEN: + CLIENT_PRE_FOP (open, this, + &this_req->compound_req_u.compound_open_req, + op_errno, out, + &args->loc, args->fd, args->flags, + args->xdata); + if (!local->fd) + local->fd = fd_ref (args->fd); + break; + case GF_FOP_READ: + op_errno = client_pre_readv (this, + &this_req->compound_req_u.compound_read_req, + args->fd, args->size, args->offset, + args->flags, args->xdata); + + if (op_errno) { + op_errno = -op_errno; + goto out; + } + if (!local->fd) + local->fd = fd_ref (args->fd); + local->attempt_reopen = client_is_reopen_needed + (args->fd, this, remote_fd); + rsp_iobuf = iobuf_get2 (this->ctx->iobuf_pool, args->size); + if (rsp_iobuf == NULL) { + op_errno = ENOMEM; + goto out; + } + + if (!rsp_iobref) { + rsp_iobref = iobref_new (); + if (rsp_iobref == NULL) { + op_errno = ENOMEM; + goto out; + } + } + + iobref_add (rsp_iobref, rsp_iobuf); + iobuf_unref (rsp_iobuf); + + if (*rsp_count + 1 >= MAX_IOVEC) { + op_errno = ENOMEM; + goto out; + } + rsp_vector[*rsp_count].iov_base = iobuf_ptr (rsp_iobuf); + rsp_vector[*rsp_count].iov_len = iobuf_pagesize (rsp_iobuf); + rsp_iobuf = NULL; + if (args->size > rsp_vector[*rsp_count].iov_len) { + gf_msg (this->name, GF_LOG_WARNING, ENOMEM, + PC_MSG_NO_MEMORY, + "read-size (%lu) is bigger than iobuf size " + "(%lu)", + (unsigned long)args->size, + (unsigned long)rsp_vector[*rsp_count].iov_len); + op_errno = EINVAL; + goto out; + } + *rsp_count += 1; + + break; + case GF_FOP_WRITE: + op_errno = client_pre_writev (this, + &this_req->compound_req_u.compound_write_req, + args->fd, args->count, args->offset, + args->flags, args->xdata); + + if (op_errno) { + op_errno = -op_errno; + goto out; + } + if (!local->fd) + local->fd = fd_ref (args->fd); + local->attempt_reopen = client_is_reopen_needed + (args->fd, this, remote_fd); + + if (*req_count + 1 >= MAX_IOVEC) { + op_errno = ENOMEM; + goto out; + } + memcpy (&req_vector[*req_count], args->vector, + (args->count * sizeof(req_vector[0]))); + *req_count += args->count; + + if (!req_iobref) + req_iobref = args->iobref; + else + if (iobref_merge (req_iobref, args->iobref)) + goto out; + break; + case GF_FOP_STATFS: + CLIENT_PRE_FOP (statfs, this, + &this_req->compound_req_u.compound_statfs_req, + op_errno, out, + &args->loc, args->xdata); + break; + case GF_FOP_FLUSH: + CLIENT_PRE_FOP (flush, this, + &this_req->compound_req_u.compound_flush_req, + op_errno, out, + args->fd, args->xdata); + if (!local->fd) + local->fd = fd_ref (args->fd); + local->owner = frame->root->lk_owner; + break; + case GF_FOP_FSYNC: + CLIENT_PRE_FOP (fsync, this, + &this_req->compound_req_u.compound_fsync_req, + op_errno, out, + args->fd, args->datasync, args->xdata); + break; + case GF_FOP_SETXATTR: + CLIENT_PRE_FOP (setxattr, this, + &this_req->compound_req_u.compound_setxattr_req, + op_errno, out, + &args->loc, args->xattr, args->flags, + args->xdata); + break; + case GF_FOP_GETXATTR: + CLIENT_PRE_FOP (getxattr, this, + &this_req->compound_req_u.compound_getxattr_req, + op_errno, out, + &args->loc, args->name, args->xdata); + if (!&local->loc) { + loc_copy (&local->loc, &args->loc); + loc_path (&local->loc, NULL); + } + break; + case GF_FOP_REMOVEXATTR: + CLIENT_PRE_FOP (removexattr, this, + &this_req->compound_req_u.compound_removexattr_req, + op_errno, out, + &args->loc, args->name, args->xdata); + break; + case GF_FOP_OPENDIR: + CLIENT_PRE_FOP (opendir, this, + &this_req->compound_req_u.compound_opendir_req, + op_errno, out, + &args->loc, args->fd, args->xdata); + if (!local->fd) + local->fd = fd_ref (args->fd); + if (!&local->loc) { + loc_copy (&local->loc, &args->loc); + loc_path (&local->loc, NULL); + } + break; + case GF_FOP_FSYNCDIR: + CLIENT_PRE_FOP (fsyncdir, this, + &this_req->compound_req_u.compound_fsyncdir_req, + op_errno, out, + args->fd, args->datasync, args->xdata); + break; + case GF_FOP_ACCESS: + CLIENT_PRE_FOP (access, this, + &this_req->compound_req_u.compound_access_req, + op_errno, out, + &args->loc, args->mask, args->xdata); + break; + case GF_FOP_CREATE: + CLIENT_PRE_FOP (create, this, + &this_req->compound_req_u.compound_create_req, + op_errno, out, + &args->loc, args->fd, args->mode, args->flags, + args->umask, args->xdata); + if (!local->fd) + local->fd = fd_ref (args->fd); + + if (!&local->loc) { + loc_copy (&local->loc, &args->loc); + loc_path (&local->loc, NULL); + } + break; + case GF_FOP_FTRUNCATE: + CLIENT_PRE_FOP (ftruncate, this, + &this_req->compound_req_u.compound_ftruncate_req, + op_errno, out, + args->fd, args->offset, args->xdata); + break; + case GF_FOP_FSTAT: + CLIENT_PRE_FOP (fstat, this, + &this_req->compound_req_u.compound_fstat_req, + op_errno, out, + args->fd, args->xdata); + break; + case GF_FOP_LK: + CLIENT_PRE_FOP (lk, this, + &this_req->compound_req_u.compound_lk_req, + op_errno, out, + args->cmd, &args->lock, args->fd, args->xdata); + if (!local->fd) + local->fd = fd_ref (args->fd); + local->owner = frame->root->lk_owner; + break; + case GF_FOP_LOOKUP: + CLIENT_PRE_FOP (lookup, this, + &this_req->compound_req_u.compound_lookup_req, + op_errno, out, + &args->loc, args->xdata); + if (!&local->loc) { + loc_copy (&local->loc, &args->loc); + loc_path (&local->loc, NULL); + } + break; + case GF_FOP_READDIR: + CLIENT_PRE_FOP (readdir, this, + &this_req->compound_req_u.compound_readdir_req, + op_errno, out, + args->fd, args->size, args->offset, + args->xdata); + break; + case GF_FOP_INODELK: + CLIENT_PRE_FOP (inodelk, this, + &this_req->compound_req_u.compound_inodelk_req, + op_errno, out, + &args->loc, args->cmd, &args->lock, + args->volume, args->xdata); + break; + case GF_FOP_FINODELK: + CLIENT_PRE_FOP (finodelk, this, + &this_req->compound_req_u.compound_finodelk_req, + op_errno, out, + args->fd, args->cmd, &args->lock, + args->volume, args->xdata); + if (!local->fd) + local->fd = fd_ref (args->fd); + local->attempt_reopen = client_is_reopen_needed + (args->fd, this, remote_fd); + break; + case GF_FOP_ENTRYLK: + CLIENT_PRE_FOP (entrylk, this, + &this_req->compound_req_u.compound_entrylk_req, + op_errno, out, + &args->loc, args->entrylkcmd, + args->entrylktype, args->volume, + args->name, args->xdata); + break; + case GF_FOP_FENTRYLK: + CLIENT_PRE_FOP (fentrylk, this, + &this_req->compound_req_u.compound_fentrylk_req, + op_errno, out, + args->fd, args->entrylkcmd, + args->entrylktype, args->volume, + args->name, args->xdata); + break; + case GF_FOP_XATTROP: + CLIENT_PRE_FOP (xattrop, this, + &this_req->compound_req_u.compound_xattrop_req, + op_errno, out, + &args->loc, args->xattr, args->optype, + args->xdata); + break; + case GF_FOP_FXATTROP: + CLIENT_PRE_FOP (fxattrop, this, + &this_req->compound_req_u.compound_fxattrop_req, + op_errno, out, + args->fd, args->xattr, args->optype, + args->xdata); + if (!local->fd) + local->fd = fd_ref (args->fd); + local->attempt_reopen = client_is_reopen_needed + (args->fd, this, remote_fd); + break; + case GF_FOP_FGETXATTR: + CLIENT_PRE_FOP (fgetxattr, this, + &this_req->compound_req_u.compound_fgetxattr_req, + op_errno, out, + args->fd, args->name, args->xdata); + break; + case GF_FOP_FSETXATTR: + CLIENT_PRE_FOP (fsetxattr, this, + &this_req->compound_req_u.compound_fsetxattr_req, + op_errno, out, + args->fd, args->flags, args->xattr, + args->xdata); + break; + case GF_FOP_RCHECKSUM: + CLIENT_PRE_FOP (rchecksum, this, + &this_req->compound_req_u.compound_rchecksum_req, + op_errno, out, + args->fd, args->size, args->offset, + args->xdata); + break; + case GF_FOP_SETATTR: + CLIENT_PRE_FOP (setattr, this, + &this_req->compound_req_u.compound_setattr_req, + op_errno, out, + &args->loc, args->valid, &args->stat, + args->xdata); + break; + case GF_FOP_FSETATTR: + CLIENT_PRE_FOP (fsetattr, this, + &this_req->compound_req_u.compound_fsetattr_req, + op_errno, out, + args->fd, args->valid, &args->stat, + args->xdata); + break; + case GF_FOP_READDIRP: + CLIENT_PRE_FOP (readdirp, this, + &this_req->compound_req_u.compound_readdirp_req, + op_errno, out, + args->fd, args->size, args->offset, + args->xdata); + if (!local->fd) + local->fd = fd_ref (args->fd); + break; + case GF_FOP_FREMOVEXATTR: + CLIENT_PRE_FOP (fremovexattr, this, + &this_req->compound_req_u.compound_fremovexattr_req, + op_errno, out, + args->fd, args->name, args->xdata); + break; + case GF_FOP_FALLOCATE: + CLIENT_PRE_FOP (fallocate, this, + &this_req->compound_req_u.compound_fallocate_req, + op_errno, out, + args->fd, args->flags, args->offset, + args->size, args->xdata); + break; + case GF_FOP_DISCARD: + CLIENT_PRE_FOP (discard, this, + &this_req->compound_req_u.compound_discard_req, + op_errno, out, + args->fd, args->offset, args->size, + args->xdata); + break; + case GF_FOP_ZEROFILL: + CLIENT_PRE_FOP (zerofill, this, + &this_req->compound_req_u.compound_zerofill_req, + op_errno, out, + args->fd, args->offset, args->size, + args->xdata); + break; + case GF_FOP_IPC: + CLIENT_PRE_FOP (ipc, this, + &this_req->compound_req_u.compound_ipc_req, + op_errno, out, + args->cmd, args->xdata); + break; + case GF_FOP_SEEK: + CLIENT_PRE_FOP (seek, this, + &this_req->compound_req_u.compound_seek_req, + op_errno, out, + args->fd, args->offset, args->what, + args->xdata); + break; + case GF_FOP_LEASE: + CLIENT_PRE_FOP (lease, this, + &this_req->compound_req_u.compound_lease_req, + op_errno, out, &args->loc, &args->lease, + args->xdata); + default: + return ENOTSUP; + } + return 0; +out: + return op_errno; +} + +void +compound_request_cleanup (gfs3_compound_req *req) +{ + int i = 0; + int length = req->compound_req_array.compound_req_array_len; + compound_req *curr_req = NULL; + + + for (i = 0; i < length; i++) { + curr_req = &req->compound_req_array.compound_req_array_val[i]; + + switch (curr_req->fop_enum) { + case GF_FOP_STAT: + CLIENT_COMPOUND_FOP_CLEANUP (curr_req, stat); + break; + case GF_FOP_READLINK: + CLIENT_COMPOUND_FOP_CLEANUP (curr_req, readlink); + break; + case GF_FOP_MKNOD: + CLIENT_COMPOUND_FOP_CLEANUP (curr_req, mknod); + break; + case GF_FOP_MKDIR: + CLIENT_COMPOUND_FOP_CLEANUP (curr_req, mkdir); + break; + case GF_FOP_UNLINK: + CLIENT_COMPOUND_FOP_CLEANUP (curr_req, unlink); + break; + case GF_FOP_RMDIR: + CLIENT_COMPOUND_FOP_CLEANUP (curr_req, rmdir); + break; + case GF_FOP_SYMLINK: + CLIENT_COMPOUND_FOP_CLEANUP (curr_req, symlink); + break; + case GF_FOP_RENAME: + CLIENT_COMPOUND_FOP_CLEANUP (curr_req, rename); + break; + case GF_FOP_LINK: + CLIENT_COMPOUND_FOP_CLEANUP (curr_req, link); + break; + case GF_FOP_TRUNCATE: + CLIENT_COMPOUND_FOP_CLEANUP (curr_req, truncate); + break; + case GF_FOP_OPEN: + CLIENT_COMPOUND_FOP_CLEANUP (curr_req, open); + break; + case GF_FOP_READ: + CLIENT_COMPOUND_FOP_CLEANUP (curr_req, read); + break; + case GF_FOP_WRITE: + CLIENT_COMPOUND_FOP_CLEANUP (curr_req, write); + break; + case GF_FOP_STATFS: + CLIENT_COMPOUND_FOP_CLEANUP (curr_req, statfs); + break; + case GF_FOP_FLUSH: + CLIENT_COMPOUND_FOP_CLEANUP (curr_req, flush); + break; + case GF_FOP_FSYNC: + CLIENT_COMPOUND_FOP_CLEANUP (curr_req, fsync); + break; + case GF_FOP_SETXATTR: + { + gfs3_setxattr_req args = curr_req->compound_req_u.compound_setxattr_req; + GF_FREE (args.dict.dict_val); + CLIENT_COMPOUND_FOP_CLEANUP (curr_req, setxattr); + break; + } + case GF_FOP_GETXATTR: + CLIENT_COMPOUND_FOP_CLEANUP (curr_req, getxattr); + break; + case GF_FOP_REMOVEXATTR: + CLIENT_COMPOUND_FOP_CLEANUP (curr_req, removexattr); + break; + case GF_FOP_OPENDIR: + CLIENT_COMPOUND_FOP_CLEANUP (curr_req, opendir); + break; + case GF_FOP_FSYNCDIR: + CLIENT_COMPOUND_FOP_CLEANUP (curr_req, fsyncdir); + break; + case GF_FOP_ACCESS: + CLIENT_COMPOUND_FOP_CLEANUP (curr_req, access); + break; + case GF_FOP_CREATE: + CLIENT_COMPOUND_FOP_CLEANUP (curr_req, create); + break; + case GF_FOP_FTRUNCATE: + CLIENT_COMPOUND_FOP_CLEANUP (curr_req, ftruncate); + break; + case GF_FOP_FSTAT: + CLIENT_COMPOUND_FOP_CLEANUP (curr_req, fstat); + break; + case GF_FOP_LK: + CLIENT_COMPOUND_FOP_CLEANUP (curr_req, lk); + break; + case GF_FOP_LOOKUP: + CLIENT_COMPOUND_FOP_CLEANUP (curr_req, lookup); + break; + case GF_FOP_READDIR: + CLIENT_COMPOUND_FOP_CLEANUP (curr_req, readdir); + break; + case GF_FOP_INODELK: + CLIENT_COMPOUND_FOP_CLEANUP (curr_req, inodelk); + break; + case GF_FOP_FINODELK: + CLIENT_COMPOUND_FOP_CLEANUP (curr_req, finodelk); + break; + case GF_FOP_ENTRYLK: + CLIENT_COMPOUND_FOP_CLEANUP (curr_req, entrylk); + break; + case GF_FOP_FENTRYLK: + CLIENT_COMPOUND_FOP_CLEANUP (curr_req, fentrylk); + break; + case GF_FOP_XATTROP: + { + gfs3_xattrop_req args = curr_req->compound_req_u.compound_xattrop_req; + GF_FREE (args.dict.dict_val); + CLIENT_COMPOUND_FOP_CLEANUP (curr_req, xattrop); + break; + } + case GF_FOP_FXATTROP: + { + gfs3_fxattrop_req args = curr_req->compound_req_u.compound_fxattrop_req; + GF_FREE (args.dict.dict_val); + CLIENT_COMPOUND_FOP_CLEANUP (curr_req, fxattrop); + break; + } + case GF_FOP_FGETXATTR: + CLIENT_COMPOUND_FOP_CLEANUP (curr_req, fgetxattr); + break; + case GF_FOP_FSETXATTR: + { + gfs3_fsetxattr_req args = curr_req->compound_req_u.compound_fsetxattr_req; + GF_FREE (args.dict.dict_val); + CLIENT_COMPOUND_FOP_CLEANUP (curr_req, fsetxattr); + break; + } + case GF_FOP_RCHECKSUM: + CLIENT_COMPOUND_FOP_CLEANUP (curr_req, rchecksum); + break; + case GF_FOP_SETATTR: + CLIENT_COMPOUND_FOP_CLEANUP (curr_req, setattr); + break; + case GF_FOP_FSETATTR: + CLIENT_COMPOUND_FOP_CLEANUP (curr_req, fsetattr); + break; + case GF_FOP_READDIRP: + { + gfs3_readdirp_req args = curr_req->compound_req_u.compound_readdirp_req; + GF_FREE (args.dict.dict_val); + break; + } + case GF_FOP_FREMOVEXATTR: + CLIENT_COMPOUND_FOP_CLEANUP (curr_req, fremovexattr); + break; + case GF_FOP_FALLOCATE: + CLIENT_COMPOUND_FOP_CLEANUP (curr_req, fallocate); + break; + case GF_FOP_DISCARD: + CLIENT_COMPOUND_FOP_CLEANUP (curr_req, discard); + break; + case GF_FOP_ZEROFILL: + CLIENT_COMPOUND_FOP_CLEANUP (curr_req, zerofill); + break; + case GF_FOP_IPC: + CLIENT_COMPOUND_FOP_CLEANUP (curr_req, ipc); + break; + case GF_FOP_SEEK: + CLIENT_COMPOUND_FOP_CLEANUP (curr_req, seek); + break; + default: + break; + } + } + + return; +} |