- ReadDir also returns whether the entry is a file or a directory

- OpenFileList has a simpler interface
This commit is contained in:
Sebastian Messmer 2015-03-11 00:22:36 +01:00
parent 498623ddab
commit 9741fb3f5c
5 changed files with 17 additions and 27 deletions

View File

@ -8,7 +8,7 @@
namespace fspp { namespace fspp {
class Device; class Device;
class File; class OpenFile;
class Dir: public virtual Node { class Dir: public virtual Node {
public: public:
@ -25,8 +25,8 @@ public:
std::string name; std::string name;
}; };
virtual std::unique_ptr<File> createFile(const std::string &name, mode_t mode) = 0; virtual std::unique_ptr<OpenFile> createAndOpenFile(const std::string &name, mode_t mode) = 0;
virtual std::unique_ptr<Dir> createDir(const std::string &name, mode_t mode) = 0; virtual void createDir(const std::string &name, mode_t mode) = 0;
virtual void rmdir() = 0; virtual void rmdir() = 0;
//TODO Allow alternative implementation returning only children names without more information //TODO Allow alternative implementation returning only children names without more information

View File

@ -468,11 +468,17 @@ int Fuse::readdir(const bf::path &path, void *buf, fuse_fill_dir_t filler, off_t
UNUSED(offset); UNUSED(offset);
try { try {
auto entries = _fs->readDir(path); auto entries = _fs->readDir(path);
struct stat stbuf;
for (const auto &entry : *entries) { for (const auto &entry : *entries) {
//We could pass file metadata to filler() in its third parameter, //We could pass file metadata to filler() in its third parameter,
//but it doesn't help performance since fuse seems to ignore it. //but it doesn't help performance since fuse seems to ignore it.
//It does getattr() calls on all entries nevertheless. //It does getattr() calls on all entries nevertheless.
if (filler(buf, entry.name.c_str(), nullptr, 0) != 0) { if (entry.type == Dir::EntryType::DIR) {
stbuf.st_mode = S_IFDIR | S_IRUSR | S_IXUSR | S_IWUSR;
} else {
stbuf.st_mode = S_IFREG | S_IRUSR | S_IXUSR | S_IWUSR;
}
if (filler(buf, entry.name.c_str(), &stbuf, 0) != 0) {
return -ENOMEM; return -ENOMEM;
} }
} }

View File

@ -52,7 +52,7 @@ int FilesystemImpl::openFile(const bf::path &path, int flags) {
} }
int FilesystemImpl::openFile(const File &file, int flags) { int FilesystemImpl::openFile(const File &file, int flags) {
return _open_files.open(file, flags); return _open_files.open(file.open(flags));
} }
void FilesystemImpl::flush(int descriptor) { void FilesystemImpl::flush(int descriptor) {
@ -103,8 +103,8 @@ int FilesystemImpl::createAndOpenFile(const bf::path &path, mode_t mode) {
//TODO Creating the file opens and closes it. We then reopen it afterwards. //TODO Creating the file opens and closes it. We then reopen it afterwards.
// This is slow. Improve! // This is slow. Improve!
auto dir = LoadDir(path.parent_path()); auto dir = LoadDir(path.parent_path());
auto file = dir->createFile(path.filename().native(), mode); auto file = dir->createAndOpenFile(path.filename().native(), mode);
return openFile(*file, O_WRONLY | O_TRUNC); return _open_files.open(std::move(file));
} }
void FilesystemImpl::mkdir(const bf::path &path, mode_t mode) { void FilesystemImpl::mkdir(const bf::path &path, mode_t mode) {

View File

@ -14,7 +14,7 @@ public:
FuseOpenFileList(); FuseOpenFileList();
virtual ~FuseOpenFileList(); virtual ~FuseOpenFileList();
int open(const File &rhs, int flags); int open(std::unique_ptr<OpenFile> file);
OpenFile *get(int descriptor); OpenFile *get(int descriptor);
void close(int descriptor); void close(int descriptor);
@ -31,8 +31,8 @@ inline FuseOpenFileList::FuseOpenFileList()
inline FuseOpenFileList::~FuseOpenFileList() { inline FuseOpenFileList::~FuseOpenFileList() {
} }
inline int FuseOpenFileList::open(const File &file, int flags) { inline int FuseOpenFileList::open(std::unique_ptr<OpenFile> file) {
return _open_files.add(file.open(flags)); return _open_files.add(std::move(file));
} }
inline OpenFile *FuseOpenFileList::get(int descriptor) { inline OpenFile *FuseOpenFileList::get(int descriptor) {

View File

@ -27,22 +27,6 @@ public:
MOCK_METHOD0(fdatasync, void()); MOCK_METHOD0(fdatasync, void());
}; };
class MockFile: public File {
public:
MockFile(int id_): id(id_) {}
int id;
unique_ptr<OpenFile> open(int flags) const override {
return make_unique<MockOpenFile>(id, flags);
}
MOCK_CONST_METHOD1(truncate, void(off_t));
MOCK_METHOD0(unlink, void());
MOCK_CONST_METHOD1(stat, void(struct ::stat*));
MOCK_CONST_METHOD1(access, void(int));
MOCK_METHOD1(rename, void(const boost::filesystem::path &));
MOCK_METHOD1(utimens, void(const timespec[2]));
};
struct FuseOpenFileListTest: public ::testing::Test { struct FuseOpenFileListTest: public ::testing::Test {
const int FILEID1 = 4; const int FILEID1 = 4;
const int FLAGS1 = 5; const int FLAGS1 = 5;
@ -53,7 +37,7 @@ struct FuseOpenFileListTest: public ::testing::Test {
FuseOpenFileList list; FuseOpenFileList list;
int open(int fileid, int flags) { int open(int fileid, int flags) {
return list.open(MockFile(fileid), flags); return list.open(make_unique<MockOpenFile>(fileid, flags));
} }
int open() { int open() {
return open(FILEID1, FILEID2); return open(FILEID1, FILEID2);