Skip to content

Commit 76f82d3

Browse files
committed
Addressed the review comments.
1 parent ca237c7 commit 76f82d3

File tree

6 files changed

+173
-184
lines changed

6 files changed

+173
-184
lines changed

turbonfs/inc/fcsm.h

+13-3
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,8 @@ class fcsm
9393
*/
9494
void ensure_flush(uint64_t write_off,
9595
uint64_t write_len,
96-
struct rpc_task *task = nullptr);
96+
struct rpc_task *task = nullptr,
97+
std::atomic<bool> *conditional_variable = nullptr);
9798

9899
/**
99100
* Ensure all or some commit-pending bytes are committed or scheduled for
@@ -106,7 +107,9 @@ class fcsm
106107
*/
107108
void ensure_commit(uint64_t write_off,
108109
uint64_t write_len,
109-
struct rpc_task *task = nullptr);
110+
struct rpc_task *task = nullptr,
111+
std::atomic<bool> *conditional_variable = nullptr,
112+
bool commit_full = false);
110113

111114
/**
112115
* Callbacks to be called when flush/commit successfully complete.
@@ -248,7 +251,8 @@ class fcsm
248251
fctgt(struct fcsm *fcsm,
249252
uint64_t _flush_seq,
250253
uint64_t _commit_seq,
251-
struct rpc_task *_task = nullptr);
254+
struct rpc_task *_task = nullptr,
255+
std::atomic<bool> *conditional_variable = nullptr);
252256

253257
/*
254258
* Flush and commit targets (in terms of flushed_seq_num/committed_seq_num)
@@ -267,6 +271,12 @@ class fcsm
267271
* Pointer to the containing fcsm.
268272
*/
269273
struct fcsm *const fcsm = nullptr;
274+
275+
/*
276+
* If non-null, it's initial value is false.
277+
* Caller who enqueue the target waiting for it to be true.
278+
*/
279+
std::atomic<bool> *conditional_variable = nullptr;
270280
#if 0
271281
/*
272282
* Has the required flush/commit task started?

turbonfs/inc/nfs_inode.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ struct nfs_inode
333333
* Note: As of now, we are not using this flag as commit changes not yet
334334
* integrated, so we are setting this flag to true.
335335
*/
336-
bool stable_write = true;
336+
bool stable_write = false;
337337

