Skip to content

Commit

Permalink
[feat] curvefs: client: optimize rmdir and readdir
Browse files Browse the repository at this point in the history
Signed-off-by: swj <1186093704@qq.com>
  • Loading branch information
201341 committed Jun 8, 2023
1 parent 4762448 commit ae298a0
Show file tree
Hide file tree
Showing 9 changed files with 54 additions and 12 deletions.
4 changes: 2 additions & 2 deletions curvefs/src/client/client_operator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,14 +142,14 @@ void RenameOperator::SetTxId(uint32_t partitionId, uint64_t txId) {
metaClient_->SetTxId(partitionId, txId);
}

// TODO(Wine93): we should improve the check for whether a directory is empty
CURVEFS_ERROR RenameOperator::CheckOverwrite() {
if (dstDentry_.flag() & DentryFlag::TYPE_FILE_FLAG) {
return CURVEFS_ERROR::OK;
}

std::list<Dentry> dentrys;
auto rc = dentryManager_->ListDentry(dstDentry_.inodeid(), &dentrys, 1);
std::string marker = "";
auto rc = dentryManager_->ListDentry(dstDentry_.inodeid(), &dentrys, 1, &marker);
if (rc == CURVEFS_ERROR::OK && !dentrys.empty()) {
LOG(ERROR) << "The directory is not empty"
<< ", dentry = (" << dstDentry_.ShortDebugString() << ")";
Expand Down
23 changes: 23 additions & 0 deletions curvefs/src/client/dentry_cache_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,5 +156,28 @@ CURVEFS_ERROR DentryCacheManagerImpl::ListDentry(uint64_t parent,
return CURVEFS_ERROR::OK;
}

CURVEFS_ERROR DentryCacheManagerImpl::ListDentry(uint64_t parent,
std::list<Dentry> *dentryList,
uint32_t limit,
std::string *marker) {
dentryList->clear();
MetaStatusCode ret = MetaStatusCode::OK;
ret = metaClient_->ListDentry(fsId_, parent, *marker, limit, false,
dentryList);
VLOG(6) << "ListDentry fsId = " << fsId_ << ", parent = " << parent
<< ", last = " << marker << ", count = " << limit
<< ", onlyDir = " << false
<< ", ret = " << ret << ", part.size() = " << dentryList.size();
if (ret != MetaStatusCode::OK) {
LOG(ERROR) << "metaClient_ ListDentry failed"
<< ", MetaStatusCode_Name = " << MetaStatusCode_Name(ret)
<< ", parent = " << parent << ", last = " << last
<< ", count = " << limit << ", onlyDir = " << onlyDir;
return ToFSError(ret);
}
*marker = dentryList.back().name();

}

} // namespace client
} // namespace curvefs
8 changes: 8 additions & 0 deletions curvefs/src/client/dentry_cache_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ class DentryCacheManager {
std::list<Dentry> *dentryList, uint32_t limit,
bool onlyDir = false, uint32_t nlink = 0) = 0;

virtual CURVEFS_ERROR ListDentry(uint64_t parent,
std::list<Dentry> *dentryList, uint32_t limit,
std::string &nextMarker) = 0;

protected:
uint32_t fsId_;
};
Expand All @@ -96,6 +100,10 @@ class DentryCacheManagerImpl : public DentryCacheManager {
std::list<Dentry> *dentryList, uint32_t limit,
bool dirOnly = false, uint32_t nlink = 0) override;

CURVEFS_ERROR ListDentry(uint64_t parent,
std::list<Dentry> *dentryList, uint32_t limit,
std::string &nextMarker) override;

std::string GetDentryCacheKey(uint64_t parent, const std::string &name) {
return std::to_string(parent) + kDentryKeyDelimiter + name;
}
Expand Down
2 changes: 2 additions & 0 deletions curvefs/src/client/dir_buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,11 @@ struct DirBufferHead {
bool wasRead;
size_t size;
char *p;
std::string marker;
DirBufferHead()
: wasRead(false),
size(0),
marker(""),
p(nullptr) {}
};

