Skip to content

Commit

Permalink
protocol: implement seek() FOP
Browse files Browse the repository at this point in the history
Network protocol extensions for the seek() FOP. The format is based on
the SEEK procedure in NFSv4.2.

Change-Id: I060768a8a4b9b1c80f4a24c0f17d630f7f028690
BUG: 1220173
Signed-off-by: Niels de Vos <ndevos@redhat.com>
Reviewed-on: http://review.gluster.org/11482
Smoke: Gluster Build System <jenkins@build.gluster.com>
NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
CentOS-regression: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Kaleb KEITHLEY <kkeithle@redhat.com>
Reviewed-by: Jeff Darcy <jdarcy@redhat.com>
  • Loading branch information
nixpanic authored and Jeff Darcy committed Feb 4, 2016
1 parent 41beab5 commit 9b71092
Show file tree
Hide file tree
Showing 8 changed files with 283 additions and 3 deletions.
1 change: 1 addition & 0 deletions rpc/rpc-lib/src/protocol-common.h
Expand Up @@ -60,6 +60,7 @@ enum gf_fop_procnum {
GFS3_OP_DISCARD,
GFS3_OP_ZEROFILL,
GFS3_OP_IPC,
GFS3_OP_SEEK,
GFS3_OP_MAXVALUE,
} ;

Expand Down
16 changes: 16 additions & 0 deletions rpc/xdr/src/glusterfs3-xdr.x
Expand Up @@ -659,6 +659,22 @@ struct gfs3_ipc_rsp {
};


struct gfs3_seek_req {
opaque gfid[16];
quad_t fd;
u_quad_t offset;
int what;
opaque xdata<>;
};

struct gfs3_seek_rsp {
int op_ret;
int op_errno;
u_quad_t offset;
opaque xdata<>;
};


struct gf_setvolume_req {
opaque dict<>;
} ;
Expand Down
101 changes: 101 additions & 0 deletions xlators/protocol/client/src/client-rpc-fops.c
Expand Up @@ -2271,6 +2271,58 @@ client3_3_ipc_cbk (struct rpc_req *req, struct iovec *iov, int count,
return 0;
}


int
client3_3_seek_cbk (struct rpc_req *req, struct iovec *iov, int count,
void *myframe)
{
call_frame_t *frame = NULL;
struct gfs3_seek_rsp rsp = {0,};
int ret = 0;
xlator_t *this = NULL;
dict_t *xdata = NULL;

this = THIS;

frame = myframe;

if (-1 == req->rpc_status) {
rsp.op_ret = -1;
rsp.op_errno = ENOTCONN;
goto out;
}
ret = xdr_to_generic(*iov, &rsp, (xdrproc_t) xdr_gfs3_seek_rsp);
if (ret < 0) {
gf_msg (this->name, GF_LOG_ERROR, EINVAL,
PC_MSG_XDR_DECODING_FAILED, "XDR decoding failed");
rsp.op_ret = -1;
rsp.op_errno = EINVAL;
goto out;
}

GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
(rsp.xdata.xdata_len), ret,
rsp.op_errno, out);

out:
if (rsp.op_ret == -1) {
gf_msg (this->name, GF_LOG_WARNING,
gf_error_to_errno (rsp.op_errno),
PC_MSG_REMOTE_OP_FAILED,
"remote operation failed");
}
CLIENT_STACK_UNWIND (seek, frame,
rsp.op_ret, gf_error_to_errno (rsp.op_errno),
rsp.offset, xdata);

free (rsp.xdata.xdata_val);

if (xdata)
dict_unref (xdata);

return 0;
}

int
client3_3_setattr_cbk (struct rpc_req *req, struct iovec *iov, int count,
void *myframe)
Expand Down Expand Up @@ -6341,6 +6393,53 @@ client3_3_ipc (call_frame_t *frame, xlator_t *this, void *data)
return 0;
}

int32_t
client3_3_seek (call_frame_t *frame, xlator_t *this, void *data)
{
clnt_args_t *args = NULL;
clnt_conf_t *conf = NULL;
struct gfs3_seek_req req = {{0,},};
int op_errno = ESTALE;
int ret = 0;
int64_t remote_fd = -1;

GF_ASSERT (frame);

if (!this || !data)
goto unwind;

args = data;
conf = this->private;

CLIENT_GET_REMOTE_FD (this, args->fd, DEFAULT_REMOTE_FD,
remote_fd, op_errno, unwind);

memcpy (req.gfid, args->fd->inode->gfid, 16);
req.fd = remote_fd;
req.offset = args->offset;
req.what = args->what;

GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
req.xdata.xdata_len, op_errno, unwind);

ret = client_submit_request(this, &req, frame, conf->fops,
GFS3_OP_SEEK, client3_3_seek_cbk,
NULL, NULL, 0, NULL, 0, NULL,
(xdrproc_t) xdr_gfs3_seek_req);
if (ret)
gf_msg (this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED,
"failed to send the fop");