338338
public:
339339
/*

turbonfs/inc/rpc_stats.h

-9
Original file line numberDiff line numberDiff line change
@@ -139,9 +139,6 @@ class rpc_stats_az
139139
*/
140140
void on_rpc_issue()
141141
{
142-
// FUSE_FLUSH is never issued as an RPC task to the server. FUSE_WRITE is issued instead.
143-
assert(optype != FUSE_FLUSH);
144-
145142
assert(stamp.issue == 0);
146143
stamp.issue = get_current_usecs();
147144
assert(stamp.issue >= stamp.create);
@@ -156,9 +153,6 @@ class rpc_stats_az
156153
*/
157154
void on_rpc_cancel()
158155
{
159-
// FUSE_FLUSH is never issued as an RPC task to the server. FUSE_WRITE is issued instead.
160-
assert(optype != FUSE_FLUSH);
161-
162156
assert(stamp.issue != 0);
163157
assert((int64_t) stamp.issue <= get_current_usecs());
164158
assert(stamp.dispatch == 0);
@@ -178,9 +172,6 @@ class rpc_stats_az
178172
*/
179173
void on_rpc_complete(struct rpc_pdu *pdu, nfsstat3 status)
180174
{
181-
// FUSE_FLUSH is never issued as an RPC task to the server. FUSE_WRITE is issued instead.
182-
assert(optype != FUSE_FLUSH);
183-
184175
assert((status == NFS3ERR_RPC_ERROR) ||
185176
(nfsstat3_to_errno(status) != -ERANGE));
186177

turbonfs/src/fcsm.cpp

+84-14
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,21 @@ fcsm::fcsm(struct nfs_client *_client,
2525
fcsm::fctgt::fctgt(struct fcsm *fcsm,
2626
uint64_t _flush_seq,
2727
uint64_t _commit_seq,
28-
struct rpc_task *_task) :
28+
struct rpc_task *_task,
29+
std::atomic<bool> *_cv) :
2930
flush_seq(_flush_seq),
3031
commit_seq(_commit_seq),
3132
task(_task),
32-
fcsm(fcsm)
33+
fcsm(fcsm),
34+
conditional_variable(_cv)
3335
{
3436
assert(fcsm->magic == FCSM_MAGIC);
3537
// At least one of flush/commit goals must be set.
3638
assert((flush_seq != 0) || (commit_seq != 0));
3739

40+
// If conditional variable, it's initial value should be false.
41+
assert(!conditional_variable || *conditional_variable == false);
42+
3843
if (task) {
3944
// Only frontend write tasks must be specified.
4045
assert(task->magic == RPC_TASK_MAGIC);
@@ -43,7 +48,7 @@ fcsm::fctgt::fctgt(struct fcsm *fcsm,
4348
assert(task->rpc_api->write_task.get_size() > 0);
4449
}
4550

46-
AZLogInfo("[{}] [FCSM] {} fctgt queued (F: {}, C: {}, T: {})",
51+
AZLogDebug("[{}] [FCSM] {} fctgt queued (F: {}, C: {}, T: {})",
4752
fcsm->get_inode()->get_fuse_ino(),
4853
task ? "Blocking" : "Non-blocking",
4954
flush_seq,
@@ -335,10 +340,13 @@ void fcsm::ctgtq_cleanup()
335340

336341
void fcsm::ensure_commit(uint64_t write_off,
337342
uint64_t write_len,
338-
struct rpc_task *task)
343+
struct rpc_task *task,
344+
std::atomic<bool> *conditional_variable,
345+
bool commit_full)
339346
{
340347
assert(inode->is_flushing);
341348
assert(!inode->is_stable_write());
349+
assert(!commit_full || task == nullptr);
342350

343351
/*
344352
* If any of the flush/commit targets are waiting completion, state machine
@@ -377,13 +385,23 @@ void fcsm::ensure_commit(uint64_t write_off,
377385
uint64_t commit_bytes =
378386
inode->get_filecache()->get_bytes_to_commit();
379387

388+
/*
389+
* If commit_full flag is true, wait_for_ongoing_flush()
390+
* committed the commit_pending bytes. Now we need to flush
391+
* dirty bytes and commit them.
392+
*/
393+
if (commit_full) {
394+
assert(commit_bytes == 0);
395+
commit_bytes = inode->get_filecache()->get_bytes_to_flush();
396+
}
397+
380398
if (commit_bytes == 0) {
381399
/*
382400
* TODO: Make sure this doesn't result in small-blocks being written.
383401
*/
384-
const int64_t bytes =
385-
inode->get_filecache()->get_bytes_to_flush() -
386-
inode->get_filecache()->max_dirty_extent_bytes();
402+
const int64_t bytes = (inode->get_filecache()->get_bytes_to_flush() -
403+
inode->get_filecache()->max_dirty_extent_bytes());
404+
387405
commit_bytes = std::max(bytes, (int64_t) 0);
388406
}
389407

@@ -395,6 +413,9 @@ void fcsm::ensure_commit(uint64_t write_off,
395413
if (task) {
396414
task->reply_write(task->rpc_api->write_task.get_size());
397415
}
416+
if (conditional_variable) {
417+
*conditional_variable = true;
418+
}
398419
return;
399420
}
400421

@@ -427,7 +448,8 @@ void fcsm::ensure_commit(uint64_t write_off,
427448
ctgtq.emplace(this,
428449
0 /* target flush_seq */,
429450
target_committed_seq_num /* target commit_seq */,
430-
task);
451+
task,
452+
conditional_variable);
431453
return;
432454
}
433455

@@ -467,11 +489,21 @@ void fcsm::ensure_commit(uint64_t write_off,
467489
ctgtq.emplace(this,
468490
0 /* target flush_seq */,
469491
target_committed_seq_num /* target commit_seq */,
470-
task);
492+
task,
493+
conditional_variable);
471494
} else {
472495
if (task) {
473496
task->reply_write(task->rpc_api->write_task.get_size());
474497
}
498+
499+
/*
500+
* Flush_cache_and_wait() waiting for dirty_bytes to flushed,
501+
* can't complete until all dirty bytes flushed. so add the
502+
* flush target.
503+
*/
504+
if (commit_full) {
505+
ensure_flush(0, 0, nullptr, conditional_variable);
506+
}
475507
}
476508

477509
return;
@@ -504,6 +536,17 @@ void fcsm::ensure_commit(uint64_t write_off,
504536

505537
assert(committing_seq_num == (prev_committing_seq_num + bytes));
506538
assert(committing_seq_num > committed_seq_num);
539+
540+
/*
541+
* Enqueue this target, on_commit_callback() completes
542+
* this target. Otherwise task/conditional_variable
543+
* waiting for this to complete never called.
544+
*/
545+
ctgtq.emplace(this,
546+
0 /* target flush_seq */,
547+
target_committed_seq_num /* target commit_seq */,
548+
task,
549+
conditional_variable);
507550
}
508551
}
509552

@@ -512,7 +555,8 @@ void fcsm::ensure_commit(uint64_t write_off,
512555
*/
513556
void fcsm::ensure_flush(uint64_t write_off,
514557
uint64_t write_len,
515-
struct rpc_task *task)
558+
struct rpc_task *task,
559+
std::atomic<bool> *conditional_variable)
516560
{
517561
assert(inode->is_flushing);
518562
/*
@@ -595,14 +639,16 @@ void fcsm::ensure_flush(uint64_t write_off,
595639
/*
596640
* If no task and no new flush target, don't add a dup target.
597641
*/
598-
if (!task && (target_flushed_seq_num == last_flush_seq)) {
642+
if (!task && conditional_variable &&
643+
(target_flushed_seq_num == last_flush_seq)) {
599644
return;
600645
}
601646

602647
ftgtq.emplace(this,
603648
target_flushed_seq_num /* target flush_seq */,
604649
0 /* commit_seq */,
605-
task);
650+
task,
651+
conditional_variable);
606652
return;
607653
}
608654

@@ -617,6 +663,10 @@ void fcsm::ensure_flush(uint64_t write_off,
617663
if (task) {
618664
task->reply_write(task->rpc_api->write_task.get_size());
619665
}
666+
667+
if (conditional_variable) {
668+
*conditional_variable = true;
669+
}
620670
return;
621671
}
622672

@@ -653,12 +703,26 @@ void fcsm::ensure_flush(uint64_t write_off,
653703
const uint64_t flushing_seq_num_before = flushing_seq_num;
654704
assert(flushed_seq_num <= flushing_seq_num);
655705

656-
// sync_membufs() will update flushing_seq_num() and mark fcsm running.
657-
inode->sync_membufs(bc_vec, false /* is_flush */, task);
706+
/*
707+
* sync_membufs() will update flushing_seq_num() and mark fcsm running.
708+
* Task is not passed to sync_membufs, but enqueued to ftgtq.
709+
*/
710+
inode->sync_membufs(bc_vec, false /* is_flush */, nullptr);
658711

659712
assert(is_running());
660713
assert(flushing_seq_num == (flushing_seq_num_before + bytes));
661714
assert(flushed_seq_num <= flushing_seq_num);
715+
716+
/*
717+
* Enqueue this target, on_flush_complete() completes
718+
* this target. Otherwise task/conditional_variable
719+
* waiting for this to complete never called.
720+
*/
721+
ftgtq.emplace(this,
722+
target_flushed_seq_num /* target flush_seq */,
723+
0 /* commit_seq */,
724+
task,
725+
conditional_variable);
662726
}
663727

664728
/**
@@ -767,6 +831,9 @@ void fcsm::on_commit_complete(uint64_t commit_bytes)
767831

768832
tgt.task->reply_write(
769833
tgt.task->rpc_api->write_task.get_size());
834+
} else if (tgt.conditional_variable) {
835+
assert(*tgt.conditional_variable == false);
836+
*tgt.conditional_variable = true;
770837
} else {
771838
AZLogDebug("[{}] [FCSM] completing non-blocking commit target: {}, "
772839
"committed_seq_num: {}",
@@ -983,6 +1050,9 @@ void fcsm::on_flush_complete(uint64_t flush_bytes)
9831050

9841051
tgt.task->reply_write(
9851052
tgt.task->rpc_api->write_task.get_size());
1053+
} else if (tgt.conditional_variable) {
1054+
assert(*tgt.conditional_variable == false);
1055+
*tgt.conditional_variable = true;
9861056
} else {
9871057
AZLogDebug("[{}] [FCSM] completing non-blocking flush target: {}, "
9881058
"flushed_seq_num: {}",

0 commit comments

Comments
 (0)