From: Michael Vrable Date: Wed, 13 Jan 2010 19:24:31 +0000 (-0800) Subject: More async RPC work. X-Git-Url: http://git.vrable.net/?p=bluesky.git;a=commitdiff_plain;h=c3245fe423dd5c3a68b4c1e90ba253e7fae3473e More async RPC work. --- diff --git a/nfs3/nfs3.c b/nfs3/nfs3.c index 9fccd00..693175b 100644 --- a/nfs3/nfs3.c +++ b/nfs3/nfs3.c @@ -140,13 +140,13 @@ void encode_pre_wcc(struct wcc_data *wcc, BlueSkyInode *inode) } void * -nfsproc3_null_3_svc(void *argp, struct svc_req *rqstp) +nfsproc3_null_3_svc(void *argp, RPCRequest *req) { return null_result; } getattr3res * -nfsproc3_getattr_3_svc(nfs_fh3 *argp, struct svc_req *rqstp) +nfsproc3_getattr_3_svc(nfs_fh3 *argp, RPCRequest *req) { static getattr3res result; @@ -162,7 +162,7 @@ nfsproc3_getattr_3_svc(nfs_fh3 *argp, struct svc_req *rqstp) } wccstat3 * -nfsproc3_setattr_3_svc(setattr3args *argp, struct svc_req *rqstp) +nfsproc3_setattr_3_svc(setattr3args *argp, RPCRequest *req) { static wccstat3 result; @@ -195,7 +195,7 @@ nfsproc3_setattr_3_svc(setattr3args *argp, struct svc_req *rqstp) } lookup3res * -nfsproc3_lookup_3_svc(diropargs3 *argp, struct svc_req *rqstp) +nfsproc3_lookup_3_svc(diropargs3 *argp, RPCRequest *req) { static lookup3res result; @@ -243,7 +243,7 @@ nfsproc3_lookup_3_svc(diropargs3 *argp, struct svc_req *rqstp) } access3res * -nfsproc3_access_3_svc(access3args *argp, struct svc_req *rqstp) +nfsproc3_access_3_svc(access3args *argp, RPCRequest *req) { static access3res result; @@ -263,7 +263,7 @@ nfsproc3_access_3_svc(access3args *argp, struct svc_req *rqstp) } readlink3res * -nfsproc3_readlink_3_svc(nfs_fh3 *argp, struct svc_req *rqstp) +nfsproc3_readlink_3_svc(nfs_fh3 *argp, RPCRequest *req) { static readlink3res result; memset(&result, 0, sizeof(result)); @@ -288,7 +288,7 @@ nfsproc3_readlink_3_svc(nfs_fh3 *argp, struct svc_req *rqstp) } read3res * -nfsproc3_read_3_svc(read3args *argp, struct svc_req *rqstp) +nfsproc3_read_3_svc(read3args *argp, RPCRequest *req) { static read3res result; static char buf[32768]; @@ -325,7 +325,7 @@ nfsproc3_read_3_svc(read3args *argp, struct svc_req *rqstp) } write3res * -nfsproc3_write_3_svc(write3args *argp, struct svc_req *rqstp) +nfsproc3_write_3_svc(write3args *argp, RPCRequest *req) { static write3res result; struct wcc_data wcc; @@ -367,7 +367,7 @@ nfsproc3_write_3_svc(write3args *argp, struct svc_req *rqstp) } diropres3 * -nfsproc3_create_3_svc(create3args *argp, struct svc_req *rqstp) +nfsproc3_create_3_svc(create3args *argp, RPCRequest *req) { static diropres3 result; struct wcc_data wcc; @@ -428,7 +428,7 @@ nfsproc3_create_3_svc(create3args *argp, struct svc_req *rqstp) } diropres3 * -nfsproc3_mkdir_3_svc(mkdir3args *argp, struct svc_req *rqstp) +nfsproc3_mkdir_3_svc(mkdir3args *argp, RPCRequest *req) { static diropres3 result; struct wcc_data wcc; @@ -489,7 +489,7 @@ nfsproc3_mkdir_3_svc(mkdir3args *argp, struct svc_req *rqstp) } diropres3 * -nfsproc3_symlink_3_svc(symlink3args *argp, struct svc_req *rqstp) +nfsproc3_symlink_3_svc(symlink3args *argp, RPCRequest *req) { static diropres3 result; struct wcc_data wcc; @@ -550,7 +550,7 @@ nfsproc3_symlink_3_svc(symlink3args *argp, struct svc_req *rqstp) } diropres3 * -nfsproc3_mknod_3_svc(mknod3args *argp, struct svc_req *rqstp) +nfsproc3_mknod_3_svc(mknod3args *argp, RPCRequest *req) { static diropres3 result; @@ -560,7 +560,7 @@ nfsproc3_mknod_3_svc(mknod3args *argp, struct svc_req *rqstp) } wccstat3 * -nfsproc3_remove_3_svc(diropargs3 *argp, struct svc_req *rqstp) +nfsproc3_remove_3_svc(diropargs3 *argp, RPCRequest *req) { static wccstat3 result; @@ -596,7 +596,7 @@ nfsproc3_remove_3_svc(diropargs3 *argp, struct svc_req *rqstp) } wccstat3 * -nfsproc3_rmdir_3_svc(diropargs3 *argp, struct svc_req *rqstp) +nfsproc3_rmdir_3_svc(diropargs3 *argp, RPCRequest *req) { static wccstat3 result; @@ -650,7 +650,7 @@ nfsproc3_rmdir_3_svc(diropargs3 *argp, struct svc_req *rqstp) } rename3res * -nfsproc3_rename_3_svc(rename3args *argp, struct svc_req *rqstp) +nfsproc3_rename_3_svc(rename3args *argp, RPCRequest *req) { static rename3res result; wcc_data *wcc1 = &result.rename3res_u.res.fromdir_wcc; @@ -689,7 +689,7 @@ nfsproc3_rename_3_svc(rename3args *argp, struct svc_req *rqstp) } link3res * -nfsproc3_link_3_svc(link3args *argp, struct svc_req *rqstp) +nfsproc3_link_3_svc(link3args *argp, RPCRequest *req) { static link3res result; struct wcc_data wcc; @@ -749,7 +749,7 @@ gint bluesky_dirent_compare(gconstpointer a, gconstpointer b, #define MAX_READDIR_DIRENTS 64 readdir3res * -nfsproc3_readdir_3_svc(readdir3args *argp, struct svc_req *rqstp) +nfsproc3_readdir_3_svc(readdir3args *argp, RPCRequest *req) { static readdir3res result; @@ -795,7 +795,7 @@ nfsproc3_readdir_3_svc(readdir3args *argp, struct svc_req *rqstp) } readdirplus3res * -nfsproc3_readdirplus_3_svc(readdirplus3args *argp, struct svc_req *rqstp) +nfsproc3_readdirplus_3_svc(readdirplus3args *argp, RPCRequest *req) { /* XDR-encoded sizes: * post_op_attr: 88 bytes @@ -866,7 +866,7 @@ nfsproc3_readdirplus_3_svc(readdirplus3args *argp, struct svc_req *rqstp) } fsstat3res * -nfsproc3_fsstat_3_svc(nfs_fh3 *argp, struct svc_req *rqstp) +nfsproc3_fsstat_3_svc(nfs_fh3 *argp, RPCRequest *req) { static fsstat3res result; @@ -893,7 +893,7 @@ nfsproc3_fsstat_3_svc(nfs_fh3 *argp, struct svc_req *rqstp) } fsinfo3res * -nfsproc3_fsinfo_3_svc(nfs_fh3 *argp, struct svc_req *rqstp) +nfsproc3_fsinfo_3_svc(nfs_fh3 *argp, RPCRequest *req) { static fsinfo3res result; @@ -918,7 +918,7 @@ nfsproc3_fsinfo_3_svc(nfs_fh3 *argp, struct svc_req *rqstp) } pathconf3res * -nfsproc3_pathconf_3_svc(nfs_fh3 *argp, struct svc_req *rqstp) +nfsproc3_pathconf_3_svc(nfs_fh3 *argp, RPCRequest *req) { static pathconf3res result; @@ -937,7 +937,7 @@ nfsproc3_pathconf_3_svc(nfs_fh3 *argp, struct svc_req *rqstp) } commit3res * -nfsproc3_commit_3_svc(commit3args *argp, struct svc_req *rqstp) +nfsproc3_commit_3_svc(commit3args *argp, RPCRequest *req) { static commit3res result; diff --git a/nfs3/nfs3_prot.h b/nfs3/nfs3_prot.h index 7f75928..0f06618 100644 --- a/nfs3/nfs3_prot.h +++ b/nfs3/nfs3_prot.h @@ -683,54 +683,55 @@ typedef struct { xdrproc_t xdr_result; } RPCRequest; +extern void async_rpc_send_reply(RPCRequest *req, void *result); + #define NFS_PROGRAM 100003 #define NFS_V3 3 #define NFSPROC3_NULL 0 -extern void * nfsproc3_null_3_svc(void *, struct svc_req *); +extern void * nfsproc3_null_3_svc(void *, RPCRequest *); #define NFSPROC3_GETATTR 1 -extern getattr3res * nfsproc3_getattr_3_svc(nfs_fh3 *, struct svc_req *); +extern getattr3res * nfsproc3_getattr_3_svc(nfs_fh3 *, RPCRequest *); #define NFSPROC3_SETATTR 2 -extern wccstat3 * nfsproc3_setattr_3_svc(setattr3args *, struct svc_req *); +extern wccstat3 * nfsproc3_setattr_3_svc(setattr3args *, RPCRequest *); #define NFSPROC3_LOOKUP 3 -extern lookup3res * nfsproc3_lookup_3_svc(diropargs3 *, struct svc_req *); +extern lookup3res * nfsproc3_lookup_3_svc(diropargs3 *, RPCRequest *); #define NFSPROC3_ACCESS 4 -extern access3res * nfsproc3_access_3_svc(access3args *, struct svc_req *); +extern access3res * nfsproc3_access_3_svc(access3args *, RPCRequest *); #define NFSPROC3_READLINK 5 -extern readlink3res * nfsproc3_readlink_3_svc(nfs_fh3 *, struct svc_req *); +extern readlink3res * nfsproc3_readlink_3_svc(nfs_fh3 *, RPCRequest *); #define NFSPROC3_READ 6 -extern read3res * nfsproc3_read_3_svc(read3args *, struct svc_req *); +extern read3res * nfsproc3_read_3_svc(read3args *, RPCRequest *); #define NFSPROC3_WRITE 7 -extern write3res * nfsproc3_write_3_svc(write3args *, struct svc_req *); +extern write3res * nfsproc3_write_3_svc(write3args *, RPCRequest *); #define NFSPROC3_CREATE 8 -extern diropres3 * nfsproc3_create_3_svc(create3args *, struct svc_req *); +extern diropres3 * nfsproc3_create_3_svc(create3args *, RPCRequest *); #define NFSPROC3_MKDIR 9 -extern diropres3 * nfsproc3_mkdir_3_svc(mkdir3args *, struct svc_req *); +extern diropres3 * nfsproc3_mkdir_3_svc(mkdir3args *, RPCRequest *); #define NFSPROC3_SYMLINK 10 -extern diropres3 * nfsproc3_symlink_3_svc(symlink3args *, struct svc_req *); +extern diropres3 * nfsproc3_symlink_3_svc(symlink3args *, RPCRequest *); #define NFSPROC3_MKNOD 11 -extern diropres3 * nfsproc3_mknod_3_svc(mknod3args *, struct svc_req *); +extern diropres3 * nfsproc3_mknod_3_svc(mknod3args *, RPCRequest *); #define NFSPROC3_REMOVE 12 -extern wccstat3 * nfsproc3_remove_3_svc(diropargs3 *, struct svc_req *); +extern wccstat3 * nfsproc3_remove_3_svc(diropargs3 *, RPCRequest *); #define NFSPROC3_RMDIR 13 -extern wccstat3 * nfsproc3_rmdir_3_svc(diropargs3 *, struct svc_req *); +extern wccstat3 * nfsproc3_rmdir_3_svc(diropargs3 *, RPCRequest *); #define NFSPROC3_RENAME 14 -extern rename3res * nfsproc3_rename_3_svc(rename3args *, struct svc_req *); +extern rename3res * nfsproc3_rename_3_svc(rename3args *, RPCRequest *); #define NFSPROC3_LINK 15 -extern link3res * nfsproc3_link_3_svc(link3args *, struct svc_req *); +extern link3res * nfsproc3_link_3_svc(link3args *, RPCRequest *); #define NFSPROC3_READDIR 16 -extern readdir3res * nfsproc3_readdir_3_svc(readdir3args *, struct svc_req *); +extern readdir3res * nfsproc3_readdir_3_svc(readdir3args *, RPCRequest *); #define NFSPROC3_READDIRPLUS 17 -extern readdirplus3res * nfsproc3_readdirplus_3_svc(readdirplus3args *, struct svc_req *); +extern readdirplus3res * nfsproc3_readdirplus_3_svc(readdirplus3args *, RPCRequest *); #define NFSPROC3_FSSTAT 18 -extern fsstat3res * nfsproc3_fsstat_3_svc(nfs_fh3 *, struct svc_req *); +extern fsstat3res * nfsproc3_fsstat_3_svc(nfs_fh3 *, RPCRequest *); #define NFSPROC3_FSINFO 19 -extern fsinfo3res * nfsproc3_fsinfo_3_svc(nfs_fh3 *, struct svc_req *); +extern fsinfo3res * nfsproc3_fsinfo_3_svc(nfs_fh3 *, RPCRequest *); #define NFSPROC3_PATHCONF 20 -extern pathconf3res * nfsproc3_pathconf_3_svc(nfs_fh3 *, struct svc_req *); +extern pathconf3res * nfsproc3_pathconf_3_svc(nfs_fh3 *, RPCRequest *); #define NFSPROC3_COMMIT 21 -extern commit3res * nfsproc3_commit_3_svc(commit3args *, struct svc_req *); -extern int nfs_program_3_freeresult (SVCXPRT *, xdrproc_t, caddr_t); +extern commit3res * nfsproc3_commit_3_svc(commit3args *, RPCRequest *); /* the xdr functions */ diff --git a/nfs3/rpc.c b/nfs3/rpc.c index d47943c..8eeec30 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 (result != NULL && !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,11 @@ nfs_program_3(RPCRequest *req) } /* Perform the call. */ - result = (*local)((char *)req->args, NULL); + req->xdr_result = _xdr_result; + result = (*local)((char *)req->args, req); /* 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); + async_rpc_send_reply(req, result); bluesky_flushd_invoke(fs);