X-Git-Url: http://git.vrable.net/?a=blobdiff_plain;f=nfs3%2Frpc.c;h=67a9c7c1f3e543f8968d8f2dcbe14493aa482809;hb=53817147ff42b54d2b103216983cbf3e1ffa341f;hp=d47943c856141bdec200e2ab7e8565400ae886c0;hpb=3ec75fa45814e987f77224887350a9f736ed5b92;p=bluesky.git diff --git a/nfs3/rpc.c b/nfs3/rpc.c index d47943c..67a9c7c 100644 --- a/nfs3/rpc.c +++ b/nfs3/rpc.c @@ -140,9 +140,49 @@ async_rpc_send_failure(RPCRequest *req, enum accept_stat stat) async_rpc_write(req->connection, (const char *)&header, sizeof(header)); g_io_channel_flush(req->connection->channel, NULL); + if (req->args != NULL) { + char buf[4]; + XDR xdr; + xdrmem_create(&xdr, buf, sizeof(buf), XDR_FREE); + if (!req->xdr_args_free(&xdr, req->args)) { + fprintf(stderr, "unable to free arguments"); + } + } + if (req->raw_args != NULL) g_string_free(req->raw_args, TRUE); + g_free(req); +} + +void +async_rpc_send_reply(RPCRequest *req, void *result) +{ + static char reply_buf[MAX_RPC_MSGSIZE]; + XDR xdr_out; + xdrmem_create(&xdr_out, reply_buf, MAX_RPC_MSGSIZE, XDR_ENCODE); + if (!req->xdr_result(&xdr_out, result)) { + async_rpc_send_failure(req, SYSTEM_ERR); + return; + } + + struct rpc_reply header; + header.xid = htonl(req->xid); + header.type = htonl(1); /* REPLY */ + header.stat = htonl(MSG_ACCEPTED); + header.verf_flavor = 0; + header.verf_len = 0; + header.accept_stat = 0; + + gsize msg_size = xdr_out.x_ops->x_getpostn(&xdr_out); + printf("Have an RPC reply of size %zd bytes\n", msg_size); + uint32_t fragment = htonl((msg_size + sizeof(header)) | 0x80000000); + async_rpc_write(req->connection, (const char *)&fragment, sizeof(fragment)); + async_rpc_write(req->connection, (const char *)&header, sizeof(header)); + async_rpc_write(req->connection, reply_buf, msg_size); + g_io_channel_flush(req->connection->channel, NULL); + + /* Clean up. */ if (req->args != NULL) { char buf[4]; XDR xdr; @@ -152,6 +192,9 @@ async_rpc_send_failure(RPCRequest *req, enum accept_stat stat) } } + if (req->raw_args != NULL) + g_string_free(req->raw_args, TRUE); + g_free(req); } @@ -188,139 +231,139 @@ nfs_program_3(RPCRequest *req) }; char *result; xdrproc_t _xdr_argument, _xdr_result; - char *(*local)(char *, struct svc_req *); + char *(*local)(char *, RPCRequest *); switch (req->req_proc) { case NFSPROC3_NULL: _xdr_argument = (xdrproc_t) xdr_void; _xdr_result = (xdrproc_t) xdr_void; - local = (char *(*)(char *, struct svc_req *)) nfsproc3_null_3_svc; + local = (char *(*)(char *, RPCRequest *)) nfsproc3_null_3_svc; break; case NFSPROC3_GETATTR: _xdr_argument = (xdrproc_t) xdr_nfs_fh3; _xdr_result = (xdrproc_t) xdr_getattr3res; - local = (char *(*)(char *, struct svc_req *)) nfsproc3_getattr_3_svc; + local = (char *(*)(char *, RPCRequest *)) nfsproc3_getattr_3_svc; break; case NFSPROC3_SETATTR: _xdr_argument = (xdrproc_t) xdr_setattr3args; _xdr_result = (xdrproc_t) xdr_wccstat3; - local = (char *(*)(char *, struct svc_req *)) nfsproc3_setattr_3_svc; + local = (char *(*)(char *, RPCRequest *)) nfsproc3_setattr_3_svc; break; case NFSPROC3_LOOKUP: _xdr_argument = (xdrproc_t) xdr_diropargs3; _xdr_result = (xdrproc_t) xdr_lookup3res; - local = (char *(*)(char *, struct svc_req *)) nfsproc3_lookup_3_svc; + local = (char *(*)(char *, RPCRequest *)) nfsproc3_lookup_3_svc; break; case NFSPROC3_ACCESS: _xdr_argument = (xdrproc_t) xdr_access3args; _xdr_result = (xdrproc_t) xdr_access3res; - local = (char *(*)(char *, struct svc_req *)) nfsproc3_access_3_svc; + local = (char *(*)(char *, RPCRequest *)) nfsproc3_access_3_svc; break; case NFSPROC3_READLINK: _xdr_argument = (xdrproc_t) xdr_nfs_fh3; _xdr_result = (xdrproc_t) xdr_readlink3res; - local = (char *(*)(char *, struct svc_req *)) nfsproc3_readlink_3_svc; + local = (char *(*)(char *, RPCRequest *)) nfsproc3_readlink_3_svc; break; case NFSPROC3_READ: _xdr_argument = (xdrproc_t) xdr_read3args; _xdr_result = (xdrproc_t) xdr_read3res; - local = (char *(*)(char *, struct svc_req *)) nfsproc3_read_3_svc; + local = (char *(*)(char *, RPCRequest *)) nfsproc3_read_3_svc; break; case NFSPROC3_WRITE: _xdr_argument = (xdrproc_t) xdr_write3args; _xdr_result = (xdrproc_t) xdr_write3res; - local = (char *(*)(char *, struct svc_req *)) nfsproc3_write_3_svc; + local = (char *(*)(char *, RPCRequest *)) nfsproc3_write_3_svc; break; case NFSPROC3_CREATE: _xdr_argument = (xdrproc_t) xdr_create3args; _xdr_result = (xdrproc_t) xdr_diropres3; - local = (char *(*)(char *, struct svc_req *)) nfsproc3_create_3_svc; + local = (char *(*)(char *, RPCRequest *)) nfsproc3_create_3_svc; break; case NFSPROC3_MKDIR: _xdr_argument = (xdrproc_t) xdr_mkdir3args; _xdr_result = (xdrproc_t) xdr_diropres3; - local = (char *(*)(char *, struct svc_req *)) nfsproc3_mkdir_3_svc; + local = (char *(*)(char *, RPCRequest *)) nfsproc3_mkdir_3_svc; break; case NFSPROC3_SYMLINK: _xdr_argument = (xdrproc_t) xdr_symlink3args; _xdr_result = (xdrproc_t) xdr_diropres3; - local = (char *(*)(char *, struct svc_req *)) nfsproc3_symlink_3_svc; + local = (char *(*)(char *, RPCRequest *)) nfsproc3_symlink_3_svc; break; case NFSPROC3_MKNOD: _xdr_argument = (xdrproc_t) xdr_mknod3args; _xdr_result = (xdrproc_t) xdr_diropres3; - local = (char *(*)(char *, struct svc_req *)) nfsproc3_mknod_3_svc; + local = (char *(*)(char *, RPCRequest *)) nfsproc3_mknod_3_svc; break; case NFSPROC3_REMOVE: _xdr_argument = (xdrproc_t) xdr_diropargs3; _xdr_result = (xdrproc_t) xdr_wccstat3; - local = (char *(*)(char *, struct svc_req *)) nfsproc3_remove_3_svc; + local = (char *(*)(char *, RPCRequest *)) nfsproc3_remove_3_svc; break; case NFSPROC3_RMDIR: _xdr_argument = (xdrproc_t) xdr_diropargs3; _xdr_result = (xdrproc_t) xdr_wccstat3; - local = (char *(*)(char *, struct svc_req *)) nfsproc3_rmdir_3_svc; + local = (char *(*)(char *, RPCRequest *)) nfsproc3_rmdir_3_svc; break; case NFSPROC3_RENAME: _xdr_argument = (xdrproc_t) xdr_rename3args; _xdr_result = (xdrproc_t) xdr_rename3res; - local = (char *(*)(char *, struct svc_req *)) nfsproc3_rename_3_svc; + local = (char *(*)(char *, RPCRequest *)) nfsproc3_rename_3_svc; break; case NFSPROC3_LINK: _xdr_argument = (xdrproc_t) xdr_link3args; _xdr_result = (xdrproc_t) xdr_link3res; - local = (char *(*)(char *, struct svc_req *)) nfsproc3_link_3_svc; + local = (char *(*)(char *, RPCRequest *)) nfsproc3_link_3_svc; break; case NFSPROC3_READDIR: _xdr_argument = (xdrproc_t) xdr_readdir3args; _xdr_result = (xdrproc_t) xdr_readdir3res; - local = (char *(*)(char *, struct svc_req *)) nfsproc3_readdir_3_svc; + local = (char *(*)(char *, RPCRequest *)) nfsproc3_readdir_3_svc; break; case NFSPROC3_READDIRPLUS: _xdr_argument = (xdrproc_t) xdr_readdirplus3args; _xdr_result = (xdrproc_t) xdr_readdirplus3res; - local = (char *(*)(char *, struct svc_req *)) nfsproc3_readdirplus_3_svc; + local = (char *(*)(char *, RPCRequest *)) nfsproc3_readdirplus_3_svc; break; case NFSPROC3_FSSTAT: _xdr_argument = (xdrproc_t) xdr_nfs_fh3; _xdr_result = (xdrproc_t) xdr_fsstat3res; - local = (char *(*)(char *, struct svc_req *)) nfsproc3_fsstat_3_svc; + local = (char *(*)(char *, RPCRequest *)) nfsproc3_fsstat_3_svc; break; case NFSPROC3_FSINFO: _xdr_argument = (xdrproc_t) xdr_nfs_fh3; _xdr_result = (xdrproc_t) xdr_fsinfo3res; - local = (char *(*)(char *, struct svc_req *)) nfsproc3_fsinfo_3_svc; + local = (char *(*)(char *, RPCRequest *)) nfsproc3_fsinfo_3_svc; break; case NFSPROC3_PATHCONF: _xdr_argument = (xdrproc_t) xdr_nfs_fh3; _xdr_result = (xdrproc_t) xdr_pathconf3res; - local = (char *(*)(char *, struct svc_req *)) nfsproc3_pathconf_3_svc; + local = (char *(*)(char *, RPCRequest *)) nfsproc3_pathconf_3_svc; break; case NFSPROC3_COMMIT: _xdr_argument = (xdrproc_t) xdr_commit3args; _xdr_result = (xdrproc_t) xdr_commit3res; - local = (char *(*)(char *, struct svc_req *)) nfsproc3_commit_3_svc; + local = (char *(*)(char *, RPCRequest *)) nfsproc3_commit_3_svc; break; default: @@ -340,39 +383,8 @@ nfs_program_3(RPCRequest *req) } /* Perform the call. */ - result = (*local)((char *)req->args, NULL); - - /* Encode result and send reply. */ - static char reply_buf[MAX_RPC_MSGSIZE]; - XDR xdr_out; - xdrmem_create(&xdr_out, reply_buf, MAX_RPC_MSGSIZE, XDR_ENCODE); - if (result != NULL && !_xdr_result(&xdr_out, result)) { - async_rpc_send_failure(req, SYSTEM_ERR); - } - - struct rpc_reply header; - header.xid = htonl(xid); - header.type = htonl(1); /* REPLY */ - header.stat = htonl(MSG_ACCEPTED); - header.verf_flavor = 0; - header.verf_len = 0; - header.accept_stat = 0; - - gsize msg_size = xdr_out.x_ops->x_getpostn(&xdr_out); - printf("Have an RPC reply of size %zd bytes\n", msg_size); - uint32_t fragment = htonl((msg_size + sizeof(header)) | 0x80000000); - async_rpc_write(connection, (const char *)&fragment, sizeof(fragment)); - async_rpc_write(connection, (const char *)&header, sizeof(header)); - async_rpc_write(connection, reply_buf, msg_size); - g_io_channel_flush(connection->channel, NULL); - - /* Clean up. */ - xdr_in.x_op = XDR_FREE; - if (!_xdr_argument(&xdr_in, (caddr_t)req->args)) { - fprintf (stderr, "%s", "unable to free arguments"); - exit (1); - } - g_free(req->args); + req->xdr_result = _xdr_result; + result = (*local)((char *)req->args, req); bluesky_flushd_invoke(fs);