fuse: rename DirList into FuseDirList

Summary:
This type is very specific to Fuse, let's make it obvious. The readdir method
has also been renamed as it is also very specific to Fuse.

Reviewed By: chadaustin

Differential Revision: D26802309

fbshipit-source-id: c2acdfd1c0006935c59b685fcda729e1bef88928
This commit is contained in:
Xavier Deguillard 2021-03-18 10:06:28 -07:00 committed by Facebook GitHub Bot
parent 38a9add1da
commit ef798f8e3b
10 changed files with 61 additions and 54 deletions

View File

@ -17,10 +17,10 @@ using folly::StringPiece;
namespace facebook {
namespace eden {
DirList::DirList(size_t maxSize)
FuseDirList::FuseDirList(size_t maxSize)
: buf_(new char[maxSize]), end_(buf_.get() + maxSize), cur_(buf_.get()) {}
bool DirList::add(StringPiece name, ino_t inode, dtype_t type, off_t off) {
bool FuseDirList::add(StringPiece name, ino_t inode, dtype_t type, off_t off) {
const size_t avail = end_ - cur_;
const auto entLength = FUSE_NAME_OFFSET + name.size();
const auto fullSize = FUSE_DIRENT_ALIGN(entLength);
@ -44,12 +44,12 @@ bool DirList::add(StringPiece name, ino_t inode, dtype_t type, off_t off) {
return true;
}
StringPiece DirList::getBuf() const {
StringPiece FuseDirList::getBuf() const {
return StringPiece(buf_.get(), cur_ - buf_.get());
}
std::vector<DirList::ExtractedEntry> DirList::extract() const {
std::vector<DirList::ExtractedEntry> result;
std::vector<FuseDirList::ExtractedEntry> FuseDirList::extract() const {
std::vector<FuseDirList::ExtractedEntry> result;
char* p = buf_.get();
while (p != cur_) {

View File

@ -17,7 +17,7 @@ namespace eden {
/**
* Helper for populating directory listings.
*/
class DirList {
class FuseDirList {
std::unique_ptr<char[]> buf_;
char* end_;
char* cur_;
@ -30,12 +30,12 @@ class DirList {
off_t offset;
};
explicit DirList(size_t maxSize);
explicit FuseDirList(size_t maxSize);
DirList(const DirList&) = delete;
DirList& operator=(const DirList&) = delete;
DirList(DirList&&) = default;
DirList& operator=(DirList&&) = default;
FuseDirList(const FuseDirList&) = delete;
FuseDirList& operator=(const FuseDirList&) = delete;
FuseDirList(FuseDirList&&) = default;
FuseDirList& operator=(FuseDirList&&) = default;
/**
* Add a new dirent to the list.

View File

@ -2222,8 +2222,8 @@ folly::Future<folly::Unit> FuseChannel::fuseReadDir(
XLOG(DBG7) << "FUSE_READDIR";
auto ino = InodeNumber{header.nodeid};
return dispatcher_
->readdir(ino, DirList{read->size}, read->offset, read->fh, request)
.thenValue([&request](DirList&& list) {
->readdir(ino, FuseDirList{read->size}, read->offset, read->fh, request)
.thenValue([&request](FuseDirList&& list) {
const auto buf = list.getBuf();
request.sendReply(StringPiece{buf});
});

View File

@ -191,9 +191,9 @@ folly::Future<folly::Unit> FuseDispatcher::fsyncdir(InodeNumber, bool) {
FUSELL_NOT_IMPL();
}
folly::Future<DirList> FuseDispatcher::readdir(
folly::Future<FuseDirList> FuseDispatcher::readdir(
InodeNumber,
DirList&&,
FuseDirList&&,
off_t,
uint64_t,
ObjectFetchContext&) {

View File

@ -29,7 +29,7 @@ namespace facebook::eden {
folly::throwSystemErrorExplicit(ENOSYS, __PRETTY_FUNCTION__); \
} while (0)
class DirList;
class FuseDirList;
class EdenStats;
class FuseDispatcher {
@ -359,14 +359,14 @@ class FuseDispatcher {
/**
* Read directory.
*
* Send a DirList filled using DirList::add().
* Send an empty DirList on end of stream.
* Send a FuseDirList filled using FuseDirList::add().
* Send an empty FuseDirList on end of stream.
*
* The fh parameter contains opendir's result.
*/
virtual folly::Future<DirList> readdir(
virtual folly::Future<FuseDirList> readdir(
InodeNumber ino,
DirList&& dirList,
FuseDirList&& dirList,
off_t offset,
uint64_t fh,
ObjectFetchContext& context);

View File

@ -312,16 +312,16 @@ folly::Future<std::string> FuseDispatcherImpl::readlink(
});
}
folly::Future<DirList> FuseDispatcherImpl::readdir(
folly::Future<FuseDirList> FuseDispatcherImpl::readdir(
InodeNumber ino,
DirList&& dirList,
FuseDirList&& dirList,
off_t offset,
uint64_t /*fh*/,
ObjectFetchContext& context) {
return inodeMap_->lookupTreeInode(ino).thenValue(
[dirList = std::move(dirList), offset, &context](
TreeInodePtr inode) mutable {
return inode->readdir(std::move(dirList), offset, context);
return inode->fuseReaddir(std::move(dirList), offset, context);
});
}

View File

@ -93,9 +93,9 @@ class FuseDispatcherImpl : public FuseDispatcher {
folly::Future<folly::Unit> fsync(InodeNumber ino, bool datasync) override;
folly::Future<folly::Unit> fsyncdir(InodeNumber ino, bool datasync) override;
folly::Future<DirList> readdir(
folly::Future<FuseDirList> readdir(
InodeNumber ino,
DirList&& dirList,
FuseDirList&& dirList,
off_t offset,
uint64_t fh,
ObjectFetchContext& context) override;

View File

@ -1791,8 +1791,10 @@ void TreeInode::TreeRenameLocks::lockDestChild(PathComponentPiece destName) {
}
#ifndef _WIN32
DirList
TreeInode::readdir(DirList&& list, off_t off, ObjectFetchContext& context) {
FuseDirList TreeInode::fuseReaddir(
FuseDirList&& list,
off_t off,
ObjectFetchContext& context) {
/*
* Implementing readdir correctly in the presence of concurrent modifications
* to the directory is nontrivial. This function will be called multiple
@ -1884,7 +1886,7 @@ TreeInode::readdir(DirList&& list, off_t off, ObjectFetchContext& context) {
}
std::make_heap(indices.begin(), indices.end(), std::greater<>{});
// The provided DirList has limited space. Add entries until no more fit.
// The provided FuseDirList has limited space. Add entries until no more fit.
while (indices.size()) {
std::pop_heap(indices.begin(), indices.end(), std::greater<>{});
auto& [name, entry] = entries.begin()[indices.back().second];

View File

@ -21,7 +21,7 @@ namespace eden {
class CheckoutAction;
class CheckoutContext;
class DiffContext;
class DirList;
class FuseDirList;
class EdenMount;
class GitIgnoreStack;
class DiffCallback;
@ -146,7 +146,8 @@ class TreeInode final : public InodeBaseMetadata<DirContents> {
InvalidationRequired invalidate);
#ifndef _WIN32
DirList readdir(DirList&& list, off_t off, ObjectFetchContext& context);
FuseDirList
fuseReaddir(FuseDirList&& list, off_t off, ObjectFetchContext& context);
#else
/**
* The following readdir() is for responding to Projected FS's directory

View File

@ -146,7 +146,7 @@ TEST(TreeInode, updateAndReaddir) {
#else
TEST(TreeInode, readdirReturnsSelfAndParentBeforeEntries) {
TEST(TreeInode, fuseReaddirReturnsSelfAndParentBeforeEntries) {
// libfuse's documentation says returning . and .. is optional, but the FUSE
// kernel module does not synthesize them, so not returning . and .. would be
// a visible behavior change relative to a native filesystem.
@ -156,7 +156,8 @@ TEST(TreeInode, readdirReturnsSelfAndParentBeforeEntries) {
auto root = mount.getEdenMount()->getRootInode();
auto result =
root->readdir(DirList{4096}, 0, ObjectFetchContext::getNullContext())
root->fuseReaddir(
FuseDirList{4096}, 0, ObjectFetchContext::getNullContext())
.extract();
ASSERT_EQ(4, result.size());
@ -166,8 +167,8 @@ TEST(TreeInode, readdirReturnsSelfAndParentBeforeEntries) {
EXPECT_EQ(".eden", result[3].name);
}
TEST(TreeInode, readdirOffsetsAreNonzero) {
// readdir's offset parameter means "start here". 0 means start from the
TEST(TreeInode, fuseReaddirOffsetsAreNonzero) {
// fuseReaddir's offset parameter means "start here". 0 means start from the
// beginning. To start after a particular entry, the offset given must be that
// entry's offset. Therefore, no entries should have offset 0.
FakeTreeBuilder builder;
@ -176,7 +177,8 @@ TEST(TreeInode, readdirOffsetsAreNonzero) {
auto root = mount.getEdenMount()->getRootInode();
auto result =
root->readdir(DirList{4096}, 0, ObjectFetchContext::getNullContext())
root->fuseReaddir(
FuseDirList{4096}, 0, ObjectFetchContext::getNullContext())
.extract();
ASSERT_EQ(4, result.size());
for (auto& entry : result) {
@ -184,7 +186,7 @@ TEST(TreeInode, readdirOffsetsAreNonzero) {
}
}
TEST(TreeInode, readdirRespectsOffset) {
TEST(TreeInode, fuseReaddirRespectsOffset) {
FakeTreeBuilder builder;
builder.setFiles({{"file", ""}});
TestMount mount{builder};
@ -192,7 +194,8 @@ TEST(TreeInode, readdirRespectsOffset) {
auto root = mount.getEdenMount()->getRootInode();
const auto resultA =
root->readdir(DirList{4096}, 0, ObjectFetchContext::getNullContext())
root->fuseReaddir(
FuseDirList{4096}, 0, ObjectFetchContext::getNullContext())
.extract();
ASSERT_EQ(4, resultA.size());
EXPECT_EQ(".", resultA[0].name);
@ -200,8 +203,8 @@ TEST(TreeInode, readdirRespectsOffset) {
EXPECT_EQ("file", resultA[2].name);
EXPECT_EQ(".eden", resultA[3].name);
const auto resultB = root->readdir(
DirList{4096},
const auto resultB = root->fuseReaddir(
FuseDirList{4096},
resultA[0].offset,
ObjectFetchContext::getNullContext())
.extract();
@ -210,8 +213,8 @@ TEST(TreeInode, readdirRespectsOffset) {
EXPECT_EQ("file", resultB[1].name);
EXPECT_EQ(".eden", resultB[2].name);
const auto resultC = root->readdir(
DirList{4096},
const auto resultC = root->fuseReaddir(
FuseDirList{4096},
resultB[0].offset,
ObjectFetchContext::getNullContext())
.extract();
@ -219,31 +222,32 @@ TEST(TreeInode, readdirRespectsOffset) {
EXPECT_EQ("file", resultC[0].name);
EXPECT_EQ(".eden", resultC[1].name);
const auto resultD = root->readdir(
DirList{4096},
const auto resultD = root->fuseReaddir(
FuseDirList{4096},
resultC[0].offset,
ObjectFetchContext::getNullContext())
.extract();
ASSERT_EQ(1, resultD.size());
EXPECT_EQ(".eden", resultD[0].name);
const auto resultE = root->readdir(
DirList{4096},
const auto resultE = root->fuseReaddir(
FuseDirList{4096},
resultD[0].offset,
ObjectFetchContext::getNullContext())
.extract();
EXPECT_EQ(0, resultE.size());
}
TEST(TreeInode, readdirIgnoresWildOffsets) {
TEST(TreeInode, fuseReaddirIgnoresWildOffsets) {
TestMount mount{FakeTreeBuilder{}};
auto root = mount.getEdenMount()->getRootInode();
auto result =
root->readdir(
DirList{4096}, 0xfaceb00c, ObjectFetchContext::getNullContext())
.extract();
auto result = root->fuseReaddir(
FuseDirList{4096},
0xfaceb00c,
ObjectFetchContext::getNullContext())
.extract();
EXPECT_EQ(0, result.size());
}
@ -294,8 +298,8 @@ void runConcurrentModificationAndReaddirIteration(
std::unordered_map<std::string, unsigned> seen;
for (;;) {
auto result = root->readdir(
DirList{kDirListBufferSize},
auto result = root->fuseReaddir(
FuseDirList{kDirListBufferSize},
lastOffset,
ObjectFetchContext::getNullContext())
.extract();
@ -336,13 +340,13 @@ void runConcurrentModificationAndReaddirIteration(
// Verify all unmodified files were read.
for (auto& name : names) {
// If modified, it is not guaranteed to be returned by readdir.
// If modified, it is not guaranteed to be returned by fuseReaddir.
if (modified.count(name)) {
continue;
}
EXPECT_EQ(1, seen[name])
<< "unmodified entries should be returned by readdir exactly once, but "
<< "unmodified entries should be returned by fuseReaddir exactly once, but "
<< name << " wasn't";
}
}