Expand Down
5 changes: 3 additions & 2 deletions curvefs/src/client/filesystem/filesystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -290,13 +290,14 @@ CURVEFS_ERROR FileSystem::OpenDir(Request req, Ino ino, FileInfo* fi) {
CURVEFS_ERROR FileSystem::ReadDir(Request req,
Ino ino,
FileInfo* fi,
std::shared_ptr<DirEntryList>* entries) {
std::shared_ptr<DirEntryList>* entries
std::string* marker) {
bool yes = dirCache_->Get(ino, entries);
if (yes) {
return CURVEFS_ERROR::OK;
}

CURVEFS_ERROR rc = rpc_->ReadDir(ino, entries);
CURVEFS_ERROR rc = rpc_->ReadDir(ino, entries, marker);
if (rc != CURVEFS_ERROR::OK) {
return rc;
}
Expand Down
3 changes: 2 additions & 1 deletion curvefs/src/client/filesystem/filesystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ class FileSystem {
CURVEFS_ERROR ReadDir(Request req,
Ino ino,
FileInfo* fi,
std::shared_ptr<DirEntryList>* entries);
std::shared_ptr<DirEntryList>* entries,
std::string* marker);

CURVEFS_ERROR ReleaseDir(Request req, Ino ino, FileInfo* fi);

Expand Down
5 changes: 3 additions & 2 deletions curvefs/src/client/filesystem/rpc_client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,12 @@ CURVEFS_ERROR RPCClient::Lookup(Ino parent,
}

CURVEFS_ERROR RPCClient::ReadDir(Ino ino,
std::shared_ptr<DirEntryList>* entries) {
std::shared_ptr<DirEntryList>* entries,
std::string* marker) {
uint32_t limit = option_.listDentryLimit;

std::list<Dentry> dentries;
CURVEFS_ERROR rc = dentryManager_->ListDentry(ino, &dentries, limit);
CURVEFS_ERROR rc = dentryManager_->ListDentry(ino, &dentries, limit, marker);
if (rc != CURVEFS_ERROR::OK) {
LOG(ERROR) << "rpc(readdir::ListDentry) failed, retCode = " << rc
<< ", ino = " << ino;
Expand Down
4 changes: 3 additions & 1 deletion curvefs/src/client/filesystem/rpc_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ class RPCClient {
const std::string& name,
EntryOut* entryOut);

CURVEFS_ERROR ReadDir(Ino ino, std::shared_ptr<DirEntryList>* entries);
CURVEFS_ERROR ReadDir(Ino ino,
std::shared_ptr<DirEntryList>* entries,
std::string* marker);

CURVEFS_ERROR Open(Ino ino, std::shared_ptr<InodeWrapper>* inode);

Expand Down
12 changes: 8 additions & 4 deletions curvefs/src/client/fuse_client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -802,13 +802,14 @@ CURVEFS_ERROR FuseClient::RemoveNode(fuse_req_t req, fuse_ino_t parent,
// check dir empty
if (FsFileType::TYPE_DIRECTORY == type) {
std::list<Dentry> dentryList;
auto limit = option_.listDentryLimit;
ret = dentryManager_->ListDentry(ino, &dentryList, limit);
std::string marker = "";
ret = dentryManager_->ListDentry(ino, &dentryList, 1, &marker);
if (ret != CURVEFS_ERROR::OK) {
LOG(ERROR) << "dentryManager_ ListDentry fail, ret = " << ret
<< ", parent = " << ino;
<< ", parent = " << ino;
return ret;
}

if (!dentryList.empty()) {
LOG(ERROR) << "rmdir not empty";
return CURVEFS_ERROR::NOTEMPTY;
Expand Down Expand Up @@ -856,9 +857,12 @@ CURVEFS_ERROR FuseClient::FuseOpReadDir(fuse_req_t req,
bool plus) {
auto handler = fs_->FindHandler(fi->fh);
DirBufferHead* buffer = handler->buffer;
if (size + off > buffer->size) {
handler->padding = false;
}
if (!handler->padding) {
auto entries = std::make_shared<DirEntryList>();
CURVEFS_ERROR rc = fs_->ReadDir(req, ino, fi, &entries);
CURVEFS_ERROR rc = fs_->ReadDir(req, ino, fi, &entries, &buffer->marker);
if (rc != CURVEFS_ERROR::OK) {
LOG(ERROR) << "readdir() failed, retCode = " << rc
<< ", ino = " << ino << ", fh = " << fi->fh;
Expand Down

0 comments on commit ae298a0

Please sign in to comment.