Skip to content

Commit 27ef5ab

Browse files
chuandewrock-git
authored andcommitted
[refactor][vfs] Add trace in read and cache slices/attr in chunk reader
1 parent 26dc1e2 commit 27ef5ab

26 files changed

+555
-132
lines changed

src/client/vfs/const.h renamed to src/client/const.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,12 @@
2121

2222
namespace dingofs {
2323
namespace client {
24-
namespace vfs {
2524

2625
// module name
2726
static const std::string kVFSMoudule = "vfs";
27+
static const std::string kVFSWrapperMoudule = "vfs_wrapper";
2828
static const std::string kVFSDataMoudule = "vfs_data";
2929

30-
} // namespace vfs
3130
} // namespace client
3231
} // namespace dingofs
3332

src/client/vfs/data/file.cc

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,11 @@
2222
#include <mutex>
2323
#include <utility>
2424

25-
#include "client/common/utils.h"
26-
#include "client/vfs/data/chunk.h"
2725
#include "client/vfs/data/common/async_util.h"
2826
#include "client/vfs/hub/vfs_hub.h"
2927
#include "common/callback.h"
3028
#include "common/status.h"
31-
#include "options/client/vfs/vfs_option.h"
29+
#include "trace/context.h"
3230

3331
namespace dingofs {
3432
namespace client {
@@ -57,13 +55,17 @@ Status File::Write(const char* buf, uint64_t size, uint64_t offset,
5755
uint64_t* out_wsize) {
5856
DINGOFS_RETURN_NOT_OK(PreCheck());
5957

60-
return file_writer_->Write(buf, size, offset, out_wsize);
58+
Status s = file_writer_->Write(buf, size, offset, out_wsize);
59+
if (s.ok()) {
60+
file_reader_->Invalidate();
61+
}
62+
return s;
6163
}
6264

63-
Status File::Read(char* buf, uint64_t size, uint64_t offset,
65+
Status File::Read(ContextSPtr ctx, char* buf, uint64_t size, uint64_t offset,
6466
uint64_t* out_rsize) {
6567
DINGOFS_RETURN_NOT_OK(PreCheck());
66-
return file_reader_->Read(buf, size, offset, out_rsize);
68+
return file_reader_->Read(ctx, buf, size, offset, out_rsize);
6769
}
6870

6971
void File::FileFlushed(StatusCallback cb, Status status) {

src/client/vfs/data/file.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,18 +35,19 @@ class VFSHub;
3535

3636
class File : public IFile {
3737
public:
38-
File(VFSHub* hub, uint64_t ino)
38+
File(VFSHub* hub, uint64_t fh, int64_t ino)
3939
: vfs_hub_(hub),
40+
fh_(fh),
4041
ino_(ino),
41-
file_writer_(std::make_unique<FileWriter>(hub, ino)),
42-
file_reader_(std::make_unique<FileReader>(hub, ino)) {}
42+
file_writer_(std::make_unique<FileWriter>(hub, fh_, ino)),
43+
file_reader_(std::make_unique<FileReader>(hub, fh_, ino)) {}
4344

4445
~File() override = default;
4546

4647
Status Write(const char* buf, uint64_t size, uint64_t offset,
4748
uint64_t* out_wsize) override;
4849

49-
Status Read(char* buf, uint64_t size, uint64_t offset,
50+
Status Read(ContextSPtr ctx, char* buf, uint64_t size, uint64_t offset,
5051
uint64_t* out_rsize) override;
5152

5253
Status Flush() override;
@@ -59,6 +60,7 @@ class File : public IFile {
5960
void FileFlushed(StatusCallback cb, Status status);
6061

6162
VFSHub* vfs_hub_;
63+
const uint64_t fh_;
6264
const uint64_t ino_;
6365

6466
FileWriterUPtr file_writer_;

src/client/vfs/data/ifile.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
#include "common/callback.h"
2323
#include "common/status.h"
24+
#include "trace/context.h"
2425

2526
namespace dingofs {
2627
namespace client {
@@ -33,7 +34,7 @@ class IFile {
3334
virtual Status Write(const char* buf, uint64_t size, uint64_t offset,
3435
uint64_t* out_wsize) = 0;
3536

36-
virtual Status Read(char* buf, uint64_t size,
37+
virtual Status Read(ContextSPtr ctx, char* buf, uint64_t size,
3738
uint64_t offset, uint64_t* out_rsize) = 0;
3839

3940
virtual Status Flush() = 0;

src/client/vfs/data/reader/chunk_reader.cc

Lines changed: 119 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -18,33 +18,42 @@
1818

1919
#include <glog/logging.h>
2020

21+
#include <atomic>
2122
#include <cstdint>
2223
#include <functional>
24+
#include <memory>
25+
#include <utility>
2326
#include <vector>
2427

2528
#include "cache/utils/context.h"
2629
#include "client/common/utils.h"
27-
#include "client/vfs/const.h"
30+
#include "client/const.h"
2831
#include "client/vfs/data/common/common.h"
2932
#include "client/vfs/data/common/data_utils.h"
3033
#include "client/vfs/data/reader/reader_common.h"
3134
#include "client/vfs/hub/vfs_hub.h"
3235
#include "common/status.h"
3336
#include "options/client/vfs/vfs_dynamic_option.h"
34-
#include "trace/tracer.h"
37+
#include "trace/context.h"
3538

3639
namespace dingofs {
3740
namespace client {
3841
namespace vfs {
3942

40-
ChunkReader::ChunkReader(VFSHub* hub, uint64_t ino, uint64_t index)
43+
#define METHOD_NAME() ("ChunkReader::" + std::string(__FUNCTION__))
44+
45+
ChunkReader::ChunkReader(VFSHub* hub, uint64_t fh, uint64_t ino, uint64_t index)
4146
: hub_(hub),
47+
fh_(fh),
4248
chunk_(hub->GetFsInfo().id, ino, index, hub->GetFsInfo().chunk_size,
4349
hub->GetFsInfo().block_size, hub->GetPageSize()) {}
4450

45-
void ChunkReader::BlockReadCallback(ChunkReader* reader,
51+
void ChunkReader::BlockReadCallback(ContextSPtr ctx, ChunkReader* reader,
4652
const BlockCacheReadReq& req,
4753
ReaderSharedState& shared, Status s) {
54+
auto span = reader->hub_->GetTracer()->StartSpanWithContext(
55+
kVFSDataMoudule, METHOD_NAME(), ctx);
56+
4857
if (!s.ok()) {
4958
LOG(WARNING) << fmt::format(
5059
"{} ChunkReader fail read block_key: {}, buf_pos: {}, block_req: {} "
@@ -60,11 +69,16 @@ void ChunkReader::BlockReadCallback(ChunkReader* reader,
6069
}
6170

6271
{
63-
std::lock_guard<std::mutex> lock(shared.mtx);
64-
72+
auto copy_span = reader->hub_->GetTracer()->StartSpanWithParent(
73+
kVFSDataMoudule, "ChunkReader::BlockReadCallback.IoBufferCopy", *span);
6574
if (s.ok()) {
6675
req.io_buffer.CopyTo(req.buf_pos);
67-
} else {
76+
}
77+
}
78+
79+
{
80+
std::lock_guard<std::mutex> lock(shared.mtx);
81+
if (!s.ok()) {
6882
// Handle read failure with error priority: other errors > NotFound
6983
if (shared.status.ok()) {
7084
// First error, record it directly
@@ -83,13 +97,17 @@ void ChunkReader::BlockReadCallback(ChunkReader* reader,
8397
}
8498
}
8599

86-
void ChunkReader::ReadAsync(const ChunkReadReq& req, StatusCallback cb) {
87-
hub_->GetReadExecutor()->Execute([this, &req, cb]() { DoRead(req, cb); });
100+
void ChunkReader::ReadAsync(ContextSPtr ctx, const ChunkReadReq& req,
101+
StatusCallback cb) {
102+
hub_->GetReadExecutor()->Execute(
103+
[this, ctx, &req, cb]() { DoRead(ctx, req, cb); });
88104
}
89105

90-
void ChunkReader::DoRead(const ChunkReadReq& req, StatusCallback cb) {
91-
// TODO: get ctx from parent
92-
auto span = hub_->GetTracer()->StartSpan(kVFSDataMoudule, __func__);
106+
void ChunkReader::DoRead(ContextSPtr ctx, const ChunkReadReq& req,
107+
StatusCallback cb) {
108+
auto* tracer = hub_->GetTracer();
109+
auto span = tracer->StartSpanWithContext(kVFSDataMoudule, METHOD_NAME(), ctx);
110+
93111
uint64_t chunk_offset = req.offset;
94112
uint64_t size = req.to_read_size;
95113
char* buf = req.buf;
@@ -112,36 +130,46 @@ void ChunkReader::DoRead(const ChunkReadReq& req, StatusCallback cb) {
112130
do {
113131
uint64_t remain_len = size;
114132

115-
std::vector<Slice> slices;
116-
Status s = hub_->GetMetaSystem()->ReadSlice(span->GetContext(), chunk_.ino,
117-
chunk_.index, 0, &slices);
133+
ChunkSlices chunk_slices;
134+
Status s = GetSlices(span->GetContext(), &chunk_slices);
118135
if (!s.ok()) {
119-
LOG(WARNING) << fmt::format("{} Read slice failed, status: {}", UUID(),
136+
LOG(WARNING) << fmt::format("{} Failed GetSlices, status: {}", UUID(),
120137
s.ToString());
121138
cb(s);
122139
}
123140

141+
std::vector<SliceReadReq> slice_reqs;
124142
FileRange range{.offset = read_file_offset, .len = size};
125-
std::vector<SliceReadReq> slice_reqs = ProcessReadRequest(slices, range);
143+
{
144+
auto process_slice_reqs_span = tracer->StartSpanWithParent(
145+
kVFSDataMoudule, "ChunkReader::DoRead.ProcessReadRequest", *span);
146+
slice_reqs = ProcessReadRequest(chunk_slices.slices, range);
147+
}
126148

127149
std::vector<BlockReadReq> block_reqs;
128150

129-
for (auto& slice_req : slice_reqs) {
130-
VLOG(6) << "{} Read slice_req: " << slice_req.ToString();
131-
132-
if (slice_req.slice.has_value() && !slice_req.slice.value().is_zero) {
133-
std::vector<BlockReadReq> reqs = ConvertSliceReadReqToBlockReadReqs(
134-
slice_req, chunk_.fs_id, chunk_.ino, chunk_.chunk_size,
135-
chunk_.block_size);
136-
137-
block_reqs.insert(block_reqs.end(),
138-
std::make_move_iterator(reqs.begin()),
139-
std::make_move_iterator(reqs.end()));
140-
} else {
141-
char* buf_pos = buf + (slice_req.file_offset - read_file_offset);
142-
VLOG(6) << fmt::format("{} Read buf: {}, zero fill, read_size: {}",
143-
UUID(), Char2Addr(buf_pos), slice_req.len);
144-
memset(buf_pos, 0, slice_req.len);
151+
{
152+
auto slice_req_to_block_req_span = tracer->StartSpanWithParent(
153+
kVFSDataMoudule,
154+
"ChunkReader::DoRead.ConvertSliceReadReqToBlockReadReqs", *span);
155+
156+
for (auto& slice_req : slice_reqs) {
157+
VLOG(6) << "{} Read slice_req: " << slice_req.ToString();
158+
159+
if (slice_req.slice.has_value() && !slice_req.slice.value().is_zero) {
160+
std::vector<BlockReadReq> reqs = ConvertSliceReadReqToBlockReadReqs(
161+
slice_req, chunk_.fs_id, chunk_.ino, chunk_.chunk_size,
162+
chunk_.block_size);
163+
164+
block_reqs.insert(block_reqs.end(),
165+
std::make_move_iterator(reqs.begin()),
166+
std::make_move_iterator(reqs.end()));
167+
} else {
168+
char* buf_pos = buf + (slice_req.file_offset - read_file_offset);
169+
VLOG(6) << fmt::format("{} Read buf: {}, zero fill, read_size: {}",
170+
UUID(), Char2Addr(buf_pos), slice_req.len);
171+
memset(buf_pos, 0, slice_req.len);
172+
}
145173
}
146174
}
147175

@@ -176,13 +204,20 @@ void ChunkReader::DoRead(const ChunkReadReq& req, StatusCallback cb) {
176204
shared.status = Status::OK();
177205

178206
for (auto& block_cache_req : block_cache_reqs) {
207+
auto block_cache_range_span = tracer->StartSpanWithParent(
208+
kVFSDataMoudule, "ChunkReader::DoRead.AsyncRange", *span);
209+
210+
auto callback = [this, &span, &block_cache_req, &shared,
211+
span_ptr = block_cache_range_span.release()](Status s) {
212+
std::unique_ptr<ITraceSpan> block_cache_range_span(span_ptr);
213+
block_cache_range_span->End();
214+
BlockReadCallback(span->GetContext(), this, block_cache_req, shared, s);
215+
};
216+
179217
hub_->GetBlockCache()->AsyncRange(
180218
cache::NewContext(), block_cache_req.key,
181219
block_cache_req.block_req.block_offset, block_cache_req.block_req.len,
182-
&block_cache_req.io_buffer,
183-
[this, &block_cache_req, &shared](Status s) {
184-
BlockReadCallback(this, block_cache_req, shared, s);
185-
},
220+
&block_cache_req.io_buffer, std::move(callback),
186221
block_cache_req.option);
187222
}
188223

@@ -201,6 +236,9 @@ void ChunkReader::DoRead(const ChunkReadReq& req, StatusCallback cb) {
201236
UUID(), ret.ToString(), retry, chunk_offset, end_read_chunk_offet,
202237
read_file_offset, end_read_file_offset);
203238

239+
if (ret.IsNotFound()) {
240+
InvalidateSlices(chunk_slices.version);
241+
}
204242
} while (ret.IsNotFound() &&
205243
retry++ < FLAGS_vfs_read_max_retry_block_not_found);
206244

@@ -209,6 +247,50 @@ void ChunkReader::DoRead(const ChunkReadReq& req, StatusCallback cb) {
209247
cb(ret);
210248
}
211249

250+
void ChunkReader::Invalidate() {
251+
VLOG(4) << fmt::format("{} Invalidate, cversion: {}", UUID(),
252+
cversion_.load(std::memory_order_relaxed));
253+
std::lock_guard<std::mutex> lg(mutex_);
254+
cversion_ = kInvalidVersion;
255+
slices_.clear();
256+
}
257+
258+
Status ChunkReader::GetSlices(ContextSPtr ctx, ChunkSlices* chunk_slices) {
259+
auto* tracer = hub_->GetTracer();
260+
auto span = tracer->StartSpanWithContext(kVFSDataMoudule, METHOD_NAME(), ctx);
261+
262+
std::lock_guard<std::mutex> lg(mutex_);
263+
if (cversion_ == kInvalidVersion) {
264+
auto slice_span = tracer->StartSpanWithParent(
265+
kVFSDataMoudule, "ChunkReader::GetSlices.ReadSlice", *span);
266+
267+
std::vector<Slice> slices;
268+
DINGOFS_RETURN_NOT_OK(hub_->GetMetaSystem()->ReadSlice(
269+
slice_span->GetContext(), chunk_.ino, chunk_.index, 0, &slices));
270+
271+
cversion_.store(next_version_, std::memory_order_relaxed);
272+
slices_ = std::move(slices);
273+
274+
next_version_++;
275+
}
276+
277+
chunk_slices->version = cversion_;
278+
chunk_slices->slices = slices_;
279+
280+
return Status::OK();
281+
}
282+
283+
void ChunkReader::InvalidateSlices(uint32_t version) {
284+
VLOG(4) << fmt::format("{} InvalidateSlices, version: {}, cversion: {}",
285+
UUID(), version,
286+
cversion_.load(std::memory_order_relaxed));
287+
std::lock_guard<std::mutex> lg(mutex_);
288+
if (cversion_ <= version) {
289+
cversion_ = kInvalidVersion;
290+
slices_.clear();
291+
}
292+
}
293+
212294
} // namespace vfs
213295

214296
} // namespace client

0 commit comments

Comments
 (0)