From e82ca8fc5164f4ba2ff396da86b4a490d9a47370 Mon Sep 17 00:00:00 2001 From: Amar Tumballi Date: Wed, 23 Jun 2010 02:55:21 +0000 Subject: minor improvements in protocol * rpc_clnt_submit() now takes 'cbkfn' as an argument. * readdir xdr now uses dirent structure directly instead of using 'opaque' buffer through which it was serializing / unserializing the dirent structure. * 'gfs_id' field (currently used for debugging) is properly updated Signed-off-by: Amar Tumballi Signed-off-by: Anand V. Avati BUG: 875 (Implement a new protocol to provide proper backward/forward compatibility) URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=875 --- xlators/protocol/client/src/client-handshake.c | 69 +- xlators/protocol/client/src/client-helpers.c | 106 +- xlators/protocol/client/src/client.c | 209 +- xlators/protocol/client/src/client.h | 12 +- xlators/protocol/client/src/client3_1-fops.c | 6957 ++++++++++++------------ xlators/protocol/lib/src/Makefile.am | 2 +- xlators/protocol/lib/src/glusterfs-xdr.c | 97 +- xlators/protocol/lib/src/glusterfs-xdr.h | 78 +- xlators/protocol/lib/src/glusterfs3.x | 42 +- xlators/protocol/lib/src/msg-xdr.h | 2 + xlators/protocol/lib/src/protocol-common.c | 109 - xlators/protocol/lib/src/protocol-common.h | 11 +- xlators/protocol/rpc/rpc-lib/src/rpc-clnt.c | 42 +- xlators/protocol/rpc/rpc-lib/src/rpc-clnt.h | 20 +- xlators/protocol/rpc/rpc-lib/src/rpcsvc.c | 1 + xlators/protocol/server/src/server-helpers.c | 100 + xlators/protocol/server/src/server-helpers.h | 5 + xlators/protocol/server/src/server.c | 6 +- xlators/protocol/server/src/server.h | 2 +- xlators/protocol/server/src/server3_1-fops.c | 82 +- 20 files changed, 4166 insertions(+), 3786 deletions(-) delete mode 100644 xlators/protocol/lib/src/protocol-common.c diff --git a/xlators/protocol/client/src/client-handshake.c b/xlators/protocol/client/src/client-handshake.c index 79cabd106b2..8d249d1b0f5 100644 --- a/xlators/protocol/client/src/client-handshake.c +++ b/xlators/protocol/client/src/client-handshake.c @@ -33,6 +33,9 @@ extern rpc_clnt_prog_t clnt3_1_fop_prog; extern rpc_clnt_prog_t clnt3_1_mgmt_prog; +int client_ping_cbk (struct rpc_req *req, struct iovec *iov, int count, + void *myframe); + /* Handshake */ void @@ -113,7 +116,6 @@ out: return; } - void client_start_ping (void *data) { @@ -185,7 +187,7 @@ client_start_ping (void *data) goto fail; ret = client_submit_request (this, NULL, frame, conf->handshake, - GF_HNDSK_PING, NULL, NULL); + GF_HNDSK_PING, client_ping_cbk, NULL, NULL); return; fail: @@ -244,13 +246,12 @@ out: int -client_getspec_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) +client3_getspec_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { gf_getspec_rsp rsp = {0,}; call_frame_t *frame = NULL; clnt_conf_t *conf = NULL; int ret = 0; - char spec[(32*1024)] = {0,}; frame = myframe; conf = frame->this->private; @@ -261,8 +262,7 @@ client_getspec_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myf goto out; } - rsp.spec = spec; - ret = xdr_to_dump_version_rsp (*iov, &rsp); + ret = xdr_to_getspec_rsp (*iov, &rsp); if (ret < 0) { gf_log ("", GF_LOG_ERROR, "error"); rsp.op_ret = -1; @@ -277,11 +277,39 @@ client_getspec_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myf } out: - /* no _STRICT for mops */ STACK_UNWIND_STRICT (getspec, frame, rsp.op_ret, rsp.op_errno, rsp.spec); + + /* Don't use 'GF_FREE', this is allocated by libc */ + if (rsp.spec) + free (rsp.spec); + return 0; } +int32_t client3_getspec (call_frame_t *frame, xlator_t *this, void *data) +{ + clnt_conf_t *conf = NULL; + clnt_args_t *args = NULL; + gf_getspec_req req = {0,}; + int op_errno = ESTALE; + + if (!frame || !this || !data) + goto unwind; + + args = data; + conf = this->private; + req.flags = args->flags; + req.key = (char *)args->name; + + client_submit_request (this, &req, frame, conf->handshake, GF_HNDSK_GETSPEC, + client3_getspec_cbk, NULL, xdr_from_getspec_req); + + return 0; +unwind: + STACK_UNWIND_STRICT (getspec, frame, -1, op_errno, NULL); + return 0; + +} int client_post_handshake (call_frame_t *frame, xlator_t *this) @@ -556,7 +584,8 @@ client_setvolume (xlator_t *this, struct rpc_clnt *rpc) goto fail; ret = client_submit_request (this, &req, fr, conf->handshake, - GF_HNDSK_SETVOLUME, NULL, xdr_from_setvolume_req); + GF_HNDSK_SETVOLUME, client_setvolume_cbk, + NULL, xdr_from_setvolume_req); fail: if (req.dict.dict_val) @@ -711,6 +740,7 @@ client_handshake (xlator_t *this, struct rpc_clnt *rpc) req.gfs_id = 123456; ret = client_submit_request (this, &req, frame, conf->handshake, GF_HNDSK_DUMP_VERSION, + client_dump_version_cbk, NULL, xdr_from_dump_version_req); out: @@ -720,19 +750,18 @@ out: /* */ /* This table should ideally remain same irrespective of versions */ -static rpc_clnt_procedure_t clnt_handshake_actors[] = { - [GF_HNDSK_NULL] = { "NULL", NULL, NULL}, - [GF_HNDSK_DUMP_VERSION] = { "VERSION", NULL, client_dump_version_cbk}, - [GF_HNDSK_SETVOLUME] = { "SETVOLUME", NULL, client_setvolume_cbk}, - [GF_HNDSK_GETSPEC] = { "GETSPEC", NULL, client_getspec_cbk }, - [GF_HNDSK_PING] = { "PING", NULL, client_ping_cbk }, + +char *clnt_handshake_procs[GF_HNDSK_MAXVALUE] = { + [GF_HNDSK_NULL] = "NULL", + [GF_HNDSK_DUMP_VERSION] = "VERSION", + [GF_HNDSK_SETVOLUME] = "SETVOLUME", + [GF_HNDSK_GETSPEC] = "GETSPEC", + [GF_HNDSK_PING] = "PING", }; rpc_clnt_prog_t clnt_handshake_prog = { - .progname = "GlusterFS Handshake", - .prognum = GLUSTER_HNDSK_PROGRAM, - .progver = GLUSTER_HNDSK_VERSION, - .actor = clnt_handshake_actors, - .numproc = (sizeof (*clnt_handshake_actors) / - sizeof (rpc_clnt_procedure_t)), + .progname = "GlusterFS Handshake", + .prognum = GLUSTER_HNDSK_PROGRAM, + .progver = GLUSTER_HNDSK_VERSION, + .procnames = clnt_handshake_procs, }; diff --git a/xlators/protocol/client/src/client-helpers.c b/xlators/protocol/client/src/client-helpers.c index ae091ed1d8d..6c028d4ebb7 100644 --- a/xlators/protocol/client/src/client-helpers.c +++ b/xlators/protocol/client/src/client-helpers.c @@ -25,7 +25,6 @@ #include "client.h" #include "fd.h" - clnt_fd_ctx_t * this_fd_del_ctx (fd_t *file, xlator_t *this) { @@ -107,3 +106,108 @@ client_local_wipe (clnt_local_t *local) return 0; } + +int +unserialize_rsp_dirent (struct gfs3_readdir_rsp *rsp, gf_dirent_t *entries) +{ + struct gfs3_dirlist *trav = NULL; + gf_dirent_t *entry = NULL; + int entry_len = 0; + int ret = -1; + + trav = rsp->reply; + while (trav) { + entry_len = gf_dirent_size (trav->name); + entry = GF_CALLOC (1, entry_len, gf_common_mt_gf_dirent_t); + if (!entry) + goto out; + + entry->d_ino = trav->d_ino; + entry->d_off = trav->d_off; + entry->d_len = trav->d_len; + entry->d_type = trav->d_type; + + strcpy (entry->d_name, trav->name); + + list_add_tail (&entry->list, &entries->list); + + trav = trav->nextentry; + } + + ret = 0; +out: + return ret; +} + +int +unserialize_rsp_direntp (struct gfs3_readdirp_rsp *rsp, gf_dirent_t *entries) +{ + struct gfs3_dirplist *trav = NULL; + gf_dirent_t *entry = NULL; + int entry_len = 0; + int ret = -1; + + trav = rsp->reply; + + while (trav) { + entry_len = gf_dirent_size (trav->name); + entry = GF_CALLOC (1, entry_len, gf_common_mt_gf_dirent_t); + if (!entry) + goto out; + + entry->d_ino = trav->d_ino; + entry->d_off = trav->d_off; + entry->d_len = trav->d_len; + entry->d_type = trav->d_type; + + gf_stat_to_iatt (&trav->stat, &entry->d_stat); + + strcpy (entry->d_name, trav->name); + + list_add_tail (&entry->list, &entries->list); + + trav = trav->nextentry; + } + + ret = 0; +out: + return ret; +} + +int +clnt_readdirp_rsp_cleanup (gfs3_readdirp_rsp *rsp) +{ + gfs3_dirplist *prev = NULL; + gfs3_dirplist *trav = NULL; + + trav = rsp->reply; + prev = trav; + while (trav) { + trav = trav->nextentry; + /* on client, the rpc lib allocates this */ + free (prev->name); + free (prev); + prev = trav; + } + + return 0; +} + +int +clnt_readdir_rsp_cleanup (gfs3_readdir_rsp *rsp) +{ + gfs3_dirlist *prev = NULL; + gfs3_dirlist *trav = NULL; + + trav = rsp->reply; + prev = trav; + while (trav) { + trav = trav->nextentry; + /* on client, the rpc lib allocates this */ + free (prev->name); + free (prev); + prev = trav; + } + + return 0; +} diff --git a/xlators/protocol/client/src/client.c b/xlators/protocol/client/src/client.c index 49e88bfdea3..f75cf3c99d2 100644 --- a/xlators/protocol/client/src/client.c +++ b/xlators/protocol/client/src/client.c @@ -39,8 +39,8 @@ void client_start_ping (void *data); int -client_submit_request (xlator_t *this, void *req, - call_frame_t *frame, rpc_clnt_prog_t *prog, int procnum, +client_submit_request (xlator_t *this, void *req, call_frame_t *frame, + rpc_clnt_prog_t *prog, int procnum, fop_cbk_fn_t cbk, struct iobref *iobref, gfs_serialize_t sfunc) { int ret = -1; @@ -81,7 +81,7 @@ client_submit_request (xlator_t *this, void *req, count = 1; } /* Send the msg */ - ret = rpc_clnt_submit (conf->rpc, prog, procnum, &iov, count, NULL, 0, + ret = rpc_clnt_submit (conf->rpc, prog, procnum, cbk, &iov, count, NULL, 0, iobref, frame); if (ret == 0) { @@ -131,13 +131,13 @@ client_releasedir (xlator_t *this, fd_t *fd) args.fd = fd; - proc = &conf->fops->actor[GF_FOP_RELEASEDIR]; + proc = &conf->fops->proctable[GF_FOP_RELEASEDIR]; if (proc->fn) { frame = create_frame (this, this->ctx->pool); if (!frame) { goto out; } - ret = proc->fn (frame, this, conf->fops, &args); + ret = proc->fn (frame, this, &args); } out: return 0; @@ -157,13 +157,13 @@ client_release (xlator_t *this, fd_t *fd) goto out; args.fd = fd; - proc = &conf->fops->actor[GF_FOP_RELEASE]; + proc = &conf->fops->proctable[GF_FOP_RELEASE]; if (proc->fn) { frame = create_frame (this, this->ctx->pool); if (!frame) { goto out; } - ret = proc->fn (frame, this, conf->fops, &args); + ret = proc->fn (frame, this, &args); } out: return 0; @@ -186,9 +186,9 @@ client_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc, args.loc = loc; args.dict = xattr_req; - proc = &conf->fops->actor[GF_FOP_LOOKUP]; + proc = &conf->fops->proctable[GF_FOP_LOOKUP]; if (proc->fn) - ret = proc->fn (frame, this, conf->fops, &args); + ret = proc->fn (frame, this, &args); out: /* think of avoiding a missing frame */ if (ret) @@ -213,9 +213,9 @@ client_stat (call_frame_t *frame, xlator_t *this, loc_t *loc) args.loc = loc; - proc = &conf->fops->actor[GF_FOP_STAT]; + proc = &conf->fops->proctable[GF_FOP_STAT]; if (proc->fn) - ret = proc->fn (frame, this, conf->fops, &args); + ret = proc->fn (frame, this, &args); out: if (ret) STACK_UNWIND_STRICT (stat, frame, -1, ENOTCONN, NULL); @@ -240,9 +240,9 @@ client_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset) args.loc = loc; args.offset = offset; - proc = &conf->fops->actor[GF_FOP_TRUNCATE]; + proc = &conf->fops->proctable[GF_FOP_TRUNCATE]; if (proc->fn) - ret = proc->fn (frame, this, conf->fops, &args); + ret = proc->fn (frame, this, &args); out: if (ret) STACK_UNWIND_STRICT (truncate, frame, -1, ENOTCONN, NULL, NULL); @@ -267,9 +267,9 @@ client_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset) args.fd = fd; args.offset = offset; - proc = &conf->fops->actor[GF_FOP_FTRUNCATE]; + proc = &conf->fops->proctable[GF_FOP_FTRUNCATE]; if (proc->fn) - ret = proc->fn (frame, this, conf->fops, &args); + ret = proc->fn (frame, this, &args); out: if (ret) STACK_UNWIND_STRICT (ftruncate, frame, -1, ENOTCONN, NULL, NULL); @@ -294,9 +294,9 @@ client_access (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask) args.loc = loc; args.mask = mask; - proc = &conf->fops->actor[GF_FOP_ACCESS]; + proc = &conf->fops->proctable[GF_FOP_ACCESS]; if (proc->fn) - ret = proc->fn (frame, this, conf->fops, &args); + ret = proc->fn (frame, this, &args); out: if (ret) STACK_UNWIND_STRICT (access, frame, -1, ENOTCONN); @@ -322,9 +322,9 @@ client_readlink (call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size) args.loc = loc; args.size = size; - proc = &conf->fops->actor[GF_FOP_READLINK]; + proc = &conf->fops->proctable[GF_FOP_READLINK]; if (proc->fn) - ret = proc->fn (frame, this, conf->fops, &args); + ret = proc->fn (frame, this, &args); out: if (ret) STACK_UNWIND_STRICT (readlink, frame, -1, ENOTCONN, NULL, NULL); @@ -351,9 +351,9 @@ client_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, args.mode = mode; args.rdev = rdev; - proc = &conf->fops->actor[GF_FOP_MKNOD]; + proc = &conf->fops->proctable[GF_FOP_MKNOD]; if (proc->fn) - ret = proc->fn (frame, this, conf->fops, &args); + ret = proc->fn (frame, this, &args); out: if (ret) STACK_UNWIND_STRICT (mknod, frame, -1, ENOTCONN, @@ -380,9 +380,9 @@ client_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc, args.loc = loc; args.mode = mode; - proc = &conf->fops->actor[GF_FOP_MKDIR]; + proc = &conf->fops->proctable[GF_FOP_MKDIR]; if (proc->fn) - ret = proc->fn (frame, this, conf->fops, &args); + ret = proc->fn (frame, this, &args); out: if (ret) STACK_UNWIND_STRICT (mkdir, frame, -1, ENOTCONN, @@ -407,9 +407,9 @@ client_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc) args.loc = loc; - proc = &conf->fops->actor[GF_FOP_UNLINK]; + proc = &conf->fops->proctable[GF_FOP_UNLINK]; if (proc->fn) - ret = proc->fn (frame, this, conf->fops, &args); + ret = proc->fn (frame, this, &args); out: if (ret) STACK_UNWIND_STRICT (unlink, frame, -1, ENOTCONN, @@ -432,9 +432,9 @@ client_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc) args.loc = loc; - proc = &conf->fops->actor[GF_FOP_RMDIR]; + proc = &conf->fops->proctable[GF_FOP_RMDIR]; if (proc->fn) - ret = proc->fn (frame, this, conf->fops, &args); + ret = proc->fn (frame, this, &args); out: /* think of avoiding a missing frame */ if (ret) @@ -462,9 +462,9 @@ client_symlink (call_frame_t *frame, xlator_t *this, const char *linkpath, args.linkname = linkpath; args.loc = loc; - proc = &conf->fops->actor[GF_FOP_SYMLINK]; + proc = &conf->fops->proctable[GF_FOP_SYMLINK]; if (proc->fn) - ret = proc->fn (frame, this, conf->fops, &args); + ret = proc->fn (frame, this, &args); out: if (ret) STACK_UNWIND_STRICT (symlink, frame, -1, ENOTCONN, @@ -490,9 +490,9 @@ client_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc, args.oldloc = oldloc; args.newloc = newloc; - proc = &conf->fops->actor[GF_FOP_RENAME]; + proc = &conf->fops->proctable[GF_FOP_RENAME]; if (proc->fn) - ret = proc->fn (frame, this, conf->fops, &args); + ret = proc->fn (frame, this, &args); out: if (ret) STACK_UNWIND_STRICT (rename, frame, -1, ENOTCONN, @@ -519,9 +519,9 @@ client_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc, args.oldloc = oldloc; args.newloc = newloc; - proc = &conf->fops->actor[GF_FOP_LINK]; + proc = &conf->fops->proctable[GF_FOP_LINK]; if (proc->fn) - ret = proc->fn (frame, this, conf->fops, &args); + ret = proc->fn (frame, this, &args); out: if (ret) STACK_UNWIND_STRICT (link, frame, -1, ENOTCONN, @@ -550,9 +550,9 @@ client_create (call_frame_t *frame, xlator_t *this, loc_t *loc, args.mode = mode; args.fd = fd; - proc = &conf->fops->actor[GF_FOP_CREATE]; + proc = &conf->fops->proctable[GF_FOP_CREATE]; if (proc->fn) - ret = proc->fn (frame, this, conf->fops, &args); + ret = proc->fn (frame, this, &args); out: if (ret) STACK_UNWIND_STRICT (create, frame, -1, ENOTCONN, @@ -581,9 +581,9 @@ client_open (call_frame_t *frame, xlator_t *this, loc_t *loc, args.fd = fd; args.wbflags = wbflags; - proc = &conf->fops->actor[GF_FOP_OPEN]; + proc = &conf->fops->proctable[GF_FOP_OPEN]; if (proc->fn) - ret = proc->fn (frame, this, conf->fops, &args); + ret = proc->fn (frame, this, &args); out: if (ret) @@ -611,9 +611,9 @@ client_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, args.size = size; args.offset = offset; - proc = &conf->fops->actor[GF_FOP_READ]; + proc = &conf->fops->proctable[GF_FOP_READ]; if (proc->fn) - ret = proc->fn (frame, this, conf->fops, &args); + ret = proc->fn (frame, this, &args); out: if (ret) @@ -646,9 +646,9 @@ client_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, args.offset = off; args.iobref = iobref; - proc = &conf->fops->actor[GF_FOP_WRITE]; + proc = &conf->fops->proctable[GF_FOP_WRITE]; if (proc->fn) - ret = proc->fn (frame, this, conf->fops, &args); + ret = proc->fn (frame, this, &args); out: if (ret) STACK_UNWIND_STRICT (writev, frame, -1, ENOTCONN, NULL, NULL); @@ -672,9 +672,9 @@ client_flush (call_frame_t *frame, xlator_t *this, fd_t *fd) args.fd = fd; - proc = &conf->fops->actor[GF_FOP_FLUSH]; + proc = &conf->fops->proctable[GF_FOP_FLUSH]; if (proc->fn) - ret = proc->fn (frame, this, conf->fops, &args); + ret = proc->fn (frame, this, &args); out: if (ret) STACK_UNWIND_STRICT (flush, frame, -1, ENOTCONN); @@ -700,9 +700,9 @@ client_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, args.fd = fd; args.flags = flags; - proc = &conf->fops->actor[GF_FOP_FSYNC]; + proc = &conf->fops->proctable[GF_FOP_FSYNC]; if (proc->fn) - ret = proc->fn (frame, this, conf->fops, &args); + ret = proc->fn (frame, this, &args); out: if (ret) STACK_UNWIND_STRICT (fsync, frame, -1, ENOTCONN, NULL, NULL); @@ -726,9 +726,9 @@ client_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd) args.fd = fd; - proc = &conf->fops->actor[GF_FOP_FSTAT]; + proc = &conf->fops->proctable[GF_FOP_FSTAT]; if (proc->fn) - ret = proc->fn (frame, this, conf->fops, &args); + ret = proc->fn (frame, this, &args); out: if (ret) STACK_UNWIND_STRICT (fstat, frame, -1, ENOTCONN, NULL); @@ -753,9 +753,9 @@ client_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd) args.loc = loc; args.fd = fd; - proc = &conf->fops->actor[GF_FOP_OPENDIR]; + proc = &conf->fops->proctable[GF_FOP_OPENDIR]; if (proc->fn) - ret = proc->fn (frame, this, conf->fops, &args); + ret = proc->fn (frame, this, &args); out: if (ret) STACK_UNWIND_STRICT (opendir, frame, -1, ENOTCONN, NULL); @@ -780,9 +780,9 @@ client_fsyncdir (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags) args.fd = fd; args.flags = flags; - proc = &conf->fops->actor[GF_FOP_FSYNCDIR]; + proc = &conf->fops->proctable[GF_FOP_FSYNCDIR]; if (proc->fn) - ret = proc->fn (frame, this, conf->fops, &args); + ret = proc->fn (frame, this, &args); out: if (ret) STACK_UNWIND_STRICT (fsyncdir, frame, -1, ENOTCONN); @@ -806,9 +806,9 @@ client_statfs (call_frame_t *frame, xlator_t *this, loc_t *loc) args.loc = loc; - proc = &conf->fops->actor[GF_FOP_STATFS]; + proc = &conf->fops->proctable[GF_FOP_STATFS]; if (proc->fn) - ret = proc->fn (frame, this, conf->fops, &args); + ret = proc->fn (frame, this, &args); out: if (ret) STACK_UNWIND_STRICT (statfs, frame, -1, ENOTCONN, NULL); @@ -835,9 +835,9 @@ client_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict, args.dict = dict; args.flags = flags; - proc = &conf->fops->actor[GF_FOP_SETXATTR]; + proc = &conf->fops->proctable[GF_FOP_SETXATTR]; if (proc->fn) - ret = proc->fn (frame, this, conf->fops, &args); + ret = proc->fn (frame, this, &args); out: if (ret) STACK_UNWIND_STRICT (setxattr, frame, -1, ENOTCONN); @@ -864,9 +864,9 @@ client_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, args.dict = dict; args.flags = flags; - proc = &conf->fops->actor[GF_FOP_FSETXATTR]; + proc = &conf->fops->proctable[GF_FOP_FSETXATTR]; if (proc->fn) - ret = proc->fn (frame, this, conf->fops, &args); + ret = proc->fn (frame, this, &args); out: if (ret) STACK_UNWIND_STRICT (fsetxattr, frame, -1, ENOTCONN); @@ -893,9 +893,9 @@ client_fgetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, args.fd = fd; args.name = name; - proc = &conf->fops->actor[GF_FOP_FGETXATTR]; + proc = &conf->fops->proctable[GF_FOP_FGETXATTR]; if (proc->fn) - ret = proc->fn (frame, this, conf->fops, &args); + ret = proc->fn (frame, this, &args); out: if (ret) STACK_UNWIND_STRICT (fgetxattr, frame, -1, ENOTCONN, NULL); @@ -921,9 +921,9 @@ client_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, args.name = name; args.loc = loc; - proc = &conf->fops->actor[GF_FOP_GETXATTR]; + proc = &conf->fops->proctable[GF_FOP_GETXATTR]; if (proc->fn) - ret = proc->fn (frame, this, conf->fops, &args); + ret = proc->fn (frame, this, &args); out: if (ret) STACK_UNWIND_STRICT (getxattr, frame, -1, ENOTCONN, NULL); @@ -950,9 +950,9 @@ client_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc, args.flags = flags; args.dict = dict; - proc = &conf->fops->actor[GF_FOP_XATTROP]; + proc = &conf->fops->proctable[GF_FOP_XATTROP]; if (proc->fn) - ret = proc->fn (frame, this, conf->fops, &args); + ret = proc->fn (frame, this, &args); out: if (ret) STACK_UNWIND_STRICT (xattrop, frame, -1, ENOTCONN, NULL); @@ -979,9 +979,9 @@ client_fxattrop (call_frame_t *frame, xlator_t *this, fd_t *fd, args.flags = flags; args.dict = dict; - proc = &conf->fops->actor[GF_FOP_FXATTROP]; + proc = &conf->fops->proctable[GF_FOP_FXATTROP]; if (proc->fn) - ret = proc->fn (frame, this, conf->fops, &args); + ret = proc->fn (frame, this, &args); out: if (ret) STACK_UNWIND_STRICT (fxattrop, frame, -1, ENOTCONN, NULL); @@ -1007,9 +1007,9 @@ client_removexattr (call_frame_t *frame, xlator_t *this, loc_t *loc, args.name = name; args.loc = loc; - proc = &conf->fops->actor[GF_FOP_REMOVEXATTR]; + proc = &conf->fops->proctable[GF_FOP_REMOVEXATTR]; if (proc->fn) - ret = proc->fn (frame, this, conf->fops, &args); + ret = proc->fn (frame, this, &args); out: if (ret) STACK_UNWIND_STRICT (removexattr, frame, -1, ENOTCONN); @@ -1035,9 +1035,9 @@ client_lk (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd, args.cmd = cmd; args.flock = lock; - proc = &conf->fops->actor[GF_FOP_LK]; + proc = &conf->fops->proctable[GF_FOP_LK]; if (proc->fn) - ret = proc->fn (frame, this, conf->fops, &args); + ret = proc->fn (frame, this, &args); out: if (ret) STACK_UNWIND_STRICT (lk, frame, -1, ENOTCONN, NULL); @@ -1064,9 +1064,9 @@ client_inodelk (call_frame_t *frame, xlator_t *this, const char *volume, args.flock = lock; args.volume = volume; - proc = &conf->fops->actor[GF_FOP_INODELK]; + proc = &conf->fops->proctable[GF_FOP_INODELK]; if (proc->fn) - ret = proc->fn (frame, this, conf->fops, &args); + ret = proc->fn (frame, this, &args); out: if (ret) STACK_UNWIND_STRICT (inodelk, frame, -1, ENOTCONN); @@ -1094,9 +1094,9 @@ client_finodelk (call_frame_t *frame, xlator_t *this, const char *volume, args.flock = lock; args.volume = volume; - proc = &conf->fops->actor[GF_FOP_FINODELK]; + proc = &conf->fops->proctable[GF_FOP_FINODELK]; if (proc->fn) - ret = proc->fn (frame, this, conf->fops, &args); + ret = proc->fn (frame, this, &args); out: if (ret) STACK_UNWIND_STRICT (finodelk, frame, -1, ENOTCONN); @@ -1125,9 +1125,9 @@ client_entrylk (call_frame_t *frame, xlator_t *this, const char *volume, args.volume = volume; args.cmd_entrylk = cmd; - proc = &conf->fops->actor[GF_FOP_ENTRYLK]; + proc = &conf->fops->proctable[GF_FOP_ENTRYLK]; if (proc->fn) - ret = proc->fn (frame, this, conf->fops, &args); + ret = proc->fn (frame, this, &args); out: if (ret) STACK_UNWIND_STRICT (entrylk, frame, -1, ENOTCONN); @@ -1157,9 +1157,9 @@ client_fentrylk (call_frame_t *frame, xlator_t *this, const char *volume, args.volume = volume; args.cmd_entrylk = cmd; - proc = &conf->fops->actor[GF_FOP_FENTRYLK]; + proc = &conf->fops->proctable[GF_FOP_FENTRYLK]; if (proc->fn) - ret = proc->fn (frame, this, conf->fops, &args); + ret = proc->fn (frame, this, &args); out: if (ret) STACK_UNWIND_STRICT (fentrylk, frame, -1, ENOTCONN); @@ -1184,9 +1184,9 @@ client_checksum (call_frame_t *frame, xlator_t *this, loc_t *loc, args.loc = loc; args.flags = flag; - proc = &conf->fops->actor[GF_FOP_CHECKSUM]; + proc = &conf->fops->proctable[GF_FOP_CHECKSUM]; if (proc->fn) - ret = proc->fn (frame, this, conf->fops, &args); + ret = proc->fn (frame, this, &args); out: if (ret) STACK_UNWIND_STRICT (checksum, frame, -1, ENOTCONN, NULL, NULL); @@ -1213,9 +1213,9 @@ client_rchecksum (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, args.offset = offset; args.len = len; - proc = &conf->fops->actor[GF_FOP_RCHECKSUM]; + proc = &conf->fops->proctable[GF_FOP_RCHECKSUM]; if (proc->fn) - ret = proc->fn (frame, this, conf->fops, &args); + ret = proc->fn (frame, this, &args); out: if (ret) STACK_UNWIND_STRICT (rchecksum, frame, -1, ENOTCONN, 0, NULL); @@ -1240,9 +1240,9 @@ client_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd, args.size = size; args.offset = off; - proc = &conf->fops->actor[GF_FOP_READDIR]; + proc = &conf->fops->proctable[GF_FOP_READDIR]; if (proc->fn) - ret = proc->fn (frame, this, conf->fops, &args); + ret = proc->fn (frame, this, &args); out: if (ret) STACK_UNWIND_STRICT (readdir, frame, -1, ENOTCONN, NULL); @@ -1268,9 +1268,9 @@ client_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, args.size = size; args.offset = off; - proc = &conf->fops->actor[GF_FOP_READDIRP]; + proc = &conf->fops->proctable[GF_FOP_READDIRP]; if (proc->fn) - ret = proc->fn (frame, this, conf->fops, &args); + ret = proc->fn (frame, this, &args); out: if (ret) STACK_UNWIND_STRICT (readdirp, frame, -1, ENOTCONN, NULL); @@ -1296,9 +1296,9 @@ client_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc, args.stbuf = stbuf; args.valid = valid; - proc = &conf->fops->actor[GF_FOP_SETATTR]; + proc = &conf->fops->proctable[GF_FOP_SETATTR]; if (proc->fn) - ret = proc->fn (frame, this, conf->fops, &args); + ret = proc->fn (frame, this, &args); out: if (ret) STACK_UNWIND_STRICT (setattr, frame, -1, ENOTCONN, NULL, NULL); @@ -1323,9 +1323,9 @@ client_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd, args.stbuf = stbuf; args.valid = valid; - proc = &conf->fops->actor[GF_FOP_FSETATTR]; + proc = &conf->fops->proctable[GF_FOP_FSETATTR]; if (proc->fn) - ret = proc->fn (frame, this, conf->fops, &args); + ret = proc->fn (frame, this, &args); out: if (ret) STACK_UNWIND_STRICT (fsetattr, frame, -1, ENOTCONN, NULL, NULL); @@ -1333,25 +1333,29 @@ out: return 0; } -///////////////// + int32_t client_getspec (call_frame_t *frame, xlator_t *this, const char *key, int32_t flags) { - int ret = -1; - clnt_conf_t *conf = NULL; - gf_getspec_req req = {0,}; + int ret = -1; + clnt_conf_t *conf = NULL; + rpc_clnt_procedure_t *proc = NULL; + clnt_args_t args = {0,}; conf = this->private; - if (!conf->handshake) + if (!conf->fops || !conf->handshake) goto out; - req.key = (char *)key; - req.flags = flags; + args.name = key; + args.flags = flags; - client_submit_request (this, &req, frame, conf->handshake, - GF_HNDSK_GETSPEC, NULL, xdr_from_getspec_req); - ret = 0; + /* For all other xlators, getspec is an fop, hence its in fops table */ + proc = &conf->fops->proctable[GF_FOP_GETSPEC]; + if (proc->fn) { + /* But at protocol level, this is handshake */ + ret = proc->fn (frame, this, &args); + } out: if (ret) STACK_UNWIND_STRICT (getspec, frame, -1, EINVAL, NULL); @@ -1502,9 +1506,7 @@ build_client_config (xlator_t *this, clnt_conf_t *conf) "remote-port is %d", conf->rpc_conf.remote_port); } else { gf_log (this->name, GF_LOG_DEBUG, - "defaulting remote-port to %d", - GF_PROTOCOL_DEFAULT_PORT); - conf->rpc_conf.remote_port = GF_PROTOCOL_DEFAULT_PORT; + "defaulting remote-port to 'auto'"); } ret = dict_get_int32 (this->options, "ping-timeout", @@ -1520,7 +1522,8 @@ build_client_config (xlator_t *this, clnt_conf_t *conf) ret = 0; out: - return ret;} + return ret; +} static int32_t diff --git a/xlators/protocol/client/src/client.h b/xlators/protocol/client/src/client.h index 9d713bed204..1422c7abeda 100644 --- a/xlators/protocol/client/src/client.h +++ b/xlators/protocol/client/src/client.h @@ -28,6 +28,7 @@ #include "inode.h" #include "client-mem-types.h" #include "protocol-common.h" +#include "glusterfs-xdr.h" struct clnt_options { char *remote_subvolume; @@ -116,10 +117,17 @@ void this_fd_set_ctx (fd_t *file, xlator_t *this, loc_t *loc, int client_local_wipe (clnt_local_t *local); int client_submit_request (xlator_t *this, void *req, call_frame_t *frame, rpc_clnt_prog_t *prog, - int procnum, struct iobref *iobref, - gfs_serialize_t sfunc); + int procnum, fop_cbk_fn_t cbk, + struct iobref *iobref, gfs_serialize_t sfunc); int protocol_client_reopendir (xlator_t *this, clnt_fd_ctx_t *fdctx); int protocol_client_reopen (xlator_t *this, clnt_fd_ctx_t *fdctx); +int unserialize_rsp_dirent (struct gfs3_readdir_rsp *rsp, gf_dirent_t *entries); +int unserialize_rsp_direntp (struct gfs3_readdirp_rsp *rsp, gf_dirent_t *entries); + +int clnt_readdir_rsp_cleanup (gfs3_readdir_rsp *rsp); +int clnt_readdirp_rsp_cleanup (gfs3_readdirp_rsp *rsp); + + #endif /* !_CLIENT_H */ diff --git a/xlators/protocol/client/src/client3_1-fops.c b/xlators/protocol/client/src/client3_1-fops.c index 01b78436c6c..891aa019e9a 100644 --- a/xlators/protocol/client/src/client3_1-fops.c +++ b/xlators/protocol/client/src/client3_1-fops.c @@ -28,12 +28,13 @@ #include "msg-xdr.h" #include "compat-errno.h" +int32_t client3_getspec (call_frame_t *frame, xlator_t *this, void *data); void client_start_ping (void *data); rpc_clnt_prog_t clnt3_1_fop_prog; int -client_submit_vec_request (xlator_t *this, void *req, - call_frame_t *frame, rpc_clnt_prog_t *prog, int procnum, +client_submit_vec_request (xlator_t *this, void *req, call_frame_t *frame, + rpc_clnt_prog_t *prog, int procnum, fop_cbk_fn_t cbk, struct iovec *payload, int payloadcnt, struct iobref *iobref, gfs_serialize_t sfunc) { @@ -78,7 +79,7 @@ client_submit_vec_request (xlator_t *this, void *req, count = 1; } /* Send the msg */ - ret = rpc_clnt_submit (conf->rpc, prog, procnum, &iov, count, + ret = rpc_clnt_submit (conf->rpc, prog, procnum, cbk, &iov, count, payload, payloadcnt, iobref, frame); if (ret == 0) { @@ -104,66 +105,33 @@ out: return 0; } -int -client_fdctx_destroy (xlator_t *this, clnt_fd_ctx_t *fdctx) -{ - call_frame_t *fr = NULL; - int32_t ret = -1; - - if (!fdctx) - goto out; - - if (fdctx->remote_fd == -1) - goto out; - - fr = create_frame (this, this->ctx->pool); - - if (fdctx->is_dir) { - gfs3_releasedir_req req = {0,}; - req.fd = fdctx->remote_fd; - client_submit_request (this, &req, fr, &clnt3_1_fop_prog, - GFS3_OP_RELEASEDIR, NULL, - xdr_from_releasedir_req); - } else { - gfs3_release_req req = {0,}; - req.fd = fdctx->remote_fd; - client_submit_request (this, &req, fr, &clnt3_1_fop_prog, - GFS3_OP_RELEASE, NULL, - xdr_from_release_req); - } - -out: - fdctx->remote_fd = -1; - inode_unref (fdctx->inode); - GF_FREE (fdctx); - - return ret; -} +/* CBK */ int -client3_1_reopen_cbk (struct rpc_req *req, struct iovec *iov, int count, - void *myframe) +client3_1_symlink_cbk (struct rpc_req *req, struct iovec *iov, int count, + void *myframe) { - int32_t ret = -1; - gfs3_open_rsp rsp = {0,}; - clnt_local_t *local = NULL; - clnt_conf_t *conf = NULL; - clnt_fd_ctx_t *fdctx = NULL; - call_frame_t *frame = NULL; + call_frame_t *frame = NULL; + gfs3_symlink_rsp rsp = {0,}; + struct iatt stbuf = {0,}; + struct iatt preparent = {0,}; + struct iatt postparent = {0,}; + int ret = 0; + clnt_local_t *local = NULL; + inode_t *inode = NULL; frame = myframe; local = frame->local; - conf = frame->this->private; - fdctx = local->fdctx; + frame->local = NULL; + inode = local->loc.inode; if (-1 == req->rpc_status) { rsp.op_ret = -1; rsp.op_errno = ENOTCONN; goto out; } - - ret = xdr_to_open_rsp (*iov, &rsp); + ret = xdr_to_symlink_rsp (*iov, &rsp); if (ret < 0) { gf_log ("", GF_LOG_ERROR, "error"); rsp.op_ret = -1; @@ -171,62 +139,61 @@ client3_1_reopen_cbk (struct rpc_req *req, struct iovec *iov, int count, goto out; } - gf_log (frame->this->name, GF_LOG_DEBUG, - "reopen on %s returned %d (%"PRId64")", - local->loc.path, rsp.op_ret, rsp.fd); - if (-1 != rsp.op_ret) { - pthread_mutex_lock (&conf->lock); - { - fdctx->remote_fd = rsp.fd; + gf_stat_to_iatt (&rsp.stat, &stbuf); - if (!fdctx->released) { - list_add_tail (&fdctx->sfd_pos, &conf->saved_fds); - fdctx = NULL; - } + ret = inode_ctx_put2 (inode, frame->this, + stbuf.ia_ino, stbuf.ia_gen); + if (ret < 0) { + gf_log (frame->this->name, GF_LOG_DEBUG, + "SYMLINK %"PRId64"/%s (%s): failed to set " + "remote inode number to inode ctx", + local->loc.parent->ino, local->loc.name, + local->loc.path); } - pthread_mutex_unlock (&conf->lock); + + gf_stat_to_iatt (&rsp.preparent, &preparent); + gf_stat_to_iatt (&rsp.postparent, &postparent); } out: - if (fdctx) - client_fdctx_destroy (frame->this, fdctx); - frame->local = NULL; - STACK_DESTROY (frame->root); + STACK_UNWIND_STRICT (symlink, frame, rsp.op_ret, + gf_error_to_errno (rsp.op_errno), inode, &stbuf, + &preparent, &postparent); - client_local_wipe (local); + if (local) + client_local_wipe (local); return 0; } + int -client3_1_reopendir_cbk (struct rpc_req *req, struct iovec *iov, int count, - void *myframe) +client3_1_mknod_cbk (struct rpc_req *req, struct iovec *iov, int count, + void *myframe) { - int32_t ret = -1; - gfs3_open_rsp rsp = {0,}; - clnt_local_t *local = NULL; - clnt_conf_t *conf = NULL; - clnt_fd_ctx_t *fdctx = NULL; - call_frame_t *frame = NULL; + call_frame_t *frame = NULL; + gfs3_mknod_rsp rsp = {0,}; + struct iatt stbuf = {0,}; + struct iatt preparent = {0,}; + struct iatt postparent = {0,}; + int ret = 0; + clnt_local_t *local = NULL; + inode_t *inode = NULL; frame = myframe; - if (!frame || !frame->this) - goto out; - local = frame->local; + local = frame->local; frame->local = NULL; - conf = frame->this->private; - fdctx = local->fdctx; + inode = local->loc.inode; if (-1 == req->rpc_status) { rsp.op_ret = -1; rsp.op_errno = ENOTCONN; goto out; } - - ret = xdr_to_opendir_rsp (*iov, &rsp); + ret = xdr_to_mknod_rsp (*iov, &rsp); if (ret < 0) { gf_log ("", GF_LOG_ERROR, "error"); rsp.op_ret = -1; @@ -234,2334 +201,2251 @@ client3_1_reopendir_cbk (struct rpc_req *req, struct iovec *iov, int count, goto out; } - gf_log (frame->this->name, GF_LOG_DEBUG, - "reopendir on %s returned %d (%"PRId64")", - local->loc.path, rsp.op_ret, rsp.fd); - - if (fdctx) { - pthread_mutex_lock (&conf->lock); - { - fdctx->remote_fd = rsp.fd; + if (-1 != rsp.op_ret) { + gf_stat_to_iatt (&rsp.stat, &stbuf); - if (!fdctx->released) { - list_add_tail (&fdctx->sfd_pos, &conf->saved_fds); - fdctx = NULL; - } + ret = inode_ctx_put2 (inode, frame->this, + stbuf.ia_ino, stbuf.ia_gen); + if (ret < 0) { + gf_log (frame->this->name, GF_LOG_DEBUG, + "MKNOD %"PRId64"/%s (%s): failed to set " + "remote inode number to inode ctx", + local->loc.parent->ino, local->loc.name, + local->loc.path); } - pthread_mutex_unlock (&conf->lock); + + gf_stat_to_iatt (&rsp.preparent, &preparent); + gf_stat_to_iatt (&rsp.postparent, &postparent); } out: - if (fdctx) - client_fdctx_destroy (frame->this, fdctx); - frame->local = NULL; - STACK_DESTROY (frame->root); + STACK_UNWIND_STRICT (mknod, frame, rsp.op_ret, + gf_error_to_errno (rsp.op_errno), inode, + &stbuf, &preparent, &postparent); - client_local_wipe (local); + if (local) + client_local_wipe (local); return 0; } int -protocol_client_reopendir (xlator_t *this, clnt_fd_ctx_t *fdctx) +client3_1_mkdir_cbk (struct rpc_req *req, struct iovec *iov, int count, + void *myframe) { - int ret = -1; - gfs3_opendir_req req = {0,}; - clnt_local_t *local = NULL; - inode_t *inode = NULL; - char *path = NULL; - call_frame_t *frame = NULL; - clnt_conf_t *conf = NULL; - - if (!this || !fdctx) - goto out; + call_frame_t *frame = NULL; + gfs3_mkdir_rsp rsp = {0,}; + struct iatt stbuf = {0,}; + struct iatt preparent = {0,}; + struct iatt postparent = {0,}; + int ret = 0; + clnt_local_t *local = NULL; + inode_t *inode = NULL; - inode = fdctx->inode; - conf = this->private; + frame = myframe; - ret = inode_path (inode, NULL, &path); - if (ret < 0) { - goto out; - } + local = frame->local; + frame->local = NULL; + inode = local->loc.inode; - local = GF_CALLOC (1, sizeof (*local), 0); - if (!local) { + if (-1 == req->rpc_status) { + rsp.op_ret = -1; + rsp.op_errno = ENOTCONN; goto out; } - - local->fdctx = fdctx; - local->op = client3_1_reopendir_cbk; - local->loc.path = path; - path = NULL; - - frame = create_frame (this, this->ctx->pool); - if (!frame) { + ret = xdr_to_mkdir_rsp (*iov, &rsp); + if (ret < 0) { + gf_log ("", GF_LOG_ERROR, "error"); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; goto out; } - req.ino = fdctx->ino; - req.gen = fdctx->gen; - req.path = (char *)local->loc.path; - - gf_log (frame->this->name, GF_LOG_DEBUG, - "attempting reopen on %s", local->loc.path); - - frame->local = local; local = NULL; + if (-1 != rsp.op_ret) { + gf_stat_to_iatt (&rsp.stat, &stbuf); - client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_OPENDIR, NULL, xdr_from_opendir_req); + ret = inode_ctx_put2 (inode, frame->this, + stbuf.ia_ino, stbuf.ia_gen); + if (ret < 0) { + gf_log (frame->this->name, GF_LOG_DEBUG, + "MKDIR %"PRId64"/%s (%s): failed to set " + "remote inode number to inode ctx", + local->loc.parent->ino, local->loc.name, + local->loc.path); + } - return ret; + gf_stat_to_iatt (&rsp.preparent, &preparent); + gf_stat_to_iatt (&rsp.postparent, &postparent); + } out: - if (frame) { - frame->local = NULL; - STACK_DESTROY (frame->root); - } + frame->local = NULL; + STACK_UNWIND_STRICT (mkdir, frame, rsp.op_ret, + gf_error_to_errno (rsp.op_errno), inode, + &stbuf, &preparent, &postparent); if (local) client_local_wipe (local); - if (path) - GF_FREE (path); - return 0; - } int -protocol_client_reopen (xlator_t *this, clnt_fd_ctx_t *fdctx) +client3_1_open_cbk (struct rpc_req *req, struct iovec *iov, int count, + void *myframe) { - int ret = -1; - gfs3_open_req req = {0,}; clnt_local_t *local = NULL; - inode_t *inode = NULL; - char *path = NULL; - call_frame_t *frame = NULL; clnt_conf_t *conf = NULL; + clnt_fd_ctx_t *fdctx = NULL; + call_frame_t *frame = NULL; + fd_t *fd = NULL; + ino_t ino = 0; + uint64_t gen = 0; + int ret = 0; + gfs3_open_rsp rsp = {0,}; - if (!this || !fdctx) - goto out; - - inode = fdctx->inode; - conf = this->private; - - ret = inode_path (inode, NULL, &path); - if (ret < 0) { - goto out; + frame = myframe; + local = frame->local; + + if (local->op) { + local->op (req, iov, 1, myframe); + return 0; } - frame = create_frame (this, this->ctx->pool); - if (!frame) { + frame->local = NULL; + conf = frame->this->private; + fd = local->fd; + + if (-1 == req->rpc_status) { + rsp.op_ret = -1; + rsp.op_errno = ENOTCONN; goto out; } - - local = GF_CALLOC (1, sizeof (*local), 0); - if (!local) { + ret = xdr_to_open_rsp (*iov, &rsp); + if (ret < 0) { + gf_log ("", GF_LOG_ERROR, "error"); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; goto out; } - local->fdctx = fdctx; - local->op = client3_1_reopen_cbk; - local->loc.path = path; - path = NULL; - frame->local = local; + if (-1 != rsp.op_ret) { + fdctx = GF_CALLOC (1, sizeof (*fdctx), + gf_client_mt_clnt_fdctx_t); + if (!fdctx) { + rsp.op_ret = -1; + rsp.op_errno = ENOMEM; + goto out; + } - req.ino = fdctx->ino; - req.gen = fdctx->gen; - req.flags = gf_flags_from_flags (fdctx->flags); - req.wbflags = fdctx->wbflags; - req.path = (char *)local->loc.path; + inode_ctx_get2 (fd->inode, frame->this, &ino, &gen); - gf_log (frame->this->name, GF_LOG_DEBUG, - "attempting reopen on %s", local->loc.path); + fdctx->remote_fd = rsp.fd; + fdctx->inode = inode_ref (fd->inode); + fdctx->ino = ino; + fdctx->gen = gen; + fdctx->flags = local->flags; + fdctx->wbflags = local->wbflags; - local = NULL; - client_submit_request (this, &req, frame, conf->fops, - GFS3_OP_OPEN, NULL, xdr_from_open_req); + INIT_LIST_HEAD (&fdctx->sfd_pos); - return ret; + this_fd_set_ctx (fd, frame->this, &local->loc, fdctx); -out: - if (frame) { - frame->local = NULL; - STACK_DESTROY (frame->root); + pthread_mutex_lock (&conf->lock); + { + list_add_tail (&fdctx->sfd_pos, &conf->saved_fds); + } + pthread_mutex_unlock (&conf->lock); } - if (local) - client_local_wipe (local); +out: + frame->local = NULL; + STACK_UNWIND_STRICT (open, frame, rsp.op_ret, + gf_error_to_errno (rsp.op_errno), fd); - if (path) - GF_FREE (path); + client_local_wipe (local); return 0; - } - -int32_t -client3_1_releasedir (call_frame_t *frame, xlator_t *this, rpc_clnt_prog_t *prog, - void *data) +int +client3_1_stat_cbk (struct rpc_req *req, struct iovec *iov, int count, + void *myframe) { - clnt_conf_t *conf = NULL; - clnt_fd_ctx_t *fdctx = NULL; - clnt_args_t *args = NULL; - gfs3_releasedir_req req = {0,}; - int64_t remote_fd = -1; - - if (!frame || !this || !prog || !data) - goto unwind; - - args = data; - conf = this->private; - - pthread_mutex_lock (&conf->lock); - { - fdctx = this_fd_del_ctx (args->fd, this); - if (fdctx != NULL) { - remote_fd = fdctx->remote_fd; - - /* fdctx->remote_fd == -1 indicates a reopen attempt - in progress. Just mark ->released = 1 and let - reopen_cbk handle releasing - */ + gfs3_stat_rsp rsp = {0,}; + call_frame_t *frame = NULL; + struct iatt iatt = {0,}; + int ret = 0; - if (remote_fd != -1) - list_del_init (&fdctx->sfd_pos); + frame = myframe; - fdctx->released = 1; - } + if (-1 == req->rpc_status) { + rsp.op_ret = -1; + rsp.op_errno = ENOTCONN; + goto out; + } + ret = xdr_to_stat_rsp (*iov, &rsp); + if (ret < 0) { + gf_log ("", GF_LOG_ERROR, "error"); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; } - pthread_mutex_unlock (&conf->lock); - if (remote_fd != -1) { - req.fd = remote_fd; - client_submit_request (this, &req, frame, prog, - GFS3_OP_RELEASEDIR, - NULL, xdr_from_releasedir_req); - inode_unref (fdctx->inode); - GF_FREE (fdctx); + if (-1 != rsp.op_ret) { + gf_stat_to_iatt (&rsp.stat, &iatt); } - return 0; -unwind: +out: + STACK_UNWIND_STRICT (stat, frame, rsp.op_ret, + gf_error_to_errno (rsp.op_errno), &iatt); + return 0; } -int32_t -client3_1_release (call_frame_t *frame, xlator_t *this, rpc_clnt_prog_t *prog, - void *data) +int +client3_1_readlink_cbk (struct rpc_req *req, struct iovec *iov, int count, + void *myframe) { - int64_t remote_fd = -1; - clnt_conf_t *conf = NULL; - clnt_fd_ctx_t *fdctx = NULL; - clnt_args_t *args = NULL; - gfs3_release_req req = {0,}; - - if (!frame || !this || !prog || !data) - goto unwind; + gfs3_readlink_rsp rsp = {0,}; + call_frame_t *frame = NULL; + struct iatt iatt = {0,}; + int ret = 0; - args = data; - conf = this->private; + frame = myframe; - pthread_mutex_lock (&conf->lock); - { - fdctx = this_fd_del_ctx (args->fd, this); - if (fdctx != NULL) { - remote_fd = fdctx->remote_fd; + if (-1 == req->rpc_status) { + rsp.op_ret = -1; + rsp.op_errno = ENOTCONN; + goto out; + } + ret = xdr_to_readlink_rsp (*iov, &rsp); + if (ret < 0) { + gf_log ("", GF_LOG_ERROR, "error"); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } - /* fdctx->remote_fd == -1 indicates a reopen attempt - in progress. Just mark ->released = 1 and let - reopen_cbk handle releasing - */ + if (-1 != rsp.op_ret) { + gf_stat_to_iatt (&rsp.buf, &iatt); + } - if (remote_fd != -1) - list_del_init (&fdctx->sfd_pos); +out: + STACK_UNWIND_STRICT (readlink, frame, rsp.op_ret, + gf_error_to_errno (rsp.op_errno), rsp.path, &iatt); - fdctx->released = 1; - } - } - pthread_mutex_unlock (&conf->lock); + /* This is allocated by the libc while decoding RPC msg */ + /* Hence no 'GF_FREE', but just 'free' */ + if (rsp.path) + free (rsp.path); - if (remote_fd != -1) { - req.fd = remote_fd; - client_submit_request (this, &req, frame, prog, - GFS3_OP_RELEASE, NULL, - xdr_from_release_req); - inode_unref (fdctx->inode); - GF_FREE (fdctx); - } - return 0; -unwind: return 0; } - -int32_t -client3_1_lookup (call_frame_t *frame, xlator_t *this, rpc_clnt_prog_t *prog, - void *data) +int +client3_1_unlink_cbk (struct rpc_req *req, struct iovec *iov, int count, + void *myframe) { - clnt_local_t *local = NULL; - clnt_args_t *args = NULL; - gfs3_lookup_req req = {0,}; - int ret = 0; - size_t dict_len = 0; - int op_errno = ESTALE; + call_frame_t *frame = NULL; + gfs3_unlink_rsp rsp = {0,}; + struct iatt preparent = {0,}; + struct iatt postparent = {0,}; + int ret = 0; - if (!frame || !this || !prog || !data) - goto unwind; + frame = myframe; - args = data; - local = GF_CALLOC (1, sizeof (*local), gf_client_mt_clnt_local_t); - if (!local) { - op_errno = ENOMEM; - goto unwind; + if (-1 == req->rpc_status) { + rsp.op_ret = -1; + rsp.op_errno = ENOTCONN; + goto out; + } + ret = xdr_to_unlink_rsp (*iov, &rsp); + if (ret < 0) { + gf_log ("", GF_LOG_ERROR, "error"); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; } - loc_copy (&local->loc, args->loc); - frame->local = local; + if (-1 != rsp.op_ret) { + gf_stat_to_iatt (&rsp.preparent, &preparent); + gf_stat_to_iatt (&rsp.postparent, &postparent); + } - if (args->loc->ino != 1 && args->loc->parent) { - ret = inode_ctx_get2 (args->loc->parent, this, - &req.par, &req.gen); - if (args->loc->parent->ino && ret < 0) { - gf_log (this->name, GF_LOG_TRACE, - "LOOKUP %"PRId64"/%s (%s): failed to get " - "remote inode number for parent", - args->loc->parent->ino, args->loc->name, - args->loc->path); - goto unwind; - } - GF_VALIDATE_OR_GOTO (this->name, args->loc->name, unwind); - } else { - req.ino = 1; - } +out: + STACK_UNWIND_STRICT (unlink, frame, rsp.op_ret, + gf_error_to_errno (rsp.op_errno), &preparent, + &postparent); - if (args->dict) { - ret = dict_allocate_and_serialize (args->dict, - &req.dict.dict_val, - &dict_len); - if (ret < 0) { - gf_log (this->name, GF_LOG_DEBUG, - "failed to get serialized length of dict"); - op_errno = EINVAL; - goto unwind; - } - } + return 0; +} - req.path = (char *)args->loc->path; - req.bname = (char *)args->loc->name; - req.dict.dict_len = dict_len; +int +client3_1_rmdir_cbk (struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + gfs3_rmdir_rsp rsp = {0,}; + call_frame_t *frame = NULL; + struct iatt preparent = {0,}; + struct iatt postparent = {0,}; + int ret = 0; - client_submit_request (this, &req, frame,prog, - GFS3_OP_LOOKUP, NULL, xdr_from_lookup_req); + frame = myframe; - if (req.dict.dict_val) { - GF_FREE (req.dict.dict_val); + if (-1 == req->rpc_status) { + rsp.op_ret = -1; + rsp.op_errno = ENOTCONN; + goto out; + } + ret = xdr_to_rmdir_rsp (*iov, &rsp); + if (ret < 0) { + gf_log ("", GF_LOG_ERROR, "error"); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; } - return 0; - -unwind: - frame->local = NULL; - STACK_UNWIND_STRICT (lookup, frame, -1, op_errno, NULL, NULL, NULL, NULL); - - if (local) - client_local_wipe (local); - - if (req.dict.dict_val) { - GF_FREE (req.dict.dict_val); + if (-1 != rsp.op_ret) { + gf_stat_to_iatt (&rsp.preparent, &preparent); + gf_stat_to_iatt (&rsp.postparent, &postparent); } +out: + STACK_UNWIND_STRICT (rmdir, frame, rsp.op_ret, + gf_error_to_errno (rsp.op_errno), &preparent, + &postparent); + return 0; } - -int32_t -client3_1_stat (call_frame_t *frame, xlator_t *this, rpc_clnt_prog_t *prog, - void *data) +int +client3_1_truncate_cbk (struct rpc_req *req, struct iovec *iov, int count, + void *myframe) { - clnt_args_t *args = NULL; - gfs3_stat_req req = {0,}; - int ret = 0; - int op_errno = ESTALE; + gfs3_truncate_rsp rsp = {0,}; + call_frame_t *frame = NULL; + struct iatt prestat = {0,}; + struct iatt poststat = {0,}; + int ret = 0; - if (!frame || !this || !prog || !data) - goto unwind; + frame = myframe; - args = data; + if (-1 == req->rpc_status) { + rsp.op_ret = -1; + rsp.op_errno = ENOTCONN; + goto out; + } + ret = xdr_to_truncate_rsp (*iov, &rsp); + if (ret < 0) { + gf_log ("", GF_LOG_ERROR, "error"); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } - ret = inode_ctx_get2 (args->loc->inode, this, &req.ino, &req.gen); - if (args->loc->inode->ino && ret < 0) { - gf_log (this->name, GF_LOG_TRACE, - "STAT %"PRId64" (%s): " - "failed to get remote inode number", - args->loc->inode->ino, args->loc->path); - goto unwind; + if (-1 != rsp.op_ret) { + gf_stat_to_iatt (&rsp.prestat, &prestat); + gf_stat_to_iatt (&rsp.poststat, &poststat); } - req.path = (char *)args->loc->path; - client_submit_request (this, &req, frame,prog, GFS3_OP_STAT, - NULL, xdr_from_stat_req); +out: + STACK_UNWIND_STRICT (truncate, frame, rsp.op_ret, + gf_error_to_errno (rsp.op_errno), &prestat, + &poststat); return 0; -unwind: - STACK_UNWIND_STRICT (stat, frame, -1, op_errno, NULL); - return 0; } -int32_t -client3_1_truncate (call_frame_t *frame, xlator_t *this, rpc_clnt_prog_t *prog, - void *data) +int +client3_1_statfs_cbk (struct rpc_req *req, struct iovec *iov, int count, + void *myframe) { - clnt_args_t *args = NULL; - gfs3_truncate_req req = {0,}; - int ret = 0; - int op_errno = ESTALE; + gfs3_statfs_rsp rsp = {0,}; + call_frame_t *frame = NULL; + struct statvfs statfs = {0,}; + int ret = 0; - if (!frame || !this || !prog || !data) - goto unwind; + frame = myframe; - args = data; + if (-1 == req->rpc_status) { + rsp.op_ret = -1; + rsp.op_errno = ENOTCONN; + goto out; + } + ret = xdr_to_statfs_rsp (*iov, &rsp); + if (ret < 0) { + gf_log ("", GF_LOG_ERROR, "error"); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } - ret = inode_ctx_get2 (args->loc->inode, this, &req.ino, &req.gen); - if (args->loc->inode->ino && ret < 0) { - gf_log (this->name, GF_LOG_TRACE, - "STAT %"PRId64" (%s): " - "failed to get remote inode number", - args->loc->inode->ino, args->loc->path); - goto unwind; + if (-1 != rsp.op_ret) { + gf_statfs_to_statfs (&rsp.statfs, &statfs); } - req.path = (char *)args->loc->path; - req.offset = args->offset; - client_submit_request (this, &req, frame,prog, GFS3_OP_TRUNCATE, - NULL, xdr_from_truncate_req); +out: + STACK_UNWIND_STRICT (statfs, frame, rsp.op_ret, + gf_error_to_errno (rsp.op_errno), &statfs); return 0; -unwind: - STACK_UNWIND_STRICT (truncate, frame, -1, op_errno, NULL, NULL); - return 0; } -int32_t -client3_1_ftruncate (call_frame_t *frame, xlator_t *this, rpc_clnt_prog_t *prog, - void *data) +int +client3_1_writev_cbk (struct rpc_req *req, struct iovec *iov, int count, + void *myframe) { - clnt_args_t *args = NULL; - clnt_fd_ctx_t *fdctx = NULL; - clnt_conf_t *conf = NULL; - gfs3_ftruncate_req req = {0,}; - int op_errno = EINVAL; - - if (!frame || !this || !prog || !data) - goto unwind; - - args = data; + gfs3_write_rsp rsp = {0,}; + call_frame_t *frame = NULL; + struct iatt prestat = {0,}; + struct iatt poststat = {0,}; + int ret = 0; - conf = this->private; + frame = myframe; - pthread_mutex_lock (&conf->lock); - { - fdctx = this_fd_get_ctx (args->fd, this); + if (-1 == req->rpc_status) { + rsp.op_ret = -1; + rsp.op_errno = ENOTCONN; + goto out; } - pthread_mutex_unlock (&conf->lock); - if (fdctx == NULL) { - gf_log (this->name, GF_LOG_DEBUG, - "(%"PRId64"): failed to get fd ctx. EBADFD", - args->fd->inode->ino); - op_errno = EBADFD; - goto unwind; + ret = xdr_to_truncate_rsp (*iov, &rsp); + if (ret < 0) { + gf_log ("", GF_LOG_ERROR, "error"); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; } - if (fdctx->remote_fd == -1) { - gf_log (this->name, GF_LOG_DEBUG, "(%"PRId64"): failed to get" - " fd ctx. EBADFD", args->fd->inode->ino); - op_errno = EBADFD; - goto unwind; + if (-1 != rsp.op_ret) { + gf_stat_to_iatt (&rsp.prestat, &prestat); + gf_stat_to_iatt (&rsp.poststat, &poststat); } - req.offset = args->offset; - req.fd = fdctx->remote_fd; - - client_submit_request (this, &req, frame,prog, GFS3_OP_FTRUNCATE, - NULL, xdr_from_ftruncate_req); +out: + STACK_UNWIND_STRICT (writev, frame, rsp.op_ret, + gf_error_to_errno (rsp.op_errno), &prestat, + &poststat); return 0; -unwind: - STACK_UNWIND_STRICT (ftruncate, frame, -1, op_errno, NULL, NULL); - return 0; } - - -int32_t -client3_1_access (call_frame_t *frame, xlator_t *this, rpc_clnt_prog_t *prog, - void *data) +int +client3_1_flush_cbk (struct rpc_req *req, struct iovec *iov, int count, + void *myframe) { - clnt_args_t *args = NULL; - gfs3_access_req req = {0,}; - int ret = 0; - int op_errno = ESTALE; - - if (!frame || !this || !prog || !data) - goto unwind; + call_frame_t *frame = NULL; + gf_common_rsp rsp = {0,}; + int ret = 0; - args = data; + frame = myframe; - ret = inode_ctx_get2 (args->loc->inode, this, &req.ino, &req.gen); - if (args->loc->inode->ino && ret < 0) { - gf_log (this->name, GF_LOG_TRACE, - "STAT %"PRId64" (%s): " - "failed to get remote inode number", - args->loc->inode->ino, args->loc->path); - goto unwind; + if (-1 == req->rpc_status) { + rsp.op_ret = -1; + rsp.op_errno = ENOTCONN; + goto out; } - req.path = (char *)args->loc->path; - req.mask = args->mask; - - client_submit_request (this, &req, frame,prog, GFS3_OP_ACCESS, - NULL, xdr_from_access_req); - - return 0; -unwind: - STACK_UNWIND_STRICT (access, frame, -1, op_errno); + ret = xdr_to_common_rsp (*iov, &rsp); + if (ret < 0) { + gf_log ("", GF_LOG_ERROR, "error"); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + +out: + STACK_UNWIND_STRICT (flush, frame, rsp.op_ret, + gf_error_to_errno (rsp.op_errno)); + return 0; } -int32_t -client3_1_readlink (call_frame_t *frame, xlator_t *this, rpc_clnt_prog_t *prog, - void *data) +int +client3_1_fsync_cbk (struct rpc_req *req, struct iovec *iov, int count, + void *myframe) { - clnt_args_t *args = NULL; - gfs3_readlink_req req = {0,}; - int ret = 0; - int op_errno = ESTALE; + gfs3_fsync_rsp rsp = {0,}; + call_frame_t *frame = NULL; + struct iatt prestat = {0,}; + struct iatt poststat = {0,}; + int ret = 0; - if (!frame || !this || !prog || !data) - goto unwind; + frame = myframe; - args = data; + if (-1 == req->rpc_status) { + rsp.op_ret = -1; + rsp.op_errno = ENOTCONN; + goto out; + } - ret = inode_ctx_get2 (args->loc->inode, this, &req.ino, &req.gen); - if (args->loc->inode->ino && ret < 0) { - gf_log (this->name, GF_LOG_TRACE, - "STAT %"PRId64" (%s): " - "failed to get remote inode number", - args->loc->inode->ino, args->loc->path); - goto unwind; + ret = xdr_to_truncate_rsp (*iov, &rsp); + if (ret < 0) { + gf_log ("", GF_LOG_ERROR, "error"); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + if (-1 != rsp.op_ret) { + gf_stat_to_iatt (&rsp.prestat, &prestat); + gf_stat_to_iatt (&rsp.poststat, &poststat); } - req.path = (char *)args->loc->path; - req.size = args->size; - client_submit_request (this, &req, frame,prog, GFS3_OP_READLINK, - NULL, xdr_from_readlink_req); +out: + STACK_UNWIND_STRICT (fsync, frame, rsp.op_ret, + gf_error_to_errno (rsp.op_errno), &prestat, + &poststat); return 0; -unwind: - STACK_UNWIND_STRICT (readlink, frame, -1, op_errno, NULL, NULL); - return 0; } - - - -int32_t -client3_1_unlink (call_frame_t *frame, xlator_t *this, rpc_clnt_prog_t *prog, - void *data) +int +client3_1_setxattr_cbk (struct rpc_req *req, struct iovec *iov, int count, + void *myframe) { - clnt_args_t *args = NULL; - gfs3_unlink_req req = {0,}; - int ret = 0; - int op_errno = 0; + call_frame_t *frame = NULL; + gf_common_rsp rsp = {0,}; + int ret = 0; - if (!frame || !this || !prog || !data) - goto unwind; + frame = myframe; - args = data; + if (-1 == req->rpc_status) { + rsp.op_ret = -1; + rsp.op_errno = ENOTCONN; + goto out; + } - ret = inode_ctx_get2 (args->loc->parent, this, &req.par, &req.gen); - if (args->loc->parent->ino && ret < 0) { - gf_log (this->name, GF_LOG_TRACE, - "STAT %"PRId64"/%s (%s): " - "failed to get remote inode number for parent", - args->loc->parent->ino, args->loc->name, args->loc->path); - goto unwind; + ret = xdr_to_common_rsp (*iov, &rsp); + if (ret < 0) { + gf_log ("", GF_LOG_ERROR, "error"); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; } - req.path = (char *)args->loc->path; - req.bname = (char *)args->loc->name; - client_submit_request (this, &req, frame,prog, GFS3_OP_UNLINK, - NULL, xdr_from_unlink_req); +out: + STACK_UNWIND_STRICT (setxattr, frame, rsp.op_ret, + gf_error_to_errno (rsp.op_errno)); return 0; -unwind: - STACK_UNWIND_STRICT (unlink, frame, -1, op_errno, NULL, NULL); - return 0; } - - -int32_t -client3_1_rmdir (call_frame_t *frame, xlator_t *this, rpc_clnt_prog_t *prog, - void *data) +int +client3_1_getxattr_cbk (struct rpc_req *req, struct iovec *iov, int count, + void *myframe) { - clnt_args_t *args = NULL; - gfs3_rmdir_req req = {0,}; - int ret = 0; - int op_errno = ESTALE; - - if (!frame || !this || !prog || !data) - goto unwind; + call_frame_t *frame = NULL; + dict_t *dict = NULL; + char *buf = NULL; + int dict_len = 0; + int op_ret = 0; + int op_errno = 0; + gfs3_getxattr_rsp rsp = {0,}; + int ret = 0; - args = data; + frame = myframe; - ret = inode_ctx_get2 (args->loc->parent, this, &req.par, &req.gen); - if (args->loc->inode->ino && ret < 0) { - gf_log (this->name, GF_LOG_TRACE, - "STAT %"PRId64"/%s (%s): " - "failed to get remote inode number for parent", - args->loc->parent->ino, args->loc->name, args->loc->path); - goto unwind; + if (-1 == req->rpc_status) { + op_ret = -1; + op_errno = ENOTCONN; + goto out; } - req.path = (char *)args->loc->path; - req.bname = (char *)args->loc->name; - - client_submit_request (this, &req, frame,prog, GFS3_OP_RMDIR, - NULL, xdr_from_rmdir_req); - - return 0; -unwind: - STACK_UNWIND_STRICT (rmdir, frame, -1, op_errno, NULL, NULL); - return 0; -} + ret = xdr_to_getxattr_rsp (*iov, &rsp); + if (ret < 0) { + gf_log ("", GF_LOG_ERROR, "error"); + op_ret = -1; + op_errno = EINVAL; + goto out; + } + op_errno = gf_error_to_errno (rsp.op_errno); + op_ret = rsp.op_ret; + if (-1 != op_ret) { + op_ret = -1; + dict_len = rsp.dict.dict_len; -int32_t -client3_1_symlink (call_frame_t *frame, xlator_t *this, rpc_clnt_prog_t *prog, - void *data) -{ - clnt_local_t *local = NULL; - clnt_args_t *args = NULL; - gfs3_symlink_req req = {0,}; - int ret = 0; - int op_errno = ESTALE; + if (dict_len > 0) { + dict = dict_new(); + buf = memdup (rsp.dict.dict_val, rsp.dict.dict_len); - if (!frame || !this || !prog || !data) - goto unwind; + GF_VALIDATE_OR_GOTO (frame->this->name, dict, out); + GF_VALIDATE_OR_GOTO (frame->this->name, buf, out); - args = data; - local = GF_CALLOC (1, sizeof (*local), gf_client_mt_clnt_local_t); - if (!local) { - op_errno = ENOMEM; - goto unwind; + ret = dict_unserialize (buf, dict_len, &dict); + if (ret < 0) { + gf_log (frame->this->name, GF_LOG_DEBUG, + "failed to unserialize xattr dict"); + op_errno = EINVAL; + goto out; + } + dict->extra_free = buf; + buf = NULL; + } + op_ret = 0; } - loc_copy (&local->loc, args->loc); - frame->local = local; +out: + STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno, dict); - ret = inode_ctx_get2 (args->loc->parent, this, &req.par, &req.gen); - if (args->loc->parent->ino && ret < 0) { - gf_log (this->name, GF_LOG_DEBUG, - "SYMLINK %"PRId64"/%s (%s): failed to get remote inode" - " number parent", - args->loc->parent->ino, args->loc->name, - args->loc->path); - goto unwind; + if (rsp.dict.dict_val) { + /* don't use GF_FREE, this memory was allocated by libc + */ + free (rsp.dict.dict_val); + rsp.dict.dict_val = NULL; } - req.path = (char *)args->loc->path; - req.linkname = (char *)args->linkname; - req.bname = (char *)args->loc->name; + if (buf) + GF_FREE (buf); - client_submit_request (this, &req, frame,prog, GFS3_OP_SYMLINK, - NULL, xdr_from_symlink_req); + if (dict) + dict_unref (dict); return 0; -unwind: - frame->local = NULL; - STACK_UNWIND_STRICT (symlink, frame, -1, op_errno, NULL, NULL, NULL, NULL); - if (local) - client_local_wipe (local); - return 0; } - - -int32_t -client3_1_rename (call_frame_t *frame, xlator_t *this, rpc_clnt_prog_t *prog, - void *data) +int +client3_1_fgetxattr_cbk (struct rpc_req *req, struct iovec *iov, int count, + void *myframe) { - clnt_args_t *args = NULL; - gfs3_rename_req req = {0,}; - int ret = 0; - int op_errno = ESTALE; - - if (!frame || !this || !prog || !data) - goto unwind; - - args = data; + call_frame_t *frame = NULL; + char *buf = NULL; + dict_t *dict = NULL; + gfs3_fgetxattr_rsp rsp = {0,}; + int ret = 0; + int dict_len = 0; + int op_ret = 0; + int op_errno = 0; - ret = inode_ctx_get2 (args->oldloc->parent, this, - &req.oldpar, &req.oldgen); - if (args->oldloc->parent->ino && ret < 0) { - gf_log (this->name, GF_LOG_DEBUG, - "RENAME %"PRId64"/%s (%s): failed to get remote inode " - "number for source parent", args->oldloc->parent->ino, - args->oldloc->name, args->oldloc->path); - goto unwind; - } + frame = myframe; - ret = inode_ctx_get2 (args->newloc->parent, this, &req.newpar, - &req.newgen); - if (args->newloc->parent->ino && ret < 0) { - gf_log (this->name, GF_LOG_DEBUG, - "CREATE %"PRId64"/%s (%s): failed to get remote inode " - "number for destination parent", - args->newloc->parent->ino, args->newloc->name, - args->newloc->path); - goto unwind; + if (-1 == req->rpc_status) { + op_ret = -1; + op_errno = ENOTCONN; + goto out; + } + ret = xdr_to_fgetxattr_rsp (*iov, &rsp); + if (ret < 0) { + gf_log ("", GF_LOG_ERROR, "error"); + op_ret = -1; + op_errno = EINVAL; + goto out; } - req.oldpath = (char *)args->oldloc->path; - req.oldbname = (char *)args->oldloc->name; - req.newpath = (char *)args->newloc->path; - req.newbname = (char *)args->newloc->name; - - client_submit_request (this, &req, frame,prog, GFS3_OP_RENAME, - NULL, xdr_from_rename_req); - - return 0; -unwind: - STACK_UNWIND_STRICT (rename, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); - return 0; -} + op_errno = gf_error_to_errno (rsp.op_errno); + op_ret = rsp.op_ret; + if (-1 != op_ret) { + op_ret = -1; + dict_len = rsp.dict.dict_len; + if (dict_len > 0) { + dict = dict_new(); + GF_VALIDATE_OR_GOTO (frame->this->name, dict, out); + buf = memdup (rsp.dict.dict_val, rsp.dict.dict_len); + GF_VALIDATE_OR_GOTO (frame->this->name, buf, out); + ret = dict_unserialize (buf, dict_len, &dict); + if (ret < 0) { + gf_log (frame->this->name, GF_LOG_DEBUG, + "failed to unserialize xattr dict"); + op_errno = EINVAL; + goto out; + } + dict->extra_free = buf; + buf = NULL; + } + op_ret = 0; + } +out: + STACK_UNWIND_STRICT (fgetxattr, frame, op_ret, op_errno, dict); + if (rsp.dict.dict_val) { + /* don't use GF_FREE, this memory was allocated by libc + */ + free (rsp.dict.dict_val); + rsp.dict.dict_val = NULL; + } -int32_t -client3_1_link (call_frame_t *frame, xlator_t *this, rpc_clnt_prog_t *prog, - void *data) -{ - clnt_local_t *local = NULL; - clnt_args_t *args = NULL; - gfs3_link_req req = {0,}; - int ret = 0; - int op_errno = ESTALE; + if (buf) + GF_FREE (buf); - if (!frame || !this || !prog || !data) - goto unwind; + if (dict) + dict_unref (dict); - args = data; + return 0; +} - local = GF_CALLOC (1, sizeof (*local), gf_client_mt_clnt_local_t); - if (!local) { - op_errno = ENOMEM; - goto unwind; - } +int +client3_1_removexattr_cbk (struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + call_frame_t *frame = NULL; + gf_common_rsp rsp = {0,}; + int ret = 0; - loc_copy (&local->loc, args->oldloc); - frame->local = local; + frame = myframe; - ret = inode_ctx_get2 (args->oldloc->inode, this, - &req.oldino, &req.oldgen); - if (args->oldloc->parent->ino && ret < 0) { - gf_log (this->name, GF_LOG_DEBUG, - "RENAME %"PRId64"/%s (%s): failed to get remote inode " - "number for source parent", args->oldloc->parent->ino, - args->oldloc->name, args->oldloc->path); - goto unwind; + if (-1 == req->rpc_status) { + rsp.op_ret = -1; + rsp.op_errno = ENOTCONN; + goto out; } - ret = inode_ctx_get2 (args->newloc->parent, this, &req.newpar, - &req.newgen); - if (args->newloc->parent->ino && ret < 0) { - gf_log (this->name, GF_LOG_DEBUG, - "CREATE %"PRId64"/%s (%s): failed to get remote inode " - "number for destination parent", - args->newloc->parent->ino, args->newloc->name, - args->newloc->path); - goto unwind; + ret = xdr_to_common_rsp (*iov, &rsp); + if (ret < 0) { + gf_log ("", GF_LOG_ERROR, "error"); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; } - req.oldpath = (char *)args->oldloc->path; - req.newpath = (char *)args->newloc->path; - req.newbname = (char *)args->newloc->name; - - client_submit_request (this, &req, frame,prog, GFS3_OP_LINK, - NULL, xdr_from_link_req); +out: + STACK_UNWIND_STRICT (removexattr, frame, rsp.op_ret, + gf_error_to_errno (rsp.op_errno)); return 0; -unwind: - STACK_UNWIND_STRICT (link, frame, -1, op_errno, NULL, NULL, NULL, NULL); - return 0; } - - -int32_t -client3_1_mknod (call_frame_t *frame, xlator_t *this, rpc_clnt_prog_t *prog, - void *data) +int +client3_1_fsyncdir_cbk (struct rpc_req *req, struct iovec *iov, int count, + void *myframe) { - clnt_local_t *local = NULL; - clnt_args_t *args = NULL; - gfs3_mknod_req req = {0,}; - int ret = 0; - int op_errno = ESTALE; - - if (!frame || !this || !prog || !data) - goto unwind; + call_frame_t *frame = NULL; + gf_common_rsp rsp = {0,}; + int ret = 0; - args = data; + frame = myframe; - local = GF_CALLOC (1, sizeof (*local), gf_client_mt_clnt_local_t); - if (!local) { - op_errno = ENOMEM; - goto unwind; + if (-1 == req->rpc_status) { + rsp.op_ret = -1; + rsp.op_errno = ENOTCONN; + goto out; } - - loc_copy (&local->loc, args->loc); - frame->local = local; - - ret = inode_ctx_get2 (args->loc->parent, this, &req.par, &req.gen); - if (args->loc->parent->ino && ret < 0) { - gf_log (this->name, GF_LOG_DEBUG, - "SYMLINK %"PRId64"/%s (%s): failed to get remote inode" - " number parent", - args->loc->parent->ino, args->loc->name, - args->loc->path); - goto unwind; + ret = xdr_to_common_rsp (*iov, &rsp); + if (ret < 0) { + gf_log ("", GF_LOG_ERROR, "error"); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; } - req.path = (char *)args->loc->path; - req.bname = (char *)args->loc->name; - req.mode = args->mode; - req.dev = args->rdev; - - client_submit_request (this, &req, frame,prog, GFS3_OP_MKNOD, - NULL, xdr_from_mknod_req); +out: + STACK_UNWIND_STRICT (fsyncdir, frame, rsp.op_ret, + gf_error_to_errno (rsp.op_errno)); return 0; -unwind: - frame->local = NULL; - STACK_UNWIND_STRICT (mknod, frame, -1, op_errno, NULL, NULL, NULL, NULL); - if (local) - client_local_wipe (local); - return 0; } - - -int32_t -client3_1_mkdir (call_frame_t *frame, xlator_t *this, rpc_clnt_prog_t *prog, - void *data) +int +client3_1_access_cbk (struct rpc_req *req, struct iovec *iov, int count, + void *myframe) { - clnt_local_t *local = NULL; - clnt_args_t *args = NULL; - gfs3_mkdir_req req = {0,}; - int ret = 0; - int op_errno = ESTALE; - - if (!frame || !this || !prog || !data) - goto unwind; + call_frame_t *frame = NULL; + gf_common_rsp rsp = {0,}; + int ret = 0; - args = data; + frame = myframe; - local = GF_CALLOC (1, sizeof (*local), gf_client_mt_clnt_local_t); - if (!local) { - op_errno = ENOMEM; - goto unwind; + if (-1 == req->rpc_status) { + rsp.op_ret = -1; + rsp.op_errno = ENOTCONN; + goto out; } - - loc_copy (&local->loc, args->loc); - frame->local = local; - - ret = inode_ctx_get2 (args->loc->parent, this, &req.par, &req.gen); - if (args->loc->parent->ino && ret < 0) { - gf_log (this->name, GF_LOG_DEBUG, - "SYMLINK %"PRId64"/%s (%s): failed to get remote inode" - " number parent", - args->loc->parent->ino, args->loc->name, - args->loc->path); - goto unwind; + ret = xdr_to_common_rsp (*iov, &rsp); + if (ret < 0) { + gf_log ("", GF_LOG_ERROR, "error"); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; } - req.path = (char *)args->loc->path; - req.bname = (char *)args->loc->name; - req.mode = args->mode; - - client_submit_request (this, &req, frame,prog, GFS3_OP_MKDIR, - NULL, xdr_from_mkdir_req); +out: + STACK_UNWIND_STRICT (access, frame, rsp.op_ret, + gf_error_to_errno (rsp.op_errno)); return 0; -unwind: - frame->local = NULL; - STACK_UNWIND_STRICT (mkdir, frame, -1, op_errno, NULL, NULL, NULL, NULL); - if (local) - client_local_wipe (local); - return 0; } -int32_t -client3_1_create (call_frame_t *frame, xlator_t *this, rpc_clnt_prog_t *prog, - void *data) +int +client3_1_ftruncate_cbk (struct rpc_req *req, struct iovec *iov, int count, + void *myframe) { - clnt_local_t *local = NULL; - clnt_args_t *args = NULL; - gfs3_create_req req = {0,}; - int ret = 0; - int op_errno = ESTALE; - - if (!frame || !this || !prog || !data) - goto unwind; + gfs3_ftruncate_rsp rsp = {0,}; + call_frame_t *frame = NULL; + struct iatt prestat = {0,}; + struct iatt poststat = {0,}; + int ret = 0; - args = data; + frame = myframe; - local = GF_CALLOC (1, sizeof (*local), gf_client_mt_clnt_local_t); - if (!local) { - op_errno = ENOMEM; - goto unwind; + if (-1 == req->rpc_status) { + rsp.op_ret = -1; + rsp.op_errno = ENOTCONN; + goto out; } - local->fd = fd_ref (args->fd); - local->flags = args->flags; - loc_copy (&local->loc, args->loc); - frame->local = local; - - ret = inode_ctx_get2 (args->loc->parent, this, &req.par, &req.gen); - if (args->loc->parent->ino && ret < 0) { - gf_log (this->name, GF_LOG_DEBUG, - "SYMLINK %"PRId64"/%s (%s): failed to get remote inode" - " number parent", - args->loc->parent->ino, args->loc->name, - args->loc->path); - goto unwind; + ret = xdr_to_ftruncate_rsp (*iov, &rsp); + if (ret < 0) { + gf_log ("", GF_LOG_ERROR, "error"); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; } - req.path = (char *)args->loc->path; - req.bname = (char *)args->loc->name; - req.mode = args->mode; - req.flags = gf_flags_from_flags (args->flags); + if (-1 != rsp.op_ret) { + gf_stat_to_iatt (&rsp.prestat, &prestat); + gf_stat_to_iatt (&rsp.poststat, &poststat); + } - client_submit_request (this, &req, frame,prog, GFS3_OP_CREATE, - NULL, xdr_from_create_req); +out: + STACK_UNWIND_STRICT (ftruncate, frame, rsp.op_ret, + gf_error_to_errno (rsp.op_errno), &prestat, + &poststat); return 0; -unwind: - frame->local = NULL; - STACK_UNWIND_STRICT (create, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); - if (local) - client_local_wipe (local); - return 0; } - - -int32_t -client3_1_open (call_frame_t *frame, xlator_t *this, rpc_clnt_prog_t *prog, - void *data) +int +client3_1_fstat_cbk (struct rpc_req *req, struct iovec *iov, int count, + void *myframe) { - clnt_local_t *local = NULL; - clnt_args_t *args = NULL; - gfs3_open_req req = {0,}; - int ret = 0; - int op_errno = ESTALE; - - if (!frame || !this || !prog || !data) - goto unwind; + gfs3_fstat_rsp rsp = {0,}; + call_frame_t *frame = NULL; + struct iatt stat = {0,}; + int ret = 0; - args = data; + frame = myframe; - local = GF_CALLOC (1, sizeof (*local), gf_client_mt_clnt_local_t); - if (!local) { - op_errno = ENOMEM; - goto unwind; + if (-1 == req->rpc_status) { + rsp.op_ret = -1; + rsp.op_errno = ENOTCONN; + goto out; + } + ret = xdr_to_fstat_rsp (*iov, &rsp); + if (ret < 0) { + gf_log ("", GF_LOG_ERROR, "error"); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; } - local->fd = fd_ref (args->fd); - local->flags = args->flags; - local->wbflags = args->wbflags; - loc_copy (&local->loc, args->loc); - frame->local = local; - ret = inode_ctx_get2 (args->loc->inode, this, &req.ino, &req.gen); - if (args->loc->inode->ino && ret < 0) { - gf_log (this->name, GF_LOG_DEBUG, - "OPEN %"PRId64" (%s): " - "failed to get remote inode number", - args->loc->inode->ino, args->loc->path); - goto unwind; + if (-1 != rsp.op_ret) { + gf_stat_to_iatt (&rsp.stat, &stat); } - req.flags = gf_flags_from_flags (args->flags); - req.wbflags = args->wbflags; - req.path = (char *)args->loc->path; - client_submit_request (this, &req, frame,prog, GFS3_OP_OPEN, - NULL, xdr_from_open_req); +out: + STACK_UNWIND_STRICT (fstat, frame, rsp.op_ret, + gf_error_to_errno (rsp.op_errno), &stat); return 0; -unwind: - frame->local = NULL; - STACK_UNWIND_STRICT (open, frame, -1, op_errno, NULL); - if (local) - client_local_wipe (local); - return 0; } - -int32_t -client3_1_readv (call_frame_t *frame, xlator_t *this, rpc_clnt_prog_t *prog, - void *data) +int +client3_1_inodelk_cbk (struct rpc_req *req, struct iovec *iov, int count, + void *myframe) { - clnt_args_t *args = NULL; - clnt_fd_ctx_t *fdctx = NULL; - clnt_conf_t *conf = NULL; - int op_errno = ESTALE; - gfs3_read_req req = {0,}; - - if (!frame || !this || !prog || !data) - goto unwind; - - args = data; - conf = this->private; + call_frame_t *frame = NULL; + gf_common_rsp rsp = {0,}; + int ret = 0; - pthread_mutex_lock (&conf->lock); - { - fdctx = this_fd_get_ctx (args->fd, this); - } - pthread_mutex_unlock (&conf->lock); + frame = myframe; - if (fdctx == NULL) { - gf_log (this->name, GF_LOG_DEBUG, - "(%"PRId64"): failed to get fd ctx. EBADFD", - args->fd->inode->ino); - op_errno = EBADFD; - goto unwind; + if (-1 == req->rpc_status) { + rsp.op_ret = -1; + rsp.op_errno = ENOTCONN; + goto out; } - - if (fdctx->remote_fd == -1) { - gf_log (this->name, GF_LOG_DEBUG, "(%"PRId64"): failed to get" - " fd ctx. EBADFD", args->fd->inode->ino); - op_errno = EBADFD; - goto unwind; + ret = xdr_to_common_rsp (*iov, &rsp); + if (ret < 0) { + gf_log ("", GF_LOG_ERROR, "error"); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; } - req.size = args->size; - req.offset = args->offset; - req.fd = fdctx->remote_fd; - - client_submit_request (this, &req, frame,prog, GFS3_OP_READ, - NULL, xdr_from_readv_req); +out: + STACK_UNWIND_STRICT (inodelk, frame, rsp.op_ret, + gf_error_to_errno (rsp.op_errno)); return 0; -unwind: - STACK_UNWIND_STRICT (readv, frame, -1, op_errno, NULL, 0, NULL, NULL); - return 0; } - -int32_t -client3_1_writev (call_frame_t *frame, xlator_t *this, rpc_clnt_prog_t *prog, - void *data) +int +client3_1_finodelk_cbk (struct rpc_req *req, struct iovec *iov, int count, + void *myframe) { - clnt_args_t *args = NULL; - clnt_fd_ctx_t *fdctx = NULL; - clnt_conf_t *conf = NULL; - gfs3_write_req req = {0,}; - int op_errno = ESTALE; - - if (!frame || !this || !prog || !data) - goto unwind; - - args = data; - conf = this->private; + call_frame_t *frame = NULL; + gf_common_rsp rsp = {0,}; + int ret = 0; - pthread_mutex_lock (&conf->lock); - { - fdctx = this_fd_get_ctx (args->fd, this); - } - pthread_mutex_unlock (&conf->lock); + frame = myframe; - if (fdctx == NULL) { - gf_log (this->name, GF_LOG_DEBUG, - "(%"PRId64"): failed to get fd ctx. EBADFD", - args->fd->inode->ino); - op_errno = EBADFD; - goto unwind; + if (-1 == req->rpc_status) { + rsp.op_ret = -1; + rsp.op_errno = ENOTCONN; + goto out; } - - if (fdctx->remote_fd == -1) { - gf_log (this->name, GF_LOG_DEBUG, "(%"PRId64"): failed to get" - " fd ctx. EBADFD", args->fd->inode->ino); - op_errno = EBADFD; - goto unwind; + ret = xdr_to_common_rsp (*iov, &rsp); + if (ret < 0) { + gf_log ("", GF_LOG_ERROR, "error"); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; } - req.size = args->size; - req.offset = args->offset; - req.fd = fdctx->remote_fd; - - /* TODO: Buffer */ - - client_submit_vec_request (this, &req, frame,prog, GFS3_OP_WRITE, - args->vector, args->count, - args->iobref, xdr_from_writev_req); +out: + STACK_UNWIND_STRICT (finodelk, frame, rsp.op_ret, + gf_error_to_errno (rsp.op_errno)); return 0; -unwind: - STACK_UNWIND_STRICT (writev, frame, -1, op_errno, NULL, NULL); - return 0; } - - -int32_t -client3_1_flush (call_frame_t *frame, xlator_t *this, rpc_clnt_prog_t *prog, - void *data) +int +client3_1_entrylk_cbk (struct rpc_req *req, struct iovec *iov, int count, + void *myframe) { - clnt_args_t *args = NULL; - gfs3_flush_req req = {0,}; - clnt_fd_ctx_t *fdctx = NULL; - clnt_conf_t *conf = NULL; - int op_errno = ESTALE; - - if (!frame || !this || !prog || !data) - goto unwind; + call_frame_t *frame = NULL; + gf_common_rsp rsp = {0,}; + int ret = 0; - args = data; - conf = this->private; + frame = myframe; - pthread_mutex_lock (&conf->lock); - { - fdctx = this_fd_get_ctx (args->fd, this); - } - pthread_mutex_unlock (&conf->lock); - - if (fdctx == NULL) { - gf_log (this->name, GF_LOG_DEBUG, - "(%"PRId64"): failed to get fd ctx. EBADFD", - args->fd->inode->ino); - op_errno = EBADFD; - goto unwind; + if (-1 == req->rpc_status) { + rsp.op_ret = -1; + rsp.op_errno = ENOTCONN; + goto out; } - - if (fdctx->remote_fd == -1) { - gf_log (this->name, GF_LOG_DEBUG, "(%"PRId64"): failed to get" - " fd ctx. EBADFD", args->fd->inode->ino); - op_errno = EBADFD; - goto unwind; + ret = xdr_to_common_rsp (*iov, &rsp); + if (ret < 0) { + gf_log ("", GF_LOG_ERROR, "error"); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; } - req.fd = fdctx->remote_fd; +out: - client_submit_request (this, &req, frame,prog, GFS3_OP_FLUSH, - NULL, xdr_from_flush_req); + STACK_UNWIND_STRICT (entrylk, frame, rsp.op_ret, + gf_error_to_errno (rsp.op_errno)); return 0; -unwind: - STACK_UNWIND_STRICT (flush, frame, -1, op_errno); - return 0; } - - -int32_t -client3_1_fsync (call_frame_t *frame, xlator_t *this, rpc_clnt_prog_t *prog, - void *data) +int +client3_1_fentrylk_cbk (struct rpc_req *req, struct iovec *iov, int count, + void *myframe) { - clnt_args_t *args = NULL; - gfs3_fsync_req req = {0,}; - clnt_fd_ctx_t *fdctx = NULL; - clnt_conf_t *conf = NULL; - int op_errno = 0; - - if (!frame || !this || !prog || !data) - goto unwind; - - args = data; - conf = this->private; + call_frame_t *frame = NULL; + gf_common_rsp rsp = {0,}; + int ret = 0; - pthread_mutex_lock (&conf->lock); - { - fdctx = this_fd_get_ctx (args->fd, this); - } - pthread_mutex_unlock (&conf->lock); + frame = myframe; - if (fdctx == NULL) { - gf_log (this->name, GF_LOG_DEBUG, - "(%"PRId64"): failed to get fd ctx. EBADFD", - args->fd->inode->ino); - op_errno = EBADFD; - goto unwind; + if (-1 == req->rpc_status) { + rsp.op_ret = -1; + rsp.op_errno = ENOTCONN; + goto out; } - - if (fdctx->remote_fd == -1) { - gf_log (this->name, GF_LOG_DEBUG, "(%"PRId64"): failed to get" - " fd ctx. EBADFD", args->fd->inode->ino); - op_errno = EBADFD; - goto unwind; + ret = xdr_to_common_rsp (*iov, &rsp); + if (ret < 0) { + gf_log ("", GF_LOG_ERROR, "error"); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; } - req.fd = fdctx->remote_fd; - req.data = args->flags; - - client_submit_request (this, &req, frame,prog, GFS3_OP_FSYNC, - NULL, xdr_from_fsync_req); +out: + STACK_UNWIND_STRICT (fentrylk, frame, rsp.op_ret, + gf_error_to_errno (rsp.op_errno)); return 0; -unwind: - STACK_UNWIND_STRICT (fsync, frame, -1, op_errno, NULL, NULL); - return 0; } +int +client3_1_xattrop_cbk (struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + call_frame_t *frame = NULL; + dict_t *dict = NULL; + char *buf = NULL; + gfs3_xattrop_rsp rsp = {0,}; + int ret = 0; + int op_ret = 0; + int dict_len = 0; + int op_errno = 0; + frame = myframe; -int32_t -client3_1_fstat (call_frame_t *frame, xlator_t *this, rpc_clnt_prog_t *prog, - void *data) -{ - clnt_args_t *args = NULL; - gfs3_fstat_req req = {0,}; - clnt_fd_ctx_t *fdctx = NULL; - clnt_conf_t *conf = NULL; - int op_errno = ESTALE; + if (-1 == req->rpc_status) { + op_ret = -1; + op_errno = ENOTCONN; + goto out; + } + ret = xdr_to_xattrop_rsp (*iov, &rsp); + if (ret < 0) { + gf_log ("", GF_LOG_ERROR, "error"); + op_ret = -1; + op_errno = EINVAL; + goto out; + } - if (!frame || !this || !prog || !data) - goto unwind; + op_ret = rsp.op_ret; + if (-1 != op_ret) { + op_ret = -1; + dict_len = rsp.dict.dict_len; - args = data; - conf = this->private; + if (dict_len > 0) { + dict = dict_new(); + GF_VALIDATE_OR_GOTO (frame->this->name, dict, out); - pthread_mutex_lock (&conf->lock); - { - fdctx = this_fd_get_ctx (args->fd, this); + buf = memdup (rsp.dict.dict_val, rsp.dict.dict_len); + GF_VALIDATE_OR_GOTO (frame->this->name, buf, out); + op_ret = dict_unserialize (buf, dict_len, &dict); + if (op_ret < 0) { + gf_log (frame->this->name, GF_LOG_DEBUG, + "failed to unserialize xattr dict"); + op_errno = EINVAL; + goto out; + } + dict->extra_free = buf; + buf = NULL; + } + op_ret = 0; } - pthread_mutex_unlock (&conf->lock); - if (fdctx == NULL) { - gf_log (this->name, GF_LOG_DEBUG, - "(%"PRId64"): failed to get fd ctx. EBADFD", - args->fd->inode->ino); - op_errno = EBADFD; - goto unwind; - } +out: - if (fdctx->remote_fd == -1) { - gf_log (this->name, GF_LOG_DEBUG, "(%"PRId64"): failed to get" - " fd ctx. EBADFD", args->fd->inode->ino); - op_errno = EBADFD; - goto unwind; + STACK_UNWIND_STRICT (xattrop, frame, op_ret, + gf_error_to_errno (rsp.op_errno), dict); + + if (rsp.dict.dict_val) { + /* don't use GF_FREE, this memory was allocated by libc + */ + free (rsp.dict.dict_val); + rsp.dict.dict_val = NULL; } - req.fd = fdctx->remote_fd; + if (buf) + GF_FREE (buf); - client_submit_request (this, &req, frame,prog, GFS3_OP_FSTAT, - NULL, xdr_from_fstat_req); + if (dict) + dict_unref (dict); return 0; -unwind: - STACK_UNWIND_STRICT (fstat, frame, -1, op_errno, NULL); - return 0; } - - -int32_t -client3_1_opendir (call_frame_t *frame, xlator_t *this, rpc_clnt_prog_t *prog, - void *data) +int +client3_1_fxattrop_cbk (struct rpc_req *req, struct iovec *iov, int count, + void *myframe) { - clnt_local_t *local = NULL; - clnt_args_t *args = NULL; - gfs3_opendir_req req = {0,}; - int ret = 0; - int op_errno = ESTALE; - - if (!frame || !this || !prog || !data) - goto unwind; + call_frame_t *frame = NULL; + dict_t *dict = NULL; + char *buf = NULL; + gfs3_fxattrop_rsp rsp = {0,}; + int ret = 0; + int op_ret = 0; + int dict_len = 0; + int op_errno = 0; - args = data; + frame = myframe; - local = GF_CALLOC (1, sizeof (*local), gf_client_mt_clnt_local_t); - if (!local) { - op_errno = ENOMEM; - goto unwind; + if (-1 == req->rpc_status) { + op_ret = -1; + op_errno = ENOTCONN; + goto out; } - local->fd = fd_ref (args->fd); - loc_copy (&local->loc, args->loc); - frame->local = local; - ret = inode_ctx_get2 (args->loc->inode, this, &req.ino, &req.gen); - if (args->loc->inode->ino && ret < 0) { - gf_log (this->name, GF_LOG_DEBUG, - "OPEN %"PRId64" (%s): " - "failed to get remote inode number", - args->loc->inode->ino, args->loc->path); - goto unwind; + ret = xdr_to_fxattrop_rsp (*iov, &rsp); + if (ret < 0) { + op_ret = -1; + op_errno = EINVAL; + gf_log ("", GF_LOG_ERROR, "error"); + goto out; } - req.path = (char *)args->loc->path; - client_submit_request (this, &req, frame,prog, GFS3_OP_OPENDIR, - NULL, xdr_from_opendir_req); + op_ret = rsp.op_ret; + if (-1 != op_ret) { + op_ret = -1; + dict_len = rsp.dict.dict_len; - return 0; -unwind: - frame->local = NULL; - STACK_UNWIND_STRICT (opendir, frame, -1, op_errno, NULL); - if (local) - client_local_wipe (local); - return 0; -} + if (dict_len > 0) { + dict = dict_new(); + GF_VALIDATE_OR_GOTO (frame->this->name, dict, out); + buf = memdup (rsp.dict.dict_val, rsp.dict.dict_len); + GF_VALIDATE_OR_GOTO (frame->this->name, buf, out); + op_ret = dict_unserialize (buf, dict_len, &dict); + if (op_ret < 0) { + gf_log (frame->this->name, GF_LOG_DEBUG, + "failed to unserialize xattr dict"); + op_errno = EINVAL; + goto out; + } + dict->extra_free = buf; + buf = NULL; + } + op_ret = 0; + } +out: -int32_t -client3_1_fsyncdir (call_frame_t *frame, xlator_t *this, rpc_clnt_prog_t *prog, - void *data) + STACK_UNWIND_STRICT (fxattrop, frame, op_ret, + gf_error_to_errno (rsp.op_errno), dict); -{ - clnt_args_t *args = NULL; - clnt_fd_ctx_t *fdctx = NULL; - clnt_conf_t *conf = NULL; - int op_errno = ESTALE; - gfs3_fsyncdir_req req = {0,}; - - if (!frame || !this || !prog || !data) - goto unwind; - - args = data; - conf = this->private; - - pthread_mutex_lock (&conf->lock); - { - fdctx = this_fd_get_ctx (args->fd, this); - } - pthread_mutex_unlock (&conf->lock); - - if (fdctx == NULL) { - gf_log (this->name, GF_LOG_DEBUG, - "(%"PRId64"): failed to get fd ctx. EBADFD", - args->fd->inode->ino); - op_errno = EBADFD; - goto unwind; - } - - if (fdctx->remote_fd == -1) { - gf_log (this->name, GF_LOG_DEBUG, "(%"PRId64"): failed to get" - " fd ctx. EBADFD", args->fd->inode->ino); - op_errno = EBADFD; - goto unwind; + if (rsp.dict.dict_val) { + /* don't use GF_FREE, this memory was allocated by libc + */ + free (rsp.dict.dict_val); + rsp.dict.dict_val = NULL; } - req.fd = fdctx->remote_fd; - req.data = args->flags; + if (buf) + GF_FREE (buf); - client_submit_request (this, &req, frame,prog, GFS3_OP_FSYNCDIR, - NULL, xdr_from_fsyncdir_req); + if (dict) + dict_unref (dict); return 0; -unwind: - STACK_UNWIND_STRICT (fsyncdir, frame, -1, op_errno); - return 0; } - - -int32_t -client3_1_statfs (call_frame_t *frame, xlator_t *this, rpc_clnt_prog_t *prog, - void *data) +int +client3_1_fsetxattr_cbk (struct rpc_req *req, struct iovec *iov, int count, + void *myframe) { - clnt_args_t *args = NULL; - gfs3_statfs_req req = {0,}; - int ret = 0; - int op_errno = ESTALE; - - if (!frame || !this || !prog || !data) - goto unwind; + call_frame_t *frame = NULL; + gf_common_rsp rsp = {0,}; + int ret = 0; - args = data; + frame = myframe; - if (args->loc->inode) { - ret = inode_ctx_get2 (args->loc->inode, this, - &req.ino, &req.gen); - if (args->loc->inode->ino && ret < 0) { - gf_log (this->name, GF_LOG_TRACE, - "STATFS %"PRId64" (%s): " - "failed to get remote inode number", - args->loc->inode->ino, args->loc->path); - goto unwind; - } + if (-1 == req->rpc_status) { + rsp.op_ret = -1; + rsp.op_errno = ENOTCONN; + goto out; + } + ret = xdr_to_common_rsp (*iov, &rsp); + if (ret < 0) { + gf_log ("", GF_LOG_ERROR, "error"); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; } - req.path = (char *)args->loc->path; - client_submit_request (this, &req, frame,prog, GFS3_OP_STATFS, - NULL, xdr_from_statfs_req); +out: + STACK_UNWIND_STRICT (fsetxattr, frame, rsp.op_ret, + gf_error_to_errno (rsp.op_errno)); return 0; -unwind: - STACK_UNWIND_STRICT (statfs, frame, -1, op_errno, NULL); - return 0; } - - -int32_t -client3_1_setxattr (call_frame_t *frame, xlator_t *this, rpc_clnt_prog_t *prog, - void *data) +int +client3_1_fsetattr_cbk (struct rpc_req *req, struct iovec *iov, int count, + void *myframe) { - clnt_args_t *args = NULL; - gfs3_setxattr_req req = {0,}; - int ret = 0; - size_t dict_len = 0; - int op_errno = ESTALE; - - if (!frame || !this || !prog || !data) - goto unwind; + call_frame_t *frame = NULL; + gfs3_fsetattr_rsp rsp = {0,}; + struct iatt prestat = {0,}; + struct iatt poststat = {0,}; + int ret = 0; - args = data; + frame = myframe; - ret = inode_ctx_get2 (args->loc->inode, this, &req.ino, &req.gen); - if (args->loc->inode->ino && ret < 0) { - gf_log (this->name, GF_LOG_DEBUG, - "SETXATTR %"PRId64" (%s): " - "failed to get remote inode number", - args->loc->inode->ino, args->loc->path); - goto unwind; + if (-1 == req->rpc_status) { + rsp.op_ret = -1; + rsp.op_errno = ENOTCONN; + goto out; } - if (args->dict) { - ret = dict_allocate_and_serialize (args->dict, - &req.dict.dict_val, - &dict_len); - if (ret < 0) { - gf_log (this->name, GF_LOG_DEBUG, - "failed to get serialized dict"); - op_errno = EINVAL; - goto unwind; - } - req.dict.dict_len = dict_len; + ret = xdr_to_fsetattr_rsp (*iov, &rsp); + if (ret < 0) { + gf_log ("", GF_LOG_ERROR, "error"); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; } - req.flags = args->flags; - req.path = (char *)args->loc->path; - client_submit_request (this, &req, frame,prog, GFS3_OP_SETXATTR, - NULL, xdr_from_setxattr_req); - - if (req.dict.dict_val) { - GF_FREE (req.dict.dict_val); + if (-1 != rsp.op_ret) { + gf_stat_to_iatt (&rsp.statpre, &prestat); + gf_stat_to_iatt (&rsp.statpost, &poststat); } - return 0; -unwind: - STACK_UNWIND_STRICT (setxattr, frame, -1, op_errno); - if (req.dict.dict_val) { - GF_FREE (req.dict.dict_val); - } +out: + STACK_UNWIND_STRICT (fsetattr, frame, rsp.op_ret, + gf_error_to_errno (rsp.op_errno), &prestat, + &poststat); + return 0; } - -int32_t -client3_1_fsetxattr (call_frame_t *frame, xlator_t *this, rpc_clnt_prog_t *prog, - void *data) +int +client3_1_setattr_cbk (struct rpc_req *req, struct iovec *iov, int count, + void *myframe) { - clnt_args_t *args = NULL; - clnt_fd_ctx_t *fdctx = NULL; - clnt_conf_t *conf = NULL; - gfs3_fsetxattr_req req = {0,}; - int op_errno = ESTALE; - int ret = 0; - size_t dict_len = 0; - - if (!frame || !this || !prog || !data) - goto unwind; - - args = data; - conf = this->private; + call_frame_t *frame = NULL; + gfs3_setattr_rsp rsp = {0,}; + struct iatt prestat = {0,}; + struct iatt poststat = {0,}; + int ret = 0; - pthread_mutex_lock (&conf->lock); - { - fdctx = this_fd_get_ctx (args->fd, this); - } - pthread_mutex_unlock (&conf->lock); + frame = myframe; - if (fdctx == NULL) { - gf_log (this->name, GF_LOG_DEBUG, - "(%"PRId64"): failed to get fd ctx. EBADFD", - args->fd->inode->ino); - op_errno = EBADFD; - goto unwind; + if (-1 == req->rpc_status) { + rsp.op_ret = -1; + rsp.op_errno = ENOTCONN; + goto out; } - if (fdctx->remote_fd == -1) { - gf_log (this->name, GF_LOG_DEBUG, "(%"PRId64"): failed to get" - " fd ctx. EBADFD", args->fd->inode->ino); - op_errno = EBADFD; - goto unwind; + ret = xdr_to_setattr_rsp (*iov, &rsp); + if (ret < 0) { + gf_log ("", GF_LOG_ERROR, "error"); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; } - req.fd = fdctx->remote_fd; - req.flags = args->flags; - req.ino = args->fd->inode->ino; - - if (args->dict) { - ret = dict_allocate_and_serialize (args->dict, - &req.dict.dict_val, - &dict_len); - if (ret < 0) { - gf_log (this->name, GF_LOG_DEBUG, - "failed to get serialized dict"); - goto unwind; - } - req.dict.dict_len = dict_len; + if (-1 != rsp.op_ret) { + gf_stat_to_iatt (&rsp.statpre, &prestat); + gf_stat_to_iatt (&rsp.statpost, &poststat); } - client_submit_request (this, &req, frame,prog, GFS3_OP_FSETXATTR, - NULL, xdr_from_fsetxattr_req); - - if (req.dict.dict_val) { - GF_FREE (req.dict.dict_val); - } +out: + STACK_UNWIND_STRICT (setattr, frame, rsp.op_ret, + gf_error_to_errno (rsp.op_errno), &prestat, + &poststat); - return 0; -unwind: - STACK_UNWIND_STRICT (fsetxattr, frame, -1, op_errno); - if (req.dict.dict_val) { - GF_FREE (req.dict.dict_val); - } return 0; } - - - -int32_t -client3_1_fgetxattr (call_frame_t *frame, xlator_t *this, rpc_clnt_prog_t *prog, - void *data) +int +client3_1_create_cbk (struct rpc_req *req, struct iovec *iov, int count, + void *myframe) { - clnt_args_t *args = NULL; - clnt_fd_ctx_t *fdctx = NULL; - clnt_conf_t *conf = NULL; - gfs3_fgetxattr_req req = {0,}; - int op_errno = ESTALE; - - if (!frame || !this || !prog || !data) - goto unwind; - - args = data; - conf = this->private; + call_frame_t *frame = NULL; + fd_t *fd = NULL; + inode_t *inode = NULL; + struct iatt stbuf = {0, }; + struct iatt preparent = {0, }; + struct iatt postparent = {0, }; + int32_t ret = -1; + clnt_local_t *local = NULL; + clnt_conf_t *conf = NULL; + clnt_fd_ctx_t *fdctx = NULL; + gfs3_create_rsp rsp = {0,}; - pthread_mutex_lock (&conf->lock); - { - fdctx = this_fd_get_ctx (args->fd, this); - } - pthread_mutex_unlock (&conf->lock); + frame = myframe; + local = frame->local; frame->local = NULL; + conf = frame->this->private; + fd = local->fd; + inode = local->loc.inode; - if (fdctx == NULL) { - gf_log (this->name, GF_LOG_DEBUG, - "(%"PRId64"): failed to get fd ctx. EBADFD", - args->fd->inode->ino); - op_errno = EBADFD; - goto unwind; + if (-1 == req->rpc_status) { + rsp.op_ret = -1; + rsp.op_errno = ENOTCONN; + goto out; } - if (fdctx->remote_fd == -1) { - gf_log (this->name, GF_LOG_DEBUG, "(%"PRId64"): failed to get" - " fd ctx. EBADFD", args->fd->inode->ino); - op_errno = EBADFD; - goto unwind; + ret = xdr_to_create_rsp (*iov, &rsp); + if (ret < 0) { + gf_log ("", GF_LOG_ERROR, "error"); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; } - req.namelen = 1; /* Use it as a flag */ - req.fd = fdctx->remote_fd; - req.name = (char *)args->name; - if (!req.name) { - req.name = ""; - req.namelen = 0; + if (-1 != rsp.op_ret) { + gf_stat_to_iatt (&rsp.stat, &stbuf); + + ret = inode_ctx_put2 (inode, frame->this, + stbuf.ia_ino, stbuf.ia_gen); + if (ret < 0) { + gf_log (frame->this->name, GF_LOG_DEBUG, + "CREATE %"PRId64"/%s (%s): failed to set " + "remote inode number to inode ctx", + local->loc.parent->ino, local->loc.name, + local->loc.path); + } + + gf_stat_to_iatt (&rsp.preparent, &preparent); + gf_stat_to_iatt (&rsp.postparent, &postparent); + + fdctx = GF_CALLOC (1, sizeof (*fdctx), + gf_client_mt_clnt_fdctx_t); + if (!fdctx) { + rsp.op_ret = -1; + rsp.op_errno = ENOMEM; + goto out; + } + + fdctx->remote_fd = rsp.fd; + fdctx->inode = inode_ref (inode); + fdctx->ino = stbuf.ia_ino; + fdctx->gen = stbuf.ia_gen; + fdctx->flags = local->flags; + + INIT_LIST_HEAD (&fdctx->sfd_pos); + + this_fd_set_ctx (fd, frame->this, &local->loc, fdctx); + + pthread_mutex_lock (&conf->lock); + { + list_add_tail (&fdctx->sfd_pos, &conf->saved_fds); + } + pthread_mutex_unlock (&conf->lock); } - client_submit_request (this, &req, frame,prog, GFS3_OP_FGETXATTR, - NULL, xdr_from_fgetxattr_req); +out: + frame->local = NULL; + STACK_UNWIND_STRICT (create, frame, rsp.op_ret, + gf_error_to_errno (rsp.op_errno), fd, inode, + &stbuf, &preparent, &postparent); - return 0; -unwind: - STACK_UNWIND_STRICT (fgetxattr, frame, -1, op_errno, NULL); + client_local_wipe (local); return 0; } - -int32_t -client3_1_getxattr (call_frame_t *frame, xlator_t *this, rpc_clnt_prog_t *prog, - void *data) +int +client3_1_rchecksum_cbk (struct rpc_req *req, struct iovec *iov, int count, + void *myframe) { - clnt_args_t *args = NULL; - gfs3_getxattr_req req = {0,}; - int ret = 0; - int op_errno = ESTALE; - - if (!frame || !this || !prog || !data) - goto unwind; + call_frame_t *frame = NULL; + gfs3_rchecksum_rsp rsp = {0,}; + int ret = 0; - args = data; + frame = myframe; - ret = inode_ctx_get2 (args->loc->inode, this, &req.ino, &req.gen); - if (args->loc->inode->ino && ret < 0) { - gf_log (this->name, GF_LOG_TRACE, - "STAT %"PRId64" (%s): " - "failed to get remote inode number", - args->loc->inode->ino, args->loc->path); - goto unwind; + if (-1 == req->rpc_status) { + rsp.op_ret = -1; + rsp.op_errno = ENOTCONN; + goto out; } - req.namelen = 1; /* Use it as a flag */ - req.path = (char *)args->loc->path; - req.name = (char *)args->name; - if (!req.name) { - req.name = ""; - req.namelen = 0; + ret = xdr_to_rchecksum_rsp (*iov, &rsp); + if (ret < 0) { + gf_log ("", GF_LOG_ERROR, "error"); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; } - client_submit_request (this, &req, frame,prog, GFS3_OP_GETXATTR, - NULL, xdr_from_getxattr_req); +out: + STACK_UNWIND_STRICT (rchecksum, frame, rsp.op_ret, + gf_error_to_errno (rsp.op_errno), + rsp.weak_checksum, + (uint8_t *)rsp.strong_checksum.strong_checksum_val); + + if (rsp.strong_checksum.strong_checksum_val) { + /* This is allocated by the libc while decoding RPC msg */ + /* Hence no 'GF_FREE', but just 'free' */ + free (rsp.strong_checksum.strong_checksum_val); + } - return 0; -unwind: - STACK_UNWIND_STRICT (getxattr, frame, -1, op_errno, NULL); return 0; } - - -int32_t -client3_1_xattrop (call_frame_t *frame, xlator_t *this, rpc_clnt_prog_t *prog, - void *data) +int +client3_1_checksum_cbk (struct rpc_req *req, struct iovec *iov, int count, + void *myframe) { - clnt_args_t *args = NULL; - gfs3_xattrop_req req = {0,}; - int ret = 0; - size_t dict_len = 0; - int op_errno = ESTALE; - - if (!frame || !this || !prog || !data) - goto unwind; + call_frame_t *frame = NULL; + gfs3_checksum_rsp rsp = {0,}; + int ret = 0; - args = data; + frame = myframe; - ret = inode_ctx_get2 (args->loc->inode, this, &req.ino, &req.gen); - if (args->loc->inode->ino && ret < 0) { - gf_log (this->name, GF_LOG_DEBUG, - "SETXATTR %"PRId64" (%s): " - "failed to get remote inode number", - args->loc->inode->ino, args->loc->path); - goto unwind; + if (-1 == req->rpc_status) { + rsp.op_ret = -1; + rsp.op_errno = ENOTCONN; + goto out; } - if (args->dict) { - ret = dict_allocate_and_serialize (args->dict, - &req.dict.dict_val, - &dict_len); - if (ret < 0) { - gf_log (this->name, GF_LOG_DEBUG, - "failed to get serialized dict"); - op_errno = EINVAL; - goto unwind; - } - req.dict.dict_len = dict_len; + + ret = xdr_to_checksum_rsp (*iov, &rsp); + if (ret < 0) { + gf_log ("", GF_LOG_ERROR, "error"); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; } - req.flags = args->flags; - req.path = (char *)args->loc->path; - client_submit_request (this, &req, frame,prog, GFS3_OP_XATTROP, - NULL, xdr_from_xattrop_req); +out: + STACK_UNWIND_STRICT (checksum, frame, rsp.op_ret, + gf_error_to_errno (rsp.op_errno), + (uint8_t *)rsp.fchecksum.fchecksum_val, + (uint8_t *)rsp.dchecksum.dchecksum_val); - if (req.dict.dict_val) { - GF_FREE (req.dict.dict_val); + /* This is allocated by the libc while decoding RPC msg */ + /* Hence no 'GF_FREE', but just 'free' */ + if (rsp.fchecksum.fchecksum_val) { + free (rsp.fchecksum.fchecksum_val); } - return 0; -unwind: - STACK_UNWIND_STRICT (xattrop, frame, -1, op_errno, NULL); - if (req.dict.dict_val) { - GF_FREE (req.dict.dict_val); + if (rsp.dchecksum.dchecksum_val) { + free (rsp.dchecksum.dchecksum_val); } return 0; } - - -int32_t -client3_1_fxattrop (call_frame_t *frame, xlator_t *this, rpc_clnt_prog_t *prog, - void *data) +int +client3_1_lk_cbk (struct rpc_req *req, struct iovec *iov, int count, + void *myframe) { - clnt_args_t *args = NULL; - clnt_fd_ctx_t *fdctx = NULL; - clnt_conf_t *conf = NULL; - gfs3_fxattrop_req req = {0,}; - int op_errno = ESTALE; - int ret = 0; - size_t dict_len = 0; - - if (!frame || !this || !prog || !data) - goto unwind; + call_frame_t *frame = NULL; + struct flock lock = {0,}; + gfs3_lk_rsp rsp = {0,}; + int ret = 0; - args = data; - conf = this->private; + frame = myframe; - pthread_mutex_lock (&conf->lock); - { - fdctx = this_fd_get_ctx (args->fd, this); + if (-1 == req->rpc_status) { + rsp.op_ret = -1; + rsp.op_errno = ENOTCONN; + goto out; } - pthread_mutex_unlock (&conf->lock); - if (fdctx == NULL) { - gf_log (this->name, GF_LOG_DEBUG, - "(%"PRId64"): failed to get fd ctx. EBADFD", - args->fd->inode->ino); - op_errno = EBADFD; - goto unwind; + ret = xdr_to_lk_rsp (*iov, &rsp); + if (ret < 0) { + gf_log ("", GF_LOG_ERROR, "error"); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; } - if (fdctx->remote_fd == -1) { - gf_log (this->name, GF_LOG_DEBUG, "(%"PRId64"): failed to get" - " fd ctx. EBADFD", args->fd->inode->ino); - op_errno = EBADFD; - goto unwind; + if (rsp.op_ret >= 0) { + gf_flock_to_flock (&rsp.flock, &lock); } - req.fd = fdctx->remote_fd; - req.flags = args->flags; - req.ino = args->fd->inode->ino; +out: + STACK_UNWIND_STRICT (lk, frame, rsp.op_ret, + gf_error_to_errno (rsp.op_errno), &lock); - if (args->dict) { - ret = dict_allocate_and_serialize (args->dict, - &req.dict.dict_val, - &dict_len); - if (ret < 0) { - gf_log (this->name, GF_LOG_DEBUG, - "failed to get serialized dict"); - goto unwind; - } - req.dict.dict_len = dict_len; + return 0; +} + +int +client3_1_readdir_cbk (struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + call_frame_t *frame = NULL; + gfs3_readdir_rsp rsp = {0,}; + int32_t ret = 0; + gf_dirent_t entries; + + frame = myframe; + + if (-1 == req->rpc_status) { + rsp.op_ret = -1; + rsp.op_errno = ENOTCONN; + goto out; } - client_submit_request (this, &req, frame,prog, GFS3_OP_FXATTROP, - NULL, xdr_from_fxattrop_req); - if (req.dict.dict_val) { - GF_FREE (req.dict.dict_val); + ret = xdr_to_readdir_rsp (*iov, &rsp); + if (ret < 0) { + gf_log ("", GF_LOG_ERROR, "error"); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; } - return 0; -unwind: - STACK_UNWIND_STRICT (fxattrop, frame, -1, op_errno, NULL); - if (req.dict.dict_val) { - GF_FREE (req.dict.dict_val); + INIT_LIST_HEAD (&entries.list); + if (rsp.op_ret > 0) { + unserialize_rsp_dirent (&rsp, &entries); } + +out: + STACK_UNWIND_STRICT (readdir, frame, rsp.op_ret, + gf_error_to_errno (rsp.op_errno), &entries); + + if (rsp.op_ret != -1) { + gf_dirent_free (&entries); + } + + clnt_readdir_rsp_cleanup (&rsp); + return 0; } - -int32_t -client3_1_removexattr (call_frame_t *frame, xlator_t *this, rpc_clnt_prog_t *prog, - void *data) +int +client3_1_readdirp_cbk (struct rpc_req *req, struct iovec *iov, int count, + void *myframe) { - clnt_args_t *args = NULL; - gfs3_removexattr_req req = {0,}; - int ret = 0; - int op_errno = ESTALE; + call_frame_t *frame = NULL; + gfs3_readdirp_rsp rsp = {0,}; + int32_t ret = 0; + gf_dirent_t entries; - if (!frame || !this || !prog || !data) - goto unwind; + frame = myframe; - args = data; + if (-1 == req->rpc_status) { + rsp.op_ret = -1; + rsp.op_errno = ENOTCONN; + goto out; + } - ret = inode_ctx_get2 (args->loc->inode, this, &req.ino, &req.gen); - if (args->loc->inode->ino && ret < 0) { - gf_log (this->name, GF_LOG_TRACE, - "REMOVEXATTR %"PRId64" (%s): " - "failed to get remote inode number", - args->loc->inode->ino, args->loc->path); - goto unwind; + ret = xdr_to_readdirp_rsp (*iov, &rsp); + if (ret < 0) { + gf_log ("", GF_LOG_ERROR, "error"); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; } - req.path = (char *)args->loc->path; - req.name = (char *)args->name; - client_submit_request (this, &req, frame,prog, GFS3_OP_REMOVEXATTR, - NULL, xdr_from_removexattr_req); + INIT_LIST_HEAD (&entries.list); + if (rsp.op_ret > 0) { + unserialize_rsp_direntp (&rsp, &entries); + } + +out: + STACK_UNWIND_STRICT (readdirp, frame, rsp.op_ret, + gf_error_to_errno (rsp.op_errno), &entries); + + if (rsp.op_ret != -1) { + gf_dirent_free (&entries); + } + + clnt_readdirp_rsp_cleanup (&rsp); - return 0; -unwind: - STACK_UNWIND_STRICT (removexattr, frame, -1, op_errno); return 0; } -int32_t -client3_1_lk (call_frame_t *frame, xlator_t *this, rpc_clnt_prog_t *prog, - void *data) +int +client3_1_rename_cbk (struct rpc_req *req, struct iovec *iov, int count, + void *myframe) { - clnt_args_t *args = NULL; - gfs3_lk_req req = {0,}; - int32_t gf_cmd = 0; - int32_t gf_type = 0; - clnt_fd_ctx_t *fdctx = NULL; - clnt_conf_t *conf = NULL; - int op_errno = ESTALE; - - if (!frame || !this || !prog || !data) - goto unwind; + call_frame_t *frame = NULL; + gfs3_rename_rsp rsp = {0,}; + struct iatt stbuf = {0,}; + struct iatt preoldparent = {0,}; + struct iatt postoldparent = {0,}; + struct iatt prenewparent = {0,}; + struct iatt postnewparent = {0,}; + int ret = 0; - args = data; - conf = this->private; + frame = myframe; - pthread_mutex_lock (&conf->lock); - { - fdctx = this_fd_get_ctx (args->fd, this); + if (-1 == req->rpc_status) { + rsp.op_ret = -1; + rsp.op_errno = ENOTCONN; + goto out; } - pthread_mutex_unlock (&conf->lock); - if (fdctx == NULL) { - gf_log (this->name, GF_LOG_DEBUG, - "(%"PRId64"): failed to get fd ctx. EBADFD", - args->fd->inode->ino); - op_errno = EBADFD; - goto unwind; + ret = xdr_to_rename_rsp (*iov, &rsp); + if (ret < 0) { + gf_log ("", GF_LOG_ERROR, "error"); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; } - if (fdctx->remote_fd == -1) { - gf_log (this->name, GF_LOG_DEBUG, "(%"PRId64"): failed to get" - " fd ctx. EBADFD", args->fd->inode->ino); - op_errno = EBADFD; - goto unwind; + if (-1 != rsp.op_ret) { + gf_stat_to_iatt (&rsp.stat, &stbuf); + + gf_stat_to_iatt (&rsp.preoldparent, &preoldparent); + gf_stat_to_iatt (&rsp.postoldparent, &postoldparent); + + gf_stat_to_iatt (&rsp.prenewparent, &prenewparent); + gf_stat_to_iatt (&rsp.postnewparent, &postnewparent); } - if (args->cmd == F_GETLK || args->cmd == F_GETLK64) - gf_cmd = GF_LK_GETLK; - else if (args->cmd == F_SETLK || args->cmd == F_SETLK64) - gf_cmd = GF_LK_SETLK; - else if (args->cmd == F_SETLKW || args->cmd == F_SETLKW64) - gf_cmd = GF_LK_SETLKW; - else { - gf_log (this->name, GF_LOG_DEBUG, - "Unknown cmd (%d)!", gf_cmd); - goto unwind; +out: + STACK_UNWIND_STRICT (rename, frame, rsp.op_ret, + gf_error_to_errno (rsp.op_errno), + &stbuf, &preoldparent, &postoldparent, + &preoldparent, &postoldparent); + + return 0; +} + +int +client3_1_link_cbk (struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + call_frame_t *frame = NULL; + gfs3_link_rsp rsp = {0,}; + struct iatt stbuf = {0,}; + struct iatt preparent = {0,}; + struct iatt postparent = {0,}; + int ret = 0; + clnt_local_t *local = NULL; + inode_t *inode = NULL; + + frame = myframe; + + local = frame->local; + frame->local = NULL; + inode = local->loc.inode; + + if (-1 == req->rpc_status) { + rsp.op_ret = -1; + rsp.op_errno = ENOTCONN; + goto out; } - switch (args->flock->l_type) { - case F_RDLCK: - gf_type = GF_LK_F_RDLCK; - break; - case F_WRLCK: - gf_type = GF_LK_F_WRLCK; - break; - case F_UNLCK: - gf_type = GF_LK_F_UNLCK; - break; + ret = xdr_to_link_rsp (*iov, &rsp); + if (ret < 0) { + gf_log ("", GF_LOG_ERROR, "error"); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; } - req.fd = fdctx->remote_fd; - req.cmd = gf_cmd; - req.type = gf_type; - gf_flock_from_flock (&req.flock, args->flock); + if (-1 != rsp.op_ret) { + gf_stat_to_iatt (&rsp.stat, &stbuf); - client_submit_request (this, &req, frame,prog, GFS3_OP_LK, - NULL, xdr_from_lk_req); + gf_stat_to_iatt (&rsp.preparent, &preparent); + gf_stat_to_iatt (&rsp.postparent, &postparent); + } - return 0; -unwind: - STACK_UNWIND_STRICT (lk, frame, -1, op_errno, NULL); +out: + frame->local = NULL; + STACK_UNWIND_STRICT (link, frame, rsp.op_ret, + gf_error_to_errno (rsp.op_errno), inode, + &stbuf, &preparent, &postparent); + + client_local_wipe (local); return 0; } -int32_t -client3_1_inodelk (call_frame_t *frame, xlator_t *this, rpc_clnt_prog_t *prog, - void *data) +int +client3_1_opendir_cbk (struct rpc_req *req, struct iovec *iov, int count, + void *myframe) { - clnt_args_t *args = NULL; - gfs3_inodelk_req req = {0,}; - int ret = 0; - int32_t gf_cmd = 0; - int32_t gf_type = 0; - int op_errno = ESTALE; + clnt_local_t *local = NULL; + clnt_conf_t *conf = NULL; + clnt_fd_ctx_t *fdctx = NULL; + ino_t ino = 0; + uint64_t gen = 0; + call_frame_t *frame = NULL; + fd_t *fd = NULL; + int ret = 0; + gfs3_opendir_rsp rsp = {0,}; - if (!frame || !this || !prog || !data) - goto unwind; + frame = myframe; + local = frame->local; - args = data; - ret = inode_ctx_get2 (args->loc->inode, this, &req.ino, &req.gen); - if (args->loc->inode->ino && ret < 0) { - gf_log (this->name, GF_LOG_TRACE, - "INODELK %"PRId64" (%s): " - "failed to get remote inode number", - args->loc->inode->ino, args->loc->path); - goto unwind; + if (local->op) { + local->op (req, iov, 1, myframe); + return 0; } - if (args->cmd == F_GETLK || args->cmd == F_GETLK64) - gf_cmd = GF_LK_GETLK; - else if (args->cmd == F_SETLK || args->cmd == F_SETLK64) - gf_cmd = GF_LK_SETLK; - else if (args->cmd == F_SETLKW || args->cmd == F_SETLKW64) - gf_cmd = GF_LK_SETLKW; - else { - gf_log (this->name, GF_LOG_DEBUG, - "Unknown cmd (%d)!", gf_cmd); - op_errno = EINVAL; - goto unwind; + frame->local = NULL; + conf = frame->this->private; + fd = local->fd; + + if (-1 == req->rpc_status) { + rsp.op_ret = -1; + rsp.op_errno = ENOTCONN; + goto out; } - switch (args->flock->l_type) { - case F_RDLCK: - gf_type = GF_LK_F_RDLCK; - break; - case F_WRLCK: - gf_type = GF_LK_F_WRLCK; - break; - case F_UNLCK: - gf_type = GF_LK_F_UNLCK; - break; + ret = xdr_to_opendir_rsp (*iov, &rsp); + if (ret < 0) { + gf_log ("", GF_LOG_ERROR, "error"); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; } - req.path = (char *)args->loc->path; - req.volume = (char *)args->volume; - req.cmd = gf_cmd; - req.type = gf_type; - gf_flock_from_flock (&req.flock, args->flock); + if (-1 != rsp.op_ret) { + fdctx = GF_CALLOC (1, sizeof (*fdctx), + gf_client_mt_clnt_fdctx_t); + if (!fdctx) { + rsp.op_ret = -1; + rsp.op_errno = ENOMEM; + goto out; + } - client_submit_request (this, &req, frame, prog, GFS3_OP_INODELK, - NULL, xdr_from_inodelk_req); + inode_ctx_get2 (fd->inode, frame->this, &ino, &gen); + + fdctx->remote_fd = rsp.fd; + fdctx->inode = inode_ref (fd->inode); + fdctx->ino = ino; + fdctx->gen = gen; + + fdctx->is_dir = 1; + + INIT_LIST_HEAD (&fdctx->sfd_pos); + + this_fd_set_ctx (fd, frame->this, &local->loc, fdctx); + + pthread_mutex_lock (&conf->lock); + { + list_add_tail (&fdctx->sfd_pos, &conf->saved_fds); + } + pthread_mutex_unlock (&conf->lock); + } + +out: + frame->local = NULL; + STACK_UNWIND_STRICT (opendir, frame, rsp.op_ret, + gf_error_to_errno (rsp.op_errno), fd); + + client_local_wipe (local); - return 0; -unwind: - STACK_UNWIND_STRICT (inodelk, frame, -1, op_errno); return 0; } - -int32_t -client3_1_finodelk (call_frame_t *frame, xlator_t *this, rpc_clnt_prog_t *prog, - void *data) +int +client3_1_lookup_cbk (struct rpc_req *req, struct iovec *iov, int count, + void *myframe) { - clnt_args_t *args = NULL; - gfs3_finodelk_req req = {0,}; - int32_t gf_cmd = 0; - int32_t gf_type = 0; - clnt_fd_ctx_t *fdctx = NULL; - clnt_conf_t *conf = NULL; - int op_errno = ESTALE; - - if (!frame || !this || !prog || !data) - goto unwind; + clnt_local_t *local = NULL; + call_frame_t *frame = NULL; + int ret = 0; + gfs3_lookup_rsp rsp = {0,}; + struct iatt stbuf = {0,}; + struct iatt postparent = {0,}; + int op_errno = 0; + ino_t oldino = 0; + uint64_t oldgen = 0; + dict_t *xattr = NULL; + inode_t *inode = NULL; + char *buf = NULL; - args = data; - conf = this->private; + frame = myframe; + local = frame->local; + inode = local->loc.inode; + frame->local = NULL; - pthread_mutex_lock (&conf->lock); - { - fdctx = this_fd_get_ctx (args->fd, this); + if (-1 == req->rpc_status) { + rsp.op_ret = -1; + rsp.op_errno = ENOTCONN; + goto out; } - pthread_mutex_unlock (&conf->lock); - if (fdctx == NULL) { - gf_log (this->name, GF_LOG_DEBUG, - "(%"PRId64"): failed to get fd ctx. EBADFD", - args->fd->inode->ino); - op_errno = EBADFD; - goto unwind; + ret = xdr_to_lookup_rsp (*iov, &rsp); + if (ret < 0) { + gf_log ("", GF_LOG_ERROR, "error"); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; } - if (fdctx->remote_fd == -1) { - gf_log (this->name, GF_LOG_DEBUG, "(%"PRId64"): failed to get" - " fd ctx. EBADFD", args->fd->inode->ino); - op_errno = EBADFD; - goto unwind; + op_errno = gf_error_to_errno (rsp.op_errno); + gf_stat_to_iatt (&rsp.postparent, &postparent); + + if (rsp.op_ret == 0) { + rsp.op_ret = -1; + gf_stat_to_iatt (&rsp.stat, &stbuf); + + ret = inode_ctx_get2 (inode, frame->this, &oldino, &oldgen); + if (oldino != stbuf.ia_ino || oldgen != stbuf.ia_gen) { + if (oldino) { + gf_log (frame->this->name, GF_LOG_DEBUG, + "LOOKUP %"PRId64"/%s (%s): " + "inode number changed from " + "{%"PRId64",%"PRId64"} to {%"PRId64",%"PRId64"}", + local->loc.parent ? + local->loc.parent->ino : (uint64_t) 0, + local->loc.name, + local->loc.path, + oldgen, oldino, stbuf.ia_gen, stbuf.ia_ino); + op_errno = ESTALE; + goto out; + } + + ret = inode_ctx_put2 (inode, frame->this, + stbuf.ia_ino, stbuf.ia_gen); + if (ret < 0) { + gf_log (frame->this->name, GF_LOG_DEBUG, + "LOOKUP %"PRId64"/%s (%s) : " + "failed to set remote inode " + "number to inode ctx", + local->loc.parent ? + local->loc.parent->ino : (uint64_t) 0, + local->loc.name, + local->loc.path); + } + } + + if (rsp.dict.dict_len > 0) { + xattr = dict_new(); + GF_VALIDATE_OR_GOTO (frame->this->name, xattr, out); + + buf = memdup (rsp.dict.dict_val, rsp.dict.dict_len); + GF_VALIDATE_OR_GOTO (frame->this->name, buf, out); + + ret = dict_unserialize (buf, rsp.dict.dict_len, &xattr); + if (ret < 0) { + gf_log (frame->this->name, GF_LOG_DEBUG, + "%s (%"PRId64"): failed to " + "unserialize dictionary", + local->loc.path, inode->ino); + op_errno = EINVAL; + goto out; + } + + xattr->extra_free = buf; + buf = NULL; + } + + rsp.op_ret = 0; } - if (args->cmd == F_GETLK || args->cmd == F_GETLK64) - gf_cmd = GF_LK_GETLK; - else if (args->cmd == F_SETLK || args->cmd == F_SETLK64) - gf_cmd = GF_LK_SETLK; - else if (args->cmd == F_SETLKW || args->cmd == F_SETLKW64) - gf_cmd = GF_LK_SETLKW; - else { - gf_log (this->name, GF_LOG_DEBUG, - "Unknown cmd (%d)!", gf_cmd); - goto unwind; - } +out: + frame->local = NULL; + STACK_UNWIND_STRICT (lookup, frame, rsp.op_ret, rsp.op_errno, inode, + &stbuf, xattr, &postparent); - switch (args->flock->l_type) { - case F_RDLCK: - gf_type = GF_LK_F_RDLCK; - break; - case F_WRLCK: - gf_type = GF_LK_F_WRLCK; - break; - case F_UNLCK: - gf_type = GF_LK_F_UNLCK; - break; - } + client_local_wipe (local); - req.volume = (char *)args->volume; - req.fd = fdctx->remote_fd; - req.cmd = gf_cmd; - req.type = gf_type; - gf_flock_from_flock (&req.flock, args->flock); + if (xattr) + dict_unref (xattr); + + if (rsp.dict.dict_val) { + /* don't use GF_FREE, this memory was allocated by libc + */ + free (rsp.dict.dict_val); + rsp.dict.dict_val = NULL; + } - client_submit_request (this, &req, frame,prog, GFS3_OP_FINODELK, - NULL, xdr_from_finodelk_req); + if (buf) { + GF_FREE (buf); + } return 0; -unwind: - STACK_UNWIND_STRICT (finodelk, frame, -1, op_errno); - return 0; } - -int32_t -client3_1_entrylk (call_frame_t *frame, xlator_t *this, rpc_clnt_prog_t *prog, - void *data) +int +client3_1_readv_cbk (struct rpc_req *req, struct iovec *iov, int count, + void *myframe) { - clnt_args_t *args = NULL; - gfs3_entrylk_req req = {0,}; - int ret = 0; - int op_errno = ESTALE; + call_frame_t *frame = NULL; + struct iobref *iobref = NULL; + struct iovec vector = {0,}; + struct iatt stat = {0,}; + gfs3_read_rsp rsp = {0,}; + int ret = 0; - if (!frame || !this || !prog || !data) - goto unwind; + frame = myframe; - args = data; + if (-1 == req->rpc_status) { + rsp.op_ret = -1; + rsp.op_errno = ENOTCONN; + goto out; + } - ret = inode_ctx_get2 (args->loc->inode, this, &req.ino, &req.gen); - if (args->loc->inode->ino && ret < 0) { - gf_log (this->name, GF_LOG_TRACE, - "STAT %"PRId64" (%s): " - "failed to get remote inode number", - args->loc->inode->ino, args->loc->path); - goto unwind; + ret = xdr_to_readv_rsp (*iov, &rsp); + if (ret < 0) { + gf_log ("", GF_LOG_ERROR, "error"); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; } - req.path = (char *)args->loc->path; - req.cmd = args->cmd_entrylk; - req.type = args->type; - req.volume = (char *)args->volume; - req.name = ""; - if (args->basename) { - req.name = (char *)args->basename; - req.namelen = 1; + + if (rsp.op_ret != -1) { + iobref = iobref_new (); + gf_stat_to_iatt (&rsp.stat, &stat); + vector.iov_len = rsp.op_ret; + + if (rsp.op_ret > 0) { + vector.iov_base = req->rsp_procpayload->ptr; + iobref_add (iobref, req->rsp_procpayload); + } } +out: + STACK_UNWIND_STRICT (readv, frame, rsp.op_ret, + gf_error_to_errno (rsp.op_errno), &vector, 1, + &stat, iobref); - client_submit_request (this, &req, frame,prog, GFS3_OP_ENTRYLK, - NULL, xdr_from_entrylk_req); + if (iobref) { + iobref_unref (iobref); + } return 0; -unwind: - STACK_UNWIND_STRICT (entrylk, frame, -1, op_errno); - return 0; } +int +client3_1_release_cbk (struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + call_frame_t *frame = NULL; - -int32_t -client3_1_fentrylk (call_frame_t *frame, xlator_t *this, rpc_clnt_prog_t *prog, - void *data) + frame = myframe; + STACK_DESTROY (frame->root); + return 0; +} +int +client3_1_releasedir_cbk (struct rpc_req *req, struct iovec *iov, int count, + void *myframe) { - clnt_args_t *args = NULL; - gfs3_fentrylk_req req = {0,}; - clnt_fd_ctx_t *fdctx = NULL; - clnt_conf_t *conf = NULL; - int op_errno = ESTALE; + call_frame_t *frame = NULL; - if (!frame || !this || !prog || !data) - goto unwind; + frame = myframe; + STACK_DESTROY (frame->root); + return 0; +} - args = data; - conf = this->private; +int +client_fdctx_destroy (xlator_t *this, clnt_fd_ctx_t *fdctx) +{ + call_frame_t *fr = NULL; + int32_t ret = -1; - pthread_mutex_lock (&conf->lock); - { - fdctx = this_fd_get_ctx (args->fd, this); - } - pthread_mutex_unlock (&conf->lock); + if (!fdctx) + goto out; - if (fdctx == NULL) { - gf_log (this->name, GF_LOG_DEBUG, - "(%"PRId64"): failed to get fd ctx. EBADFD", - args->fd->inode->ino); - op_errno = EBADFD; - goto unwind; - } + if (fdctx->remote_fd == -1) + goto out; - if (fdctx->remote_fd == -1) { - gf_log (this->name, GF_LOG_DEBUG, "(%"PRId64"): failed to get" - " fd ctx. EBADFD", args->fd->inode->ino); - op_errno = EBADFD; - goto unwind; - } + fr = create_frame (this, this->ctx->pool); - req.fd = fdctx->remote_fd; - req.cmd = args->cmd_entrylk; - req.type = args->type; - req.volume = (char *)args->volume; - req.name = ""; - if (args->basename) { - req.name = (char *)args->basename; - req.namelen = 1; + if (fdctx->is_dir) { + gfs3_releasedir_req req = {0,}; + req.fd = fdctx->remote_fd; + req.gfs_id = GFS3_OP_RELEASEDIR; + client_submit_request (this, &req, fr, &clnt3_1_fop_prog, + GFS3_OP_RELEASEDIR, client3_1_releasedir_cbk, + NULL, xdr_from_releasedir_req); + } else { + gfs3_release_req req = {0,}; + req.fd = fdctx->remote_fd; + req.gfs_id = GFS3_OP_RELEASE; + client_submit_request (this, &req, fr, &clnt3_1_fop_prog, + GFS3_OP_RELEASE, client3_1_release_cbk, NULL, + xdr_from_release_req); } - client_submit_request (this, &req, frame,prog, GFS3_OP_FENTRYLK, - NULL, xdr_from_fentrylk_req); +out: + fdctx->remote_fd = -1; + inode_unref (fdctx->inode); + GF_FREE (fdctx); - return 0; -unwind: - STACK_UNWIND_STRICT (fentrylk, frame, -1, op_errno); - return 0; + return ret; } +int +client3_1_reopen_cbk (struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + int32_t ret = -1; + gfs3_open_rsp rsp = {0,}; + clnt_local_t *local = NULL; + clnt_conf_t *conf = NULL; + clnt_fd_ctx_t *fdctx = NULL; + call_frame_t *frame = NULL; + frame = myframe; + local = frame->local; + conf = frame->this->private; + fdctx = local->fdctx; -int32_t -client3_1_checksum (call_frame_t *frame, xlator_t *this, rpc_clnt_prog_t *prog, - void *data) -{ - clnt_args_t *args = NULL; - gfs3_checksum_req req = {0,}; - int ret = 0; - int op_errno = ESTALE; + if (-1 == req->rpc_status) { + rsp.op_ret = -1; + rsp.op_errno = ENOTCONN; + goto out; + } - if (!frame || !this || !prog || !data) - goto unwind; + ret = xdr_to_open_rsp (*iov, &rsp); + if (ret < 0) { + gf_log ("", GF_LOG_ERROR, "error"); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } - args = data; + gf_log (frame->this->name, GF_LOG_DEBUG, + "reopen on %s returned %d (%"PRId64")", + local->loc.path, rsp.op_ret, rsp.fd); - ret = inode_ctx_get2 (args->loc->inode, this, &req.ino, &req.gen); - if (args->loc->inode->ino && ret < 0) { - gf_log (this->name, GF_LOG_TRACE, - "STAT %"PRId64" (%s): " - "failed to get remote inode number", - args->loc->inode->ino, args->loc->path); - goto unwind; + if (-1 != rsp.op_ret) { + pthread_mutex_lock (&conf->lock); + { + fdctx->remote_fd = rsp.fd; + + if (!fdctx->released) { + list_add_tail (&fdctx->sfd_pos, &conf->saved_fds); + fdctx = NULL; + } + } + pthread_mutex_unlock (&conf->lock); } - req.path = (char *)args->loc->path; - req.flag = args->flags; - client_submit_request (this, &req, frame,prog, GFS3_OP_CHECKSUM, - NULL, xdr_from_checksum_req); +out: + if (fdctx) + client_fdctx_destroy (frame->this, fdctx); - return 0; -unwind: - STACK_UNWIND_STRICT (checksum, frame, -1, op_errno, NULL, NULL); - return 0; -} + frame->local = NULL; + STACK_DESTROY (frame->root); + client_local_wipe (local); + return 0; +} -int32_t -client3_1_rchecksum (call_frame_t *frame, xlator_t *this, rpc_clnt_prog_t *prog, - void *data) +int +client3_1_reopendir_cbk (struct rpc_req *req, struct iovec *iov, int count, + void *myframe) { - clnt_args_t *args = NULL; - clnt_fd_ctx_t *fdctx = NULL; - clnt_conf_t *conf = NULL; - gfs3_rchecksum_req req = {0,}; - int op_errno = ESTALE; + int32_t ret = -1; + gfs3_open_rsp rsp = {0,}; + clnt_local_t *local = NULL; + clnt_conf_t *conf = NULL; + clnt_fd_ctx_t *fdctx = NULL; + call_frame_t *frame = NULL; - if (!frame || !this || !prog || !data) - goto unwind; + frame = myframe; + if (!frame || !frame->this) + goto out; - args = data; - conf = this->private; + local = frame->local; + frame->local = NULL; + conf = frame->this->private; + fdctx = local->fdctx; - pthread_mutex_lock (&conf->lock); - { - fdctx = this_fd_get_ctx (args->fd, this); + if (-1 == req->rpc_status) { + rsp.op_ret = -1; + rsp.op_errno = ENOTCONN; + goto out; } - pthread_mutex_unlock (&conf->lock); - if (fdctx == NULL) { - gf_log (this->name, GF_LOG_DEBUG, - "(%"PRId64"): failed to get fd ctx. EBADFD", - args->fd->inode->ino); - op_errno = EBADFD; - goto unwind; + ret = xdr_to_opendir_rsp (*iov, &rsp); + if (ret < 0) { + gf_log ("", GF_LOG_ERROR, "error"); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; } - if (fdctx->remote_fd == -1) { - gf_log (this->name, GF_LOG_DEBUG, "(%"PRId64"): failed to get" - " fd ctx. EBADFD", args->fd->inode->ino); - op_errno = EBADFD; - goto unwind; + gf_log (frame->this->name, GF_LOG_DEBUG, + "reopendir on %s returned %d (%"PRId64")", + local->loc.path, rsp.op_ret, rsp.fd); + + if (fdctx) { + pthread_mutex_lock (&conf->lock); + { + fdctx->remote_fd = rsp.fd; + + if (!fdctx->released) { + list_add_tail (&fdctx->sfd_pos, &conf->saved_fds); + fdctx = NULL; + } + } + pthread_mutex_unlock (&conf->lock); } - req.len = args->len; - req.offset = args->offset; - req.fd = fdctx->remote_fd; +out: + if (fdctx) + client_fdctx_destroy (frame->this, fdctx); - client_submit_request (this, &req, frame,prog, GFS3_OP_RCHECKSUM, - NULL, xdr_from_rchecksum_req); + frame->local = NULL; + STACK_DESTROY (frame->root); + + client_local_wipe (local); - return 0; -unwind: - STACK_UNWIND_STRICT (rchecksum, frame, -1, op_errno, 0, NULL); return 0; } - - -int32_t -client3_1_readdir (call_frame_t *frame, xlator_t *this, rpc_clnt_prog_t *prog, - void *data) +int +protocol_client_reopendir (xlator_t *this, clnt_fd_ctx_t *fdctx) { - clnt_args_t *args = NULL; - clnt_fd_ctx_t *fdctx = NULL; - clnt_conf_t *conf = NULL; - gfs3_readdir_req req = {0,}; - int op_errno = ESTALE; + int ret = -1; + gfs3_opendir_req req = {0,}; + clnt_local_t *local = NULL; + inode_t *inode = NULL; + char *path = NULL; + call_frame_t *frame = NULL; + clnt_conf_t *conf = NULL; - if (!frame || !this || !prog || !data) - goto unwind; + if (!this || !fdctx) + goto out; - args = data; + inode = fdctx->inode; conf = this->private; - pthread_mutex_lock (&conf->lock); - { - fdctx = this_fd_get_ctx (args->fd, this); + ret = inode_path (inode, NULL, &path); + if (ret < 0) { + goto out; } - pthread_mutex_unlock (&conf->lock); - if (fdctx == NULL) { - gf_log (this->name, GF_LOG_DEBUG, - "(%"PRId64"): failed to get fd ctx. EBADFD", - args->fd->inode->ino); - op_errno = EBADFD; - goto unwind; + local = GF_CALLOC (1, sizeof (*local), 0); + if (!local) { + goto out; } - if (fdctx->remote_fd == -1) { - gf_log (this->name, GF_LOG_DEBUG, "(%"PRId64"): failed to get" - " fd ctx. EBADFD", args->fd->inode->ino); - op_errno = EBADFD; - goto unwind; + local->fdctx = fdctx; + local->op = client3_1_reopendir_cbk; + local->loc.path = path; + path = NULL; + + frame = create_frame (this, this->ctx->pool); + if (!frame) { + goto out; } - req.size = args->size; - req.offset = args->offset; - req.fd = fdctx->remote_fd; + req.ino = fdctx->ino; + req.gen = fdctx->gen; + req.path = (char *)local->loc.path; + req.gfs_id = GFS3_OP_OPENDIR; - client_submit_request (this, &req, frame,prog, GFS3_OP_READDIR, - NULL, xdr_from_readdir_req); + gf_log (frame->this->name, GF_LOG_DEBUG, + "attempting reopen on %s", local->loc.path); + + frame->local = local; local = NULL; + + client_submit_request (this, &req, frame, conf->fops, GFS3_OP_OPENDIR, + client3_1_opendir_cbk, NULL, xdr_from_opendir_req); + + return ret; + +out: + if (frame) { + frame->local = NULL; + STACK_DESTROY (frame->root); + } + + if (local) + client_local_wipe (local); + + if (path) + GF_FREE (path); return 0; -unwind: - STACK_UNWIND_STRICT (readdir, frame, -1, op_errno, NULL); - return 0; -} +} -int32_t -client3_1_readdirp (call_frame_t *frame, xlator_t *this, rpc_clnt_prog_t *prog, - void *data) +int +protocol_client_reopen (xlator_t *this, clnt_fd_ctx_t *fdctx) { - clnt_args_t *args = NULL; - gfs3_readdirp_req req = {0,}; - clnt_fd_ctx_t *fdctx = NULL; - clnt_conf_t *conf = NULL; - int op_errno = ESTALE; + int ret = -1; + gfs3_open_req req = {0,}; + clnt_local_t *local = NULL; + inode_t *inode = NULL; + char *path = NULL; + call_frame_t *frame = NULL; + clnt_conf_t *conf = NULL; - if (!frame || !this || !prog || !data) - goto unwind; + if (!this || !fdctx) + goto out; - args = data; - conf = this->private; + inode = fdctx->inode; + conf = this->private; - pthread_mutex_lock (&conf->lock); - { - fdctx = this_fd_get_ctx (args->fd, this); + ret = inode_path (inode, NULL, &path); + if (ret < 0) { + goto out; } - pthread_mutex_unlock (&conf->lock); - if (fdctx == NULL) { - gf_log (this->name, GF_LOG_DEBUG, - "(%"PRId64"): failed to get fd ctx. EBADFD", - args->fd->inode->ino); - op_errno = EBADFD; - goto unwind; + frame = create_frame (this, this->ctx->pool); + if (!frame) { + goto out; } - if (fdctx->remote_fd == -1) { - gf_log (this->name, GF_LOG_DEBUG, "(%"PRId64"): failed to get" - " fd ctx. EBADFD", args->fd->inode->ino); - op_errno = EBADFD; - goto unwind; + local = GF_CALLOC (1, sizeof (*local), 0); + if (!local) { + goto out; } - req.size = args->size; - req.offset = args->offset; - req.fd = fdctx->remote_fd; + local->fdctx = fdctx; + local->op = client3_1_reopen_cbk; + local->loc.path = path; + path = NULL; + frame->local = local; + + req.ino = fdctx->ino; + req.gen = fdctx->gen; + req.flags = gf_flags_from_flags (fdctx->flags); + req.wbflags = fdctx->wbflags; + req.path = (char *)local->loc.path; + req.gfs_id = GFS3_OP_OPEN; + + gf_log (frame->this->name, GF_LOG_DEBUG, + "attempting reopen on %s", local->loc.path); + + local = NULL; + client_submit_request (this, &req, frame, conf->fops, GFS3_OP_OPEN, + client3_1_open_cbk, NULL, xdr_from_open_req); + + return ret; + +out: + if (frame) { + frame->local = NULL; + STACK_DESTROY (frame->root); + } + + if (local) + client_local_wipe (local); - client_submit_request (this, &req, frame,prog, GFS3_OP_READDIRP, - NULL, xdr_from_readdirp_req); + if (path) + GF_FREE (path); return 0; -unwind: - STACK_UNWIND_STRICT (readdirp, frame, -1, op_errno, NULL); - return 0; + } + int32_t -client3_1_setattr (call_frame_t *frame, xlator_t *this, rpc_clnt_prog_t *prog, - void *data) +client3_1_releasedir (call_frame_t *frame, xlator_t *this, + void *data) { - clnt_args_t *args = NULL; - gfs3_setattr_req req = {0,}; - int ret = 0; - int op_errno = ESTALE; + clnt_conf_t *conf = NULL; + clnt_fd_ctx_t *fdctx = NULL; + clnt_args_t *args = NULL; + gfs3_releasedir_req req = {0,}; + int64_t remote_fd = -1; - if (!frame || !this || !prog || !data) + if (!frame || !this || !data) goto unwind; args = data; + conf = this->private; - ret = inode_ctx_get2 (args->loc->inode, this, &req.ino, &req.gen); - if (args->loc->inode->ino && ret < 0) { - gf_log (this->name, GF_LOG_TRACE, - "STAT %"PRId64" (%s): " - "failed to get remote inode number", - args->loc->inode->ino, args->loc->path); - goto unwind; + pthread_mutex_lock (&conf->lock); + { + fdctx = this_fd_del_ctx (args->fd, this); + if (fdctx != NULL) { + remote_fd = fdctx->remote_fd; + + /* fdctx->remote_fd == -1 indicates a reopen attempt + in progress. Just mark ->released = 1 and let + reopen_cbk handle releasing + */ + + if (remote_fd != -1) + list_del_init (&fdctx->sfd_pos); + + fdctx->released = 1; + } } - req.path = (char *)args->loc->path; - req.valid = args->valid; - gf_stat_from_iatt (&req.stbuf, args->stbuf); + pthread_mutex_unlock (&conf->lock); - client_submit_request (this, &req, frame,prog, GFS3_OP_SETATTR, - NULL, xdr_from_setattr_req); + if (remote_fd != -1) { + req.fd = remote_fd; + req.gfs_id = GFS3_OP_RELEASEDIR; + client_submit_request (this, &req, frame, conf->fops, + GFS3_OP_RELEASEDIR, client3_1_releasedir_cbk, + NULL, xdr_from_releasedir_req); + inode_unref (fdctx->inode); + GF_FREE (fdctx); + } return 0; unwind: - STACK_UNWIND_STRICT (setattr, frame, -1, op_errno, NULL, NULL); return 0; } int32_t -client3_1_fsetattr (call_frame_t *frame, xlator_t *this, rpc_clnt_prog_t *prog, - void *data) +client3_1_release (call_frame_t *frame, xlator_t *this, + void *data) { - clnt_args_t *args = NULL; - clnt_fd_ctx_t *fdctx = NULL; - clnt_conf_t *conf = NULL; - gfs3_fsetattr_req req = {0,}; - int op_errno = ESTALE; + int64_t remote_fd = -1; + clnt_conf_t *conf = NULL; + clnt_fd_ctx_t *fdctx = NULL; + clnt_args_t *args = NULL; + gfs3_release_req req = {0,}; - if (!frame || !this || !prog || !data) + if (!frame || !this || !data) goto unwind; args = data; @@ -2569,2094 +2453,2355 @@ client3_1_fsetattr (call_frame_t *frame, xlator_t *this, rpc_clnt_prog_t *prog, pthread_mutex_lock (&conf->lock); { - fdctx = this_fd_get_ctx (args->fd, this); - } - pthread_mutex_unlock (&conf->lock); - - if (fdctx == NULL) { - gf_log (this->name, GF_LOG_DEBUG, - "(%"PRId64"): failed to get fd ctx. EBADFD", - args->fd->inode->ino); - op_errno = EBADFD; - goto unwind; - } + fdctx = this_fd_del_ctx (args->fd, this); + if (fdctx != NULL) { + remote_fd = fdctx->remote_fd; - if (fdctx->remote_fd == -1) { - gf_log (this->name, GF_LOG_DEBUG, "(%"PRId64"): failed to get" - " fd ctx. EBADFD", args->fd->inode->ino); - op_errno = EBADFD; - goto unwind; - } + /* fdctx->remote_fd == -1 indicates a reopen attempt + in progress. Just mark ->released = 1 and let + reopen_cbk handle releasing + */ - req.fd = fdctx->remote_fd; - req.valid = args->valid; - gf_stat_from_iatt (&req.stbuf, args->stbuf); + if (remote_fd != -1) + list_del_init (&fdctx->sfd_pos); - client_submit_request (this, &req, frame,prog, GFS3_OP_FSETATTR, - NULL, xdr_from_fsetattr_req); + fdctx->released = 1; + } + } + pthread_mutex_unlock (&conf->lock); + if (remote_fd != -1) { + req.fd = remote_fd; + req.gfs_id = GFS3_OP_RELEASE; + client_submit_request (this, &req, frame, conf->fops, + GFS3_OP_RELEASE, client3_1_release_cbk, NULL, + xdr_from_release_req); + inode_unref (fdctx->inode); + GF_FREE (fdctx); + } return 0; unwind: - STACK_UNWIND_STRICT (fsetattr, frame, -1, op_errno, NULL, NULL); - return 0; -} - -/* CBK */ -int -client3_1_release_cbk (struct rpc_req *req, struct iovec *iov, int count, - void *myframe) -{ - call_frame_t *frame = NULL; - - frame = myframe; - STACK_DESTROY (frame->root); - return 0; -} -int -client3_1_releasedir_cbk (struct rpc_req *req, struct iovec *iov, int count, - void *myframe) -{ - call_frame_t *frame = NULL; - - frame = myframe; - STACK_DESTROY (frame->root); return 0; } -int -client3_1_symlink_cbk (struct rpc_req *req, struct iovec *iov, int count, - void *myframe) +int32_t +client3_1_lookup (call_frame_t *frame, xlator_t *this, + void *data) { - call_frame_t *frame = NULL; - gfs3_symlink_rsp rsp = {0,}; - struct iatt stbuf = {0,}; - struct iatt preparent = {0,}; - struct iatt postparent = {0,}; - int ret = 0; - clnt_local_t *local = NULL; - inode_t *inode = NULL; - - frame = myframe; + clnt_conf_t *conf = NULL; + clnt_local_t *local = NULL; + clnt_args_t *args = NULL; + gfs3_lookup_req req = {0,}; + int ret = 0; + size_t dict_len = 0; + int op_errno = ESTALE; - local = frame->local; - frame->local = NULL; - inode = local->loc.inode; + if (!frame || !this || !data) + goto unwind; - if (-1 == req->rpc_status) { - rsp.op_ret = -1; - rsp.op_errno = ENOTCONN; - goto out; - } - ret = xdr_to_symlink_rsp (*iov, &rsp); - if (ret < 0) { - gf_log ("", GF_LOG_ERROR, "error"); - rsp.op_ret = -1; - rsp.op_errno = EINVAL; - goto out; + conf = this->private; + args = data; + local = GF_CALLOC (1, sizeof (*local), gf_client_mt_clnt_local_t); + if (!local) { + op_errno = ENOMEM; + goto unwind; } - if (-1 != rsp.op_ret) { - gf_stat_to_iatt (&rsp.stat, &stbuf); + loc_copy (&local->loc, args->loc); + frame->local = local; - ret = inode_ctx_put2 (inode, frame->this, - stbuf.ia_ino, stbuf.ia_gen); - if (ret < 0) { - gf_log (frame->this->name, GF_LOG_DEBUG, - "SYMLINK %"PRId64"/%s (%s): failed to set " - "remote inode number to inode ctx", - local->loc.parent->ino, local->loc.name, - local->loc.path); + if (args->loc->ino != 1 && args->loc->parent) { + ret = inode_ctx_get2 (args->loc->parent, this, + &req.par, &req.gen); + if (args->loc->parent->ino && ret < 0) { + gf_log (this->name, GF_LOG_TRACE, + "LOOKUP %"PRId64"/%s (%s): failed to get " + "remote inode number for parent", + args->loc->parent->ino, args->loc->name, + args->loc->path); + goto unwind; } - - gf_stat_to_iatt (&rsp.preparent, &preparent); - gf_stat_to_iatt (&rsp.postparent, &postparent); - } - -out: - frame->local = NULL; - STACK_UNWIND_STRICT (symlink, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno), inode, &stbuf, - &preparent, &postparent); - - if (local) - client_local_wipe (local); - - return 0; -} - - -int -client3_1_mknod_cbk (struct rpc_req *req, struct iovec *iov, int count, - void *myframe) -{ - call_frame_t *frame = NULL; - gfs3_mknod_rsp rsp = {0,}; - struct iatt stbuf = {0,}; - struct iatt preparent = {0,}; - struct iatt postparent = {0,}; - int ret = 0; - clnt_local_t *local = NULL; - inode_t *inode = NULL; - - frame = myframe; - - local = frame->local; - frame->local = NULL; - inode = local->loc.inode; - - if (-1 == req->rpc_status) { - rsp.op_ret = -1; - rsp.op_errno = ENOTCONN; - goto out; - } - ret = xdr_to_mknod_rsp (*iov, &rsp); - if (ret < 0) { - gf_log ("", GF_LOG_ERROR, "error"); - rsp.op_ret = -1; - rsp.op_errno = EINVAL; - goto out; + GF_VALIDATE_OR_GOTO (this->name, args->loc->name, unwind); + } else { + req.ino = 1; } - if (-1 != rsp.op_ret) { - gf_stat_to_iatt (&rsp.stat, &stbuf); - - ret = inode_ctx_put2 (inode, frame->this, - stbuf.ia_ino, stbuf.ia_gen); + if (args->dict) { + ret = dict_allocate_and_serialize (args->dict, + &req.dict.dict_val, + &dict_len); if (ret < 0) { - gf_log (frame->this->name, GF_LOG_DEBUG, - "MKNOD %"PRId64"/%s (%s): failed to set " - "remote inode number to inode ctx", - local->loc.parent->ino, local->loc.name, - local->loc.path); + gf_log (this->name, GF_LOG_DEBUG, + "failed to get serialized length of dict"); + op_errno = EINVAL; + goto unwind; } + } - gf_stat_to_iatt (&rsp.preparent, &preparent); - gf_stat_to_iatt (&rsp.postparent, &postparent); + req.path = (char *)args->loc->path; + req.bname = (char *)args->loc->name; + req.dict.dict_len = dict_len; + req.gfs_id = GFS3_OP_LOOKUP; + + client_submit_request (this, &req, frame, conf->fops, + GFS3_OP_LOOKUP, client3_1_lookup_cbk, + NULL, xdr_from_lookup_req); + + if (req.dict.dict_val) { + GF_FREE (req.dict.dict_val); } -out: + return 0; + +unwind: frame->local = NULL; - STACK_UNWIND_STRICT (mknod, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno), inode, - &stbuf, &preparent, &postparent); + STACK_UNWIND_STRICT (lookup, frame, -1, op_errno, NULL, NULL, NULL, NULL); if (local) client_local_wipe (local); + if (req.dict.dict_val) { + GF_FREE (req.dict.dict_val); + } + return 0; } -int -client3_1_mkdir_cbk (struct rpc_req *req, struct iovec *iov, int count, - void *myframe) + + +int32_t +client3_1_stat (call_frame_t *frame, xlator_t *this, + void *data) { - call_frame_t *frame = NULL; - gfs3_mkdir_rsp rsp = {0,}; - struct iatt stbuf = {0,}; - struct iatt preparent = {0,}; - struct iatt postparent = {0,}; - int ret = 0; - clnt_local_t *local = NULL; - inode_t *inode = NULL; + clnt_conf_t *conf = NULL; + clnt_args_t *args = NULL; + gfs3_stat_req req = {0,}; + int ret = 0; + int op_errno = ESTALE; - frame = myframe; + if (!frame || !this || !data) + goto unwind; - local = frame->local; - frame->local = NULL; - inode = local->loc.inode; + args = data; - if (-1 == req->rpc_status) { - rsp.op_ret = -1; - rsp.op_errno = ENOTCONN; - goto out; - } - ret = xdr_to_mkdir_rsp (*iov, &rsp); - if (ret < 0) { - gf_log ("", GF_LOG_ERROR, "error"); - rsp.op_ret = -1; - rsp.op_errno = EINVAL; - goto out; + ret = inode_ctx_get2 (args->loc->inode, this, &req.ino, &req.gen); + if (args->loc->inode->ino && ret < 0) { + gf_log (this->name, GF_LOG_TRACE, + "STAT %"PRId64" (%s): " + "failed to get remote inode number", + args->loc->inode->ino, args->loc->path); + goto unwind; } + req.path = (char *)args->loc->path; + req.gfs_id = GFS3_OP_STAT; + conf = this->private; - if (-1 != rsp.op_ret) { - gf_stat_to_iatt (&rsp.stat, &stbuf); + client_submit_request (this, &req, frame, conf->fops, GFS3_OP_STAT, + client3_1_stat_cbk, NULL, xdr_from_stat_req); - ret = inode_ctx_put2 (inode, frame->this, - stbuf.ia_ino, stbuf.ia_gen); - if (ret < 0) { - gf_log (frame->this->name, GF_LOG_DEBUG, - "MKDIR %"PRId64"/%s (%s): failed to set " - "remote inode number to inode ctx", - local->loc.parent->ino, local->loc.name, - local->loc.path); - } + return 0; +unwind: + STACK_UNWIND_STRICT (stat, frame, -1, op_errno, NULL); + return 0; +} - gf_stat_to_iatt (&rsp.preparent, &preparent); - gf_stat_to_iatt (&rsp.postparent, &postparent); + +int32_t +client3_1_truncate (call_frame_t *frame, xlator_t *this, + void *data) +{ + clnt_conf_t *conf = NULL; + clnt_args_t *args = NULL; + gfs3_truncate_req req = {0,}; + int ret = 0; + int op_errno = ESTALE; + + if (!frame || !this || !data) + goto unwind; + + args = data; + + ret = inode_ctx_get2 (args->loc->inode, this, &req.ino, &req.gen); + if (args->loc->inode->ino && ret < 0) { + gf_log (this->name, GF_LOG_TRACE, + "STAT %"PRId64" (%s): " + "failed to get remote inode number", + args->loc->inode->ino, args->loc->path); + goto unwind; } + req.path = (char *)args->loc->path; + req.offset = args->offset; + req.gfs_id = GFS3_OP_TRUNCATE; -out: - frame->local = NULL; - STACK_UNWIND_STRICT (mkdir, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno), inode, - &stbuf, &preparent, &postparent); + conf = this->private; - if (local) - client_local_wipe (local); + client_submit_request (this, &req, frame, conf->fops, GFS3_OP_TRUNCATE, + client3_1_truncate_cbk, NULL, xdr_from_truncate_req); return 0; +unwind: + STACK_UNWIND_STRICT (truncate, frame, -1, op_errno, NULL, NULL); + return 0; } -int -client3_1_open_cbk (struct rpc_req *req, struct iovec *iov, int count, - void *myframe) + +int32_t +client3_1_ftruncate (call_frame_t *frame, xlator_t *this, + void *data) { - clnt_local_t *local = NULL; - clnt_conf_t *conf = NULL; - clnt_fd_ctx_t *fdctx = NULL; - call_frame_t *frame = NULL; - fd_t *fd = NULL; - ino_t ino = 0; - uint64_t gen = 0; - int ret = 0; - gfs3_open_rsp rsp = {0,}; + clnt_args_t *args = NULL; + clnt_fd_ctx_t *fdctx = NULL; + clnt_conf_t *conf = NULL; + gfs3_ftruncate_req req = {0,}; + int op_errno = EINVAL; - frame = myframe; - local = frame->local; + if (!frame || !this || !data) + goto unwind; - if (local->op) { - local->op (req, iov, 1, myframe); - return 0; - } + args = data; - frame->local = NULL; - conf = frame->this->private; - fd = local->fd; + conf = this->private; - if (-1 == req->rpc_status) { - rsp.op_ret = -1; - rsp.op_errno = ENOTCONN; - goto out; + pthread_mutex_lock (&conf->lock); + { + fdctx = this_fd_get_ctx (args->fd, this); } - ret = xdr_to_open_rsp (*iov, &rsp); - if (ret < 0) { - gf_log ("", GF_LOG_ERROR, "error"); - rsp.op_ret = -1; - rsp.op_errno = EINVAL; - goto out; + pthread_mutex_unlock (&conf->lock); + + if (fdctx == NULL) { + gf_log (this->name, GF_LOG_DEBUG, + "(%"PRId64"): failed to get fd ctx. EBADFD", + args->fd->inode->ino); + op_errno = EBADFD; + goto unwind; } - if (-1 != rsp.op_ret) { - fdctx = GF_CALLOC (1, sizeof (*fdctx), - gf_client_mt_clnt_fdctx_t); - if (!fdctx) { - rsp.op_ret = -1; - rsp.op_errno = ENOMEM; - goto out; - } + if (fdctx->remote_fd == -1) { + gf_log (this->name, GF_LOG_DEBUG, "(%"PRId64"): failed to get" + " fd ctx. EBADFD", args->fd->inode->ino); + op_errno = EBADFD; + goto unwind; + } - inode_ctx_get2 (fd->inode, frame->this, &ino, &gen); + req.offset = args->offset; + req.fd = fdctx->remote_fd; + req.gfs_id = GFS3_OP_FTRUNCATE; - fdctx->remote_fd = rsp.fd; - fdctx->inode = inode_ref (fd->inode); - fdctx->ino = ino; - fdctx->gen = gen; - fdctx->flags = local->flags; - fdctx->wbflags = local->wbflags; + client_submit_request (this, &req, frame, conf->fops, GFS3_OP_FTRUNCATE, + client3_1_ftruncate_cbk, NULL, xdr_from_ftruncate_req); - INIT_LIST_HEAD (&fdctx->sfd_pos); + return 0; +unwind: + STACK_UNWIND_STRICT (ftruncate, frame, -1, op_errno, NULL, NULL); + return 0; +} - this_fd_set_ctx (fd, frame->this, &local->loc, fdctx); - pthread_mutex_lock (&conf->lock); - { - list_add_tail (&fdctx->sfd_pos, &conf->saved_fds); - } - pthread_mutex_unlock (&conf->lock); + +int32_t +client3_1_access (call_frame_t *frame, xlator_t *this, + void *data) +{ + clnt_conf_t *conf = NULL; + clnt_args_t *args = NULL; + gfs3_access_req req = {0,}; + int ret = 0; + int op_errno = ESTALE; + + if (!frame || !this || !data) + goto unwind; + + args = data; + + ret = inode_ctx_get2 (args->loc->inode, this, &req.ino, &req.gen); + if (args->loc->inode->ino && ret < 0) { + gf_log (this->name, GF_LOG_TRACE, + "STAT %"PRId64" (%s): " + "failed to get remote inode number", + args->loc->inode->ino, args->loc->path); + goto unwind; } + req.path = (char *)args->loc->path; + req.mask = args->mask; + req.gfs_id = GFS3_OP_ACCESS; -out: - frame->local = NULL; - STACK_UNWIND_STRICT (open, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno), fd); + conf = this->private; - client_local_wipe (local); + client_submit_request (this, &req, frame, conf->fops, GFS3_OP_ACCESS, + client3_1_access_cbk, NULL, xdr_from_access_req); return 0; +unwind: + STACK_UNWIND_STRICT (access, frame, -1, op_errno); + return 0; } - -int -client3_1_stat_cbk (struct rpc_req *req, struct iovec *iov, int count, - void *myframe) +int32_t +client3_1_readlink (call_frame_t *frame, xlator_t *this, + void *data) { - gfs3_stat_rsp rsp = {0,}; - call_frame_t *frame = NULL; - struct iatt iatt = {0,}; - int ret = 0; + clnt_conf_t *conf = NULL; + clnt_args_t *args = NULL; + gfs3_readlink_req req = {0,}; + int ret = 0; + int op_errno = ESTALE; - frame = myframe; + if (!frame || !this || !data) + goto unwind; - if (-1 == req->rpc_status) { - rsp.op_ret = -1; - rsp.op_errno = ENOTCONN; - goto out; - } - ret = xdr_to_stat_rsp (*iov, &rsp); - if (ret < 0) { - gf_log ("", GF_LOG_ERROR, "error"); - rsp.op_ret = -1; - rsp.op_errno = EINVAL; - goto out; - } + args = data; - if (-1 != rsp.op_ret) { - gf_stat_to_iatt (&rsp.stat, &iatt); + ret = inode_ctx_get2 (args->loc->inode, this, &req.ino, &req.gen); + if (args->loc->inode->ino && ret < 0) { + gf_log (this->name, GF_LOG_TRACE, + "STAT %"PRId64" (%s): " + "failed to get remote inode number", + args->loc->inode->ino, args->loc->path); + goto unwind; } + req.path = (char *)args->loc->path; + req.size = args->size; + req.gfs_id = GFS3_OP_READLINK; + conf = this->private; -out: - STACK_UNWIND_STRICT (stat, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno), &iatt); + client_submit_request (this, &req, frame, conf->fops, GFS3_OP_READLINK, + client3_1_readlink_cbk, NULL, xdr_from_readlink_req); return 0; +unwind: + STACK_UNWIND_STRICT (readlink, frame, -1, op_errno, NULL, NULL); + return 0; } -int -client3_1_readlink_cbk (struct rpc_req *req, struct iovec *iov, int count, - void *myframe) + + + +int32_t +client3_1_unlink (call_frame_t *frame, xlator_t *this, + void *data) { - gfs3_readlink_rsp rsp = {0,}; - call_frame_t *frame = NULL; - struct iatt iatt = {0,}; - int ret = 0; + clnt_conf_t *conf = NULL; + clnt_args_t *args = NULL; + gfs3_unlink_req req = {0,}; + int ret = 0; + int op_errno = 0; - frame = myframe; + if (!frame || !this || !data) + goto unwind; - if (-1 == req->rpc_status) { - rsp.op_ret = -1; - rsp.op_errno = ENOTCONN; - goto out; - } - ret = xdr_to_readlink_rsp (*iov, &rsp); - if (ret < 0) { - gf_log ("", GF_LOG_ERROR, "error"); - rsp.op_ret = -1; - rsp.op_errno = EINVAL; - goto out; - } + args = data; - if (-1 != rsp.op_ret) { - gf_stat_to_iatt (&rsp.buf, &iatt); + ret = inode_ctx_get2 (args->loc->parent, this, &req.par, &req.gen); + if (args->loc->parent->ino && ret < 0) { + gf_log (this->name, GF_LOG_TRACE, + "STAT %"PRId64"/%s (%s): " + "failed to get remote inode number for parent", + args->loc->parent->ino, args->loc->name, args->loc->path); + goto unwind; } + req.path = (char *)args->loc->path; + req.bname = (char *)args->loc->name; + req.gfs_id = GFS3_OP_UNLINK; + conf = this->private; -out: - STACK_UNWIND_STRICT (readlink, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno), rsp.path, &iatt); - - /* This is allocated by the libc while decoding RPC msg */ - /* Hence no 'GF_FREE', but just 'free' */ - if (rsp.path) - free (rsp.path); + client_submit_request (this, &req, frame, conf->fops, GFS3_OP_UNLINK, + client3_1_unlink_cbk, NULL, xdr_from_unlink_req); return 0; +unwind: + STACK_UNWIND_STRICT (unlink, frame, -1, op_errno, NULL, NULL); + return 0; } -int -client3_1_unlink_cbk (struct rpc_req *req, struct iovec *iov, int count, - void *myframe) + + +int32_t +client3_1_rmdir (call_frame_t *frame, xlator_t *this, + void *data) { - call_frame_t *frame = NULL; - gfs3_unlink_rsp rsp = {0,}; - struct iatt preparent = {0,}; - struct iatt postparent = {0,}; - int ret = 0; + clnt_conf_t *conf = NULL; + clnt_args_t *args = NULL; + gfs3_rmdir_req req = {0,}; + int ret = 0; + int op_errno = ESTALE; - frame = myframe; + if (!frame || !this || !data) + goto unwind; - if (-1 == req->rpc_status) { - rsp.op_ret = -1; - rsp.op_errno = ENOTCONN; - goto out; - } - ret = xdr_to_unlink_rsp (*iov, &rsp); - if (ret < 0) { - gf_log ("", GF_LOG_ERROR, "error"); - rsp.op_ret = -1; - rsp.op_errno = EINVAL; - goto out; - } + args = data; - if (-1 != rsp.op_ret) { - gf_stat_to_iatt (&rsp.preparent, &preparent); - gf_stat_to_iatt (&rsp.postparent, &postparent); + ret = inode_ctx_get2 (args->loc->parent, this, &req.par, &req.gen); + if (args->loc->inode->ino && ret < 0) { + gf_log (this->name, GF_LOG_TRACE, + "STAT %"PRId64"/%s (%s): " + "failed to get remote inode number for parent", + args->loc->parent->ino, args->loc->name, args->loc->path); + goto unwind; } + req.path = (char *)args->loc->path; + req.bname = (char *)args->loc->name; + req.gfs_id = GFS3_OP_RMDIR; + conf = this->private; -out: - STACK_UNWIND_STRICT (unlink, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno), &preparent, - &postparent); + client_submit_request (this, &req, frame, conf->fops, GFS3_OP_RMDIR, + client3_1_rmdir_cbk, NULL, xdr_from_rmdir_req); return 0; +unwind: + STACK_UNWIND_STRICT (rmdir, frame, -1, op_errno, NULL, NULL); + return 0; } -int -client3_1_rmdir_cbk (struct rpc_req *req, struct iovec *iov, int count, - void *myframe) + + +int32_t +client3_1_symlink (call_frame_t *frame, xlator_t *this, + void *data) { - gfs3_rmdir_rsp rsp = {0,}; - call_frame_t *frame = NULL; - struct iatt preparent = {0,}; - struct iatt postparent = {0,}; - int ret = 0; + clnt_local_t *local = NULL; + clnt_conf_t *conf = NULL; + clnt_args_t *args = NULL; + gfs3_symlink_req req = {0,}; + int ret = 0; + int op_errno = ESTALE; - frame = myframe; + if (!frame || !this || !data) + goto unwind; - if (-1 == req->rpc_status) { - rsp.op_ret = -1; - rsp.op_errno = ENOTCONN; - goto out; - } - ret = xdr_to_rmdir_rsp (*iov, &rsp); - if (ret < 0) { - gf_log ("", GF_LOG_ERROR, "error"); - rsp.op_ret = -1; - rsp.op_errno = EINVAL; - goto out; + args = data; + local = GF_CALLOC (1, sizeof (*local), gf_client_mt_clnt_local_t); + if (!local) { + op_errno = ENOMEM; + goto unwind; } - if (-1 != rsp.op_ret) { - gf_stat_to_iatt (&rsp.preparent, &preparent); - gf_stat_to_iatt (&rsp.postparent, &postparent); + loc_copy (&local->loc, args->loc); + frame->local = local; + + ret = inode_ctx_get2 (args->loc->parent, this, &req.par, &req.gen); + if (args->loc->parent->ino && ret < 0) { + gf_log (this->name, GF_LOG_DEBUG, + "SYMLINK %"PRId64"/%s (%s): failed to get remote inode" + " number parent", + args->loc->parent->ino, args->loc->name, + args->loc->path); + goto unwind; } -out: - STACK_UNWIND_STRICT (rmdir, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno), &preparent, - &postparent); + req.path = (char *)args->loc->path; + req.linkname = (char *)args->linkname; + req.bname = (char *)args->loc->name; + req.gfs_id = GFS3_OP_SYMLINK; + conf = this->private; + client_submit_request (this, &req, frame, conf->fops, GFS3_OP_SYMLINK, + client3_1_symlink_cbk, NULL, xdr_from_symlink_req); + + return 0; +unwind: + frame->local = NULL; + STACK_UNWIND_STRICT (symlink, frame, -1, op_errno, NULL, NULL, NULL, NULL); + if (local) + client_local_wipe (local); return 0; } -int -client3_1_truncate_cbk (struct rpc_req *req, struct iovec *iov, int count, - void *myframe) + +int32_t +client3_1_rename (call_frame_t *frame, xlator_t *this, + void *data) { - gfs3_truncate_rsp rsp = {0,}; - call_frame_t *frame = NULL; - struct iatt prestat = {0,}; - struct iatt poststat = {0,}; - int ret = 0; + clnt_conf_t *conf = NULL; + clnt_args_t *args = NULL; + gfs3_rename_req req = {0,}; + int ret = 0; + int op_errno = ESTALE; - frame = myframe; + if (!frame || !this || !data) + goto unwind; - if (-1 == req->rpc_status) { - rsp.op_ret = -1; - rsp.op_errno = ENOTCONN; - goto out; - } - ret = xdr_to_truncate_rsp (*iov, &rsp); - if (ret < 0) { - gf_log ("", GF_LOG_ERROR, "error"); - rsp.op_ret = -1; - rsp.op_errno = EINVAL; - goto out; + args = data; + + ret = inode_ctx_get2 (args->oldloc->parent, this, + &req.oldpar, &req.oldgen); + if (args->oldloc->parent->ino && ret < 0) { + gf_log (this->name, GF_LOG_DEBUG, + "RENAME %"PRId64"/%s (%s): failed to get remote inode " + "number for source parent", args->oldloc->parent->ino, + args->oldloc->name, args->oldloc->path); + goto unwind; } - if (-1 != rsp.op_ret) { - gf_stat_to_iatt (&rsp.prestat, &prestat); - gf_stat_to_iatt (&rsp.poststat, &poststat); + ret = inode_ctx_get2 (args->newloc->parent, this, &req.newpar, + &req.newgen); + if (args->newloc->parent->ino && ret < 0) { + gf_log (this->name, GF_LOG_DEBUG, + "CREATE %"PRId64"/%s (%s): failed to get remote inode " + "number for destination parent", + args->newloc->parent->ino, args->newloc->name, + args->newloc->path); + goto unwind; } -out: - STACK_UNWIND_STRICT (truncate, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno), &prestat, - &poststat); + req.oldpath = (char *)args->oldloc->path; + req.oldbname = (char *)args->oldloc->name; + req.newpath = (char *)args->newloc->path; + req.newbname = (char *)args->newloc->name; + req.gfs_id = GFS3_OP_RENAME; + conf = this->private; + client_submit_request (this, &req, frame, conf->fops, GFS3_OP_RENAME, + client3_1_rename_cbk, NULL, xdr_from_rename_req); + + return 0; +unwind: + STACK_UNWIND_STRICT (rename, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); return 0; } -int -client3_1_statfs_cbk (struct rpc_req *req, struct iovec *iov, int count, - void *myframe) + +int32_t +client3_1_link (call_frame_t *frame, xlator_t *this, + void *data) { - gfs3_statfs_rsp rsp = {0,}; - call_frame_t *frame = NULL; - struct statvfs statfs = {0,}; - int ret = 0; + clnt_local_t *local = NULL; + clnt_conf_t *conf = NULL; + clnt_args_t *args = NULL; + gfs3_link_req req = {0,}; + int ret = 0; + int op_errno = ESTALE; - frame = myframe; + if (!frame || !this || !data) + goto unwind; - if (-1 == req->rpc_status) { - rsp.op_ret = -1; - rsp.op_errno = ENOTCONN; - goto out; + args = data; + + local = GF_CALLOC (1, sizeof (*local), gf_client_mt_clnt_local_t); + if (!local) { + op_errno = ENOMEM; + goto unwind; } - ret = xdr_to_statfs_rsp (*iov, &rsp); - if (ret < 0) { - gf_log ("", GF_LOG_ERROR, "error"); - rsp.op_ret = -1; - rsp.op_errno = EINVAL; - goto out; + + loc_copy (&local->loc, args->oldloc); + frame->local = local; + + ret = inode_ctx_get2 (args->oldloc->inode, this, + &req.oldino, &req.oldgen); + if (args->oldloc->parent->ino && ret < 0) { + gf_log (this->name, GF_LOG_DEBUG, + "RENAME %"PRId64"/%s (%s): failed to get remote inode " + "number for source parent", args->oldloc->parent->ino, + args->oldloc->name, args->oldloc->path); + goto unwind; } - if (-1 != rsp.op_ret) { - gf_statfs_to_statfs (&rsp.statfs, &statfs); + ret = inode_ctx_get2 (args->newloc->parent, this, &req.newpar, + &req.newgen); + if (args->newloc->parent->ino && ret < 0) { + gf_log (this->name, GF_LOG_DEBUG, + "CREATE %"PRId64"/%s (%s): failed to get remote inode " + "number for destination parent", + args->newloc->parent->ino, args->newloc->name, + args->newloc->path); + goto unwind; } -out: - STACK_UNWIND_STRICT (statfs, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno), &statfs); + req.oldpath = (char *)args->oldloc->path; + req.newpath = (char *)args->newloc->path; + req.newbname = (char *)args->newloc->name; + req.gfs_id = GFS3_OP_LINK; + conf = this->private; + client_submit_request (this, &req, frame, conf->fops, GFS3_OP_LINK, + client3_1_link_cbk, NULL, xdr_from_link_req); + + return 0; +unwind: + STACK_UNWIND_STRICT (link, frame, -1, op_errno, NULL, NULL, NULL, NULL); return 0; } -int -client3_1_writev_cbk (struct rpc_req *req, struct iovec *iov, int count, - void *myframe) + +int32_t +client3_1_mknod (call_frame_t *frame, xlator_t *this, + void *data) { - gfs3_write_rsp rsp = {0,}; - call_frame_t *frame = NULL; - struct iatt prestat = {0,}; - struct iatt poststat = {0,}; - int ret = 0; + clnt_local_t *local = NULL; + clnt_conf_t *conf = NULL; + clnt_args_t *args = NULL; + gfs3_mknod_req req = {0,}; + int ret = 0; + int op_errno = ESTALE; - frame = myframe; + if (!frame || !this || !data) + goto unwind; - if (-1 == req->rpc_status) { - rsp.op_ret = -1; - rsp.op_errno = ENOTCONN; - goto out; - } + args = data; - ret = xdr_to_truncate_rsp (*iov, &rsp); - if (ret < 0) { - gf_log ("", GF_LOG_ERROR, "error"); - rsp.op_ret = -1; - rsp.op_errno = EINVAL; - goto out; + local = GF_CALLOC (1, sizeof (*local), gf_client_mt_clnt_local_t); + if (!local) { + op_errno = ENOMEM; + goto unwind; } - if (-1 != rsp.op_ret) { - gf_stat_to_iatt (&rsp.prestat, &prestat); - gf_stat_to_iatt (&rsp.poststat, &poststat); + loc_copy (&local->loc, args->loc); + frame->local = local; + + ret = inode_ctx_get2 (args->loc->parent, this, &req.par, &req.gen); + if (args->loc->parent->ino && ret < 0) { + gf_log (this->name, GF_LOG_DEBUG, + "SYMLINK %"PRId64"/%s (%s): failed to get remote inode" + " number parent", + args->loc->parent->ino, args->loc->name, + args->loc->path); + goto unwind; } -out: - STACK_UNWIND_STRICT (writev, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno), &prestat, - &poststat); + req.path = (char *)args->loc->path; + req.bname = (char *)args->loc->name; + req.mode = args->mode; + req.dev = args->rdev; + req.gfs_id = GFS3_OP_MKNOD; + + conf = this->private; + + client_submit_request (this, &req, frame, conf->fops, GFS3_OP_MKNOD, + client3_1_mknod_cbk, NULL, xdr_from_mknod_req); return 0; +unwind: + frame->local = NULL; + STACK_UNWIND_STRICT (mknod, frame, -1, op_errno, NULL, NULL, NULL, NULL); + if (local) + client_local_wipe (local); + return 0; } -int -client3_1_flush_cbk (struct rpc_req *req, struct iovec *iov, int count, - void *myframe) + + +int32_t +client3_1_mkdir (call_frame_t *frame, xlator_t *this, + void *data) { - call_frame_t *frame = NULL; - gf_common_rsp rsp = {0,}; - int ret = 0; + clnt_local_t *local = NULL; + clnt_conf_t *conf = NULL; + clnt_args_t *args = NULL; + gfs3_mkdir_req req = {0,}; + int ret = 0; + int op_errno = ESTALE; - frame = myframe; + if (!frame || !this || !data) + goto unwind; - if (-1 == req->rpc_status) { - rsp.op_ret = -1; - rsp.op_errno = ENOTCONN; - goto out; + args = data; + + local = GF_CALLOC (1, sizeof (*local), gf_client_mt_clnt_local_t); + if (!local) { + op_errno = ENOMEM; + goto unwind; } - ret = xdr_to_common_rsp (*iov, &rsp); - if (ret < 0) { - gf_log ("", GF_LOG_ERROR, "error"); - rsp.op_ret = -1; - rsp.op_errno = EINVAL; - goto out; + + loc_copy (&local->loc, args->loc); + frame->local = local; + + ret = inode_ctx_get2 (args->loc->parent, this, &req.par, &req.gen); + if (args->loc->parent->ino && ret < 0) { + gf_log (this->name, GF_LOG_DEBUG, + "SYMLINK %"PRId64"/%s (%s): failed to get remote inode" + " number parent", + args->loc->parent->ino, args->loc->name, + args->loc->path); + goto unwind; } -out: - STACK_UNWIND_STRICT (flush, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno)); + req.path = (char *)args->loc->path; + req.bname = (char *)args->loc->name; + req.mode = args->mode; + req.gfs_id = GFS3_OP_MKDIR; + conf = this->private; + + client_submit_request (this, &req, frame, conf->fops, GFS3_OP_MKDIR, + client3_1_mkdir_cbk, NULL, xdr_from_mkdir_req); + + return 0; +unwind: + frame->local = NULL; + STACK_UNWIND_STRICT (mkdir, frame, -1, op_errno, NULL, NULL, NULL, NULL); + if (local) + client_local_wipe (local); return 0; } -int -client3_1_fsync_cbk (struct rpc_req *req, struct iovec *iov, int count, - void *myframe) + +int32_t +client3_1_create (call_frame_t *frame, xlator_t *this, + void *data) { - gfs3_fsync_rsp rsp = {0,}; - call_frame_t *frame = NULL; - struct iatt prestat = {0,}; - struct iatt poststat = {0,}; - int ret = 0; + clnt_local_t *local = NULL; + clnt_conf_t *conf = NULL; + clnt_args_t *args = NULL; + gfs3_create_req req = {0,}; + int ret = 0; + int op_errno = ESTALE; - frame = myframe; + if (!frame || !this || !data) + goto unwind; - if (-1 == req->rpc_status) { - rsp.op_ret = -1; - rsp.op_errno = ENOTCONN; - goto out; - } + args = data; - ret = xdr_to_truncate_rsp (*iov, &rsp); - if (ret < 0) { - gf_log ("", GF_LOG_ERROR, "error"); - rsp.op_ret = -1; - rsp.op_errno = EINVAL; - goto out; + local = GF_CALLOC (1, sizeof (*local), gf_client_mt_clnt_local_t); + if (!local) { + op_errno = ENOMEM; + goto unwind; } + local->fd = fd_ref (args->fd); + local->flags = args->flags; + loc_copy (&local->loc, args->loc); + frame->local = local; - if (-1 != rsp.op_ret) { - gf_stat_to_iatt (&rsp.prestat, &prestat); - gf_stat_to_iatt (&rsp.poststat, &poststat); + ret = inode_ctx_get2 (args->loc->parent, this, &req.par, &req.gen); + if (args->loc->parent->ino && ret < 0) { + gf_log (this->name, GF_LOG_DEBUG, + "SYMLINK %"PRId64"/%s (%s): failed to get remote inode" + " number parent", + args->loc->parent->ino, args->loc->name, + args->loc->path); + goto unwind; } -out: - STACK_UNWIND_STRICT (fsync, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno), &prestat, - &poststat); + req.path = (char *)args->loc->path; + req.bname = (char *)args->loc->name; + req.mode = args->mode; + req.flags = gf_flags_from_flags (args->flags); + req.gfs_id = GFS3_OP_CREATE; + + conf = this->private; + client_submit_request (this, &req, frame, conf->fops, GFS3_OP_CREATE, + client3_1_create_cbk, NULL, xdr_from_create_req); + + return 0; +unwind: + frame->local = NULL; + STACK_UNWIND_STRICT (create, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); + if (local) + client_local_wipe (local); return 0; } -int -client3_1_setxattr_cbk (struct rpc_req *req, struct iovec *iov, int count, - void *myframe) + + +int32_t +client3_1_open (call_frame_t *frame, xlator_t *this, + void *data) { - call_frame_t *frame = NULL; - gf_common_rsp rsp = {0,}; - int ret = 0; + clnt_local_t *local = NULL; + clnt_conf_t *conf = NULL; + clnt_args_t *args = NULL; + gfs3_open_req req = {0,}; + int ret = 0; + int op_errno = ESTALE; - frame = myframe; + if (!frame || !this || !data) + goto unwind; - if (-1 == req->rpc_status) { - rsp.op_ret = -1; - rsp.op_errno = ENOTCONN; - goto out; + args = data; + + local = GF_CALLOC (1, sizeof (*local), gf_client_mt_clnt_local_t); + if (!local) { + op_errno = ENOMEM; + goto unwind; } + local->fd = fd_ref (args->fd); + local->flags = args->flags; + local->wbflags = args->wbflags; + loc_copy (&local->loc, args->loc); + frame->local = local; - ret = xdr_to_common_rsp (*iov, &rsp); - if (ret < 0) { - gf_log ("", GF_LOG_ERROR, "error"); - rsp.op_ret = -1; - rsp.op_errno = EINVAL; - goto out; + ret = inode_ctx_get2 (args->loc->inode, this, &req.ino, &req.gen); + if (args->loc->inode->ino && ret < 0) { + gf_log (this->name, GF_LOG_DEBUG, + "OPEN %"PRId64" (%s): " + "failed to get remote inode number", + args->loc->inode->ino, args->loc->path); + goto unwind; } + req.flags = gf_flags_from_flags (args->flags); + req.wbflags = args->wbflags; + req.path = (char *)args->loc->path; + req.gfs_id = GFS3_OP_OPEN; -out: - STACK_UNWIND_STRICT (setxattr, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno)); + conf = this->private; + client_submit_request (this, &req, frame, conf->fops, GFS3_OP_OPEN, + client3_1_open_cbk, NULL, xdr_from_open_req); + + return 0; +unwind: + frame->local = NULL; + STACK_UNWIND_STRICT (open, frame, -1, op_errno, NULL); + if (local) + client_local_wipe (local); return 0; } -int -client3_1_getxattr_cbk (struct rpc_req *req, struct iovec *iov, int count, - void *myframe) -{ - call_frame_t *frame = NULL; - dict_t *dict = NULL; - char *buf = NULL; - int dict_len = 0; - int op_ret = 0; - int op_errno = 0; - gfs3_getxattr_rsp rsp = {0,}; - int ret = 0; - - frame = myframe; - - if (-1 == req->rpc_status) { - op_ret = -1; - op_errno = ENOTCONN; - goto out; - } - ret = xdr_to_getxattr_rsp (*iov, &rsp); - if (ret < 0) { - gf_log ("", GF_LOG_ERROR, "error"); - op_ret = -1; - op_errno = EINVAL; - goto out; - } - op_errno = gf_error_to_errno (rsp.op_errno); - op_ret = rsp.op_ret; - if (-1 != op_ret) { - op_ret = -1; - dict_len = rsp.dict.dict_len; +int32_t +client3_1_readv (call_frame_t *frame, xlator_t *this, + void *data) +{ + clnt_args_t *args = NULL; + clnt_fd_ctx_t *fdctx = NULL; + clnt_conf_t *conf = NULL; + int op_errno = ESTALE; + gfs3_read_req req = {0,}; - if (dict_len > 0) { - dict = dict_new(); - buf = memdup (rsp.dict.dict_val, rsp.dict.dict_len); + if (!frame || !this || !data) + goto unwind; - GF_VALIDATE_OR_GOTO (frame->this->name, dict, out); - GF_VALIDATE_OR_GOTO (frame->this->name, buf, out); + args = data; + conf = this->private; - ret = dict_unserialize (buf, dict_len, &dict); - if (ret < 0) { - gf_log (frame->this->name, GF_LOG_DEBUG, - "failed to unserialize xattr dict"); - op_errno = EINVAL; - goto out; - } - dict->extra_free = buf; - buf = NULL; - } - op_ret = 0; + pthread_mutex_lock (&conf->lock); + { + fdctx = this_fd_get_ctx (args->fd, this); } + pthread_mutex_unlock (&conf->lock); -out: - STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno, dict); + if (fdctx == NULL) { + gf_log (this->name, GF_LOG_DEBUG, + "(%"PRId64"): failed to get fd ctx. EBADFD", + args->fd->inode->ino); + op_errno = EBADFD; + goto unwind; + } - if (rsp.dict.dict_val) { - /* don't use GF_FREE, this memory was allocated by libc - */ - free (rsp.dict.dict_val); - rsp.dict.dict_val = NULL; + if (fdctx->remote_fd == -1) { + gf_log (this->name, GF_LOG_DEBUG, "(%"PRId64"): failed to get" + " fd ctx. EBADFD", args->fd->inode->ino); + op_errno = EBADFD; + goto unwind; } - if (buf) - GF_FREE (buf); + req.size = args->size; + req.offset = args->offset; + req.fd = fdctx->remote_fd; + req.gfs_id = GFS3_OP_READ; - if (dict) - dict_unref (dict); + client_submit_request (this, &req, frame, conf->fops, GFS3_OP_READ, + client3_1_readv_cbk, NULL, xdr_from_readv_req); return 0; +unwind: + STACK_UNWIND_STRICT (readv, frame, -1, op_errno, NULL, 0, NULL, NULL); + return 0; } -int -client3_1_fgetxattr_cbk (struct rpc_req *req, struct iovec *iov, int count, - void *myframe) -{ - call_frame_t *frame = NULL; - char *buf = NULL; - dict_t *dict = NULL; - gfs3_fgetxattr_rsp rsp = {0,}; - int ret = 0; - int dict_len = 0; - int op_ret = 0; - int op_errno = 0; - frame = myframe; +int32_t +client3_1_writev (call_frame_t *frame, xlator_t *this, void *data) +{ + clnt_args_t *args = NULL; + clnt_fd_ctx_t *fdctx = NULL; + clnt_conf_t *conf = NULL; + gfs3_write_req req = {0,}; + int op_errno = ESTALE; - if (-1 == req->rpc_status) { - op_ret = -1; - op_errno = ENOTCONN; - goto out; - } - ret = xdr_to_fgetxattr_rsp (*iov, &rsp); - if (ret < 0) { - gf_log ("", GF_LOG_ERROR, "error"); - op_ret = -1; - op_errno = EINVAL; - goto out; - } + if (!frame || !this || !data) + goto unwind; - op_errno = gf_error_to_errno (rsp.op_errno); - op_ret = rsp.op_ret; - if (-1 != op_ret) { - op_ret = -1; - dict_len = rsp.dict.dict_len; + args = data; + conf = this->private; - if (dict_len > 0) { - dict = dict_new(); - GF_VALIDATE_OR_GOTO (frame->this->name, dict, out); - buf = memdup (rsp.dict.dict_val, rsp.dict.dict_len); - GF_VALIDATE_OR_GOTO (frame->this->name, buf, out); + pthread_mutex_lock (&conf->lock); + { + fdctx = this_fd_get_ctx (args->fd, this); + } + pthread_mutex_unlock (&conf->lock); - ret = dict_unserialize (buf, dict_len, &dict); - if (ret < 0) { - gf_log (frame->this->name, GF_LOG_DEBUG, - "failed to unserialize xattr dict"); - op_errno = EINVAL; - goto out; - } - dict->extra_free = buf; - buf = NULL; - } - op_ret = 0; + if (fdctx == NULL) { + gf_log (this->name, GF_LOG_DEBUG, + "(%"PRId64"): failed to get fd ctx. EBADFD", + args->fd->inode->ino); + op_errno = EBADFD; + goto unwind; } -out: - STACK_UNWIND_STRICT (fgetxattr, frame, op_ret, op_errno, dict); - if (rsp.dict.dict_val) { - /* don't use GF_FREE, this memory was allocated by libc - */ - free (rsp.dict.dict_val); - rsp.dict.dict_val = NULL; + + if (fdctx->remote_fd == -1) { + gf_log (this->name, GF_LOG_DEBUG, "(%"PRId64"): failed to get" + " fd ctx. EBADFD", args->fd->inode->ino); + op_errno = EBADFD; + goto unwind; } - if (buf) - GF_FREE (buf); + req.size = args->size; + req.offset = args->offset; + req.fd = fdctx->remote_fd; + req.gfs_id = GFS3_OP_WRITE; - if (dict) - dict_unref (dict); + client_submit_vec_request (this, &req, frame, conf->fops, GFS3_OP_WRITE, + client3_1_writev_cbk, + args->vector, args->count, + args->iobref, xdr_from_writev_req); return 0; +unwind: + STACK_UNWIND_STRICT (writev, frame, -1, op_errno, NULL, NULL); + return 0; } -int -client3_1_removexattr_cbk (struct rpc_req *req, struct iovec *iov, int count, - void *myframe) + + +int32_t +client3_1_flush (call_frame_t *frame, xlator_t *this, + void *data) { - call_frame_t *frame = NULL; - gf_common_rsp rsp = {0,}; - int ret = 0; + clnt_args_t *args = NULL; + gfs3_flush_req req = {0,}; + clnt_fd_ctx_t *fdctx = NULL; + clnt_conf_t *conf = NULL; + int op_errno = ESTALE; - frame = myframe; + if (!frame || !this || !data) + goto unwind; - if (-1 == req->rpc_status) { - rsp.op_ret = -1; - rsp.op_errno = ENOTCONN; - goto out; + args = data; + conf = this->private; + + pthread_mutex_lock (&conf->lock); + { + fdctx = this_fd_get_ctx (args->fd, this); } + pthread_mutex_unlock (&conf->lock); - ret = xdr_to_common_rsp (*iov, &rsp); - if (ret < 0) { - gf_log ("", GF_LOG_ERROR, "error"); - rsp.op_ret = -1; - rsp.op_errno = EINVAL; - goto out; + if (fdctx == NULL) { + gf_log (this->name, GF_LOG_DEBUG, + "(%"PRId64"): failed to get fd ctx. EBADFD", + args->fd->inode->ino); + op_errno = EBADFD; + goto unwind; } -out: - STACK_UNWIND_STRICT (removexattr, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno)); + if (fdctx->remote_fd == -1) { + gf_log (this->name, GF_LOG_DEBUG, "(%"PRId64"): failed to get" + " fd ctx. EBADFD", args->fd->inode->ino); + op_errno = EBADFD; + goto unwind; + } + req.fd = fdctx->remote_fd; + req.gfs_id = GFS3_OP_FLUSH; + + client_submit_request (this, &req, frame, conf->fops, GFS3_OP_FLUSH, + client3_1_flush_cbk, NULL, xdr_from_flush_req); + + return 0; +unwind: + STACK_UNWIND_STRICT (flush, frame, -1, op_errno); return 0; } -int -client3_1_fsyncdir_cbk (struct rpc_req *req, struct iovec *iov, int count, - void *myframe) -{ - call_frame_t *frame = NULL; - gf_common_rsp rsp = {0,}; - int ret = 0; - - frame = myframe; - if (-1 == req->rpc_status) { - rsp.op_ret = -1; - rsp.op_errno = ENOTCONN; - goto out; - } - ret = xdr_to_common_rsp (*iov, &rsp); - if (ret < 0) { - gf_log ("", GF_LOG_ERROR, "error"); - rsp.op_ret = -1; - rsp.op_errno = EINVAL; - goto out; - } -out: - STACK_UNWIND_STRICT (fsyncdir, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno)); +int32_t +client3_1_fsync (call_frame_t *frame, xlator_t *this, + void *data) +{ + clnt_args_t *args = NULL; + gfs3_fsync_req req = {0,}; + clnt_fd_ctx_t *fdctx = NULL; + clnt_conf_t *conf = NULL; + int op_errno = 0; - return 0; -} + if (!frame || !this || !data) + goto unwind; -int -client3_1_access_cbk (struct rpc_req *req, struct iovec *iov, int count, - void *myframe) -{ - call_frame_t *frame = NULL; - gf_common_rsp rsp = {0,}; - int ret = 0; + args = data; + conf = this->private; - frame = myframe; + pthread_mutex_lock (&conf->lock); + { + fdctx = this_fd_get_ctx (args->fd, this); + } + pthread_mutex_unlock (&conf->lock); - if (-1 == req->rpc_status) { - rsp.op_ret = -1; - rsp.op_errno = ENOTCONN; - goto out; + if (fdctx == NULL) { + gf_log (this->name, GF_LOG_DEBUG, + "(%"PRId64"): failed to get fd ctx. EBADFD", + args->fd->inode->ino); + op_errno = EBADFD; + goto unwind; } - ret = xdr_to_common_rsp (*iov, &rsp); - if (ret < 0) { - gf_log ("", GF_LOG_ERROR, "error"); - rsp.op_ret = -1; - rsp.op_errno = EINVAL; - goto out; + + if (fdctx->remote_fd == -1) { + gf_log (this->name, GF_LOG_DEBUG, "(%"PRId64"): failed to get" + " fd ctx. EBADFD", args->fd->inode->ino); + op_errno = EBADFD; + goto unwind; } -out: - STACK_UNWIND_STRICT (access, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno)); + req.fd = fdctx->remote_fd; + req.data = args->flags; + req.gfs_id = GFS3_OP_FSYNC; + + client_submit_request (this, &req, frame, conf->fops, GFS3_OP_FSYNC, + client3_1_fsync_cbk, NULL, xdr_from_fsync_req); return 0; +unwind: + STACK_UNWIND_STRICT (fsync, frame, -1, op_errno, NULL, NULL); + return 0; } -int -client3_1_ftruncate_cbk (struct rpc_req *req, struct iovec *iov, int count, - void *myframe) + +int32_t +client3_1_fstat (call_frame_t *frame, xlator_t *this, + void *data) { - gfs3_ftruncate_rsp rsp = {0,}; - call_frame_t *frame = NULL; - struct iatt prestat = {0,}; - struct iatt poststat = {0,}; - int ret = 0; + clnt_args_t *args = NULL; + gfs3_fstat_req req = {0,}; + clnt_fd_ctx_t *fdctx = NULL; + clnt_conf_t *conf = NULL; + int op_errno = ESTALE; - frame = myframe; + if (!frame || !this || !data) + goto unwind; - if (-1 == req->rpc_status) { - rsp.op_ret = -1; - rsp.op_errno = ENOTCONN; - goto out; + args = data; + conf = this->private; + + pthread_mutex_lock (&conf->lock); + { + fdctx = this_fd_get_ctx (args->fd, this); } - ret = xdr_to_ftruncate_rsp (*iov, &rsp); - if (ret < 0) { - gf_log ("", GF_LOG_ERROR, "error"); - rsp.op_ret = -1; - rsp.op_errno = EINVAL; - goto out; + pthread_mutex_unlock (&conf->lock); + + if (fdctx == NULL) { + gf_log (this->name, GF_LOG_DEBUG, + "(%"PRId64"): failed to get fd ctx. EBADFD", + args->fd->inode->ino); + op_errno = EBADFD; + goto unwind; } - if (-1 != rsp.op_ret) { - gf_stat_to_iatt (&rsp.prestat, &prestat); - gf_stat_to_iatt (&rsp.poststat, &poststat); + if (fdctx->remote_fd == -1) { + gf_log (this->name, GF_LOG_DEBUG, "(%"PRId64"): failed to get" + " fd ctx. EBADFD", args->fd->inode->ino); + op_errno = EBADFD; + goto unwind; } -out: - STACK_UNWIND_STRICT (ftruncate, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno), &prestat, - &poststat); + req.fd = fdctx->remote_fd; + req.gfs_id = GFS3_OP_FSTAT; + client_submit_request (this, &req, frame, conf->fops, GFS3_OP_FSTAT, + client3_1_fstat_cbk, NULL, xdr_from_fstat_req); + + return 0; +unwind: + STACK_UNWIND_STRICT (fstat, frame, -1, op_errno, NULL); return 0; } -int -client3_1_fstat_cbk (struct rpc_req *req, struct iovec *iov, int count, - void *myframe) + + +int32_t +client3_1_opendir (call_frame_t *frame, xlator_t *this, + void *data) { - gfs3_fstat_rsp rsp = {0,}; - call_frame_t *frame = NULL; - struct iatt stat = {0,}; - int ret = 0; + clnt_local_t *local = NULL; + clnt_conf_t *conf = NULL; + clnt_args_t *args = NULL; + gfs3_opendir_req req = {0,}; + int ret = 0; + int op_errno = ESTALE; - frame = myframe; + if (!frame || !this || !data) + goto unwind; - if (-1 == req->rpc_status) { - rsp.op_ret = -1; - rsp.op_errno = ENOTCONN; - goto out; - } - ret = xdr_to_fstat_rsp (*iov, &rsp); - if (ret < 0) { - gf_log ("", GF_LOG_ERROR, "error"); - rsp.op_ret = -1; - rsp.op_errno = EINVAL; - goto out; + args = data; + + local = GF_CALLOC (1, sizeof (*local), gf_client_mt_clnt_local_t); + if (!local) { + op_errno = ENOMEM; + goto unwind; } + local->fd = fd_ref (args->fd); + loc_copy (&local->loc, args->loc); + frame->local = local; - if (-1 != rsp.op_ret) { - gf_stat_to_iatt (&rsp.stat, &stat); + ret = inode_ctx_get2 (args->loc->inode, this, &req.ino, &req.gen); + if (args->loc->inode->ino && ret < 0) { + gf_log (this->name, GF_LOG_DEBUG, + "OPEN %"PRId64" (%s): " + "failed to get remote inode number", + args->loc->inode->ino, args->loc->path); + goto unwind; } + req.path = (char *)args->loc->path; + req.gfs_id = GFS3_OP_OPENDIR; -out: - STACK_UNWIND_STRICT (fstat, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno), &stat); + conf = this->private; + client_submit_request (this, &req, frame, conf->fops, GFS3_OP_OPENDIR, + client3_1_opendir_cbk, NULL, xdr_from_opendir_req); + + return 0; +unwind: + frame->local = NULL; + STACK_UNWIND_STRICT (opendir, frame, -1, op_errno, NULL); + if (local) + client_local_wipe (local); return 0; } -int -client3_1_inodelk_cbk (struct rpc_req *req, struct iovec *iov, int count, - void *myframe) + +int32_t +client3_1_fsyncdir (call_frame_t *frame, xlator_t *this, void *data) { - call_frame_t *frame = NULL; - gf_common_rsp rsp = {0,}; - int ret = 0; + clnt_args_t *args = NULL; + clnt_fd_ctx_t *fdctx = NULL; + clnt_conf_t *conf = NULL; + int op_errno = ESTALE; + gfs3_fsyncdir_req req = {0,}; - frame = myframe; + if (!frame || !this || !data) + goto unwind; - if (-1 == req->rpc_status) { - rsp.op_ret = -1; - rsp.op_errno = ENOTCONN; - goto out; - } - ret = xdr_to_common_rsp (*iov, &rsp); - if (ret < 0) { - gf_log ("", GF_LOG_ERROR, "error"); - rsp.op_ret = -1; - rsp.op_errno = EINVAL; - goto out; - } + args = data; + conf = this->private; -out: - STACK_UNWIND_STRICT (inodelk, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno)); + pthread_mutex_lock (&conf->lock); + { + fdctx = this_fd_get_ctx (args->fd, this); + } + pthread_mutex_unlock (&conf->lock); - return 0; -} + if (fdctx == NULL) { + gf_log (this->name, GF_LOG_DEBUG, + "(%"PRId64"): failed to get fd ctx. EBADFD", + args->fd->inode->ino); + op_errno = EBADFD; + goto unwind; + } -int -client3_1_finodelk_cbk (struct rpc_req *req, struct iovec *iov, int count, - void *myframe) -{ - call_frame_t *frame = NULL; - gf_common_rsp rsp = {0,}; - int ret = 0; + if (fdctx->remote_fd == -1) { + gf_log (this->name, GF_LOG_DEBUG, "(%"PRId64"): failed to get" + " fd ctx. EBADFD", args->fd->inode->ino); + op_errno = EBADFD; + goto unwind; + } - frame = myframe; + req.fd = fdctx->remote_fd; + req.data = args->flags; + req.gfs_id = GFS3_OP_FSYNCDIR; - if (-1 == req->rpc_status) { - rsp.op_ret = -1; - rsp.op_errno = ENOTCONN; - goto out; - } - ret = xdr_to_common_rsp (*iov, &rsp); - if (ret < 0) { - gf_log ("", GF_LOG_ERROR, "error"); - rsp.op_ret = -1; - rsp.op_errno = EINVAL; - goto out; - } + conf = this->private; -out: - STACK_UNWIND_STRICT (finodelk, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno)); + client_submit_request (this, &req, frame, conf->fops, GFS3_OP_FSYNCDIR, + client3_1_fsyncdir_cbk, NULL, xdr_from_fsyncdir_req); return 0; +unwind: + STACK_UNWIND_STRICT (fsyncdir, frame, -1, op_errno); + return 0; } -int -client3_1_entrylk_cbk (struct rpc_req *req, struct iovec *iov, int count, - void *myframe) + + +int32_t +client3_1_statfs (call_frame_t *frame, xlator_t *this, + void *data) { - call_frame_t *frame = NULL; - gf_common_rsp rsp = {0,}; - int ret = 0; + clnt_conf_t *conf = NULL; + clnt_args_t *args = NULL; + gfs3_statfs_req req = {0,}; + int ret = 0; + int op_errno = ESTALE; - frame = myframe; + if (!frame || !this || !data) + goto unwind; - if (-1 == req->rpc_status) { - rsp.op_ret = -1; - rsp.op_errno = ENOTCONN; - goto out; - } - ret = xdr_to_common_rsp (*iov, &rsp); - if (ret < 0) { - gf_log ("", GF_LOG_ERROR, "error"); - rsp.op_ret = -1; - rsp.op_errno = EINVAL; - goto out; + args = data; + + if (args->loc->inode) { + ret = inode_ctx_get2 (args->loc->inode, this, + &req.ino, &req.gen); + if (args->loc->inode->ino && ret < 0) { + gf_log (this->name, GF_LOG_TRACE, + "STATFS %"PRId64" (%s): " + "failed to get remote inode number", + args->loc->inode->ino, args->loc->path); + goto unwind; + } } + req.path = (char *)args->loc->path; + req.gfs_id = GFS3_OP_STATFS; -out: + conf = this->private; - STACK_UNWIND_STRICT (entrylk, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno)); + client_submit_request (this, &req, frame, conf->fops, GFS3_OP_STATFS, + client3_1_statfs_cbk, NULL, xdr_from_statfs_req); return 0; +unwind: + STACK_UNWIND_STRICT (statfs, frame, -1, op_errno, NULL); + return 0; } -int -client3_1_fentrylk_cbk (struct rpc_req *req, struct iovec *iov, int count, - void *myframe) + + +int32_t +client3_1_setxattr (call_frame_t *frame, xlator_t *this, + void *data) { - call_frame_t *frame = NULL; - gf_common_rsp rsp = {0,}; - int ret = 0; + clnt_conf_t *conf = NULL; + clnt_args_t *args = NULL; + gfs3_setxattr_req req = {0,}; + int ret = 0; + size_t dict_len = 0; + int op_errno = ESTALE; - frame = myframe; + if (!frame || !this || !data) + goto unwind; - if (-1 == req->rpc_status) { - rsp.op_ret = -1; - rsp.op_errno = ENOTCONN; - goto out; + args = data; + + ret = inode_ctx_get2 (args->loc->inode, this, &req.ino, &req.gen); + if (args->loc->inode->ino && ret < 0) { + gf_log (this->name, GF_LOG_DEBUG, + "SETXATTR %"PRId64" (%s): " + "failed to get remote inode number", + args->loc->inode->ino, args->loc->path); + goto unwind; } - ret = xdr_to_common_rsp (*iov, &rsp); - if (ret < 0) { - gf_log ("", GF_LOG_ERROR, "error"); - rsp.op_ret = -1; - rsp.op_errno = EINVAL; - goto out; + if (args->dict) { + ret = dict_allocate_and_serialize (args->dict, + &req.dict.dict_val, + &dict_len); + if (ret < 0) { + gf_log (this->name, GF_LOG_DEBUG, + "failed to get serialized dict"); + op_errno = EINVAL; + goto unwind; + } + req.dict.dict_len = dict_len; } + req.flags = args->flags; + req.path = (char *)args->loc->path; + req.gfs_id = GFS3_OP_SETXATTR; -out: - STACK_UNWIND_STRICT (fentrylk, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno)); + conf = this->private; + + client_submit_request (this, &req, frame, conf->fops, GFS3_OP_SETXATTR, + client3_1_setxattr_cbk, NULL, xdr_from_setxattr_req); + + if (req.dict.dict_val) { + GF_FREE (req.dict.dict_val); + } + return 0; +unwind: + STACK_UNWIND_STRICT (setxattr, frame, -1, op_errno); + if (req.dict.dict_val) { + GF_FREE (req.dict.dict_val); + } return 0; } -int -client3_1_xattrop_cbk (struct rpc_req *req, struct iovec *iov, int count, - void *myframe) -{ - call_frame_t *frame = NULL; - dict_t *dict = NULL; - char *buf = NULL; - gfs3_xattrop_rsp rsp = {0,}; - int ret = 0; - int op_ret = 0; - int dict_len = 0; - int op_errno = 0; - - frame = myframe; - if (-1 == req->rpc_status) { - op_ret = -1; - op_errno = ENOTCONN; - goto out; - } - ret = xdr_to_xattrop_rsp (*iov, &rsp); - if (ret < 0) { - gf_log ("", GF_LOG_ERROR, "error"); - op_ret = -1; - op_errno = EINVAL; - goto out; - } - op_ret = rsp.op_ret; - if (-1 != op_ret) { - op_ret = -1; - dict_len = rsp.dict.dict_len; +int32_t +client3_1_fsetxattr (call_frame_t *frame, xlator_t *this, + void *data) +{ + clnt_args_t *args = NULL; + clnt_fd_ctx_t *fdctx = NULL; + clnt_conf_t *conf = NULL; + gfs3_fsetxattr_req req = {0,}; + int op_errno = ESTALE; + int ret = 0; + size_t dict_len = 0; - if (dict_len > 0) { - dict = dict_new(); - GF_VALIDATE_OR_GOTO (frame->this->name, dict, out); + if (!frame || !this || !data) + goto unwind; - buf = memdup (rsp.dict.dict_val, rsp.dict.dict_len); - GF_VALIDATE_OR_GOTO (frame->this->name, buf, out); - op_ret = dict_unserialize (buf, dict_len, &dict); - if (op_ret < 0) { - gf_log (frame->this->name, GF_LOG_DEBUG, - "failed to unserialize xattr dict"); - op_errno = EINVAL; - goto out; - } - dict->extra_free = buf; - buf = NULL; - } - op_ret = 0; + args = data; + conf = this->private; + + pthread_mutex_lock (&conf->lock); + { + fdctx = this_fd_get_ctx (args->fd, this); } + pthread_mutex_unlock (&conf->lock); -out: + if (fdctx == NULL) { + gf_log (this->name, GF_LOG_DEBUG, + "(%"PRId64"): failed to get fd ctx. EBADFD", + args->fd->inode->ino); + op_errno = EBADFD; + goto unwind; + } - STACK_UNWIND_STRICT (xattrop, frame, op_ret, - gf_error_to_errno (rsp.op_errno), dict); + if (fdctx->remote_fd == -1) { + gf_log (this->name, GF_LOG_DEBUG, "(%"PRId64"): failed to get" + " fd ctx. EBADFD", args->fd->inode->ino); + op_errno = EBADFD; + goto unwind; + } - if (rsp.dict.dict_val) { - /* don't use GF_FREE, this memory was allocated by libc - */ - free (rsp.dict.dict_val); - rsp.dict.dict_val = NULL; + req.fd = fdctx->remote_fd; + req.flags = args->flags; + req.ino = args->fd->inode->ino; + req.gfs_id = GFS3_OP_FSETXATTR; + + if (args->dict) { + ret = dict_allocate_and_serialize (args->dict, + &req.dict.dict_val, + &dict_len); + if (ret < 0) { + gf_log (this->name, GF_LOG_DEBUG, + "failed to get serialized dict"); + goto unwind; + } + req.dict.dict_len = dict_len; } - if (buf) - GF_FREE (buf); + client_submit_request (this, &req, frame, conf->fops, GFS3_OP_FSETXATTR, + client3_1_fsetxattr_cbk, NULL, xdr_from_fsetxattr_req); - if (dict) - dict_unref (dict); + if (req.dict.dict_val) { + GF_FREE (req.dict.dict_val); + } + return 0; +unwind: + STACK_UNWIND_STRICT (fsetxattr, frame, -1, op_errno); + if (req.dict.dict_val) { + GF_FREE (req.dict.dict_val); + } return 0; } -int -client3_1_fxattrop_cbk (struct rpc_req *req, struct iovec *iov, int count, - void *myframe) -{ - call_frame_t *frame = NULL; - dict_t *dict = NULL; - char *buf = NULL; - gfs3_fxattrop_rsp rsp = {0,}; - int ret = 0; - int op_ret = 0; - int dict_len = 0; - int op_errno = 0; - frame = myframe; - if (-1 == req->rpc_status) { - op_ret = -1; - op_errno = ENOTCONN; - goto out; - } - ret = xdr_to_fxattrop_rsp (*iov, &rsp); - if (ret < 0) { - op_ret = -1; - op_errno = EINVAL; - gf_log ("", GF_LOG_ERROR, "error"); - goto out; - } +int32_t +client3_1_fgetxattr (call_frame_t *frame, xlator_t *this, + void *data) +{ + clnt_args_t *args = NULL; + clnt_fd_ctx_t *fdctx = NULL; + clnt_conf_t *conf = NULL; + gfs3_fgetxattr_req req = {0,}; + int op_errno = ESTALE; - op_ret = rsp.op_ret; - if (-1 != op_ret) { - op_ret = -1; - dict_len = rsp.dict.dict_len; + if (!frame || !this || !data) + goto unwind; - if (dict_len > 0) { - dict = dict_new(); - GF_VALIDATE_OR_GOTO (frame->this->name, dict, out); + args = data; + conf = this->private; - buf = memdup (rsp.dict.dict_val, rsp.dict.dict_len); - GF_VALIDATE_OR_GOTO (frame->this->name, buf, out); - op_ret = dict_unserialize (buf, dict_len, &dict); - if (op_ret < 0) { - gf_log (frame->this->name, GF_LOG_DEBUG, - "failed to unserialize xattr dict"); - op_errno = EINVAL; - goto out; - } - dict->extra_free = buf; - buf = NULL; - } - op_ret = 0; + pthread_mutex_lock (&conf->lock); + { + fdctx = this_fd_get_ctx (args->fd, this); } + pthread_mutex_unlock (&conf->lock); -out: - - STACK_UNWIND_STRICT (fxattrop, frame, op_ret, - gf_error_to_errno (rsp.op_errno), dict); + if (fdctx == NULL) { + gf_log (this->name, GF_LOG_DEBUG, + "(%"PRId64"): failed to get fd ctx. EBADFD", + args->fd->inode->ino); + op_errno = EBADFD; + goto unwind; + } - if (rsp.dict.dict_val) { - /* don't use GF_FREE, this memory was allocated by libc - */ - free (rsp.dict.dict_val); - rsp.dict.dict_val = NULL; + if (fdctx->remote_fd == -1) { + gf_log (this->name, GF_LOG_DEBUG, "(%"PRId64"): failed to get" + " fd ctx. EBADFD", args->fd->inode->ino); + op_errno = EBADFD; + goto unwind; } - if (buf) - GF_FREE (buf); + req.namelen = 1; /* Use it as a flag */ + req.fd = fdctx->remote_fd; + req.name = (char *)args->name; + if (!req.name) { + req.name = ""; + req.namelen = 0; + } + req.gfs_id = GFS3_OP_FGETXATTR; - if (dict) - dict_unref (dict); + client_submit_request (this, &req, frame, conf->fops, GFS3_OP_FGETXATTR, + client3_1_fgetxattr_cbk, NULL, xdr_from_fgetxattr_req); return 0; +unwind: + STACK_UNWIND_STRICT (fgetxattr, frame, -1, op_errno, NULL); + return 0; } -int -client3_1_fsetxattr_cbk (struct rpc_req *req, struct iovec *iov, int count, - void *myframe) + + +int32_t +client3_1_getxattr (call_frame_t *frame, xlator_t *this, + void *data) { - call_frame_t *frame = NULL; - gf_common_rsp rsp = {0,}; - int ret = 0; + clnt_conf_t *conf = NULL; + clnt_args_t *args = NULL; + gfs3_getxattr_req req = {0,}; + int ret = 0; + int op_errno = ESTALE; - frame = myframe; + if (!frame || !this || !data) + goto unwind; - if (-1 == req->rpc_status) { - rsp.op_ret = -1; - rsp.op_errno = ENOTCONN; - goto out; + args = data; + + ret = inode_ctx_get2 (args->loc->inode, this, &req.ino, &req.gen); + if (args->loc->inode->ino && ret < 0) { + gf_log (this->name, GF_LOG_TRACE, + "STAT %"PRId64" (%s): " + "failed to get remote inode number", + args->loc->inode->ino, args->loc->path); + goto unwind; } - ret = xdr_to_common_rsp (*iov, &rsp); - if (ret < 0) { - gf_log ("", GF_LOG_ERROR, "error"); - rsp.op_ret = -1; - rsp.op_errno = EINVAL; - goto out; + + req.namelen = 1; /* Use it as a flag */ + req.path = (char *)args->loc->path; + req.name = (char *)args->name; + if (!req.name) { + req.name = ""; + req.namelen = 0; } + req.gfs_id = GFS3_OP_GETXATTR; -out: - STACK_UNWIND_STRICT (fsetxattr, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno)); + conf = this->private; + client_submit_request (this, &req, frame, conf->fops, GFS3_OP_GETXATTR, + client3_1_getxattr_cbk, NULL, xdr_from_getxattr_req); + + return 0; +unwind: + STACK_UNWIND_STRICT (getxattr, frame, -1, op_errno, NULL); return 0; } -int -client3_1_fsetattr_cbk (struct rpc_req *req, struct iovec *iov, int count, - void *myframe) + + +int32_t +client3_1_xattrop (call_frame_t *frame, xlator_t *this, + void *data) { - call_frame_t *frame = NULL; - gfs3_fsetattr_rsp rsp = {0,}; - struct iatt prestat = {0,}; - struct iatt poststat = {0,}; - int ret = 0; + clnt_conf_t *conf = NULL; + clnt_args_t *args = NULL; + gfs3_xattrop_req req = {0,}; + int ret = 0; + size_t dict_len = 0; + int op_errno = ESTALE; - frame = myframe; + if (!frame || !this || !data) + goto unwind; - if (-1 == req->rpc_status) { - rsp.op_ret = -1; - rsp.op_errno = ENOTCONN; - goto out; + args = data; + + ret = inode_ctx_get2 (args->loc->inode, this, &req.ino, &req.gen); + if (args->loc->inode->ino && ret < 0) { + gf_log (this->name, GF_LOG_DEBUG, + "SETXATTR %"PRId64" (%s): " + "failed to get remote inode number", + args->loc->inode->ino, args->loc->path); + goto unwind; } - ret = xdr_to_fsetattr_rsp (*iov, &rsp); - if (ret < 0) { - gf_log ("", GF_LOG_ERROR, "error"); - rsp.op_ret = -1; - rsp.op_errno = EINVAL; - goto out; + if (args->dict) { + ret = dict_allocate_and_serialize (args->dict, + &req.dict.dict_val, + &dict_len); + if (ret < 0) { + gf_log (this->name, GF_LOG_DEBUG, + "failed to get serialized dict"); + op_errno = EINVAL; + goto unwind; + } + req.dict.dict_len = dict_len; } + req.flags = args->flags; + req.path = (char *)args->loc->path; + req.gfs_id = GFS3_OP_XATTROP; - if (-1 != rsp.op_ret) { - gf_stat_to_iatt (&rsp.statpre, &prestat); - gf_stat_to_iatt (&rsp.statpost, &poststat); - } + conf = this->private; -out: - STACK_UNWIND_STRICT (fsetattr, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno), &prestat, - &poststat); + client_submit_request (this, &req, frame, conf->fops, GFS3_OP_XATTROP, + client3_1_xattrop_cbk, NULL, xdr_from_xattrop_req); + if (req.dict.dict_val) { + GF_FREE (req.dict.dict_val); + } + return 0; +unwind: + STACK_UNWIND_STRICT (xattrop, frame, -1, op_errno, NULL); + if (req.dict.dict_val) { + GF_FREE (req.dict.dict_val); + } return 0; } -int -client3_1_setattr_cbk (struct rpc_req *req, struct iovec *iov, int count, - void *myframe) -{ - call_frame_t *frame = NULL; - gfs3_setattr_rsp rsp = {0,}; - struct iatt prestat = {0,}; - struct iatt poststat = {0,}; - int ret = 0; - frame = myframe; +int32_t +client3_1_fxattrop (call_frame_t *frame, xlator_t *this, + void *data) +{ + clnt_args_t *args = NULL; + clnt_fd_ctx_t *fdctx = NULL; + clnt_conf_t *conf = NULL; + gfs3_fxattrop_req req = {0,}; + int op_errno = ESTALE; + int ret = 0; + size_t dict_len = 0; - if (-1 == req->rpc_status) { - rsp.op_ret = -1; - rsp.op_errno = ENOTCONN; - goto out; - } + if (!frame || !this || !data) + goto unwind; - ret = xdr_to_setattr_rsp (*iov, &rsp); - if (ret < 0) { - gf_log ("", GF_LOG_ERROR, "error"); - rsp.op_ret = -1; - rsp.op_errno = EINVAL; - goto out; - } + args = data; + conf = this->private; - if (-1 != rsp.op_ret) { - gf_stat_to_iatt (&rsp.statpre, &prestat); - gf_stat_to_iatt (&rsp.statpost, &poststat); + pthread_mutex_lock (&conf->lock); + { + fdctx = this_fd_get_ctx (args->fd, this); } + pthread_mutex_unlock (&conf->lock); -out: - STACK_UNWIND_STRICT (setattr, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno), &prestat, - &poststat); - - return 0; -} - -int -client3_1_create_cbk (struct rpc_req *req, struct iovec *iov, int count, - void *myframe) -{ - call_frame_t *frame = NULL; - fd_t *fd = NULL; - inode_t *inode = NULL; - struct iatt stbuf = {0, }; - struct iatt preparent = {0, }; - struct iatt postparent = {0, }; - int32_t ret = -1; - clnt_local_t *local = NULL; - clnt_conf_t *conf = NULL; - clnt_fd_ctx_t *fdctx = NULL; - gfs3_create_rsp rsp = {0,}; - - frame = myframe; - local = frame->local; frame->local = NULL; - conf = frame->this->private; - fd = local->fd; - inode = local->loc.inode; - - if (-1 == req->rpc_status) { - rsp.op_ret = -1; - rsp.op_errno = ENOTCONN; - goto out; + if (fdctx == NULL) { + gf_log (this->name, GF_LOG_DEBUG, + "(%"PRId64"): failed to get fd ctx. EBADFD", + args->fd->inode->ino); + op_errno = EBADFD; + goto unwind; } - ret = xdr_to_create_rsp (*iov, &rsp); - if (ret < 0) { - gf_log ("", GF_LOG_ERROR, "error"); - rsp.op_ret = -1; - rsp.op_errno = EINVAL; - goto out; + if (fdctx->remote_fd == -1) { + gf_log (this->name, GF_LOG_DEBUG, "(%"PRId64"): failed to get" + " fd ctx. EBADFD", args->fd->inode->ino); + op_errno = EBADFD; + goto unwind; } - if (-1 != rsp.op_ret) { - gf_stat_to_iatt (&rsp.stat, &stbuf); + req.fd = fdctx->remote_fd; + req.flags = args->flags; + req.ino = args->fd->inode->ino; + req.gfs_id = GFS3_OP_FXATTROP; - ret = inode_ctx_put2 (inode, frame->this, - stbuf.ia_ino, stbuf.ia_gen); + if (args->dict) { + ret = dict_allocate_and_serialize (args->dict, + &req.dict.dict_val, + &dict_len); if (ret < 0) { - gf_log (frame->this->name, GF_LOG_DEBUG, - "CREATE %"PRId64"/%s (%s): failed to set " - "remote inode number to inode ctx", - local->loc.parent->ino, local->loc.name, - local->loc.path); - } - - gf_stat_to_iatt (&rsp.preparent, &preparent); - gf_stat_to_iatt (&rsp.postparent, &postparent); - - fdctx = GF_CALLOC (1, sizeof (*fdctx), - gf_client_mt_clnt_fdctx_t); - if (!fdctx) { - rsp.op_ret = -1; - rsp.op_errno = ENOMEM; - goto out; - } - - fdctx->remote_fd = rsp.fd; - fdctx->inode = inode_ref (inode); - fdctx->ino = stbuf.ia_ino; - fdctx->gen = stbuf.ia_gen; - fdctx->flags = local->flags; - - INIT_LIST_HEAD (&fdctx->sfd_pos); - - this_fd_set_ctx (fd, frame->this, &local->loc, fdctx); - - pthread_mutex_lock (&conf->lock); - { - list_add_tail (&fdctx->sfd_pos, &conf->saved_fds); + gf_log (this->name, GF_LOG_DEBUG, + "failed to get serialized dict"); + goto unwind; } - pthread_mutex_unlock (&conf->lock); + req.dict.dict_len = dict_len; } -out: - frame->local = NULL; - STACK_UNWIND_STRICT (create, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno), fd, inode, - &stbuf, &preparent, &postparent); + client_submit_request (this, &req, frame, conf->fops, GFS3_OP_FXATTROP, + client3_1_fxattrop_cbk, NULL, xdr_from_fxattrop_req); + if (req.dict.dict_val) { + GF_FREE (req.dict.dict_val); + } - client_local_wipe (local); + return 0; +unwind: + STACK_UNWIND_STRICT (fxattrop, frame, -1, op_errno, NULL); + if (req.dict.dict_val) { + GF_FREE (req.dict.dict_val); + } return 0; } -int -client3_1_rchecksum_cbk (struct rpc_req *req, struct iovec *iov, int count, - void *myframe) + +int32_t +client3_1_removexattr (call_frame_t *frame, xlator_t *this, + void *data) { - call_frame_t *frame = NULL; - gfs3_rchecksum_rsp rsp = {0,}; - int ret = 0; + clnt_conf_t *conf = NULL; + clnt_args_t *args = NULL; + gfs3_removexattr_req req = {0,}; + int ret = 0; + int op_errno = ESTALE; - frame = myframe; + if (!frame || !this || !data) + goto unwind; - if (-1 == req->rpc_status) { - rsp.op_ret = -1; - rsp.op_errno = ENOTCONN; - goto out; - } + args = data; - ret = xdr_to_rchecksum_rsp (*iov, &rsp); - if (ret < 0) { - gf_log ("", GF_LOG_ERROR, "error"); - rsp.op_ret = -1; - rsp.op_errno = EINVAL; - goto out; + ret = inode_ctx_get2 (args->loc->inode, this, &req.ino, &req.gen); + if (args->loc->inode->ino && ret < 0) { + gf_log (this->name, GF_LOG_TRACE, + "REMOVEXATTR %"PRId64" (%s): " + "failed to get remote inode number", + args->loc->inode->ino, args->loc->path); + goto unwind; } + req.path = (char *)args->loc->path; + req.name = (char *)args->name; + req.gfs_id = GFS3_OP_REMOVEXATTR; -out: - STACK_UNWIND_STRICT (rchecksum, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno), - rsp.weak_checksum, - (uint8_t *)rsp.strong_checksum.strong_checksum_val); + conf = this->private; - if (rsp.strong_checksum.strong_checksum_val) { - /* This is allocated by the libc while decoding RPC msg */ - /* Hence no 'GF_FREE', but just 'free' */ - free (rsp.strong_checksum.strong_checksum_val); - } + client_submit_request (this, &req, frame, conf->fops, GFS3_OP_REMOVEXATTR, + client3_1_removexattr_cbk, NULL, xdr_from_removexattr_req); return 0; +unwind: + STACK_UNWIND_STRICT (removexattr, frame, -1, op_errno); + return 0; } -int -client3_1_checksum_cbk (struct rpc_req *req, struct iovec *iov, int count, - void *myframe) + +int32_t +client3_1_lk (call_frame_t *frame, xlator_t *this, + void *data) { - call_frame_t *frame = NULL; - gfs3_checksum_rsp rsp = {0,}; - int ret = 0; + clnt_args_t *args = NULL; + gfs3_lk_req req = {0,}; + int32_t gf_cmd = 0; + int32_t gf_type = 0; + clnt_fd_ctx_t *fdctx = NULL; + clnt_conf_t *conf = NULL; + int op_errno = ESTALE; - frame = myframe; + if (!frame || !this || !data) + goto unwind; - if (-1 == req->rpc_status) { - rsp.op_ret = -1; - rsp.op_errno = ENOTCONN; - goto out; + args = data; + conf = this->private; + + pthread_mutex_lock (&conf->lock); + { + fdctx = this_fd_get_ctx (args->fd, this); + } + pthread_mutex_unlock (&conf->lock); + + if (fdctx == NULL) { + gf_log (this->name, GF_LOG_DEBUG, + "(%"PRId64"): failed to get fd ctx. EBADFD", + args->fd->inode->ino); + op_errno = EBADFD; + goto unwind; } - ret = xdr_to_checksum_rsp (*iov, &rsp); - if (ret < 0) { - gf_log ("", GF_LOG_ERROR, "error"); - rsp.op_ret = -1; - rsp.op_errno = EINVAL; - goto out; + if (fdctx->remote_fd == -1) { + gf_log (this->name, GF_LOG_DEBUG, "(%"PRId64"): failed to get" + " fd ctx. EBADFD", args->fd->inode->ino); + op_errno = EBADFD; + goto unwind; } -out: - STACK_UNWIND_STRICT (checksum, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno), - (uint8_t *)rsp.fchecksum.fchecksum_val, - (uint8_t *)rsp.dchecksum.dchecksum_val); - - /* This is allocated by the libc while decoding RPC msg */ - /* Hence no 'GF_FREE', but just 'free' */ - if (rsp.fchecksum.fchecksum_val) { - free (rsp.fchecksum.fchecksum_val); + if (args->cmd == F_GETLK || args->cmd == F_GETLK64) + gf_cmd = GF_LK_GETLK; + else if (args->cmd == F_SETLK || args->cmd == F_SETLK64) + gf_cmd = GF_LK_SETLK; + else if (args->cmd == F_SETLKW || args->cmd == F_SETLKW64) + gf_cmd = GF_LK_SETLKW; + else { + gf_log (this->name, GF_LOG_DEBUG, + "Unknown cmd (%d)!", gf_cmd); + goto unwind; } - if (rsp.dchecksum.dchecksum_val) { - free (rsp.dchecksum.dchecksum_val); + + switch (args->flock->l_type) { + case F_RDLCK: + gf_type = GF_LK_F_RDLCK; + break; + case F_WRLCK: + gf_type = GF_LK_F_WRLCK; + break; + case F_UNLCK: + gf_type = GF_LK_F_UNLCK; + break; } + + req.fd = fdctx->remote_fd; + req.cmd = gf_cmd; + req.type = gf_type; + gf_flock_from_flock (&req.flock, args->flock); + req.gfs_id = GFS3_OP_LK; + + client_submit_request (this, &req, frame, conf->fops, GFS3_OP_LK, + client3_1_lk_cbk, NULL, xdr_from_lk_req); + + return 0; +unwind: + STACK_UNWIND_STRICT (lk, frame, -1, op_errno, NULL); return 0; } -int -client3_1_lk_cbk (struct rpc_req *req, struct iovec *iov, int count, - void *myframe) + +int32_t +client3_1_inodelk (call_frame_t *frame, xlator_t *this, + void *data) { - call_frame_t *frame = NULL; - struct flock lock = {0,}; - gfs3_lk_rsp rsp = {0,}; - int ret = 0; + clnt_conf_t *conf = NULL; + clnt_args_t *args = NULL; + gfs3_inodelk_req req = {0,}; + int ret = 0; + int32_t gf_cmd = 0; + int32_t gf_type = 0; + int op_errno = ESTALE; - frame = myframe; + if (!frame || !this || !data) + goto unwind; - if (-1 == req->rpc_status) { - rsp.op_ret = -1; - rsp.op_errno = ENOTCONN; - goto out; + args = data; + ret = inode_ctx_get2 (args->loc->inode, this, &req.ino, &req.gen); + if (args->loc->inode->ino && ret < 0) { + gf_log (this->name, GF_LOG_TRACE, + "INODELK %"PRId64" (%s): " + "failed to get remote inode number", + args->loc->inode->ino, args->loc->path); + goto unwind; } - ret = xdr_to_lk_rsp (*iov, &rsp); - if (ret < 0) { - gf_log ("", GF_LOG_ERROR, "error"); - rsp.op_ret = -1; - rsp.op_errno = EINVAL; - goto out; + if (args->cmd == F_GETLK || args->cmd == F_GETLK64) + gf_cmd = GF_LK_GETLK; + else if (args->cmd == F_SETLK || args->cmd == F_SETLK64) + gf_cmd = GF_LK_SETLK; + else if (args->cmd == F_SETLKW || args->cmd == F_SETLKW64) + gf_cmd = GF_LK_SETLKW; + else { + gf_log (this->name, GF_LOG_DEBUG, + "Unknown cmd (%d)!", gf_cmd); + op_errno = EINVAL; + goto unwind; } - if (rsp.op_ret >= 0) { - gf_flock_to_flock (&rsp.flock, &lock); + switch (args->flock->l_type) { + case F_RDLCK: + gf_type = GF_LK_F_RDLCK; + break; + case F_WRLCK: + gf_type = GF_LK_F_WRLCK; + break; + case F_UNLCK: + gf_type = GF_LK_F_UNLCK; + break; } -out: - STACK_UNWIND_STRICT (lk, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno), &lock); + req.path = (char *)args->loc->path; + req.volume = (char *)args->volume; + req.cmd = gf_cmd; + req.type = gf_type; + gf_flock_from_flock (&req.flock, args->flock); + req.gfs_id = GFS3_OP_INODELK; + + conf = this->private; + client_submit_request (this, &req, frame, conf->fops, GFS3_OP_INODELK, + client3_1_inodelk_cbk, NULL, xdr_from_inodelk_req); + + return 0; +unwind: + STACK_UNWIND_STRICT (inodelk, frame, -1, op_errno); return 0; } -int -client3_1_readdir_cbk (struct rpc_req *req, struct iovec *iov, int count, - void *myframe) + + +int32_t +client3_1_finodelk (call_frame_t *frame, xlator_t *this, + void *data) { - call_frame_t *frame = NULL; - gfs3_readdir_rsp rsp = {0,}; - int32_t ret = 0; - gf_dirent_t entries; + clnt_args_t *args = NULL; + gfs3_finodelk_req req = {0,}; + int32_t gf_cmd = 0; + int32_t gf_type = 0; + clnt_fd_ctx_t *fdctx = NULL; + clnt_conf_t *conf = NULL; + int op_errno = ESTALE; - frame = myframe; + if (!frame || !this || !data) + goto unwind; - if (-1 == req->rpc_status) { - rsp.op_ret = -1; - rsp.op_errno = ENOTCONN; - goto out; + args = data; + conf = this->private; + + pthread_mutex_lock (&conf->lock); + { + fdctx = this_fd_get_ctx (args->fd, this); } + pthread_mutex_unlock (&conf->lock); - ret = xdr_to_readdir_rsp (*iov, &rsp); - if (ret < 0) { - gf_log ("", GF_LOG_ERROR, "error"); - rsp.op_ret = -1; - rsp.op_errno = EINVAL; - goto out; + if (fdctx == NULL) { + gf_log (this->name, GF_LOG_DEBUG, + "(%"PRId64"): failed to get fd ctx. EBADFD", + args->fd->inode->ino); + op_errno = EBADFD; + goto unwind; } - INIT_LIST_HEAD (&entries.list); - if (rsp.op_ret > 0) { - gf_dirent_unserialize (&entries, rsp.buf.buf_val, - rsp.buf.buf_len); + if (fdctx->remote_fd == -1) { + gf_log (this->name, GF_LOG_DEBUG, "(%"PRId64"): failed to get" + " fd ctx. EBADFD", args->fd->inode->ino); + op_errno = EBADFD; + goto unwind; } -out: - STACK_UNWIND_STRICT (readdir, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno), &entries); + if (args->cmd == F_GETLK || args->cmd == F_GETLK64) + gf_cmd = GF_LK_GETLK; + else if (args->cmd == F_SETLK || args->cmd == F_SETLK64) + gf_cmd = GF_LK_SETLK; + else if (args->cmd == F_SETLKW || args->cmd == F_SETLKW64) + gf_cmd = GF_LK_SETLKW; + else { + gf_log (this->name, GF_LOG_DEBUG, + "Unknown cmd (%d)!", gf_cmd); + goto unwind; + } - if (rsp.op_ret != -1) { - gf_dirent_free (&entries); + switch (args->flock->l_type) { + case F_RDLCK: + gf_type = GF_LK_F_RDLCK; + break; + case F_WRLCK: + gf_type = GF_LK_F_WRLCK; + break; + case F_UNLCK: + gf_type = GF_LK_F_UNLCK; + break; } - /* This is allocated by the libc while decoding RPC msg */ - /* Hence no 'GF_FREE', but just 'free' */ - if (rsp.buf.buf_val) - free (rsp.buf.buf_val); + req.volume = (char *)args->volume; + req.fd = fdctx->remote_fd; + req.cmd = gf_cmd; + req.type = gf_type; + gf_flock_from_flock (&req.flock, args->flock); + req.gfs_id = GFS3_OP_FINODELK; + + client_submit_request (this, &req, frame, conf->fops, GFS3_OP_FINODELK, + client3_1_finodelk_cbk, NULL, xdr_from_finodelk_req); return 0; +unwind: + STACK_UNWIND_STRICT (finodelk, frame, -1, op_errno); + return 0; } -int -client3_1_readdirp_cbk (struct rpc_req *req, struct iovec *iov, int count, - void *myframe) +int32_t +client3_1_entrylk (call_frame_t *frame, xlator_t *this, + void *data) { - call_frame_t *frame = NULL; - gfs3_readdirp_rsp rsp = {0,}; - int32_t ret = 0; - gf_dirent_t entries; + clnt_conf_t *conf = NULL; + clnt_args_t *args = NULL; + gfs3_entrylk_req req = {0,}; + int ret = 0; + int op_errno = ESTALE; - frame = myframe; + if (!frame || !this || !data) + goto unwind; - if (-1 == req->rpc_status) { - rsp.op_ret = -1; - rsp.op_errno = ENOTCONN; - goto out; - } + args = data; - ret = xdr_to_readdirp_rsp (*iov, &rsp); - if (ret < 0) { - gf_log ("", GF_LOG_ERROR, "error"); - rsp.op_ret = -1; - rsp.op_errno = EINVAL; - goto out; + ret = inode_ctx_get2 (args->loc->inode, this, &req.ino, &req.gen); + if (args->loc->inode->ino && ret < 0) { + gf_log (this->name, GF_LOG_TRACE, + "STAT %"PRId64" (%s): " + "failed to get remote inode number", + args->loc->inode->ino, args->loc->path); + goto unwind; } - - INIT_LIST_HEAD (&entries.list); - if (rsp.op_ret > 0) { - gf_dirent_unserialize (&entries, rsp.buf.buf_val, - rsp.buf.buf_len); + req.path = (char *)args->loc->path; + req.cmd = args->cmd_entrylk; + req.type = args->type; + req.volume = (char *)args->volume; + req.name = ""; + if (args->basename) { + req.name = (char *)args->basename; + req.namelen = 1; } + req.gfs_id = GFS3_OP_ENTRYLK; -out: - STACK_UNWIND_STRICT (readdirp, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno), &entries); - - if (rsp.op_ret != -1) { - gf_dirent_free (&entries); - } + conf = this->private; - if (rsp.buf.buf_val) { - /* don't use GF_FREE as this memory was allocated by libc */ - free (rsp.buf.buf_val); - } + client_submit_request (this, &req, frame, conf->fops, GFS3_OP_ENTRYLK, + client3_1_entrylk_cbk, NULL, xdr_from_entrylk_req); return 0; +unwind: + STACK_UNWIND_STRICT (entrylk, frame, -1, op_errno); + return 0; } -int -client3_1_rename_cbk (struct rpc_req *req, struct iovec *iov, int count, - void *myframe) + +int32_t +client3_1_fentrylk (call_frame_t *frame, xlator_t *this, + void *data) { - call_frame_t *frame = NULL; - gfs3_rename_rsp rsp = {0,}; - struct iatt stbuf = {0,}; - struct iatt preoldparent = {0,}; - struct iatt postoldparent = {0,}; - struct iatt prenewparent = {0,}; - struct iatt postnewparent = {0,}; - int ret = 0; + clnt_args_t *args = NULL; + gfs3_fentrylk_req req = {0,}; + clnt_fd_ctx_t *fdctx = NULL; + clnt_conf_t *conf = NULL; + int op_errno = ESTALE; - frame = myframe; + if (!frame || !this || !data) + goto unwind; - if (-1 == req->rpc_status) { - rsp.op_ret = -1; - rsp.op_errno = ENOTCONN; - goto out; - } + args = data; + conf = this->private; - ret = xdr_to_rename_rsp (*iov, &rsp); - if (ret < 0) { - gf_log ("", GF_LOG_ERROR, "error"); - rsp.op_ret = -1; - rsp.op_errno = EINVAL; - goto out; + pthread_mutex_lock (&conf->lock); + { + fdctx = this_fd_get_ctx (args->fd, this); } + pthread_mutex_unlock (&conf->lock); - if (-1 != rsp.op_ret) { - gf_stat_to_iatt (&rsp.stat, &stbuf); + if (fdctx == NULL) { + gf_log (this->name, GF_LOG_DEBUG, + "(%"PRId64"): failed to get fd ctx. EBADFD", + args->fd->inode->ino); + op_errno = EBADFD; + goto unwind; + } - gf_stat_to_iatt (&rsp.preoldparent, &preoldparent); - gf_stat_to_iatt (&rsp.postoldparent, &postoldparent); + if (fdctx->remote_fd == -1) { + gf_log (this->name, GF_LOG_DEBUG, "(%"PRId64"): failed to get" + " fd ctx. EBADFD", args->fd->inode->ino); + op_errno = EBADFD; + goto unwind; + } - gf_stat_to_iatt (&rsp.prenewparent, &prenewparent); - gf_stat_to_iatt (&rsp.postnewparent, &postnewparent); + req.fd = fdctx->remote_fd; + req.cmd = args->cmd_entrylk; + req.type = args->type; + req.volume = (char *)args->volume; + req.name = ""; + if (args->basename) { + req.name = (char *)args->basename; + req.namelen = 1; } + req.gfs_id = GFS3_OP_FENTRYLK; -out: - STACK_UNWIND_STRICT (rename, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno), - &stbuf, &preoldparent, &postoldparent, - &preoldparent, &postoldparent); + client_submit_request (this, &req, frame, conf->fops, GFS3_OP_FENTRYLK, + client3_1_fentrylk_cbk, NULL, xdr_from_fentrylk_req); return 0; +unwind: + STACK_UNWIND_STRICT (fentrylk, frame, -1, op_errno); + return 0; } -int -client3_1_link_cbk (struct rpc_req *req, struct iovec *iov, int count, - void *myframe) -{ - call_frame_t *frame = NULL; - gfs3_link_rsp rsp = {0,}; - struct iatt stbuf = {0,}; - struct iatt preparent = {0,}; - struct iatt postparent = {0,}; - int ret = 0; - clnt_local_t *local = NULL; - inode_t *inode = NULL; - frame = myframe; - local = frame->local; - frame->local = NULL; - inode = local->loc.inode; - if (-1 == req->rpc_status) { - rsp.op_ret = -1; - rsp.op_errno = ENOTCONN; - goto out; - } +int32_t +client3_1_checksum (call_frame_t *frame, xlator_t *this, + void *data) +{ + clnt_conf_t *conf = NULL; + clnt_args_t *args = NULL; + gfs3_checksum_req req = {0,}; + int ret = 0; + int op_errno = ESTALE; - ret = xdr_to_link_rsp (*iov, &rsp); - if (ret < 0) { - gf_log ("", GF_LOG_ERROR, "error"); - rsp.op_ret = -1; - rsp.op_errno = EINVAL; - goto out; - } + if (!frame || !this || !data) + goto unwind; - if (-1 != rsp.op_ret) { - gf_stat_to_iatt (&rsp.stat, &stbuf); + args = data; - gf_stat_to_iatt (&rsp.preparent, &preparent); - gf_stat_to_iatt (&rsp.postparent, &postparent); + ret = inode_ctx_get2 (args->loc->inode, this, &req.ino, &req.gen); + if (args->loc->inode->ino && ret < 0) { + gf_log (this->name, GF_LOG_TRACE, + "STAT %"PRId64" (%s): " + "failed to get remote inode number", + args->loc->inode->ino, args->loc->path); + goto unwind; } + req.path = (char *)args->loc->path; + req.flag = args->flags; + req.gfs_id = GFS3_OP_CHECKSUM; -out: - frame->local = NULL; - STACK_UNWIND_STRICT (link, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno), inode, - &stbuf, &preparent, &postparent); + conf = this->private; - client_local_wipe (local); + client_submit_request (this, &req, frame, conf->fops, GFS3_OP_CHECKSUM, + client3_1_checksum_cbk, NULL, xdr_from_checksum_req); + + return 0; +unwind: + STACK_UNWIND_STRICT (checksum, frame, -1, op_errno, NULL, NULL); return 0; } -int -client3_1_opendir_cbk (struct rpc_req *req, struct iovec *iov, int count, - void *myframe) + +int32_t +client3_1_rchecksum (call_frame_t *frame, xlator_t *this, + void *data) { - clnt_local_t *local = NULL; - clnt_conf_t *conf = NULL; - clnt_fd_ctx_t *fdctx = NULL; - ino_t ino = 0; - uint64_t gen = 0; - call_frame_t *frame = NULL; - fd_t *fd = NULL; - int ret = 0; - gfs3_opendir_rsp rsp = {0,}; + clnt_args_t *args = NULL; + clnt_fd_ctx_t *fdctx = NULL; + clnt_conf_t *conf = NULL; + gfs3_rchecksum_req req = {0,}; + int op_errno = ESTALE; - frame = myframe; - local = frame->local; + if (!frame || !this || !data) + goto unwind; - if (local->op) { - local->op (req, iov, 1, myframe); - return 0; - } + args = data; + conf = this->private; - frame->local = NULL; - conf = frame->this->private; - fd = local->fd; + pthread_mutex_lock (&conf->lock); + { + fdctx = this_fd_get_ctx (args->fd, this); + } + pthread_mutex_unlock (&conf->lock); - if (-1 == req->rpc_status) { - rsp.op_ret = -1; - rsp.op_errno = ENOTCONN; - goto out; + if (fdctx == NULL) { + gf_log (this->name, GF_LOG_DEBUG, + "(%"PRId64"): failed to get fd ctx. EBADFD", + args->fd->inode->ino); + op_errno = EBADFD; + goto unwind; } - ret = xdr_to_opendir_rsp (*iov, &rsp); - if (ret < 0) { - gf_log ("", GF_LOG_ERROR, "error"); - rsp.op_ret = -1; - rsp.op_errno = EINVAL; - goto out; + if (fdctx->remote_fd == -1) { + gf_log (this->name, GF_LOG_DEBUG, "(%"PRId64"): failed to get" + " fd ctx. EBADFD", args->fd->inode->ino); + op_errno = EBADFD; + goto unwind; } - if (-1 != rsp.op_ret) { - fdctx = GF_CALLOC (1, sizeof (*fdctx), - gf_client_mt_clnt_fdctx_t); - if (!fdctx) { - rsp.op_ret = -1; - rsp.op_errno = ENOMEM; - goto out; - } + req.len = args->len; + req.offset = args->offset; + req.fd = fdctx->remote_fd; + req.gfs_id = GFS3_OP_RCHECKSUM; - inode_ctx_get2 (fd->inode, frame->this, &ino, &gen); + client_submit_request (this, &req, frame, conf->fops, GFS3_OP_RCHECKSUM, + client3_1_rchecksum_cbk, NULL, xdr_from_rchecksum_req); - fdctx->remote_fd = rsp.fd; - fdctx->inode = inode_ref (fd->inode); - fdctx->ino = ino; - fdctx->gen = gen; + return 0; +unwind: + STACK_UNWIND_STRICT (rchecksum, frame, -1, op_errno, 0, NULL); + return 0; +} - fdctx->is_dir = 1; - INIT_LIST_HEAD (&fdctx->sfd_pos); - this_fd_set_ctx (fd, frame->this, &local->loc, fdctx); +int32_t +client3_1_readdir (call_frame_t *frame, xlator_t *this, + void *data) +{ + clnt_args_t *args = NULL; + clnt_fd_ctx_t *fdctx = NULL; + clnt_conf_t *conf = NULL; + gfs3_readdir_req req = {0,}; + int op_errno = ESTALE; + + if (!frame || !this || !data) + goto unwind; + + args = data; + conf = this->private; + + pthread_mutex_lock (&conf->lock); + { + fdctx = this_fd_get_ctx (args->fd, this); + } + pthread_mutex_unlock (&conf->lock); + + if (fdctx == NULL) { + gf_log (this->name, GF_LOG_DEBUG, + "(%"PRId64"): failed to get fd ctx. EBADFD", + args->fd->inode->ino); + op_errno = EBADFD; + goto unwind; + } - pthread_mutex_lock (&conf->lock); - { - list_add_tail (&fdctx->sfd_pos, &conf->saved_fds); - } - pthread_mutex_unlock (&conf->lock); + if (fdctx->remote_fd == -1) { + gf_log (this->name, GF_LOG_DEBUG, "(%"PRId64"): failed to get" + " fd ctx. EBADFD", args->fd->inode->ino); + op_errno = EBADFD; + goto unwind; } -out: - frame->local = NULL; - STACK_UNWIND_STRICT (opendir, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno), fd); + req.size = args->size; + req.offset = args->offset; + req.fd = fdctx->remote_fd; + req.gfs_id = GFS3_OP_READDIR; - client_local_wipe (local); + client_submit_request (this, &req, frame, conf->fops, GFS3_OP_READDIR, + client3_1_readdir_cbk, NULL, xdr_from_readdir_req); return 0; +unwind: + STACK_UNWIND_STRICT (readdir, frame, -1, op_errno, NULL); + return 0; } -int -client3_1_lookup_cbk (struct rpc_req *req, struct iovec *iov, int count, - void *myframe) +int32_t +client3_1_readdirp (call_frame_t *frame, xlator_t *this, + void *data) { - clnt_local_t *local = NULL; - call_frame_t *frame = NULL; - int ret = 0; - gfs3_lookup_rsp rsp = {0,}; - struct iatt stbuf = {0,}; - struct iatt postparent = {0,}; - int op_errno = 0; - ino_t oldino = 0; - uint64_t oldgen = 0; - dict_t *xattr = NULL; - inode_t *inode = NULL; - char *buf = NULL; + clnt_args_t *args = NULL; + gfs3_readdirp_req req = {0,}; + clnt_fd_ctx_t *fdctx = NULL; + clnt_conf_t *conf = NULL; + int op_errno = ESTALE; - frame = myframe; - local = frame->local; - inode = local->loc.inode; - frame->local = NULL; + if (!frame || !this || !data) + goto unwind; - if (-1 == req->rpc_status) { - rsp.op_ret = -1; - rsp.op_errno = ENOTCONN; - goto out; + args = data; + conf = this->private; + + pthread_mutex_lock (&conf->lock); + { + fdctx = this_fd_get_ctx (args->fd, this); } + pthread_mutex_unlock (&conf->lock); - ret = xdr_to_lookup_rsp (*iov, &rsp); - if (ret < 0) { - gf_log ("", GF_LOG_ERROR, "error"); - rsp.op_ret = -1; - rsp.op_errno = EINVAL; - goto out; + if (fdctx == NULL) { + gf_log (this->name, GF_LOG_DEBUG, + "(%"PRId64"): failed to get fd ctx. EBADFD", + args->fd->inode->ino); + op_errno = EBADFD; + goto unwind; } - op_errno = gf_error_to_errno (rsp.op_errno); - gf_stat_to_iatt (&rsp.postparent, &postparent); + if (fdctx->remote_fd == -1) { + gf_log (this->name, GF_LOG_DEBUG, "(%"PRId64"): failed to get" + " fd ctx. EBADFD", args->fd->inode->ino); + op_errno = EBADFD; + goto unwind; + } - if (rsp.op_ret == 0) { - rsp.op_ret = -1; - gf_stat_to_iatt (&rsp.stat, &stbuf); + req.size = args->size; + req.offset = args->offset; + req.fd = fdctx->remote_fd; + req.gfs_id = GFS3_OP_READDIRP; - ret = inode_ctx_get2 (inode, frame->this, &oldino, &oldgen); - if (oldino != stbuf.ia_ino || oldgen != stbuf.ia_gen) { - if (oldino) { - gf_log (frame->this->name, GF_LOG_DEBUG, - "LOOKUP %"PRId64"/%s (%s): " - "inode number changed from " - "{%"PRId64",%"PRId64"} to {%"PRId64",%"PRId64"}", - local->loc.parent ? - local->loc.parent->ino : (uint64_t) 0, - local->loc.name, - local->loc.path, - oldgen, oldino, stbuf.ia_gen, stbuf.ia_ino); - op_errno = ESTALE; - goto out; - } + client_submit_request (this, &req, frame, conf->fops, GFS3_OP_READDIRP, + client3_1_readdirp_cbk, NULL, xdr_from_readdirp_req); - ret = inode_ctx_put2 (inode, frame->this, - stbuf.ia_ino, stbuf.ia_gen); - if (ret < 0) { - gf_log (frame->this->name, GF_LOG_DEBUG, - "LOOKUP %"PRId64"/%s (%s) : " - "failed to set remote inode " - "number to inode ctx", - local->loc.parent ? - local->loc.parent->ino : (uint64_t) 0, - local->loc.name, - local->loc.path); - } - } + return 0; +unwind: + STACK_UNWIND_STRICT (readdirp, frame, -1, op_errno, NULL); + return 0; +} - if (rsp.dict.dict_len > 0) { - xattr = dict_new(); - GF_VALIDATE_OR_GOTO (frame->this->name, xattr, out); - buf = memdup (rsp.dict.dict_val, rsp.dict.dict_len); - GF_VALIDATE_OR_GOTO (frame->this->name, buf, out); +int32_t +client3_1_setattr (call_frame_t *frame, xlator_t *this, + void *data) +{ + clnt_conf_t *conf = NULL; + clnt_args_t *args = NULL; + gfs3_setattr_req req = {0,}; + int ret = 0; + int op_errno = ESTALE; - ret = dict_unserialize (buf, rsp.dict.dict_len, &xattr); - if (ret < 0) { - gf_log (frame->this->name, GF_LOG_DEBUG, - "%s (%"PRId64"): failed to " - "unserialize dictionary", - local->loc.path, inode->ino); - op_errno = EINVAL; - goto out; - } + if (!frame || !this || !data) + goto unwind; - xattr->extra_free = buf; - buf = NULL; - } + args = data; - rsp.op_ret = 0; + ret = inode_ctx_get2 (args->loc->inode, this, &req.ino, &req.gen); + if (args->loc->inode->ino && ret < 0) { + gf_log (this->name, GF_LOG_TRACE, + "STAT %"PRId64" (%s): " + "failed to get remote inode number", + args->loc->inode->ino, args->loc->path); + goto unwind; } + req.path = (char *)args->loc->path; + req.valid = args->valid; + gf_stat_from_iatt (&req.stbuf, args->stbuf); + req.gfs_id = GFS3_OP_SETATTR; -out: - frame->local = NULL; - STACK_UNWIND_STRICT (lookup, frame, rsp.op_ret, rsp.op_errno, inode, - &stbuf, xattr, &postparent); - - client_local_wipe (local); - - if (xattr) - dict_unref (xattr); - - if (rsp.dict.dict_val) { - /* don't use GF_FREE, this memory was allocated by libc - */ - free (rsp.dict.dict_val); - rsp.dict.dict_val = NULL; - } + conf = this->private; - if (buf) { - GF_FREE (buf); - } + client_submit_request (this, &req, frame, conf->fops, GFS3_OP_SETATTR, + client3_1_setattr_cbk, NULL, xdr_from_setattr_req); return 0; +unwind: + STACK_UNWIND_STRICT (setattr, frame, -1, op_errno, NULL, NULL); + return 0; } -int -client3_1_readv_cbk (struct rpc_req *req, struct iovec *iov, int count, - void *myframe) +int32_t +client3_1_fsetattr (call_frame_t *frame, xlator_t *this, void *data) { - call_frame_t *frame = NULL; - struct iobref *iobref = NULL; - struct iovec vector = {0,}; - struct iatt stat = {0,}; - gfs3_read_rsp rsp = {0,}; - int ret = 0; + clnt_args_t *args = NULL; + clnt_fd_ctx_t *fdctx = NULL; + clnt_conf_t *conf = NULL; + gfs3_fsetattr_req req = {0,}; + int op_errno = ESTALE; - frame = myframe; + if (!frame || !this || !data) + goto unwind; - if (-1 == req->rpc_status) { - rsp.op_ret = -1; - rsp.op_errno = ENOTCONN; - goto out; - } + args = data; + conf = this->private; - ret = xdr_to_readv_rsp (*iov, &rsp); - if (ret < 0) { - gf_log ("", GF_LOG_ERROR, "error"); - rsp.op_ret = -1; - rsp.op_errno = EINVAL; - goto out; + pthread_mutex_lock (&conf->lock); + { + fdctx = this_fd_get_ctx (args->fd, this); } + pthread_mutex_unlock (&conf->lock); - if (rsp.op_ret != -1) { - iobref = iobref_new (); - gf_stat_to_iatt (&rsp.stat, &stat); - vector.iov_len = rsp.op_ret; - - if (rsp.op_ret > 0) { - vector.iov_base = req->rsp_procpayload->ptr; - iobref_add (iobref, req->rsp_procpayload); - } + if (fdctx == NULL) { + gf_log (this->name, GF_LOG_DEBUG, + "(%"PRId64"): failed to get fd ctx. EBADFD", + args->fd->inode->ino); + op_errno = EBADFD; + goto unwind; } -out: - STACK_UNWIND_STRICT (readv, frame, rsp.op_ret, - gf_error_to_errno (rsp.op_errno), &vector, 1, - &stat, iobref); - if (iobref) { - iobref_unref (iobref); + if (fdctx->remote_fd == -1) { + gf_log (this->name, GF_LOG_DEBUG, "(%"PRId64"): failed to get" + " fd ctx. EBADFD", args->fd->inode->ino); + op_errno = EBADFD; + goto unwind; } + req.fd = fdctx->remote_fd; + req.valid = args->valid; + gf_stat_from_iatt (&req.stbuf, args->stbuf); + req.gfs_id = GFS3_OP_FSETATTR; + + client_submit_request (this, &req, frame, conf->fops, GFS3_OP_FSETATTR, + client3_1_fsetattr_cbk, NULL, xdr_from_fsetattr_req); + + return 0; +unwind: + STACK_UNWIND_STRICT (fsetattr, frame, -1, op_errno, NULL, NULL); return 0; } + + /* Table Specific to FOPS */ rpc_clnt_procedure_t clnt3_1_fop_actors[GF_FOP_MAXVALUE] = { - [GF_FOP_NULL] = {"NULL", NULL, NULL }, - [GF_FOP_STAT] = { "STAT", client3_1_stat, client3_1_stat_cbk }, - [GF_FOP_READLINK] = { "READLINK", client3_1_readlink, client3_1_readlink_cbk }, - [GF_FOP_MKNOD] = { "MKNOD", client3_1_mknod, client3_1_mknod_cbk }, - [GF_FOP_MKDIR] = { "MKDIR", client3_1_mkdir, client3_1_mkdir_cbk }, - [GF_FOP_UNLINK] = { "UNLINK", client3_1_unlink, client3_1_unlink_cbk }, - [GF_FOP_RMDIR] = { "RMDIR", client3_1_rmdir, client3_1_rmdir_cbk }, - [GF_FOP_SYMLINK] = { "SYMLINK", client3_1_symlink, client3_1_symlink_cbk }, - [GF_FOP_RENAME] = { "RENAME", client3_1_rename, client3_1_rename_cbk }, - [GF_FOP_LINK] = { "LINK", client3_1_link, client3_1_link_cbk }, - [GF_FOP_TRUNCATE] = { "TRUNCATE", client3_1_truncate, client3_1_truncate_cbk }, - [GF_FOP_OPEN] = { "OPEN", client3_1_open, client3_1_open_cbk }, - [GF_FOP_READ] = { "READ", client3_1_readv, client3_1_readv_cbk }, - [GF_FOP_WRITE] = { "WRITE", client3_1_writev, client3_1_writev_cbk }, - [GF_FOP_STATFS] = { "STATFS", client3_1_statfs, client3_1_statfs_cbk }, - [GF_FOP_FLUSH] = { "FLUSH", client3_1_flush, client3_1_flush_cbk }, - [GF_FOP_FSYNC] = { "FSYNC", client3_1_fsync, client3_1_fsync_cbk }, - [GF_FOP_SETXATTR] = { "SETXATTR", client3_1_setxattr, client3_1_setxattr_cbk }, - [GF_FOP_GETXATTR] = { "GETXATTR", client3_1_getxattr, client3_1_getxattr_cbk }, - [GF_FOP_REMOVEXATTR] = { "REMOVEXATTR", client3_1_removexattr, client3_1_removexattr_cbk }, - [GF_FOP_OPENDIR] = { "OPENDIR", client3_1_opendir, client3_1_opendir_cbk }, - [GF_FOP_FSYNCDIR] = { "FSYNCDIR", client3_1_fsyncdir, client3_1_fsyncdir_cbk }, - [GF_FOP_ACCESS] = { "ACCESS", client3_1_access, client3_1_access_cbk }, - [GF_FOP_CREATE] = { "CREATE", client3_1_create, client3_1_create_cbk }, - [GF_FOP_FTRUNCATE] = { "FTRUNCATE", client3_1_ftruncate, client3_1_ftruncate_cbk }, - [GF_FOP_FSTAT] = { "FSTAT", client3_1_fstat, client3_1_fstat_cbk }, - [GF_FOP_LK] = { "LK", client3_1_lk, client3_1_lk_cbk }, - [GF_FOP_LOOKUP] = { "LOOKUP", client3_1_lookup, client3_1_lookup_cbk }, - [GF_FOP_READDIR] = { "READDIR", client3_1_readdir, client3_1_readdir_cbk }, - [GF_FOP_INODELK] = { "INODELK", client3_1_inodelk, client3_1_inodelk_cbk }, - [GF_FOP_FINODELK] = { "FINODELK", client3_1_finodelk, client3_1_finodelk_cbk }, - [GF_FOP_ENTRYLK] = { "ENTRYLK", client3_1_entrylk, client3_1_entrylk_cbk }, - [GF_FOP_FENTRYLK] = { "FENTRYLK", client3_1_fentrylk, client3_1_fentrylk_cbk }, - [GF_FOP_CHECKSUM] = { "CHECKSUM", client3_1_checksum, client3_1_checksum_cbk }, - [GF_FOP_XATTROP] = { "XATTROP", client3_1_xattrop, client3_1_xattrop_cbk }, - [GF_FOP_FXATTROP] = { "FXATTROP", client3_1_fxattrop, client3_1_fxattrop_cbk }, - [GF_FOP_FGETXATTR] = { "FGETXATTR", client3_1_fgetxattr, client3_1_fgetxattr_cbk }, - [GF_FOP_FSETXATTR] = { "FSETXATTR", client3_1_fsetxattr, client3_1_fsetxattr_cbk }, - [GF_FOP_RCHECKSUM] = { "RCHECKSUM", client3_1_rchecksum, client3_1_rchecksum_cbk }, - [GF_FOP_SETATTR] = { "SETATTR", client3_1_setattr, client3_1_setattr_cbk }, - [GF_FOP_FSETATTR] = { "FSETATTR", client3_1_fsetattr, client3_1_fsetattr_cbk }, - [GF_FOP_READDIRP] = { "READDIRP", client3_1_readdirp, client3_1_readdirp_cbk }, - [GF_FOP_FORGET] = { "FORGET", NULL, client3_1_release_cbk }, - [GF_FOP_RELEASE] = { "RELEASE", client3_1_release, client3_1_release_cbk }, - [GF_FOP_RELEASEDIR] = { "RELEASEDIR", client3_1_releasedir, client3_1_releasedir_cbk }, -// [GF_FOP_GETSPEC] = { "GETSPEC", client_getspec, client_getspec_cbk }, + [GF_FOP_NULL] = { "NULL", NULL}, + [GF_FOP_STAT] = { "STAT", client3_1_stat }, + [GF_FOP_READLINK] = { "READLINK", client3_1_readlink }, + [GF_FOP_MKNOD] = { "MKNOD", client3_1_mknod }, + [GF_FOP_MKDIR] = { "MKDIR", client3_1_mkdir }, + [GF_FOP_UNLINK] = { "UNLINK", client3_1_unlink }, + [GF_FOP_RMDIR] = { "RMDIR", client3_1_rmdir }, + [GF_FOP_SYMLINK] = { "SYMLINK", client3_1_symlink }, + [GF_FOP_RENAME] = { "RENAME", client3_1_rename }, + [GF_FOP_LINK] = { "LINK", client3_1_link }, + [GF_FOP_TRUNCATE] = { "TRUNCATE", client3_1_truncate }, + [GF_FOP_OPEN] = { "OPEN", client3_1_open }, + [GF_FOP_READ] = { "READ", client3_1_readv }, + [GF_FOP_WRITE] = { "WRITE", client3_1_writev }, + [GF_FOP_STATFS] = { "STATFS", client3_1_statfs }, + [GF_FOP_FLUSH] = { "FLUSH", client3_1_flush }, + [GF_FOP_FSYNC] = { "FSYNC", client3_1_fsync }, + [GF_FOP_SETXATTR] = { "SETXATTR", client3_1_setxattr }, + [GF_FOP_GETXATTR] = { "GETXATTR", client3_1_getxattr }, + [GF_FOP_REMOVEXATTR] = { "REMOVEXATTR", client3_1_removexattr }, + [GF_FOP_OPENDIR] = { "OPENDIR", client3_1_opendir }, + [GF_FOP_FSYNCDIR] = { "FSYNCDIR", client3_1_fsyncdir }, + [GF_FOP_ACCESS] = { "ACCESS", client3_1_access }, + [GF_FOP_CREATE] = { "CREATE", client3_1_create }, + [GF_FOP_FTRUNCATE] = { "FTRUNCATE", client3_1_ftruncate }, + [GF_FOP_FSTAT] = { "FSTAT", client3_1_fstat }, + [GF_FOP_LK] = { "LK", client3_1_lk }, + [GF_FOP_LOOKUP] = { "LOOKUP", client3_1_lookup }, + [GF_FOP_READDIR] = { "READDIR", client3_1_readdir }, + [GF_FOP_INODELK] = { "INODELK", client3_1_inodelk }, + [GF_FOP_FINODELK] = { "FINODELK", client3_1_finodelk }, + [GF_FOP_ENTRYLK] = { "ENTRYLK", client3_1_entrylk }, + [GF_FOP_FENTRYLK] = { "FENTRYLK", client3_1_fentrylk }, + [GF_FOP_CHECKSUM] = { "CHECKSUM", client3_1_checksum }, + [GF_FOP_XATTROP] = { "XATTROP", client3_1_xattrop }, + [GF_FOP_FXATTROP] = { "FXATTROP", client3_1_fxattrop }, + [GF_FOP_FGETXATTR] = { "FGETXATTR", client3_1_fgetxattr }, + [GF_FOP_FSETXATTR] = { "FSETXATTR", client3_1_fsetxattr }, + [GF_FOP_RCHECKSUM] = { "RCHECKSUM", client3_1_rchecksum }, + [GF_FOP_SETATTR] = { "SETATTR", client3_1_setattr }, + [GF_FOP_FSETATTR] = { "FSETATTR", client3_1_fsetattr }, + [GF_FOP_READDIRP] = { "READDIRP", client3_1_readdirp }, + [GF_FOP_RELEASE] = { "RELEASE", client3_1_release }, + [GF_FOP_RELEASEDIR] = { "RELEASEDIR", client3_1_releasedir }, + [GF_FOP_GETSPEC] = { "GETSPEC", client3_getspec }, }; -rpc_clnt_prog_t clnt3_1_fop_prog = { - .progname = "GlusterFS 3.1", - .prognum = GLUSTER3_1_FOP_PROGRAM, - .progver = GLUSTER3_1_FOP_VERSION, - .numproc = GLUSTER3_1_FOP_PROCCNT, - .actor = clnt3_1_fop_actors, +/* Used From RPC-CLNT library to log proper name of procedure based on number */ +char *clnt3_1_fop_names[GFS3_OP_MAXVALUE] = { + [GFS3_OP_NULL] = "NULL", + [GFS3_OP_STAT] = "STAT", + [GFS3_OP_READLINK] = "READLINK", + [GFS3_OP_MKNOD] = "MKNOD", + [GFS3_OP_MKDIR] = "MKDIR", + [GFS3_OP_UNLINK] = "UNLINK", + [GFS3_OP_RMDIR] = "RMDIR", + [GFS3_OP_SYMLINK] = "SYMLINK", + [GFS3_OP_RENAME] = "RENAME", + [GFS3_OP_LINK] = "LINK", + [GFS3_OP_TRUNCATE] = "TRUNCATE", + [GFS3_OP_OPEN] = "OPEN", + [GFS3_OP_READ] = "READ", + [GFS3_OP_WRITE] = "WRITE", + [GFS3_OP_STATFS] = "STATFS", + [GFS3_OP_FLUSH] = "FLUSH", + [GFS3_OP_FSYNC] = "FSYNC", + [GFS3_OP_SETXATTR] = "SETXATTR", + [GFS3_OP_GETXATTR] = "GETXATTR", + [GFS3_OP_REMOVEXATTR] = "REMOVEXATTR", + [GFS3_OP_OPENDIR] = "OPENDIR", + [GFS3_OP_FSYNCDIR] = "FSYNCDIR", + [GFS3_OP_ACCESS] = "ACCESS", + [GFS3_OP_CREATE] = "CREATE", + [GFS3_OP_FTRUNCATE] = "FTRUNCATE", + [GFS3_OP_FSTAT] = "FSTAT", + [GFS3_OP_LK] = "LK", + [GFS3_OP_LOOKUP] = "LOOKUP", + [GFS3_OP_READDIR] = "READDIR", + [GFS3_OP_INODELK] = "INODELK", + [GFS3_OP_FINODELK] = "FINODELK", + [GFS3_OP_ENTRYLK] = "ENTRYLK", + [GFS3_OP_FENTRYLK] = "FENTRYLK", + [GFS3_OP_CHECKSUM] = "CHECKSUM", + [GFS3_OP_XATTROP] = "XATTROP", + [GFS3_OP_FXATTROP] = "FXATTROP", + [GFS3_OP_FGETXATTR] = "FGETXATTR", + [GFS3_OP_FSETXATTR] = "FSETXATTR", + [GFS3_OP_RCHECKSUM] = "RCHECKSUM", + [GFS3_OP_SETATTR] = "SETATTR", + [GFS3_OP_FSETATTR] = "FSETATTR", + [GFS3_OP_READDIRP] = "READDIRP", + [GFS3_OP_RELEASE] = "RELEASE", + [GFS3_OP_RELEASEDIR] = "RELEASEDIR", }; -rpc_clnt_procedure_t clnt3_1_mgmt_actors[] = { - {0,} +rpc_clnt_prog_t clnt3_1_fop_prog = { + .progname = "GlusterFS 3.1", + .prognum = GLUSTER3_1_FOP_PROGRAM, + .progver = GLUSTER3_1_FOP_VERSION, + .numproc = GLUSTER3_1_FOP_PROCCNT, + .proctable = clnt3_1_fop_actors, + .procnames = clnt3_1_fop_names, }; rpc_clnt_prog_t clnt3_1_mgmt_prog = { - .progname = "Mgmt 3.1", + .progname = "Gluster Mgmt 3.1", .prognum = GLUSTER1_MGMT_PROGRAM, .progver = GLUSTER1_MGMT_VERSION, - .actor = clnt3_1_mgmt_actors, - .numproc = (sizeof (*clnt3_1_mgmt_actors) / - sizeof (rpc_clnt_procedure_t)), }; diff --git a/xlators/protocol/lib/src/Makefile.am b/xlators/protocol/lib/src/Makefile.am index ece59ef905a..98cf44d0948 100644 --- a/xlators/protocol/lib/src/Makefile.am +++ b/xlators/protocol/lib/src/Makefile.am @@ -10,6 +10,6 @@ libgfproto1_la_CPPFLAGS = -D_FILE_OFFSET_BITS=64 -D__USE_FILE_OFFSET64 -D_GNU_SO libgfproto1_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la -libgfproto1_la_SOURCES = authenticate.c protocol-common.c msg-xdr.c glusterfs-xdr.c +libgfproto1_la_SOURCES = authenticate.c msg-xdr.c glusterfs-xdr.c noinst_HEADERS = authenticate.h protocol-common.h msg-xdr.h glusterfs-xdr.h diff --git a/xlators/protocol/lib/src/glusterfs-xdr.c b/xlators/protocol/lib/src/glusterfs-xdr.c index 6538d6d26f8..e8a254094f9 100644 --- a/xlators/protocol/lib/src/glusterfs-xdr.c +++ b/xlators/protocol/lib/src/glusterfs-xdr.c @@ -1147,21 +1147,6 @@ xdr_gfs3_readdir_req (XDR *xdrs, gfs3_readdir_req *objp) return TRUE; } -bool_t -xdr_gfs3_readdir_rsp (XDR *xdrs, gfs3_readdir_rsp *objp) -{ - - if (!xdr_u_quad_t (xdrs, &objp->gfs_id)) - return FALSE; - if (!xdr_int (xdrs, &objp->op_ret)) - return FALSE; - if (!xdr_int (xdrs, &objp->op_errno)) - return FALSE; - if (!xdr_bytes (xdrs, (char **)&objp->buf.buf_val, (u_int *) &objp->buf.buf_len, ~0)) - return FALSE; - return TRUE; -} - bool_t xdr_gfs3_readdirp_req (XDR *xdrs, gfs3_readdirp_req *objp) { @@ -1181,21 +1166,6 @@ xdr_gfs3_readdirp_req (XDR *xdrs, gfs3_readdirp_req *objp) return TRUE; } -bool_t -xdr_gfs3_readdirp_rsp (XDR *xdrs, gfs3_readdirp_rsp *objp) -{ - - if (!xdr_u_quad_t (xdrs, &objp->gfs_id)) - return FALSE; - if (!xdr_int (xdrs, &objp->op_ret)) - return FALSE; - if (!xdr_int (xdrs, &objp->op_errno)) - return FALSE; - if (!xdr_bytes (xdrs, (char **)&objp->buf.buf_val, (u_int *) &objp->buf.buf_len, ~0)) - return FALSE; - return TRUE; -} - bool_t xdr_gf_setvolume_req (XDR *xdrs, gf_setvolume_req *objp) { @@ -1759,3 +1729,70 @@ xdr_gf_dump_version_rsp (XDR *xdrs, gf_dump_version_rsp *objp) return TRUE; } + + +bool_t +xdr_gfs3_dirlist (XDR *xdrs, gfs3_dirlist *objp) +{ + if (!xdr_u_quad_t (xdrs, &objp->d_ino)) + return FALSE; + if (!xdr_u_quad_t (xdrs, &objp->d_off)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->d_len)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->d_type)) + return FALSE; + if (!xdr_string (xdrs, &objp->name, ~0)) + return FALSE; + if (!xdr_pointer (xdrs, (char **)&objp->nextentry, sizeof (gfs3_dirlist), (xdrproc_t) xdr_gfs3_dirlist)) + return FALSE; + return TRUE; +} + +bool_t +xdr_gfs3_readdir_rsp (XDR *xdrs, gfs3_readdir_rsp *objp) +{ + if (!xdr_u_quad_t (xdrs, &objp->gfs_id)) + return FALSE; + if (!xdr_int (xdrs, &objp->op_ret)) + return FALSE; + if (!xdr_int (xdrs, &objp->op_errno)) + return FALSE; + if (!xdr_pointer (xdrs, (char **)&objp->reply, sizeof (gfs3_dirlist), (xdrproc_t) xdr_gfs3_dirlist)) + return FALSE; + return TRUE; +} + +bool_t +xdr_gfs3_dirplist (XDR *xdrs, gfs3_dirplist *objp) +{ + if (!xdr_u_quad_t (xdrs, &objp->d_ino)) + return FALSE; + if (!xdr_u_quad_t (xdrs, &objp->d_off)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->d_len)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->d_type)) + return FALSE; + if (!xdr_string (xdrs, &objp->name, ~0)) + return FALSE; + if (!xdr_gf_iatt (xdrs, &objp->stat)) + return FALSE; + if (!xdr_pointer (xdrs, (char **)&objp->nextentry, sizeof (gfs3_dirplist), (xdrproc_t) xdr_gfs3_dirplist)) + return FALSE; + return TRUE; +} + +bool_t +xdr_gfs3_readdirp_rsp (XDR *xdrs, gfs3_readdirp_rsp *objp) +{ + if (!xdr_u_quad_t (xdrs, &objp->gfs_id)) + return FALSE; + if (!xdr_int (xdrs, &objp->op_ret)) + return FALSE; + if (!xdr_int (xdrs, &objp->op_errno)) + return FALSE; + if (!xdr_pointer (xdrs, (char **)&objp->reply, sizeof (struct gfs3_dirplist), (xdrproc_t) xdr_gfs3_dirplist)) + return FALSE; + return TRUE; +} diff --git a/xlators/protocol/lib/src/glusterfs-xdr.h b/xlators/protocol/lib/src/glusterfs-xdr.h index 1870f319d63..f99335c4210 100644 --- a/xlators/protocol/lib/src/glusterfs-xdr.h +++ b/xlators/protocol/lib/src/glusterfs-xdr.h @@ -294,16 +294,6 @@ gf_stat_from_iatt (struct gf_iatt *gf_stat, struct iatt *iatt) } -struct gf_dirent_nb { - uint64_t d_ino; - uint64_t d_off; - uint32_t d_len; - uint32_t d_type; - struct gf_iatt d_stat; - char d_name[0]; -} __attribute__((packed)); - - /* Gluster FS Payload structures */ struct gfs3_stat_req { @@ -831,17 +821,6 @@ struct gfs3_readdir_req { }; typedef struct gfs3_readdir_req gfs3_readdir_req; -struct gfs3_readdir_rsp { - u_quad_t gfs_id; - int op_ret; - int op_errno; - struct { - u_int buf_len; - char *buf_val; - } buf; -}; -typedef struct gfs3_readdir_rsp gfs3_readdir_rsp; - struct gfs3_readdirp_req { u_quad_t gfs_id; u_quad_t ino; @@ -852,17 +831,6 @@ struct gfs3_readdirp_req { }; typedef struct gfs3_readdirp_req gfs3_readdirp_req; -struct gfs3_readdirp_rsp { - u_quad_t gfs_id; - int op_ret; - int op_errno; - struct { - u_int buf_len; - char *buf_val; - } buf; -}; -typedef struct gfs3_readdirp_rsp gfs3_readdirp_rsp; - struct gf_setvolume_req { u_quad_t gfs_id; struct { @@ -1136,6 +1104,44 @@ struct gf_dump_version_rsp { }; typedef struct gf_dump_version_rsp gf_dump_version_rsp; +struct gfs3_dirlist { + u_quad_t d_ino; + u_quad_t d_off; + u_int d_len; + u_int d_type; + char *name; + struct gfs3_dirlist *nextentry; +}; +typedef struct gfs3_dirlist gfs3_dirlist; + +struct gfs3_readdir_rsp { + u_quad_t gfs_id; + int op_ret; + int op_errno; + struct gfs3_dirlist *reply; +}; +typedef struct gfs3_readdir_rsp gfs3_readdir_rsp; + +struct gfs3_dirplist { + u_quad_t d_ino; + u_quad_t d_off; + u_int d_len; + u_int d_type; + char *name; + struct gf_iatt stat; + struct gfs3_dirplist *nextentry; +}; +typedef struct gfs3_dirplist gfs3_dirplist; + +struct gfs3_readdirp_rsp { + u_quad_t gfs_id; + int op_ret; + int op_errno; + struct gfs3_dirplist *reply; +}; +typedef struct gfs3_readdirp_rsp gfs3_readdirp_rsp; + + /* the xdr functions */ #if defined(__STDC__) || defined(__cplusplus) @@ -1194,9 +1200,11 @@ extern bool_t xdr_gfs3_opendir_req (XDR *, gfs3_opendir_req*); extern bool_t xdr_gfs3_opendir_rsp (XDR *, gfs3_opendir_rsp*); extern bool_t xdr_gfs3_fsyncdir_req (XDR *, gfs3_fsyncdir_req*); extern bool_t xdr_gfs3_readdir_req (XDR *, gfs3_readdir_req*); +extern bool_t xdr_gfs3_dirlist (XDR *, gfs3_dirlist*); extern bool_t xdr_gfs3_readdir_rsp (XDR *, gfs3_readdir_rsp*); -extern bool_t xdr_gfs3_readdirp_req (XDR *, gfs3_readdirp_req*); +extern bool_t xdr_gfs3_dirplist (XDR *, gfs3_dirplist*); extern bool_t xdr_gfs3_readdirp_rsp (XDR *, gfs3_readdirp_rsp*); +extern bool_t xdr_gfs3_readdirp_req (XDR *, gfs3_readdirp_req*); extern bool_t xdr_gf_setvolume_req (XDR *, gf_setvolume_req*); extern bool_t xdr_gf_setvolume_rsp (XDR *, gf_setvolume_rsp*); extern bool_t xdr_gfs3_access_req (XDR *, gfs3_access_req*); @@ -1283,9 +1291,11 @@ extern bool_t xdr_gfs3_opendir_req (); extern bool_t xdr_gfs3_opendir_rsp (); extern bool_t xdr_gfs3_fsyncdir_req (); extern bool_t xdr_gfs3_readdir_req (); +extern bool_t xdr_gfs3_dirlist (); extern bool_t xdr_gfs3_readdir_rsp (); -extern bool_t xdr_gfs3_readdirp_req (); +extern bool_t xdr_gfs3_dirplist (); extern bool_t xdr_gfs3_readdirp_rsp (); +extern bool_t xdr_gfs3_readdirp_req (); extern bool_t xdr_gf_setvolume_req (); extern bool_t xdr_gf_setvolume_rsp (); extern bool_t xdr_gfs3_access_req (); diff --git a/xlators/protocol/lib/src/glusterfs3.x b/xlators/protocol/lib/src/glusterfs3.x index b6cc6e6abad..c9510527c27 100644 --- a/xlators/protocol/lib/src/glusterfs3.x +++ b/xlators/protocol/lib/src/glusterfs3.x @@ -491,10 +491,40 @@ struct gfs3_finodelk_req { unsigned hyper offset; unsigned int size; }; -struct gfs3_readdir_res { +struct gfs3_dirlist { + unsigned hyper d_ino; + unsigned hyper d_off; + unsigned int d_len; + unsigned int d_type; + char *name; + struct gfs3_dirlist *nextentry; +}; + +struct gfs3_readdir_rsp { unsigned hyper gfs_id; - opaque buf<>; -} ; + int op_ret; + int op_errno; + struct gfs3_dirlist reply; +}; + + + +struct gfs3_dirplist { + unsigned hyper d_ino; + unsigned hyper d_off; + unsigned int d_len; + unsigned int d_type; + char *name; + struct gf_iatt name_attributes; + struct gfs3_dirplist *nextentry; +}; + +struct gfs3_readdirp_rsp { + unsigned hyper gfs_id; + int op_ret; + int op_errno; + struct gfs3_dirlistp reply; +}; struct gfs3_readdirp_req { @@ -505,12 +535,6 @@ struct gfs3_readdir_res { unsigned hyper offset; unsigned int size; } ; - struct gfs3_readdirp_rsp { - unsigned hyper gfs_id; - int op_ret; - int op_errno; - opaque buf<>; -} ; struct gf_setvolume_req { diff --git a/xlators/protocol/lib/src/msg-xdr.h b/xlators/protocol/lib/src/msg-xdr.h index 4c383e5a52a..872d9401e48 100644 --- a/xlators/protocol/lib/src/msg-xdr.h +++ b/xlators/protocol/lib/src/msg-xdr.h @@ -532,5 +532,7 @@ ssize_t xdr_to_lookup_rsp (struct iovec inmsg, void *args); ssize_t xdr_to_readv_rsp (struct iovec inmsg, void *args); +ssize_t +xdr_to_getspec_rsp (struct iovec inmsg, void *args); #endif /* !_MSG_XDR_H */ diff --git a/xlators/protocol/lib/src/protocol-common.c b/xlators/protocol/lib/src/protocol-common.c deleted file mode 100644 index 4a9845e082d..00000000000 --- a/xlators/protocol/lib/src/protocol-common.c +++ /dev/null @@ -1,109 +0,0 @@ -/* - Copyright (c) 2007-2010 Gluster, Inc. - This file is part of GlusterFS. - - GlusterFS is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - GlusterFS is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see - . -*/ - - -#include "globals.h" -#include "compat.h" -#include "protocol-common.h" -#include "glusterfs-xdr.h" - - -static int -gf_dirent_nb_size (gf_dirent_t *entries) -{ - return (sizeof (struct gf_dirent_nb) + strlen (entries->d_name) + 1); -} - -int -gf_dirent_serialize (gf_dirent_t *entries, char *buf, size_t buf_size) -{ - struct gf_dirent_nb *entry_nb = NULL; - gf_dirent_t *entry = NULL; - int size = 0; - int entry_size = 0; - - - list_for_each_entry (entry, &entries->list, list) { - entry_size = gf_dirent_nb_size (entry); - - if (buf && (size + entry_size <= buf_size)) { - entry_nb = (void *) (buf + size); - - entry_nb->d_ino = entry->d_ino; - entry_nb->d_off = entry->d_off; - entry_nb->d_len = entry->d_len; - entry_nb->d_type = entry->d_type; - - gf_stat_from_iatt (&entry_nb->d_stat, &entry->d_stat); - - strcpy (entry_nb->d_name, entry->d_name); - } - size += entry_size; - } - - return size; -} - - -int -gf_dirent_unserialize (gf_dirent_t *entries, const char *buf, size_t buf_size) -{ - struct gf_dirent_nb *entry_nb = NULL; - int remaining_size = 0; - int least_dirent_size = 0; - int count = 0; - gf_dirent_t *entry = NULL; - int entry_strlen = 0; - int entry_len = 0; - - - remaining_size = buf_size; - least_dirent_size = (sizeof (struct gf_dirent_nb) + 2); - - while (remaining_size >= least_dirent_size) { - entry_nb = (void *)(buf + (buf_size - remaining_size)); - - entry_strlen = strnlen (entry_nb->d_name, remaining_size); - if (entry_strlen == remaining_size) { - break; - } - - entry_len = sizeof (gf_dirent_t) + entry_strlen + 1; - entry = GF_CALLOC (1, entry_len, gf_common_mt_gf_dirent_t); - if (!entry) { - break; - } - - entry->d_ino = entry_nb->d_ino; - entry->d_off = entry_nb->d_off; - entry->d_len = entry_nb->d_len; - entry->d_type = entry_nb->d_type; - - gf_stat_to_iatt (&entry_nb->d_stat, &entry->d_stat); - - strcpy (entry->d_name, entry_nb->d_name); - - list_add_tail (&entry->list, &entries->list); - - remaining_size -= (sizeof (*entry_nb) + entry_strlen + 1); - count++; - } - - return count; -} diff --git a/xlators/protocol/lib/src/protocol-common.h b/xlators/protocol/lib/src/protocol-common.h index 98a79d0fa17..5378d90ba45 100644 --- a/xlators/protocol/lib/src/protocol-common.h +++ b/xlators/protocol/lib/src/protocol-common.h @@ -20,11 +20,6 @@ #ifndef _PROTOCOL_COMMON_H #define _PROTOCOL_COMMON_H -#define GF_PROTOCOL_DEFAULT_PORT 6971 - -#define GF_LOCAL_IOV 1 /* All headers are here */ -#define GF_EXTRA_IOV 2 /* needed for write/read etc */ - enum gf_fop_procnum { GFS3_OP_NULL, /* 0 */ GFS3_OP_STAT, @@ -79,6 +74,7 @@ enum gf_handshake_procnum { GF_HNDSK_SETVOLUME, GF_HNDSK_GETSPEC, GF_HNDSK_PING, + GF_HNDSK_MAXVALUE, }; enum gf_mgmt_procnum { @@ -96,9 +92,4 @@ enum gf_mgmt_procnum { #define GLUSTER_HNDSK_PROGRAM 14398633 /* Completely random */ #define GLUSTER_HNDSK_VERSION 1 /* 0.0.1 */ -int -gf_dirent_unserialize (gf_dirent_t *entries, const char *buf, size_t buf_size); -int -gf_dirent_serialize (gf_dirent_t *entries, char *buf, size_t buf_size); - #endif /* !_PROTOCOL_COMMON_H */ diff --git a/xlators/protocol/rpc/rpc-lib/src/rpc-clnt.c b/xlators/protocol/rpc/rpc-lib/src/rpc-clnt.c index 92f57e5213f..da02b9f4230 100644 --- a/xlators/protocol/rpc/rpc-lib/src/rpc-clnt.c +++ b/xlators/protocol/rpc/rpc-lib/src/rpc-clnt.c @@ -63,8 +63,8 @@ __saved_frames_get_timedout (struct saved_frames *frames, uint32_t timeout, struct saved_frame * -__saved_frames_put (struct saved_frames *frames, void *frame, - int32_t procnum, rpc_clnt_prog_t *prog, int64_t callid) +__saved_frames_put (struct saved_frames *frames, void *frame, int32_t procnum, + rpc_clnt_prog_t *prog, fop_cbk_fn_t cbk, int64_t callid) { struct saved_frame *saved_frame = NULL; @@ -82,6 +82,7 @@ __saved_frames_put (struct saved_frames *frames, void *frame, saved_frame->procnum = procnum; saved_frame->callid = callid; saved_frame->prog = prog; + saved_frame->cbkfn = cbk; gettimeofday (&saved_frame->saved_at, NULL); @@ -179,14 +180,14 @@ call_bail (void *data) strftime (frame_sent, 32, "%Y-%m-%d %H:%M:%S", &frame_sent_tm); gf_log (conn->trans->name, GF_LOG_ERROR, - "bailing out frame type(%s) op(%s) frame sent = %s. " - "frame-timeout = %d", - trav->prog->progname, - trav->prog->actor[trav->procnum].procname, frame_sent, + "bailing out frame type(%s) op(%s(%d)) sent = %s. " + "timeout = %d", + trav->prog->progname, (trav->prog->procnames) ? + trav->prog->procnames[trav->procnum] : "--", + trav->procnum, frame_sent, conn->frame_timeout); - trav->prog->actor [trav->procnum].cbkfn (&req, &iov, 1, - trav->frame); + trav->cbkfn (&req, &iov, 1, trav->frame); list_del_init (&trav->list); GF_FREE (trav); @@ -199,7 +200,7 @@ out: /* to be called with conn->lock held */ struct saved_frame * __save_frame (struct rpc_clnt *rpc_clnt, call_frame_t *frame, int procnum, - rpc_clnt_prog_t *prog, uint64_t callid) + rpc_clnt_prog_t *prog, fop_cbk_fn_t cbk, uint64_t callid) { rpc_clnt_connection_t *conn = NULL; struct timeval timeout = {0, }; @@ -208,7 +209,7 @@ __save_frame (struct rpc_clnt *rpc_clnt, call_frame_t *frame, int procnum, conn = &rpc_clnt->conn; saved_frame = __saved_frames_put (conn->saved_frames, frame, - procnum, prog, callid); + procnum, prog, cbk, callid); if (saved_frame == NULL) { goto out; } @@ -307,14 +308,14 @@ saved_frames_unwind (struct saved_frames *saved_frames) list_for_each_entry_safe (trav, tmp, &saved_frames->sf.list, list) { gf_log ("rpc-clnt", GF_LOG_ERROR, - "forced unwinding frame type(%s) op(%s)", - trav->prog->progname, - trav->prog->actor [trav->procnum].procname); + "forced unwinding frame type(%s) op(%s(%d))", + trav->prog->progname, (trav->prog->procnames) ? + trav->prog->procnames[trav->procnum] : "--", + trav->procnum); saved_frames->count--; - trav->prog->actor [trav->procnum].cbkfn (&req, &iov, 1, - trav->frame); + trav->cbkfn (&req, &iov, 1, trav->frame); list_del_init (&trav->list); GF_FREE (trav); @@ -655,9 +656,7 @@ rpc_clnt_handle_reply (struct rpc_clnt *clnt, rpc_transport_pollin_t *pollin) "failed"); } - saved_frame->prog->actor [request_info->procnum].cbkfn (&req, req.rsp, - req.rspcnt, - saved_frame->frame); + saved_frame->cbkfn (&req, req.rsp, req.rspcnt, saved_frame->frame); if (ret == 0) { rpc_clnt_reply_deinit (&req); @@ -1155,7 +1154,8 @@ out: int -rpc_clnt_submit (struct rpc_clnt *rpc, rpc_clnt_prog_t *prog, int procnum, +rpc_clnt_submit (struct rpc_clnt *rpc, rpc_clnt_prog_t *prog, + int procnum, fop_cbk_fn_t cbkfn, struct iovec *proghdr, int proghdrcount, struct iovec *progpayload, int progpayloadcount, struct iobref *iobref, void *frame) @@ -1242,7 +1242,7 @@ rpc_clnt_submit (struct rpc_clnt *rpc, rpc_clnt_prog_t *prog, int procnum, if ((ret >= 0) && frame) { gettimeofday (&conn->last_sent, NULL); /* Save the frame in queue */ - __save_frame (rpc, frame, procnum, prog, callid); + __save_frame (rpc, frame, procnum, prog, cbkfn, callid); } } @@ -1264,7 +1264,7 @@ out: if (frame && (ret == -1)) { rpcreq.rpc_status = -1; - prog->actor [procnum].cbkfn (&rpcreq, NULL, 0, frame); + cbkfn (&rpcreq, NULL, 0, frame); } return ret; } diff --git a/xlators/protocol/rpc/rpc-lib/src/rpc-clnt.h b/xlators/protocol/rpc/rpc-lib/src/rpc-clnt.h index 89942ce7f57..efc256cd261 100644 --- a/xlators/protocol/rpc/rpc-lib/src/rpc-clnt.h +++ b/xlators/protocol/rpc/rpc-lib/src/rpc-clnt.h @@ -45,8 +45,7 @@ typedef int (*rpc_clnt_notify_t) (struct rpc_clnt *rpc, void *mydata, typedef int (*fop_cbk_fn_t) (struct rpc_req *req, struct iovec *iov, int count, void *myframe); -typedef int (*clnt_fn_t) (call_frame_t *, xlator_t *, - struct rpc_clnt_program *, void *args); +typedef int (*clnt_fn_t) (call_frame_t *fr, xlator_t *xl, void *args); struct saved_frame { union { @@ -61,37 +60,29 @@ struct saved_frame { struct timeval saved_at; int32_t procnum; struct rpc_clnt_program *prog; + fop_cbk_fn_t cbkfn; uint64_t callid; rpc_transport_rsp_t rsp; }; - struct saved_frames { int64_t count; struct saved_frame sf; }; -/* TODO: */ -struct xptr_clnt { - int remote_port; - char * remote_host; - - /* xptr specific */ - peer_info_t peerinfo; -}; /* Initialized by procnum */ typedef struct rpc_clnt_procedure { char *procname; clnt_fn_t fn; - fop_cbk_fn_t cbkfn; } rpc_clnt_procedure_t; typedef struct rpc_clnt_program { char *progname; int prognum; int progver; - rpc_clnt_procedure_t *actor; + rpc_clnt_procedure_t *proctable; + char **procnames; int numproc; } rpc_clnt_prog_t; @@ -158,7 +149,8 @@ struct rpc_clnt * rpc_clnt_init (struct rpc_clnt_config *config, int rpc_clnt_register_notify (struct rpc_clnt *rpc, rpc_clnt_notify_t fn, void *mydata); -int rpc_clnt_submit (struct rpc_clnt *rpc, rpc_clnt_prog_t *prog, int procnum, +int rpc_clnt_submit (struct rpc_clnt *rpc, rpc_clnt_prog_t *prog, + int procnum, fop_cbk_fn_t cbkfn, struct iovec *proghdr, int proghdrcount, struct iovec *progpayload, int progpayloadcount, struct iobref *iobref, void *frame); diff --git a/xlators/protocol/rpc/rpc-lib/src/rpcsvc.c b/xlators/protocol/rpc/rpc-lib/src/rpcsvc.c index 10d74759cf0..1e0a05e451c 100644 --- a/xlators/protocol/rpc/rpc-lib/src/rpcsvc.c +++ b/xlators/protocol/rpc/rpc-lib/src/rpcsvc.c @@ -492,6 +492,7 @@ rpcsvc_conn_alloc (rpcsvc_t *svc, rpc_transport_t *trans) gf_log (GF_RPCSVC, GF_LOG_TRACE, "rx pool: %d", poolcount); conn->rxpool = mem_pool_new (rpcsvc_request_t, poolcount); + /* TODO: leak */ if (!conn->rxpool) { gf_log (GF_RPCSVC, GF_LOG_ERROR, "mem pool allocation failed"); goto free_conn; diff --git a/xlators/protocol/server/src/server-helpers.c b/xlators/protocol/server/src/server-helpers.c index 5cae205d76f..44496a1592b 100644 --- a/xlators/protocol/server/src/server-helpers.c +++ b/xlators/protocol/server/src/server-helpers.c @@ -1390,3 +1390,103 @@ server_print_request (call_frame_t *frame) op, caller, resolve_vars, loc_vars, resolve2_vars, loc2_vars, other_vars); } + +int +serialize_rsp_direntp (gf_dirent_t *entries, gfs3_readdirp_rsp *rsp) +{ + gf_dirent_t *entry = NULL; + gfs3_dirplist *trav = NULL; + gfs3_dirplist *prev = NULL; + int ret = -1; + + list_for_each_entry (entry, &entries->list, list) { + trav = GF_CALLOC (1, sizeof (*trav), 0); + if (!trav) + goto out; + + trav->d_ino = entry->d_ino; + trav->d_off = entry->d_off; + trav->d_len = entry->d_len; + trav->d_type = entry->d_type; + //trav->name = memdup (entry->d_name, entry->d_len + 1); + trav->name = entry->d_name; + + gf_stat_from_iatt (&trav->stat, &entry->d_stat); + + if (prev) + prev->nextentry = trav; + else + rsp->reply = trav; + + prev = trav; + } + + ret = 0; +out: + return ret; +} + + +int +serialize_rsp_dirent (gf_dirent_t *entries, gfs3_readdir_rsp *rsp) +{ + gf_dirent_t *entry = NULL; + gfs3_dirlist *trav = NULL; + gfs3_dirlist *prev = NULL; + int ret = -1; + + list_for_each_entry (entry, &entries->list, list) { + trav = GF_CALLOC (1, sizeof (*trav), 0); + if (!trav) + goto out; + trav->d_ino = entry->d_ino; + trav->d_off = entry->d_off; + trav->d_len = entry->d_len; + trav->d_type = entry->d_type; + trav->name = entry->d_name; + if (prev) + prev->nextentry = trav; + else + rsp->reply = trav; + + prev = trav; + } + + ret = 0; +out: + return ret; +} + +int +readdir_rsp_cleanup (gfs3_readdir_rsp *rsp) +{ + gfs3_dirlist *prev = NULL; + gfs3_dirlist *trav = NULL; + + trav = rsp->reply; + prev = trav; + while (trav) { + trav = trav->nextentry; + GF_FREE (prev); + prev = trav; + } + + return 0; +} + +int +readdirp_rsp_cleanup (gfs3_readdirp_rsp *rsp) +{ + gfs3_dirplist *prev = NULL; + gfs3_dirplist *trav = NULL; + + trav = rsp->reply; + prev = trav; + while (trav) { + trav = trav->nextentry; + GF_FREE (prev); + prev = trav; + } + + return 0; +} diff --git a/xlators/protocol/server/src/server-helpers.h b/xlators/protocol/server/src/server-helpers.h index 4897336af69..ef27b612a64 100644 --- a/xlators/protocol/server/src/server-helpers.h +++ b/xlators/protocol/server/src/server-helpers.h @@ -86,4 +86,9 @@ destroy_server_conn_state (server_connection_t *conn); int server_build_config (xlator_t *this, server_conf_t *conf); +int serialize_rsp_dirent (gf_dirent_t *entries, gfs3_readdir_rsp *rsp); +int serialize_rsp_direntp (gf_dirent_t *entries, gfs3_readdirp_rsp *rsp); +int readdirp_rsp_cleanup (gfs3_readdirp_rsp *rsp); +int readdir_rsp_cleanup (gfs3_readdir_rsp *rsp); + #endif /* !_SERVER_HELPERS_H */ diff --git a/xlators/protocol/server/src/server.c b/xlators/protocol/server/src/server.c index 18be607a94d..190da28e374 100644 --- a/xlators/protocol/server/src/server.c +++ b/xlators/protocol/server/src/server.c @@ -60,8 +60,12 @@ gfs_serialize_reply (rpcsvc_request_t *req, void *arg, gfs_serialize_t sfunc, */ retlen = sfunc (*outmsg, arg); if (retlen == -1) { + /* Failed to Encode 'GlusterFS' msg in RPC is not exactly + failure of RPC return values.. client should get + notified about this, so there are no missing frames */ gf_log ("", GF_LOG_ERROR, "Failed to encode message"); - goto ret; + req->rpc_err = GARBAGE_ARGS; + retlen = 0; } outmsg->iov_len = retlen; diff --git a/xlators/protocol/server/src/server.h b/xlators/protocol/server/src/server.h index aaa036e83b6..6626a7c46e4 100644 --- a/xlators/protocol/server/src/server.h +++ b/xlators/protocol/server/src/server.h @@ -26,8 +26,8 @@ #include "fd.h" #include "protocol-common.h" - #include "server-mem-types.h" +#include "glusterfs-xdr.h" #define DEFAULT_BLOCK_SIZE 4194304 /* 4MB */ #define DEFAULT_VOLUME_FILE_PATH CONFDIR "/glusterfs.vol" diff --git a/xlators/protocol/server/src/server3_1-fops.c b/xlators/protocol/server/src/server3_1-fops.c index 4156e7be96f..54dda8964a0 100644 --- a/xlators/protocol/server/src/server3_1-fops.c +++ b/xlators/protocol/server/src/server3_1-fops.c @@ -44,6 +44,7 @@ server_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this, req = frame->local; frame->local = NULL; + rsp.gfs_id = req->gfs_id; rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); @@ -158,6 +159,7 @@ server_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this, op_ret, strerror (op_errno)); } out: + rsp.gfs_id = req->gfs_id; rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); @@ -182,6 +184,7 @@ server_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this, req = frame->local; frame->local = NULL; + rsp.gfs_id = req->gfs_id; rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); @@ -216,6 +219,7 @@ server_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this, req = frame->local; frame->local = NULL; + rsp.gfs_id = req->gfs_id; rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); @@ -256,6 +260,7 @@ server_finodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this, req = frame->local; frame->local = NULL; + rsp.gfs_id = req->gfs_id; rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); @@ -297,6 +302,7 @@ server_entrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this, req = frame->local; frame->local = NULL; + rsp.gfs_id = req->gfs_id; rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); @@ -336,6 +342,7 @@ server_fentrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this, req = frame->local; frame->local = NULL; + rsp.gfs_id = req->gfs_id; rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); @@ -374,6 +381,7 @@ server_access_cbk (call_frame_t *frame, void *cookie, xlator_t *this, req = frame->local; frame->local = NULL; + rsp.gfs_id = req->gfs_id; rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); @@ -396,6 +404,7 @@ server_rmdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, req = frame->local; frame->local = NULL; + rsp.gfs_id = req->gfs_id; rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); @@ -440,6 +449,7 @@ server_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, req = frame->local; frame->local = NULL; + rsp.gfs_id = req->gfs_id; rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); @@ -480,6 +490,7 @@ server_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this, req = frame->local; frame->local = NULL; + rsp.gfs_id = req->gfs_id; rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); @@ -518,6 +529,7 @@ server_fsyncdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, req = frame->local; frame->local = NULL; + rsp.gfs_id = req->gfs_id; rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); @@ -544,22 +556,18 @@ server_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, gfs3_readdir_rsp rsp = {0,}; server_state_t *state = NULL; rpcsvc_request_t *req = NULL; + int ret = 0; req = frame->local; frame->local = NULL; state = CALL_STATE(frame); if (op_ret > 0) { - rsp.buf.buf_len = gf_dirent_serialize (entries, NULL, 0); - if (rsp.buf.buf_len > 0) { - rsp.buf.buf_val = GF_CALLOC (1, rsp.buf.buf_len, 0); - if (!rsp.buf.buf_val) { - op_ret = -1; - op_errno = ENOMEM; - goto unwind; - } - gf_dirent_serialize (entries, rsp.buf.buf_val, - rsp.buf.buf_len); + ret = serialize_rsp_dirent (entries, &rsp); + if (ret == -1) { + op_ret = -1; + op_errno = ENOMEM; + goto unwind; } } else { gf_log (this->name, GF_LOG_TRACE, @@ -569,15 +577,14 @@ server_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, strerror (op_errno)); } unwind: + rsp.gfs_id = req->gfs_id; rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); - server_submit_reply (frame, req, &rsp, NULL, 0, NULL, xdr_serialize_readdir_rsp); - if (rsp.buf.buf_val) - GF_FREE (rsp.buf.buf_val); + readdir_rsp_cleanup (&rsp); return 0; } @@ -593,6 +600,7 @@ server_releasedir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, req = frame->local; frame->local = NULL; + rsp.gfs_id = req->gfs_id; rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); @@ -632,6 +640,7 @@ server_opendir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, frame->local = NULL; rsp.fd = fd_no; + rsp.gfs_id = req->gfs_id; rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); @@ -651,6 +660,7 @@ server_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, req = frame->local; frame->local = NULL; + rsp.gfs_id = req->gfs_id; rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); @@ -703,13 +713,14 @@ server_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, } } out: + req = frame->local; + frame->local = NULL; + + rsp.gfs_id = req->gfs_id; rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); rsp.dict.dict_len = len; - req = frame->local; - frame->local = NULL; - server_submit_reply (frame, req, &rsp, NULL, 0, NULL, xdr_serialize_getxattr_rsp); @@ -766,6 +777,7 @@ out: req = frame->local; frame->local = NULL; + rsp.gfs_id = req->gfs_id; rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); rsp.dict.dict_len = len; @@ -788,6 +800,7 @@ server_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, req = frame->local; frame->local = NULL; + rsp.gfs_id = req->gfs_id; rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); @@ -808,6 +821,7 @@ server_fsetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, req = frame->local; frame->local = NULL; + rsp.gfs_id = req->gfs_id; rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); @@ -830,6 +844,7 @@ server_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this, req = frame->local; frame->local = NULL; + rsp.gfs_id = req->gfs_id; rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); @@ -878,6 +893,7 @@ server_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this, req = frame->local; frame->local = NULL; + rsp.gfs_id = req->gfs_id; rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); @@ -929,6 +945,7 @@ server_symlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this, req = frame->local; frame->local = NULL; + rsp.gfs_id = req->gfs_id; rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); @@ -971,6 +988,7 @@ server_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this, req = frame->local; frame->local = NULL; + rsp.gfs_id = req->gfs_id; rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); @@ -1022,6 +1040,7 @@ server_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this, req = frame->local; frame->local = NULL; + rsp.gfs_id = req->gfs_id; rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); @@ -1055,6 +1074,7 @@ server_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, req = frame->local; frame->local = NULL; + rsp.gfs_id = req->gfs_id; rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); @@ -1088,6 +1108,7 @@ server_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this, req = frame->local; frame->local = NULL; + rsp.gfs_id = req->gfs_id; rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); @@ -1121,6 +1142,7 @@ server_flush_cbk (call_frame_t *frame, void *cookie, xlator_t *this, req = frame->local; frame->local = NULL; + rsp.gfs_id = req->gfs_id; rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); @@ -1152,6 +1174,7 @@ server_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this, req = frame->local; frame->local = NULL; + rsp.gfs_id = req->gfs_id; rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); @@ -1184,6 +1207,7 @@ server_release_cbk (call_frame_t *frame, void *cookie, xlator_t *this, req = frame->local; frame->local = NULL; + rsp.gfs_id = req->gfs_id; rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); @@ -1205,6 +1229,7 @@ server_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this, req = frame->local; frame->local = NULL; + rsp.gfs_id = req->gfs_id; rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); @@ -1240,6 +1265,7 @@ server_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this, req = frame->local; frame->local = NULL; + rsp.gfs_id = req->gfs_id; rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); @@ -1272,6 +1298,7 @@ server_checksum_cbk (call_frame_t *frame, void *cookie, xlator_t *this, req = frame->local; frame->local = NULL; + rsp.gfs_id = req->gfs_id; rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); @@ -1300,6 +1327,7 @@ server_rchecksum_cbk (call_frame_t *frame, void *cookie, xlator_t *this, req = frame->local; frame->local = NULL; + rsp.gfs_id = req->gfs_id; rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); @@ -1346,6 +1374,7 @@ server_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this, frame->local = NULL; rsp.fd = fd_no; + rsp.gfs_id = req->gfs_id; rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); @@ -1426,6 +1455,7 @@ server_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this, frame->local = NULL; rsp.fd = fd_no; + rsp.gfs_id = req->gfs_id; rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); @@ -1447,6 +1477,7 @@ server_readlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this, req = frame->local; frame->local = NULL; + rsp.gfs_id = req->gfs_id; rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); @@ -1481,6 +1512,7 @@ server_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, req = frame->local; frame->local = NULL; + rsp.gfs_id = req->gfs_id; rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); @@ -1515,6 +1547,7 @@ server_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, req = frame->local; frame->local = NULL; + rsp.gfs_id = req->gfs_id; rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); @@ -1563,6 +1596,7 @@ server_fsetattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, req = frame->local; frame->local = NULL; + rsp.gfs_id = req->gfs_id; rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); @@ -1627,6 +1661,7 @@ out: req = frame->local; frame->local = NULL; + rsp.gfs_id = req->gfs_id; rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); rsp.dict.dict_len = len; @@ -1696,6 +1731,7 @@ out: req = frame->local; frame->local = NULL; + rsp.gfs_id = req->gfs_id; rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); rsp.dict.dict_len = len; @@ -1717,21 +1753,19 @@ server_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this, gfs3_readdirp_rsp rsp = {0,}; server_state_t *state = NULL; rpcsvc_request_t *req = NULL; + int ret = 0; req = frame->local; frame->local = NULL; state = CALL_STATE(frame); if (op_ret > 0) { - rsp.buf.buf_len = gf_dirent_serialize (entries, NULL, 0); - rsp.buf.buf_val = GF_CALLOC (1, rsp.buf.buf_len, 0); - if (!rsp.buf.buf_val) { - op_ret = -1; + ret = serialize_rsp_direntp (entries, &rsp); + if (ret == -1) { + op_ret = -1; op_errno = ENOMEM; - rsp.buf.buf_len = 0; goto out; } - gf_dirent_serialize (entries, rsp.buf.buf_val, rsp.buf.buf_len); } else { gf_log (this->name, GF_LOG_TRACE, "%"PRId64": READDIRP %"PRId64" (%"PRId64") ==>" @@ -1742,14 +1776,14 @@ server_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this, } out: + rsp.gfs_id = req->gfs_id; rsp.op_ret = op_ret; rsp.op_errno = gf_errno_to_error (op_errno); server_submit_reply (frame, req, &rsp, NULL, 0, NULL, xdr_serialize_readdirp_rsp); - if (rsp.buf.buf_val) - GF_FREE (rsp.buf.buf_val); + readdirp_rsp_cleanup (&rsp); return 0; } -- cgit