Mercurial > nomad > experimental
changeset 246:a3bdecfe2560
{common,client,objstore}: define and implement WRITE RPC
Closes #68.
Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
author | Josef 'Jeff' Sipek <jeffpc@josefsipek.net> |
---|---|
date | Thu, 14 Apr 2016 22:35:26 -0400 |
parents | a43d127ecfce |
children | aba404338d73 |
files | docs/fs-protocol.md src/client/cmd_obj.c src/client/cmds.c src/client/cmds.h src/common/include/nomad/rpc_fs.h src/common/rpc_fs.x src/objstore/include/nomad/objstore.h src/objstore/include/nomad/objstore_impl.h src/objstore/obj.c src/objstore/vg.c |
diffstat | 10 files changed, 100 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/docs/fs-protocol.md Thu Apr 14 22:35:17 2016 -0400 +++ b/docs/fs-protocol.md Thu Apr 14 22:35:26 2016 -0400 @@ -225,10 +225,32 @@ Fails with `EPROTO` if the client hasn't gotten a successful LOGIN. +WRITE (0x0009) +============== + +Write a portion of an open object. Trying to write to a directory fails with +`EISDIR`. Writing past the end of the object succeeds and the object length is +updated automatically. + +Inputs +------ +* open file handle +* offset into the object version's data +* length (in bytes) to write +* data + +Outputs +------- +None. + +Limitations +----------- +Fails with `EPROTO` if the client hasn't gotten a successful LOGIN. + + Other RPCs that may end up useful ================================= * RENAME - rename a "file" * LINK - create a symlink or a hardlink * GETDENTS - list contents of a directory -* WRITE - write an open file
--- a/src/client/cmd_obj.c Thu Apr 14 22:35:17 2016 -0400 +++ b/src/client/cmd_obj.c Thu Apr 14 22:35:26 2016 -0400 @@ -104,6 +104,26 @@ return 0; } +int cmd_write(struct fsconn *conn, union cmd *cmd) +{ + struct rpc_write_req *req = &cmd->write.req; + struct ohandle *oh; + ssize_t ret; + + oh = ohandle_find(conn, req->handle); + if (!oh) + return -EINVAL; + + /* TODO: should we limit the requested write size? */ + + ret = objstore_write(conn->vg, oh->cookie, req->data.data_val, + req->data.data_len, req->offset); + + VERIFY3S(ret, ==, req->data.data_len); + + return (ret < 0) ? ret : 0; +} + int cmd_stat(struct fsconn *conn, union cmd *cmd) { struct rpc_stat_req *req = &cmd->stat.req;
--- a/src/client/cmds.c Thu Apr 14 22:35:17 2016 -0400 +++ b/src/client/cmds.c Thu Apr 14 22:35:26 2016 -0400 @@ -83,6 +83,7 @@ CMD_ARG_RET(NRPC_READ, read, cmd_read, true), CMD_ARG (NRPC_REMOVE, remove, cmd_remove, true), CMD_ARG_RET(NRPC_STAT, stat, cmd_stat, true), + CMD_ARG (NRPC_WRITE, write, cmd_write, true), }; static bool send_response(XDR *xdr, int fd, int err)
--- a/src/client/cmds.h Thu Apr 14 22:35:17 2016 -0400 +++ b/src/client/cmds.h Thu Apr 14 22:35:26 2016 -0400 @@ -77,6 +77,11 @@ struct rpc_stat_req req; struct rpc_stat_res res; } stat; + + /* write */ + struct { + struct rpc_write_req req; + } write; }; struct fsconn { @@ -98,5 +103,6 @@ extern int cmd_read(struct fsconn *conn, union cmd *cmd); extern int cmd_remove(struct fsconn *conn, union cmd *cmd); extern int cmd_stat(struct fsconn *conn, union cmd *cmd); +extern int cmd_write(struct fsconn *conn, union cmd *cmd); #endif
--- a/src/common/include/nomad/rpc_fs.h Thu Apr 14 22:35:17 2016 -0400 +++ b/src/common/include/nomad/rpc_fs.h Thu Apr 14 22:35:26 2016 -0400 @@ -35,5 +35,6 @@ #define NRPC_OPEN 0x0006 #define NRPC_CLOSE 0x0007 #define NRPC_READ 0x0008 +#define NRPC_WRITE 0x0009 #endif
--- a/src/common/rpc_fs.x Thu Apr 14 22:35:17 2016 -0400 +++ b/src/common/rpc_fs.x Thu Apr 14 22:35:26 2016 -0400 @@ -112,3 +112,11 @@ /* length is sent as part of data */ opaque data<4294967295>; }; + +%/***** WRITE *****/ +struct rpc_write_req { + HANDLE(handle); + uint64_t offset; + /* length is sent as part of data */ + opaque data<4294967295>; +};
--- a/src/objstore/include/nomad/objstore.h Thu Apr 14 22:35:17 2016 -0400 +++ b/src/objstore/include/nomad/objstore.h Thu Apr 14 22:35:26 2016 -0400 @@ -85,6 +85,8 @@ struct nattr *attr); extern ssize_t objstore_read(struct objstore *vg, void *cookie, void *buf, size_t len, uint64_t offset); +extern ssize_t objstore_write(struct objstore *vg, void *cookie, + const void *buf, size_t len, uint64_t offset); extern int objstore_lookup(struct objstore *vg, void *dircookie, const char *name, struct noid *child); extern int objstore_create(struct objstore *vg, void *dircookie,
--- a/src/objstore/include/nomad/objstore_impl.h Thu Apr 14 22:35:17 2016 -0400 +++ b/src/objstore/include/nomad/objstore_impl.h Thu Apr 14 22:35:26 2016 -0400 @@ -54,7 +54,8 @@ int (*setattr)(); /* set attributes of an object */ ssize_t (*read)(struct objstore_vol *store, void *cookie, void *buf, size_t len, uint64_t offset); - ssize_t (*write)(); /* write portion of an object */ + ssize_t (*write)(struct objstore_vol *store, void *cookie, + const void *buf, size_t len, uint64_t offset); int (*lookup)(struct objstore_vol *vol, void *dircookie, const char *name, struct noid *child); @@ -85,6 +86,8 @@ struct nattr *attr); extern ssize_t vol_read(struct objstore_vol *vol, void *cookie, void *buf, size_t len, uint64_t offset); +extern ssize_t vol_write(struct objstore_vol *vol, void *cookie, + const void *buf, size_t len, uint64_t offset); extern int vol_lookup(struct objstore_vol *vol, void *dircookie, const char *name, struct noid *child); extern int vol_create(struct objstore_vol *vol, void *dircookie,
--- a/src/objstore/obj.c Thu Apr 14 22:35:17 2016 -0400 +++ b/src/objstore/obj.c Thu Apr 14 22:35:26 2016 -0400 @@ -71,6 +71,18 @@ return vol->def->obj_ops->read(vol, cookie, buf, len, offset); } +ssize_t vol_write(struct objstore_vol *vol, void *cookie, const void *buf, + size_t len, uint64_t offset) +{ + if (!vol || !buf) + return -EINVAL; + + if (!vol->def->obj_ops || !vol->def->obj_ops->write) + return -ENOTSUP; + + return vol->def->obj_ops->write(vol, cookie, buf, len, offset); +} + int vol_lookup(struct objstore_vol *vol, void *dircookie, const char *name, struct noid *child) {
--- a/src/objstore/vg.c Thu Apr 14 22:35:17 2016 -0400 +++ b/src/objstore/vg.c Thu Apr 14 22:35:26 2016 -0400 @@ -214,6 +214,29 @@ return ret; } +ssize_t objstore_write(struct objstore *vg, void *cookie, const void *buf, + size_t len, uint64_t offset) +{ + struct objstore_vol *vol; + ssize_t ret; + + if (!vg || !buf) + return -EINVAL; + + if (len > (SIZE_MAX / 2)) + return -EOVERFLOW; + + vol = findvol(vg); + if (!vol) + return -ENXIO; + + ret = vol_write(vol, cookie, buf, len, offset); + + vol_putref(vol); + + return ret; +} + int objstore_lookup(struct objstore *vg, void *dircookie, const char *name, struct noid *child) {