From 86765e018c4f08150e62b0a3272b0ab505da0983 Mon Sep 17 00:00:00 2001 From: Michael Vrable Date: Tue, 23 Feb 2010 15:10:51 -0800 Subject: [PATCH] synclient: Issue read requests for files after lookups return. --- nfs3/synclient.c | 65 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 59 insertions(+), 6 deletions(-) diff --git a/nfs3/synclient.c b/nfs3/synclient.c index 4db3cc8..ef614d3 100644 --- a/nfs3/synclient.c +++ b/nfs3/synclient.c @@ -88,8 +88,12 @@ typedef struct { GHashTable *xid_table; } NFSConnection; + +typedef void (*NFSFunc)(NFSConnection *nfs, + gpointer user_data, const char *reply, size_t len); + typedef struct { - GFunc callback; + NFSFunc callback; gpointer user_data; int64_t start, end; } CallInfo; @@ -128,7 +132,7 @@ static void do_write(NFSConnection *conn, const char *buf, size_t len) } static void send_rpc(NFSConnection *nfs, int proc, GString *msg, - GFunc completion_handler, gpointer user_data) + NFSFunc completion_handler, gpointer user_data) { static int xid_count = 0; struct rpc_call_header header; @@ -178,13 +182,14 @@ static void process_reply(NFSConnection *nfs, GString *msg) info->end = now_hires(); printf("XID %d: Time = %"PRIi64"\n", xid, info->end - info->start); if (info->callback != NULL) - info->callback(nfs, info->user_data); + info->callback(nfs, info->user_data, + msg->str + sizeof(*reply), msg->len - sizeof(*reply)); g_hash_table_remove(nfs->xid_table, key); g_free(info); completed++; - if (completed == threads) { + if (completed == 5 * threads) { g_main_loop_quit(main_loop); } } @@ -257,7 +262,7 @@ static gboolean read_handler(GIOChannel *channel, /* We were reading in the fragment body. */ nfs->frag_len -= bytes_read; - if (nfs->frag_len = 0x80000000) { + if (nfs->frag_len == 0x80000000) { process_reply(nfs, nfs->msgbuf); nfs->frag_len = 0; g_string_set_size(nfs->msgbuf, 0); @@ -267,6 +272,54 @@ static gboolean read_handler(GIOChannel *channel, return TRUE; } +static void send_read_requests(NFSConnection *nfs, const struct nfs_fh3 *fh) +{ + int i; + + g_print("Sending read requests...\n"); + for (i = 0; i < 4; i++) { + char buf[64]; + struct read3args read; + memcpy(&read.file, fh, sizeof(struct nfs_fh3)); + read.offset = (1 << 20) * i; + read.count = (1 << 20); + + GString *str = g_string_new(""); + XDR xdr; + xdr_string_create(&xdr, str, XDR_ENCODE); + xdr_read3args(&xdr, &read); + send_rpc(nfs, NFSPROC3_READ, str, NULL, NULL); + g_string_free(str, TRUE); + } +} + +static void store_fh(NFSConnection *nfs, gpointer user_data, + const char *reply, size_t len) +{ + struct lookup3res res; + XDR xdr; + memset(&res, 0, sizeof(res)); + xdrmem_create(&xdr, (char *)reply, len, XDR_DECODE); + if (!xdr_lookup3res(&xdr, &res)) { + g_print("Decode error for lookup3res!\n"); + return; + } + if (res.status != NFS3_OK) { + g_print("Response not NFS3_OK\n"); + return; + } + + struct nfs_fh3 *fh = g_new0(struct nfs_fh3, 1); + fh->data.data_len = res.lookup3res_u.resok.object.data.data_len; + fh->data.data_val = g_memdup(res.lookup3res_u.resok.object.data.data_val, + fh->data.data_len); + + xdr.x_op = XDR_FREE; + xdr_lookup3res(&xdr, &res); + + send_read_requests(nfs, fh); +} + static gboolean idle_handler(gpointer data) { NFSConnection *nfs = (NFSConnection *)data; @@ -287,7 +340,7 @@ static gboolean idle_handler(gpointer data) XDR xdr; xdr_string_create(&xdr, str, XDR_ENCODE); xdr_diropargs3(&xdr, &lookup); - send_rpc(nfs, NFSPROC3_LOOKUP, str, NULL, NULL); + send_rpc(nfs, NFSPROC3_LOOKUP, str, store_fh, NULL); g_string_free(str, TRUE); } -- 2.20.1