Attempt to coalesce range requests for inodes where possible.
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);
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
* 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