Skip to content

Commit

Permalink
curve-fuse: fix SEGV when creating partition concurrently
Browse files Browse the repository at this point in the history
Signed-off-by: Hanqing Wu <[email protected]>
  • Loading branch information
wu-hanqing committed Jun 30, 2022
1 parent 1d164c2 commit c9d6500
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 25 deletions.
7 changes: 4 additions & 3 deletions curvefs/src/client/rpcclient/mds_client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -304,10 +304,11 @@ bool MdsClientImpl::CreatePartition(
return TopoStatusCode::TOPO_CREATE_PARTITION_FAIL;
}

partitionInfos->reserve(count);
partitionInfos->clear();
for (int i = 0; i < partitionNum; i++) {
partitionInfos->push_back(response.partitioninfolist(i));
}
std::move(response.mutable_partitioninfolist()->begin(),
response.mutable_partitioninfolist()->end(),
std::back_inserter(*partitionInfos));

return TopoStatusCode::TOPO_OK;
};
Expand Down
28 changes: 17 additions & 11 deletions curvefs/src/client/rpcclient/metacache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ bool MetaCache::SelectTarget(uint32_t fsID, CopysetTarget *target,

if (!SelectPartition(target)) {
LOG(ERROR) << "select target for {fsid:" << fsID
<< "} fail, select paritiotn fail";
<< "} fail, select partition fail";
return false;
}
}
Expand Down Expand Up @@ -254,7 +254,7 @@ bool MetaCache::ListPartitions(uint32_t fsID) {
WriteLockGuard wl4CopysetMap(rwlock4copysetInfoMap_);

fsID_ = fsID;
PatitionInfoList partitionInfos;
PartitionInfoList partitionInfos;
std::map<PoolIDCopysetID, CopysetInfo<MetaserverID>> copysetMap;
if (!DoListOrCreatePartitions(true, &partitionInfos, &copysetMap)) {
return false;
Expand All @@ -266,13 +266,17 @@ bool MetaCache::ListPartitions(uint32_t fsID) {
}

bool MetaCache::CreatePartitions(int currentNum,
PatitionInfoList *newPartitions) {
PartitionInfoList *newPartitions) {
std::lock_guard<Mutex> lg(createMutex_);

// already create
{
ReadLockGuard rl(rwlock4Partitions_);
if (partitionInfos_.size() > currentNum) {
newPartitions->reserve(partitionInfos_.size() - currentNum);
newPartitions->insert(newPartitions->end(),
partitionInfos_.begin() + currentNum,
partitionInfos_.end());
return true;
}
}
Expand All @@ -293,7 +297,7 @@ bool MetaCache::CreatePartitions(int currentNum,
}

bool MetaCache::DoListOrCreatePartitions(
bool list, PatitionInfoList *partitionInfos,
bool list, PartitionInfoList *partitionInfos,
std::map<PoolIDCopysetID, CopysetInfo<MetaserverID>> *copysetMap) {
// TODO(@lixiaocui): list or get partition need too many rpc,
// it's better to return all infos once.
Expand Down Expand Up @@ -374,7 +378,7 @@ bool MetaCache::DoListOrCreatePartitions(
}

void MetaCache::DoAddOrResetPartitionAndCopyset(
PatitionInfoList partitionInfos,
PartitionInfoList partitionInfos,
std::map<PoolIDCopysetID, CopysetInfo<MetaserverID>> copysetMap,
bool reset) {
if (reset) {
Expand Down Expand Up @@ -498,18 +502,20 @@ bool MetaCache::SelectPartition(CopysetTarget *target) {
}

if (candidate.empty()) {
// create parition for fs
// create partition for fs
LOG(INFO) << "no partition can be select for fsid:" << fsID_
<< ", need create new partitions";
PatitionInfoList newPartitions;
PartitionInfoList newPartitions;
if (!CreatePartitions(currentNum, &newPartitions)) {
LOG(ERROR) << "create partition for fsid:" << fsID_ << " fail";
return false;
}
target->groupID = CopysetGroupID(newPartitions[0].poolid(),
newPartitions[0].copysetid());
target->partitionID = newPartitions[0].partitionid();
target->txId = newPartitions[0].txid();
CHECK(!newPartitions.empty());
const auto index = butil::fast_rand() % newPartitions.size();
auto iter = newPartitions.begin() + index;
target->groupID = CopysetGroupID(iter->poolid(), iter->copysetid());
target->partitionID = iter->partitionid();
target->txId = iter->txid();
} else {
// random select a partition
const auto index = butil::fast_rand() % candidate.size();
Expand Down
17 changes: 8 additions & 9 deletions curvefs/src/client/rpcclient/metacache.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,15 +111,14 @@ class MetaCache {
public:
void Init(MetaCacheOpt opt, std::shared_ptr<Cli2Client> cli2Client,
std::shared_ptr<MdsClient> mdsClient) {
metacacheopt_ = opt;
cli2Client_ = cli2Client;
mdsClient_ = mdsClient;
metacacheopt_ = std::move(opt);
cli2Client_ = std::move(cli2Client);
mdsClient_ = std::move(mdsClient);
init_ = false;
}

using PoolIDCopysetID = uint64_t;
using PatitionInfoList = std::vector<PartitionInfo>;
using FS2PatitionInfoMap = std::unordered_map<uint32_t, PatitionInfoList>;
using PartitionInfoList = std::vector<PartitionInfo>;
using CopysetInfoMap =
std::unordered_map<PoolIDCopysetID, CopysetInfo<MetaserverID>>;

Expand Down Expand Up @@ -162,12 +161,12 @@ class MetaCache {

private:
void GetTxId(uint32_t partitionId, uint64_t *txId);
bool CreatePartitions(int currentNum, PatitionInfoList *newPartitions);
bool CreatePartitions(int currentNum, PartitionInfoList *newPartitions);
bool DoListOrCreatePartitions(
bool list, PatitionInfoList *partitionInfos,
bool list, PartitionInfoList *partitionInfos,
std::map<PoolIDCopysetID, CopysetInfo<MetaserverID>> *copysetMap);
void DoAddOrResetPartitionAndCopyset(
PatitionInfoList partitionInfos,
PartitionInfoList partitionInfos,
std::map<PoolIDCopysetID, CopysetInfo<MetaserverID>> copysetMap,
bool reset);

Expand Down Expand Up @@ -206,7 +205,7 @@ class MetaCache {
std::unordered_map<uint32_t, uint64_t> partitionTxId_;

RWLock rwlock4Partitions_;
PatitionInfoList partitionInfos_;
PartitionInfoList partitionInfos_;
RWLock rwlock4copysetInfoMap_;
CopysetInfoMap copysetInfoMap_;

Expand Down
4 changes: 2 additions & 2 deletions curvefs/test/client/rpcclient/metacache_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,8 @@ class MetaCacheTest : public testing::Test {
std::shared_ptr<MockCli2Client> mockCli2Client_;

curve::client::CopysetInfo<MetaserverID> metaServerList_;
MetaCache::PatitionInfoList pInfoList_;
MetaCache::PatitionInfoList pInfoList2_;
MetaCache::PartitionInfoList pInfoList_;
MetaCache::PartitionInfoList pInfoList2_;
std::map<PartitionID, Copyset> copysetMap_;

CopysetTarget expect;
Expand Down

0 comments on commit c9d6500

Please sign in to comment.