summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--netfs/daemon/daemonDirectory.cpp29
-rw-r--r--netfs/daemon/daemonDirectory.h6
-rw-r--r--netfs/daemon/daemonVolume.cpp2
-rw-r--r--netfs/fuse/fuseApp.h2
-rw-r--r--netfs/fuse/fuseDirs.cpp29
-rw-r--r--netfs/ice/directory.ice3
-rw-r--r--netfs/ice/types.ice2
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