mirror of
https://github.com/facebook/sapling.git
synced 2024-10-07 07:17:55 +03:00
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:
parent
38a9add1da
commit
ef798f8e3b
@ -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_) {
|
||||
|
@ -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.
|
||||
|
@ -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});
|
||||
});
|
||||
|
@ -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&) {
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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];
|
||||
|
@ -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
|
||||
|
@ -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";
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user