synclient: Issue read requests for files after lookups return.
authorMichael Vrable <mvrable@cs.ucsd.edu>
Tue, 23 Feb 2010 23:10:51 +0000 (15:10 -0800)
committerMichael Vrable <mvrable@cs.ucsd.edu>
Tue, 23 Feb 2010 23:10:51 +0000 (15:10 -0800)
nfs3/synclient.c

index 4db3cc8..ef614d3 100644 (file)
@@ -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);
     }