From 7475fd7f960ccae454d7d6cd7489b72fe6400466 Mon Sep 17 00:00:00 2001 From: randomdan Date: Mon, 19 May 2014 13:36:41 +0000 Subject: Asynchronously call getattr for directory entries on readdir and cache them for likely client getattr call --- netfs/fuse/fuse.cpp | 4 ++++ netfs/fuse/fuse.h | 4 ++++ netfs/fuse/fuseDirs.cpp | 13 ++++++++++++- netfs/fuse/fuseMisc.cpp | 8 +++++++- 4 files changed, 27 insertions(+), 2 deletions(-) diff --git a/netfs/fuse/fuse.cpp b/netfs/fuse/fuse.cpp index d9d49fc..3d14d1c 100644 --- a/netfs/fuse/fuse.cpp +++ b/netfs/fuse/fuse.cpp @@ -3,6 +3,10 @@ #include #include "fuse.h" #include "lockHelpers.h" +#include "cache.impl.h" + +template class Cache>>; +template class OptimisticCallCacheable; NetFS::FuseApp::FuseApp(int & argc, char ** argv) : _argc(argc), diff --git a/netfs/fuse/fuse.h b/netfs/fuse/fuse.h index a271630..d95dec4 100644 --- a/netfs/fuse/fuse.h +++ b/netfs/fuse/fuse.h @@ -7,6 +7,7 @@ #include "fuseapp.h" #include "fuseConfig.h" #include "entCache.h" +#include "cache.h" namespace NetFS { class FuseApp : public FuseAppBase { @@ -107,6 +108,9 @@ namespace NetFS { int openDirID; OpenFiles openFiles; int openFileID; + + typedef Cache>> StatCache; + StatCache statCache; }; } diff --git a/netfs/fuse/fuseDirs.cpp b/netfs/fuse/fuseDirs.cpp index e09b68b..35aad94 100644 --- a/netfs/fuse/fuseDirs.cpp +++ b/netfs/fuse/fuseDirs.cpp @@ -2,6 +2,7 @@ #include "fuse.h" #include "misc.h" #include "lockHelpers.h" +#include NetFS::FuseApp::OpenDir::OpenDir(DirectoryPrx r, const std::string & p) : remote(r), @@ -63,13 +64,23 @@ NetFS::FuseApp::releasedir(const char *, struct fuse_file_info * fi) } int -NetFS::FuseApp::readdir(const char *, void * buf, fuse_fill_dir_t filler, off_t, struct fuse_file_info * fi) +NetFS::FuseApp::readdir(const char * p, void * buf, fuse_fill_dir_t filler, off_t, struct fuse_file_info * fi) { try { auto remote = getDirProxy(fi->fh)->remote; NetFS::NameList ds = remote->readdir(); + std::string path(p); + NetFS::VolumePrx vc = volume; BOOST_FOREACH(const auto & e, ds) { filler(buf, e.c_str(), NULL, 0); + std::string epath = path + "/" + e; + auto asga = volume->begin_getattr(reqEnv(), epath); + statCache.Add(new OptimisticCallCacheable( + [asga,this]() { + struct stat s; + s << AttrSource { volume->end_getattr(asga), boost::bind(&UserEntCache::getID, &uentries, _1), boost::bind(&GroupEntCache::getID, &gentries, _1) }; + return s; + }, epath, time_t(NULL) + 2)); } return 0; } diff --git a/netfs/fuse/fuseMisc.cpp b/netfs/fuse/fuseMisc.cpp index 568cf52..1eecdd4 100644 --- a/netfs/fuse/fuseMisc.cpp +++ b/netfs/fuse/fuseMisc.cpp @@ -13,7 +13,13 @@ int NetFS::FuseApp::getattr(const char * p, struct stat * s) { try { - *s << AttrSource { volume->getattr(reqEnv(), p), boost::bind(&UserEntCache::getID, &uentries, _1), boost::bind(&GroupEntCache::getID, &gentries, _1) }; + auto cacehedStat = statCache.Get(p); + if (cacehedStat) { + *s = *cacehedStat; + } + else { + *s << AttrSource { volume->getattr(reqEnv(), p), boost::bind(&UserEntCache::getID, &uentries, _1), boost::bind(&GroupEntCache::getID, &gentries, _1) }; + } return 0; } catch (NetFS::SystemError & e) { -- cgit v1.2.3