Skip to content

Commit

Permalink
curvefs/client: fix update nlink error
Browse files Browse the repository at this point in the history
Signed-off-by: wanghai01 <[email protected]>
  • Loading branch information
SeanHai committed Sep 8, 2022
1 parent fc574a8 commit bab48e0
Show file tree
Hide file tree
Showing 7 changed files with 169 additions and 101 deletions.
5 changes: 5 additions & 0 deletions curvefs/src/client/common/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,11 @@ enum class FileHandle : uint64_t {
kKeepCache = 1,
};

enum class NlinkChange : int32_t {
kAddOne = 1,
kSubOne = -1,
};

} // namespace common
} // namespace client
} // namespace curvefs
Expand Down
25 changes: 13 additions & 12 deletions curvefs/src/client/fuse_client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -565,8 +565,8 @@ CURVEFS_ERROR FuseClient::FuseOpOpen(fuse_req_t req, fuse_ino_t ino,
return ret;
}

CURVEFS_ERROR FuseClient::UpdateParentInodeMCTimeAndInvalidNlink(
fuse_ino_t parent, FsFileType type) {
CURVEFS_ERROR FuseClient::UpdateParentMCTimeAndNlink(
fuse_ino_t parent, FsFileType type, NlinkChange nlink) {
std::shared_ptr<InodeWrapper> parentInodeWrapper;
auto ret = inodeManager_->GetInode(parent, parentInodeWrapper);
if (ret != CURVEFS_ERROR::OK) {
Expand All @@ -580,9 +580,10 @@ CURVEFS_ERROR FuseClient::UpdateParentInodeMCTimeAndInvalidNlink(
parentInodeWrapper->UpdateTimestampLocked(kModifyTime | kChangeTime);

if (FsFileType::TYPE_DIRECTORY == type) {
parentInodeWrapper->InvalidateNlink();
parentInodeWrapper->UpdateNlinkLocked(nlink);
}
}
inodeManager_->ShipToFlush(parentInodeWrapper);
return CURVEFS_ERROR::OK;
}

Expand Down Expand Up @@ -647,9 +648,9 @@ CURVEFS_ERROR FuseClient::MakeNode(fuse_req_t req, fuse_ino_t parent,
return ret;
}

ret = UpdateParentInodeMCTimeAndInvalidNlink(parent, type);
ret = UpdateParentMCTimeAndNlink(parent, type, NlinkChange::kAddOne);
if (ret != CURVEFS_ERROR::OK) {
LOG(ERROR) << "UpdateParentInodeMCTimeAndInvalidNlink failed"
LOG(ERROR) << "UpdateParentMCTimeAndNlink failed"
<< ", parent: " << parent
<< ", name: " << name
<< ", type: " << type;
Expand Down Expand Up @@ -738,9 +739,9 @@ CURVEFS_ERROR FuseClient::RemoveNode(fuse_req_t req, fuse_ino_t parent,
return ret;
}

ret = UpdateParentInodeMCTimeAndInvalidNlink(parent, type);
ret = UpdateParentMCTimeAndNlink(parent, type, NlinkChange::kSubOne);
if (ret != CURVEFS_ERROR::OK) {
LOG(ERROR) << "UpdateParentInodeMCTimeAndInvalidNlink failed"
LOG(ERROR) << "UpdateParentMCTimeAndNlink failed"
<< ", parent: " << parent
<< ", name: " << name
<< ", type: " << type;
Expand Down Expand Up @@ -1249,10 +1250,10 @@ CURVEFS_ERROR FuseClient::FuseOpSymlink(fuse_req_t req, const char *link,
return ret;
}

ret = UpdateParentInodeMCTimeAndInvalidNlink(
parent, FsFileType::TYPE_SYM_LINK);
ret = UpdateParentMCTimeAndNlink(parent, FsFileType::TYPE_SYM_LINK,
NlinkChange::kAddOne);
if (ret != CURVEFS_ERROR::OK) {
LOG(ERROR) << "UpdateParentInodeMCTimeAndInvalidNlink failed"
LOG(ERROR) << "UpdateParentMCTimeAndNlink failed"
<< ", link:" << link
<< ", parent: " << parent
<< ", name: " << name
Expand Down Expand Up @@ -1321,9 +1322,9 @@ CURVEFS_ERROR FuseClient::FuseOpLink(fuse_req_t req, fuse_ino_t ino,
return ret;
}

ret = UpdateParentInodeMCTimeAndInvalidNlink(newparent, type);
ret = UpdateParentMCTimeAndNlink(newparent, type, NlinkChange::kAddOne);
if (ret != CURVEFS_ERROR::OK) {
LOG(ERROR) << "UpdateParentInodeMCTimeAndInvalidNlink failed"
LOG(ERROR) << "UpdateParentMCTimeAndNlink failed"
<< ", parent: " << newparent
<< ", name: " << newname
<< ", type: " << type;
Expand Down
4 changes: 2 additions & 2 deletions curvefs/src/client/fuse_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -348,8 +348,8 @@ class FuseClient {

virtual void FlushData() = 0;

CURVEFS_ERROR UpdateParentInodeMCTimeAndInvalidNlink(
fuse_ino_t parent, FsFileType type);
CURVEFS_ERROR UpdateParentMCTimeAndNlink(
fuse_ino_t parent, FsFileType type, NlinkChange nlink);

void WarmUpTask();

Expand Down
49 changes: 46 additions & 3 deletions curvefs/src/client/inode_wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,14 @@ using rpcclient::DataIndices;

bvar::Adder<int64_t> g_alive_inode_count{"alive_inode_count"};

#define REFRESH_NLINK \
do { \
CURVEFS_ERROR ret = RefreshNlink(); \
if (ret != CURVEFS_ERROR::OK) { \
return ret; \
} \
} while (0)

std::ostream &operator<<(std::ostream &os, const struct stat &attr) {
os << "{ st_ino = " << attr.st_ino << ", st_mode = " << attr.st_mode
<< ", st_nlink = " << attr.st_nlink << ", st_uid = " << attr.st_uid
Expand Down Expand Up @@ -136,6 +144,42 @@ class GetOrModifyS3ChunkInfoAsyncDone : public MetaServerClientDone {
std::shared_ptr<InodeWrapper> inodeWrapper_;
};

CURVEFS_ERROR InodeWrapper::GetInodeAttrLocked(InodeAttr *attr) {
attr->set_inodeid(inode_.inodeid());
attr->set_fsid(inode_.fsid());
attr->set_length(inode_.length());
attr->set_ctime(inode_.ctime());
attr->set_ctime_ns(inode_.ctime_ns());
attr->set_mtime(inode_.mtime());
attr->set_mtime_ns(inode_.mtime_ns());
attr->set_atime(inode_.atime());
attr->set_atime_ns(inode_.atime_ns());
attr->set_uid(inode_.uid());
attr->set_gid(inode_.gid());
attr->set_mode(inode_.mode());
attr->set_nlink(inode_.nlink());
attr->set_type(inode_.type());
*(attr->mutable_parent()) = inode_.parent();
if (inode_.has_symlink()) {
attr->set_symlink(inode_.symlink());
}
if (inode_.has_rdev()) {
attr->set_rdev(inode_.rdev());
}
if (inode_.has_dtime()) {
attr->set_dtime(inode_.dtime());
}
if (inode_.xattr_size() > 0) {
*(attr->mutable_xattr()) = inode_.xattr();
}
return CURVEFS_ERROR::OK;
}

void InodeWrapper::GetInodeAttr(InodeAttr *attr) {
curve::common::UniqueLock lg(mtx_);
GetInodeAttrLocked(attr);
}

CURVEFS_ERROR InodeWrapper::SyncAttr(bool internal) {
curve::common::UniqueLock lock = GetSyncingInodeUniqueLock();
if (dirty_) {
Expand Down Expand Up @@ -263,7 +307,7 @@ CURVEFS_ERROR InodeWrapper::RefreshS3ChunkInfo() {

CURVEFS_ERROR InodeWrapper::Link(uint64_t parent) {
curve::common::UniqueLock lg(mtx_);
REFRESH_NLINK_IF_NEED;
REFRESH_NLINK;
uint32_t old = inode_.nlink();
inode_.set_nlink(old + 1);
dirtyAttr_.set_nlink(inode_.nlink());
Expand Down Expand Up @@ -294,7 +338,7 @@ CURVEFS_ERROR InodeWrapper::Link(uint64_t parent) {

CURVEFS_ERROR InodeWrapper::UnLink(uint64_t parent) {
curve::common::UniqueLock lg(mtx_);
REFRESH_NLINK_IF_NEED;
REFRESH_NLINK;
uint32_t old = inode_.nlink();
VLOG(1) << "Unlink inode = " << inode_.DebugString();
if (old > 0) {
Expand Down Expand Up @@ -567,7 +611,6 @@ CURVEFS_ERROR InodeWrapper::RefreshNlink() {
}
inode_.set_nlink(attr.nlink());
VLOG(3) << "RefreshNlink from metaserver, newnlink: " << attr.nlink();
ResetNlinkValid();
return CURVEFS_ERROR::OK;
}

Expand Down
73 changes: 11 additions & 62 deletions curvefs/src/client/inode_wrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,6 @@ constexpr int kAccessTime = 1 << 0;
constexpr int kChangeTime = 1 << 1;
constexpr int kModifyTime = 1 << 2;

#define REFRESH_NLINK_IF_NEED \
do { \
if (!isNlinkValid_) { \
CURVEFS_ERROR ret = RefreshNlink(); \
if (ret != CURVEFS_ERROR::OK) { \
return ret; \
} \
} \
} while (0)

using ::curvefs::metaserver::VolumeExtentList;

enum class InodeStatus {
Expand All @@ -76,6 +66,7 @@ using rpcclient::MetaServerClient;
using rpcclient::MetaServerClientImpl;
using rpcclient::MetaServerClientDone;
using metric::S3ChunkInfoMetric;
using common::NlinkChange;

std::ostream &operator<<(std::ostream &os, const struct stat &attr);
void AppendS3ChunkInfoToMap(uint64_t chunkIndex, const S3ChunkInfo &info,
Expand All @@ -96,7 +87,6 @@ class InodeWrapper : public std::enable_shared_from_this<InodeWrapper> {
maxDataSize_(maxDataSize),
refreshDataInterval_(refreshDataInterval),
lastRefreshTime_(::curve::common::TimeUtility::GetTimeofDaySec()),
isNlinkValid_(true),
s3ChunkInfoAddSize_(0),
metaClient_(std::move(metaClient)),
s3ChunkInfoMetric_(std::move(s3ChunkInfoMetric)),
Expand Down Expand Up @@ -196,43 +186,9 @@ class InodeWrapper : public std::enable_shared_from_this<InodeWrapper> {
void MergeXAttrLocked(
const google::protobuf::Map<std::string, std::string>& xattrs);

CURVEFS_ERROR GetInodeAttrLocked(InodeAttr *attr) {
REFRESH_NLINK_IF_NEED;

attr->set_inodeid(inode_.inodeid());
attr->set_fsid(inode_.fsid());
attr->set_length(inode_.length());
attr->set_ctime(inode_.ctime());
attr->set_ctime_ns(inode_.ctime_ns());
attr->set_mtime(inode_.mtime());
attr->set_mtime_ns(inode_.mtime_ns());
attr->set_atime(inode_.atime());
attr->set_atime_ns(inode_.atime_ns());
attr->set_uid(inode_.uid());
attr->set_gid(inode_.gid());
attr->set_mode(inode_.mode());
attr->set_nlink(inode_.nlink());
attr->set_type(inode_.type());
*(attr->mutable_parent()) = inode_.parent();
if (inode_.has_symlink()) {
attr->set_symlink(inode_.symlink());
}
if (inode_.has_rdev()) {
attr->set_rdev(inode_.rdev());
}
if (inode_.has_dtime()) {
attr->set_dtime(inode_.dtime());
}
if (inode_.xattr_size() > 0) {
*(attr->mutable_xattr()) = inode_.xattr();
}
return CURVEFS_ERROR::OK;
}
CURVEFS_ERROR GetInodeAttrLocked(InodeAttr *attr);

void GetInodeAttr(InodeAttr *attr) {
curve::common::UniqueLock lg(mtx_);
GetInodeAttrLocked(attr);
}
void GetInodeAttr(InodeAttr *attr);

XAttr GetXattr() const {
XAttr ret;
Expand All @@ -254,19 +210,6 @@ class InodeWrapper : public std::enable_shared_from_this<InodeWrapper> {

CURVEFS_ERROR UnLink(uint64_t parent = 0);

// mark nlink invalid, need to refresh from metaserver
void InvalidateNlink() {
isNlinkValid_ = false;
}

void ResetNlinkValid() {
isNlinkValid_ = true;
}

bool IsNlinkValid() {
return isNlinkValid_;
}

CURVEFS_ERROR RefreshNlink();

CURVEFS_ERROR Sync(bool internal = false);
Expand Down Expand Up @@ -312,6 +255,14 @@ class InodeWrapper : public std::enable_shared_from_this<InodeWrapper> {
return s3ChunkInfoAdd_.empty();
}

uint32_t GetNlinkLocked() {
return inode_.nlink();
}

void UpdateNlinkLocked(NlinkChange nlink) {
inode_.set_nlink(inode_.nlink() + static_cast<int32_t>(nlink));
}

void AppendS3ChunkInfo(uint64_t chunkIndex, const S3ChunkInfo &info) {
curve::common::UniqueLock lg(mtx_);
AppendS3ChunkInfoToMap(chunkIndex, info, &s3ChunkInfoAdd_);
Expand Down Expand Up @@ -438,8 +389,6 @@ class InodeWrapper : public std::enable_shared_from_this<InodeWrapper> {
uint32_t refreshDataInterval_;
uint64_t lastRefreshTime_;

bool isNlinkValid_;

google::protobuf::Map<uint64_t, S3ChunkInfoList> s3ChunkInfoAdd_;
int64_t s3ChunkInfoAddSize_;
int64_t s3ChunkInfoSize_;
Expand Down
7 changes: 0 additions & 7 deletions curvefs/src/metaserver/inode_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -460,13 +460,6 @@ MetaStatusCode InodeManager::UpdateInodeWhenCreateOrRemoveSubNode(
}
}

struct timespec now;
clock_gettime(CLOCK_REALTIME, &now);
inode.set_ctime(now.tv_sec);
inode.set_ctime_ns(now.tv_nsec);
inode.set_mtime(now.tv_sec);
inode.set_mtime_ns(now.tv_nsec);

ret = inodeStorage_->Update(inode);
if (ret != MetaStatusCode::OK) {
LOG(ERROR) << "UpdateInode fail, " << inode.ShortDebugString()
Expand Down
Loading

0 comments on commit bab48e0

Please sign in to comment.