GF_FREE (req.xdata.xdata_val);

return 0;
unwind:
CLIENT_STACK_UNWIND(ipc, frame, -1, op_errno, NULL);
GF_FREE (req.xdata.xdata_val);

return 0;
}

/* Table Specific to FOPS */


Expand Down Expand Up @@ -6394,6 +6493,7 @@ rpc_clnt_procedure_t clnt3_3_fop_actors[GF_FOP_MAXVALUE] = {
[GF_FOP_GETSPEC] = { "GETSPEC", client3_getspec },
[GF_FOP_FREMOVEXATTR] = { "FREMOVEXATTR", client3_3_fremovexattr },
[GF_FOP_IPC] = { "IPC", client3_3_ipc },
[GF_FOP_SEEK] = { "SEEK", client3_3_seek },
};

/* Used From RPC-CLNT library to log proper name of procedure based on number */
Expand Down Expand Up @@ -6446,6 +6546,7 @@ char *clnt3_3_fop_names[GFS3_OP_MAXVALUE] = {
[GFS3_OP_DISCARD] = "DISCARD",
[GFS3_OP_ZEROFILL] = "ZEROFILL",
[GFS3_OP_IPC] = "IPC",
[GFS3_OP_SEEK] = "SEEK",

};

Expand Down
30 changes: 30 additions & 0 deletions xlators/protocol/client/src/client.c
Expand Up @@ -1893,6 +1893,35 @@ client_ipc (call_frame_t *frame, xlator_t *this, int32_t op, dict_t *xdata)
}


int32_t
client_seek (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
gf_seek_what_t what, dict_t *xdata)
{
int ret = -1;
clnt_conf_t *conf = NULL;
rpc_clnt_procedure_t *proc = NULL;
clnt_args_t args = {0,};

conf = this->private;
if (!conf || !conf->fops)
goto out;

args.fd = fd;
args.offset = offset;
args.what = what;
args.xdata = xdata;

proc = &conf->fops->proctable[GF_FOP_SEEK];
if (proc->fn)
ret = proc->fn (frame, this, &args);
out:
if (ret)
STACK_UNWIND_STRICT(seek, frame, -1, ENOTCONN, 0, NULL);

return 0;
}


int32_t
client_getspec (call_frame_t *frame, xlator_t *this, const char *key,
int32_t flags)
Expand Down Expand Up @@ -2688,6 +2717,7 @@ struct xlator_fops fops = {
.zerofill = client_zerofill,
.getspec = client_getspec,
.ipc = client_ipc,
.seek = client_seek,
};


Expand Down
1 change: 1 addition & 0 deletions xlators/protocol/client/src/client.h
Expand Up @@ -209,6 +209,7 @@ typedef struct client_args {
gf_xattrop_flags_t optype;
int32_t valid;
int32_t len;
gf_seek_what_t what;

mode_t umask;
dict_t *xdata;
Expand Down
11 changes: 10 additions & 1 deletion xlators/protocol/server/src/server-messages.h
Expand Up @@ -40,7 +40,7 @@
*/

#define GLFS_PS_BASE GLFS_MSGID_COMP_PS
#define GLFS_NUM_MESSAGES 88
#define GLFS_NUM_MESSAGES 89
#define GLFS_MSGID_END (GLFS_PS_BASE + GLFS_NUM_MESSAGES + 1)
/* Messages with message IDs */
#define glfs_msg_start_x GLFS_PS_BASE, "Invalid: Start of messages"
Expand Down Expand Up @@ -830,6 +830,15 @@
*/

#define PS_MSG_SERVER_IPC_INFO (GLFS_PS_BASE + 88)

/*!
* @messageid
* @diagnosis
* @recommendedaction
*
*/

#define PS_MSG_SEEK_INFO (GLFS_PS_BASE + 89)
/*------------*/
#define glfs_msg_end_x GLFS_MSGID_END, "Invalid: End of messages"

Expand Down
125 changes: 123 additions & 2 deletions xlators/protocol/server/src/server-rpc-fops.c
Expand Up @@ -2116,6 +2116,45 @@ server_ipc_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}


int
server_seek_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, off_t offset, dict_t *xdata)
{
struct gfs3_seek_rsp rsp = {0, };
server_state_t *state = NULL;
rpcsvc_request_t *req = NULL;

req = frame->local;
state = CALL_STATE (frame);

GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val),
rsp.xdata.xdata_len, op_errno, out);

if (op_ret) {
gf_msg (this->name, GF_LOG_INFO, op_errno,
PS_MSG_SEEK_INFO,
"%"PRId64": SEEK%"PRId64" (%s) ==> (%s)",
frame->root->unique, state->resolve.fd_no,
uuid_utoa (state->resolve.gfid),
strerror (op_errno));
goto out;
}

