Skip to content

Commit

Permalink
curvefs: implement setxattr interface.
Browse files Browse the repository at this point in the history
Signed-off-by: wanghai01 <seanhaizi@163.com>
  • Loading branch information
SeanHai committed Sep 23, 2022
1 parent ed8d569 commit 5bc8e32
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 3 deletions.
11 changes: 8 additions & 3 deletions curvefs/src/client/curve_fuse_op.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -322,17 +322,22 @@ int Warmup(const std::string& name, const std::string& value) {

void FuseOpSetXattr(fuse_req_t req, fuse_ino_t ino, const char* name,
const char* value, size_t size, int flags) {
// only support "curvefs.warmup.op" xattr
std::string xattrValue(value, size);
VLOG(9) << "FuseOpSetXattr"
<< " ino " << ino << " name " << name << " value " << xattrValue
<< " flags " << flags;
int code = ENOTSUP;
int code = 0;
if (strcmp(name, curvefs::client::common::kCurveFsWarmupXAttr) == 0) {
// warmup
code = Warmup(name, xattrValue);
fuse_reply_err(req, code);
} else {
// set xattr
CURVEFS_ERROR ret = g_ClientInstance->FuseOpSetXattr(req, ino, name,
value, size, flags);
FuseReplyErrByErrCode(req, ret);
}
fuse_reply_err(req, code);

VLOG(9) << "FuseOpSetXattr done";
}

Expand Down
35 changes: 35 additions & 0 deletions curvefs/src/client/fuse_client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1156,6 +1156,41 @@ CURVEFS_ERROR FuseClient::FuseOpGetXattr(fuse_req_t req, fuse_ino_t ino,
return ret;
}

CURVEFS_ERROR FuseClient::FuseOpSetXattr(fuse_req_t req, fuse_ino_t ino,
const char* name, const char* value,
size_t size, int flags) {
if (option_.disableXattr) {
return CURVEFS_ERROR::NOTSUPPORT;
}

std::string strname(name);
std::string strvalue(value, size);
if (strname.length() > MAXXATTRLENGTH || size > MAXXATTRLENGTH) {
LOG(ERROR) << "xattr length is too long, name = " << name
<< ", name length = " << strname.length()
<< ", value length = " << size;
return CURVEFS_ERROR::OUT_OF_RANGE;
}

std::shared_ptr<InodeWrapper> inodeWrapper;
CURVEFS_ERROR ret = inodeManager_->GetInode(ino, inodeWrapper);
if (ret != CURVEFS_ERROR::OK) {
LOG(ERROR) << "inodeManager get inode fail, ret = " << ret
<< ", inodeid = " << ino;
return ret;
}

::curve::common::UniqueLock lgGuard = inodeWrapper->GetUniqueLock();
inodeWrapper->SetXattrLocked(strname, strvalue);
ret = inodeWrapper->SyncAttr();
if (ret != CURVEFS_ERROR::OK) {
LOG(ERROR) << "set xattr fail, ret = " << ret << ", inodeid = " << ino
<< ", name = " << strname << ", value = " << strvalue;
return ret;
}
return CURVEFS_ERROR::OK;
}

CURVEFS_ERROR FuseClient::FuseOpListXattr(fuse_req_t req, fuse_ino_t ino,
char *value, size_t size, size_t *realSize) {
VLOG(1) << "FuseOpListXattr, ino: " << ino << ", size = " << size;
Expand Down
4 changes: 4 additions & 0 deletions curvefs/src/client/fuse_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,10 @@ class FuseClient {
const char* name, void* value,
size_t size);

virtual CURVEFS_ERROR FuseOpSetXattr(fuse_req_t req, fuse_ino_t ino,
const char* name, const char* value,
size_t size, int flags);

virtual CURVEFS_ERROR FuseOpListXattr(fuse_req_t req, fuse_ino_t ino,
char *value, size_t size, size_t *realSize);

Expand Down
6 changes: 6 additions & 0 deletions curvefs/src/client/inode_wrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,12 @@ class InodeWrapper : public std::enable_shared_from_this<InodeWrapper> {
return ret;
}

void SetXattrLocked(const std::string &key, const std::string &value) {
(*inode_.mutable_xattr())[key] = value;
(*dirtyAttr_.mutable_xattr()) = inode_.xattr();
dirty_ = true;
}

curve::common::UniqueLock GetUniqueLock() {
return curve::common::UniqueLock(mtx_);
}
Expand Down
53 changes: 53 additions & 0 deletions curvefs/test/client/test_fuse_client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3484,5 +3484,58 @@ TEST_F(TestFuseS3Client, FuseOpListXattr) {
ASSERT_EQ(CURVEFS_ERROR::OK, ret);
}

TEST_F(TestFuseS3Client, FuseOpSetXattr_TooLong) {
// in
fuse_req_t req;
fuse_ino_t ino = 1;
const char name[] = "security.selinux";
size_t size = 300;
char value[300];
std::memset(value, 0, 300);

CURVEFS_ERROR ret = client_->FuseOpSetXattr(
req, ino, name, value, size, 0);
ASSERT_EQ(CURVEFS_ERROR::OUT_OF_RANGE, ret);
}

TEST_F(TestFuseS3Client, FuseOpSetXattr) {
// in
fuse_req_t req;
fuse_ino_t ino = 1;
const char name[] = "security.selinux";
size_t size = 100;
char value[100];
std::memset(value, 0, 100);

// get inode failed
EXPECT_CALL(*inodeManager_, GetInode(ino, _))
.WillOnce(Return(CURVEFS_ERROR::INTERNAL));
CURVEFS_ERROR ret = client_->FuseOpSetXattr(
req, ino, name, value, size, 0);
ASSERT_EQ(CURVEFS_ERROR::INTERNAL, ret);

// updateInode failed
auto inodeWrapper = std::make_shared<InodeWrapper>(Inode(), metaClient_);
EXPECT_CALL(*inodeManager_, GetInode(ino, _))
.WillOnce(
DoAll(SetArgReferee<1>(inodeWrapper), Return(CURVEFS_ERROR::OK)));
EXPECT_CALL(*metaClient_, UpdateInodeAttrWithOutNlink(_, _, _, _, _))
.WillOnce(Return(MetaStatusCode::NOT_FOUND));
ret = client_->FuseOpSetXattr(
req, ino, name, value, size, 0);
ASSERT_EQ(CURVEFS_ERROR::NOTEXIST, ret);

// success
EXPECT_CALL(*inodeManager_, GetInode(ino, _))
.WillOnce(
DoAll(SetArgReferee<1>(inodeWrapper), Return(CURVEFS_ERROR::OK)));
EXPECT_CALL(*metaClient_, UpdateInodeAttrWithOutNlink(_, _, _, _, _))
.WillOnce(Return(MetaStatusCode::OK));
ret = client_->FuseOpSetXattr(
req, ino, name, value, size, 0);
ASSERT_EQ(CURVEFS_ERROR::OK, ret);
}


} // namespace client
} // namespace curvefs
8 changes: 8 additions & 0 deletions curvefs/test/client/test_inodeWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -333,5 +333,13 @@ TEST_F(TestInodeWrapper, TestUpdateInodeAttrIncrementally) {
ASSERT_FALSE(wrapper.dirtyAttr_.has_atime_ns());
}

TEST_F(TestInodeWrapper, TestSetXattr) {
inodeWrapper_->SetXattrLocked("name", "value");
XAttr xattr = inodeWrapper_->GetXattr();
ASSERT_TRUE(xattr.xattrinfos().find("name") != xattr.xattrinfos().end());
ASSERT_TRUE((*xattr.mutable_xattrinfos())["name"] == "value");
ASSERT_TRUE(inodeWrapper_->IsDirty());
}

} // namespace client
} // namespace curvefs

0 comments on commit 5bc8e32

Please sign in to comment.