Rework inode prefetching.
authorMichael Vrable <mvrable@cs.ucsd.edu>
Wed, 9 Mar 2011 04:57:15 +0000 (20:57 -0800)
committerMichael Vrable <mvrable@cs.ucsd.edu>
Wed, 9 Mar 2011 04:57:15 +0000 (20:57 -0800)
Attempt to coalesce range requests for inodes where possible.

bluesky/bluesky.h
bluesky/inode.c
nfs3/nfs3.c

index ae751fd..9921091 100644 (file)
@@ -356,6 +356,7 @@ void bluesky_file_read(BlueSkyInode *inode, uint64_t offset,
                        char *buf, gint len);
 
 void bluesky_inode_fetch(BlueSkyFS *fs, uint64_t inum);
+void bluesky_inode_prefetch(BlueSkyFS *fs, uint64_t inum);
 
 gint bluesky_dirent_compare(gconstpointer a, gconstpointer b,
                             gpointer unused);
index fe68328..42ae708 100644 (file)
@@ -270,6 +270,30 @@ BlueSkyInode *bluesky_new_inode(uint64_t inum, BlueSkyFS *fs,
     return i;
 }
 
+/* Issue a prefetch hint for an inode.  This signals that the inode may be
+ * needed soon.  Does not return any useful data. */
+void bluesky_inode_prefetch(BlueSkyFS *fs, uint64_t inum)
+{
+    BlueSkyInode *inode = NULL;
+
+    g_mutex_lock(fs->lock);
+    inode = (BlueSkyInode *)g_hash_table_lookup(fs->inodes, &inum);
+
+    if (inode != NULL) {
+        /* Inode is already available, no need for any prefetching... */
+        g_mutex_unlock(fs->lock);
+        return;
+    }
+
+    InodeMapEntry *entry = bluesky_inode_map_lookup(fs->inode_map, inum, 0);
+    if (entry != NULL) {
+        bluesky_cloudlog_prefetch(entry->item);
+    }
+
+    g_mutex_unlock(fs->lock);
+    return;
+}
+
 /* Retrieve an inode from the filesystem.  Eventually this will be a cache and
  * so we might need to go fetch the inode from elsewhere; for now all
  * filesystem state is stored here.  inode is returned with a reference held
index b5dae80..8f15857 100644 (file)
@@ -1006,6 +1006,22 @@ void nfsproc3_readdirplus_3_svc(readdirplus3args *argp, RPCRequest *req)
      * should let multiple inodes be fetched in parallel, instead of
      * sequentially in the loop that follows. */
     i = g_sequence_search(dir->dirents, &start, bluesky_dirent_compare, NULL);
+    while (count < MAX_READDIR_DIRENTS
+           && !g_sequence_iter_is_end(i)
+           && dircount <= argp->dircount
+           && dircount + attrcount <= argp->maxcount)
+    {
+        BlueSkyDirent *d = g_sequence_get(i);
+        bluesky_inode_prefetch(fs, d->inum);
+        dircount += 24 + ((strlen(d->name) + 3) & ~3);
+        attrcount += 88 + 8 + 8;
+        i = g_sequence_iter_next(i);
+    }
+
+    i = g_sequence_search(dir->dirents, &start, bluesky_dirent_compare, NULL);
+    count = 0;
+    dircount = 88 + 16;
+    attrcount = 0;
     while (count < MAX_READDIR_DIRENTS
            && !g_sequence_iter_is_end(i)
            && dircount <= argp->dircount