- 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 {
class Device;
class File;
class OpenFile;
class Dir: public virtual Node {
public:
@ -25,8 +25,8 @@ public:
std::string name;
};
virtual std::unique_ptr<File> createFile(const std::string &name, mode_t mode) = 0;
virtual std::unique_ptr<Dir> createDir(const std::string &name, mode_t mode) = 0;
virtual std::unique_ptr<OpenFile> createAndOpenFile(const std::string &name, mode_t mode) = 0;
virtual void createDir(const std::string &name, mode_t mode) = 0;
virtual void rmdir() = 0;
//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);
try {
auto entries = _fs->readDir(path);
struct stat stbuf;
for (const auto &entry : *entries) {
//We could pass file metadata to filler() in its third parameter,
//but it doesn't help performance since fuse seems to ignore it.
//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;
}
}

View File

@ -52,7 +52,7 @@ int FilesystemImpl::openFile(const bf::path &path, 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) {
@ -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.
// This is slow. Improve!
auto dir = LoadDir(path.parent_path());
auto file = dir->createFile(path.filename().native(), mode);
return openFile(*file, O_WRONLY | O_TRUNC);
auto file = dir->createAndOpenFile(path.filename().native(), mode);
return _open_files.open(std::move(file));
}
void FilesystemImpl::mkdir(const bf::path &path, mode_t mode) {

View File

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

View File

@ -27,22 +27,6 @@ public:
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 {
const int FILEID1 = 4;
const int FLAGS1 = 5;
@ -53,7 +37,7 @@ struct FuseOpenFileListTest: public ::testing::Test {
FuseOpenFileList list;
int open(int fileid, int flags) {
return list.open(MockFile(fileid), flags);
return list.open(make_unique<MockOpenFile>(fileid, flags));
}
int open() {
return open(FILEID1, FILEID2);