diff options
-rw-r--r-- | netfs/daemon/daemonDirectory.cpp | 29 | ||||
-rw-r--r-- | netfs/daemon/daemonDirectory.h | 6 | ||||
-rw-r--r-- | netfs/daemon/daemonVolume.cpp | 2 | ||||
-rw-r--r-- | netfs/fuse/fuseApp.h | 2 | ||||
-rw-r--r-- | netfs/fuse/fuseDirs.cpp | 29 | ||||
-rw-r--r-- | netfs/ice/directory.ice | 3 | ||||
-rw-r--r-- | netfs/ice/types.ice | 2 |
7 files changed, 57 insertions, 16 deletions
diff --git a/netfs/daemon/daemonDirectory.cpp b/netfs/daemon/daemonDirectory.cpp index 8c6c344..134fde5 100644 --- a/netfs/daemon/daemonDirectory.cpp +++ b/netfs/daemon/daemonDirectory.cpp @@ -4,9 +4,11 @@ #include <map> #include <sys/stat.h> #include <sys/types.h> +#include <fcntl.h> #include "daemonDirectory.h" -DirectoryServer::DirectoryServer(DIR * d) : +DirectoryServer::DirectoryServer(DIR * d, TypeConverter & t) : + TypeConverter(t), od(d) { } @@ -24,7 +26,7 @@ DirectoryServer::close(const Ice::Current & ice) throw NetFS::SystemError(errno); // LCOV_EXCL_STOP } - ice.adapter->remove(ice.id); + ice.adapter->removeFacet(ice.id, "v2"); } NetFS::NameList @@ -43,3 +45,26 @@ DirectoryServer::readdir(const Ice::Current&) return list; } +NetFS::DirectoryContents +DirectoryServer::listdir(const Ice::Current&) +{ + errno = 0; + NetFS::DirectoryContents list; + int fd = dirfd(od); + while (dirent * d = ::readdir(od)) { + if (errno) { + // LCOV_EXCL_START + throw NetFS::SystemError(errno); + // LCOV_EXCL_STOP + } + struct stat s; + if (::fstatat(fd, d->d_name, &s, AT_SYMLINK_NOFOLLOW) != 0) { + // LCOV_EXCL_START + throw NetFS::SystemError(errno); + // LCOV_EXCL_STOP + } + list[d->d_name] = convert(s); + } + return list; +} + diff --git a/netfs/daemon/daemonDirectory.h b/netfs/daemon/daemonDirectory.h index 2909dae..28c04a9 100644 --- a/netfs/daemon/daemonDirectory.h +++ b/netfs/daemon/daemonDirectory.h @@ -3,14 +3,16 @@ #include <directory.h> #include <dirent.h> +#include <typeConverter.h> -class DirectoryServer : public NetFS::Directory { +class DirectoryServer : public NetFS::DirectoryV2, TypeConverter { public: - DirectoryServer(DIR * od); + DirectoryServer(DIR * od, TypeConverter &); virtual ~DirectoryServer(); virtual void close(const Ice::Current&) override; virtual NetFS::NameList readdir(const Ice::Current&) override; + virtual NetFS::DirectoryContents listdir(const Ice::Current&) override; private: DIR * od; diff --git a/netfs/daemon/daemonVolume.cpp b/netfs/daemon/daemonVolume.cpp index fef26a1..ea5714a 100644 --- a/netfs/daemon/daemonVolume.cpp +++ b/netfs/daemon/daemonVolume.cpp @@ -275,7 +275,7 @@ VolumeServer::opendir(const NetFS::ReqEnv & re, const std::string & path, const if (!od) { throw NetFS::SystemError(errno); } - return NetFS::DirectoryPrx::checkedCast(ice.adapter->addWithUUID(new DirectoryServer(od))); + return NetFS::DirectoryPrx::checkedCast(ice.adapter->addFacetWithUUID(new DirectoryServer(od, converter), "v2")); } void diff --git a/netfs/fuse/fuseApp.h b/netfs/fuse/fuseApp.h index ec75d03..2c9824b 100644 --- a/netfs/fuse/fuseApp.h +++ b/netfs/fuse/fuseApp.h @@ -22,6 +22,7 @@ namespace NetFS { OpenDir(DirectoryPrx remote, const std::string & path); DirectoryPrx remote; + DirectoryV2Prx remoteV2; const std::string path; }; typedef IceUtil::Handle<OpenDir> OpenDirPtr; @@ -95,7 +96,6 @@ namespace NetFS { virtual NetFS::Client::ResourcePtr configureFromUri(const std::string &) const; private: - void setProxy(OpenFilePtr, uint64_t & fh); OpenFilePtr getFileProxy(uint64_t localID) const; void clearFileProxy(uint64_t localID); diff --git a/netfs/fuse/fuseDirs.cpp b/netfs/fuse/fuseDirs.cpp index 00c0ca4..03cc712 100644 --- a/netfs/fuse/fuseDirs.cpp +++ b/netfs/fuse/fuseDirs.cpp @@ -4,6 +4,7 @@ NetFS::FuseApp::OpenDir::OpenDir(DirectoryPrx r, const std::string & p) : remote(r), + remoteV2(r->ice_getFacet() == "v2" ? DirectoryV2Prx::uncheckedCast(r) : nullptr), path(p) { } @@ -65,18 +66,26 @@ int 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(); + auto od = getDirProxy(fi->fh); std::string path(p); - NetFS::VolumePrx vc = volume; - for (const auto & e : ds) { - filler(buf, e.c_str(), NULL, 0); - std::string epath = path + "/" + e; - auto asga = volume->begin_getattr(reqEnv(), epath); - statCache.addFactory(epath, + path += "/"; + auto expiry = time(NULL) + 2; + if (od->remoteV2) { + for (const auto & e : od->remoteV2->listdir()) { + filler(buf, e.first.c_str(), NULL, 0); + statCache.add(path + e.first, converter.convert(e.second), expiry); + } + } + else { + for (const auto & e : od->remote->readdir()) { + filler(buf, e.c_str(), NULL, 0); + std::string epath = path + e; + auto asga = volume->begin_getattr(reqEnv(), epath); + statCache.addFactory(epath, [asga,this]() { - return converter.convert(volume->end_getattr(asga)); - }, time(NULL) + 2); + return converter.convert(volume->end_getattr(asga)); + }, expiry); + } } return 0; } diff --git a/netfs/ice/directory.ice b/netfs/ice/directory.ice index b77a1ad..3718f69 100644 --- a/netfs/ice/directory.ice +++ b/netfs/ice/directory.ice @@ -10,6 +10,9 @@ module NetFS { idempotent NameList readdir() throws AuthError, SystemError; }; + interface DirectoryV2 extends Directory { + idempotent DirectoryContents listdir() throws AuthError, SystemError; + }; }; #endif diff --git a/netfs/ice/types.ice b/netfs/ice/types.ice index 74f48ce..de83f6f 100644 --- a/netfs/ice/types.ice +++ b/netfs/ice/types.ice @@ -40,6 +40,8 @@ module NetFS { sequence<byte> Buffer; sequence<string> NameList; + + dictionary<string, Attr> DirectoryContents; }; #endif |