rsp.offset = offset;

out:
rsp.op_ret = op_ret;
rsp.op_errno = gf_errno_to_error (op_errno);

server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
(xdrproc_t) xdr_gfs3_seek_rsp);

GF_FREE (rsp.xdata.xdata_val);

return 0;
}


/* Resume function section */

int
Expand Down Expand Up @@ -3165,6 +3204,26 @@ server_zerofill_resume (call_frame_t *frame, xlator_t *bound_xl)
return 0;
}

int
server_seek_resume (call_frame_t *frame, xlator_t *bound_xl)
{
server_state_t *state = NULL;

state = CALL_STATE (frame);

if (state->resolve.op_ret != 0)
goto err;

STACK_WIND (frame, server_seek_cbk, bound_xl, bound_xl->fops->seek,
state->fd, state->offset, state->what, state->xdata);
return 0;
err:
server_seek_cbk (frame, NULL, frame->this, state->resolve.op_ret,
state->resolve.op_errno, 0, NULL);

return 0;
}



/* Fop section */
Expand Down Expand Up @@ -3584,6 +3643,67 @@ server3_3_ipc (rpcsvc_request_t *req)
return ret;
}

int
server3_3_seek (rpcsvc_request_t *req)
{
server_state_t *state = NULL;
call_frame_t *frame = NULL;
struct gfs3_seek_req args = {{0,},};
int ret = -1;
int op_errno = 0;
dict_t *xdata = NULL;
xlator_t *bound_xl = NULL;

if (!req)
return ret;

ret = xdr_to_generic (req->msg[0], &args,
(xdrproc_t)xdr_gfs3_seek_req);
if (ret < 0) {
/*failed to decode msg*/;
req->rpc_err = GARBAGE_ARGS;
goto out;
}

frame = get_frame_from_request (req);
if (!frame) {
/* something wrong, mostly insufficient memory*/
req->rpc_err = GARBAGE_ARGS; /* TODO */
goto out;
}
frame->root->op = GF_FOP_SEEK;

state = CALL_STATE (frame);
if (!frame->root->client->bound_xl) {
/* auth failure, request on subvolume without setvolume */
SERVER_REQ_SET_ERROR (req, ret);
goto out;
}

state->resolve.type = RESOLVE_MUST;
state->resolve.fd_no = args.fd;

state->offset = args.offset;
state->what = args.what;
memcpy(state->resolve.gfid, args.gfid, 16);

GF_PROTOCOL_DICT_UNSERIALIZE (bound_xl, xdata,
args.xdata.xdata_val,
args.xdata.xdata_len,
ret, op_errno, out);

ret = 0;
resolve_and_resume (frame, server_seek_resume);

out:
free (args.xdata.xdata_val);

if (op_errno)
SERVER_REQ_SET_ERROR (req, ret);

return ret;
}

int
server3_3_readlink (rpcsvc_request_t *req)
{
Expand Down Expand Up @@ -6316,8 +6436,9 @@ rpcsvc_actor_t glusterfs3_3_fop_actors[GLUSTER_FOP_PROCCNT] = {
[GFS3_OP_FREMOVEXATTR] = {"FREMOVEXATTR", GFS3_OP_FREMOVEXATTR, server3_3_fremovexattr, NULL, 0, DRC_NA},
[GFS3_OP_FALLOCATE] = {"FALLOCATE", GFS3_OP_FALLOCATE, server3_3_fallocate, NULL, 0, DRC_NA},
[GFS3_OP_DISCARD] = {"DISCARD", GFS3_OP_DISCARD, server3_3_discard, NULL, 0, DRC_NA},
[GFS3_OP_ZEROFILL] = {"ZEROFILL", GFS3_OP_ZEROFILL, server3_3_zerofill, NULL, 0, DRC_NA},
[GFS3_OP_IPC] = {"IPC", GFS3_OP_IPC, server3_3_ipc, NULL, 0, DRC_NA},
[GFS3_OP_ZEROFILL] = {"ZEROFILL", GFS3_OP_ZEROFILL, server3_3_zerofill, NULL, 0, DRC_NA},
[GFS3_OP_IPC] = {"IPC", GFS3_OP_IPC, server3_3_ipc, NULL, 0, DRC_NA},
[GFS3_OP_SEEK] = {"SEEK", GFS3_OP_SEEK, server3_3_seek, NULL, 0, DRC_NA},
};


Expand Down
1 change: 1 addition & 0 deletions xlators/protocol/server/src/server.h
Expand Up @@ -151,6 +151,7 @@ struct _server_state {
struct gf_flock flock;
const char *volume;
dir_entry_t *entry;
gf_seek_what_t what;

dict_t *xdata;
mode_t umask;
Expand Down

0 comments on commit 9b71092

Please sign in to comment.