# HG changeset patch # User Josef 'Jeff' Sipek # Date 1671313139 18000 # Node ID 0c94a9835dfd1634b6258632191a531845fd8eb2 # Parent fe84110a0b10e4875d4e7e705379f7b0637215ee client: handle LINK Signed-off-by: Josef 'Jeff' Sipek diff -r fe84110a0b10 -r 0c94a9835dfd src/client/cmd_dir.c --- a/src/client/cmd_dir.c Sat Dec 17 16:32:57 2022 -0500 +++ b/src/client/cmd_dir.c Sat Dec 17 16:38:59 2022 -0500 @@ -70,6 +70,48 @@ return ret; } +static int __cmd_symlink(struct fsconn *conn, struct ohandle *diroh, + struct rpc_link_req *req, struct rpc_link_res *res) +{ + if (req->target_handle) + return -EINVAL; /* target handle is only for hardlinks */ + + return objstore_symlink(diroh->cookie, req->name, req->owner, + req->group, req->mode, req->target_name, + &res->oid); +} + +static int __cmd_link(struct fsconn *conn, struct ohandle *diroh, + struct rpc_link_req *req) +{ + struct ohandle *tgtoh; + + if (req->target_name || req->owner || req->group || req->mode) + return -EINVAL; /* these fields are only for symlinks */ + + tgtoh = ohandle_find(conn, req->target_handle); + if (!tgtoh) + return -EINVAL; + + return objstore_link(diroh->cookie, req->name, tgtoh->cookie); +} + +int cmd_link(struct fsconn *conn, union cmd *cmd) +{ + struct rpc_link_req *req = &cmd->link.req; + struct rpc_link_res *res = &cmd->link.res; + struct ohandle *oh; + + oh = ohandle_find(conn, req->parent); + if (!oh) + return -EINVAL; + + if (req->symlink) + return __cmd_symlink(conn, oh, req, res); + else + return __cmd_link(conn, oh, req); +} + int cmd_unlink(struct fsconn *conn, union cmd *cmd) { struct rpc_unlink_req *req = &cmd->unlink.req; diff -r fe84110a0b10 -r 0c94a9835dfd src/client/cmds.c --- a/src/client/cmds.c Sat Dec 17 16:32:57 2022 -0500 +++ b/src/client/cmds.c Sat Dec 17 16:38:59 2022 -0500 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019,2022 Josef 'Jeff' Sipek + * Copyright (c) 2015-2020,2022 Josef 'Jeff' Sipek * Copyright (c) 2015 Holly Sipek * Copyright (c) 2016 Steve Dougherty * @@ -97,6 +97,7 @@ CMD_ARG_RET(NRPC_OPEN, open, cmd_open, true), CMD_ARG_RET(NRPC_READ, read, cmd_read, true), CMD_ARG_RET(NRPC_SETATTR, setattr, cmd_setattr, true), + CMD_ARG_RET(NRPC_LINK, link, cmd_link, true), CMD_ARG (NRPC_UNLINK, unlink, cmd_unlink, true), CMD_ARG_RET(NRPC_VDEV_IMPORT, vdev_import, cmd_vdev_import, false), CMD_RET (NRPC_VDEV_LIST, vdev_list, cmd_vdev_list, false), diff -r fe84110a0b10 -r 0c94a9835dfd src/client/cmds.h --- a/src/client/cmds.h Sat Dec 17 16:32:57 2022 -0500 +++ b/src/client/cmds.h Sat Dec 17 16:38:59 2022 -0500 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019,2022 Josef 'Jeff' Sipek + * Copyright (c) 2015-2020,2022 Josef 'Jeff' Sipek * Copyright (c) 2015 Holly Sipek * Copyright (c) 2016 Steve Dougherty * @@ -56,6 +56,12 @@ struct rpc_getdent_res res; } getdent; + /* link */ + struct { + struct rpc_link_req req; + struct rpc_link_res res; + } link; + /* login */ struct { struct rpc_login_req req; @@ -165,6 +171,7 @@ extern int cmd_open(struct fsconn *conn, union cmd *cmd); extern int cmd_read(struct fsconn *conn, union cmd *cmd); extern int cmd_setattr(struct fsconn *conn, union cmd *cmd); +extern int cmd_link(struct fsconn *conn, union cmd *cmd); extern int cmd_unlink(struct fsconn *conn, union cmd *cmd); extern int cmd_write(struct fsconn *conn, union cmd *cmd); extern int cmd_vdev_import(struct fsconn *conn, union cmd *cmd);