-
Notifications
You must be signed in to change notification settings - Fork 30
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[TA3151]feat(snap_rebuild)Flush outstanding IOs before taking snapshot on rebuild clone. #123
Changes from 2 commits
0b95fd2
acff067
03b762c
963ad74
bdd090b
8d7e1d0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -169,6 +169,7 @@ enum zvol_status { | |
|
||
typedef enum zvol_status zvol_status_t; | ||
|
||
#define ZVOL_IS_HEALTHY(zv) (zv->zv_status == ZVOL_STATUS_HEALTHY) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. lets us uzfs_zinfo_get_status(zinfo) getter function There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are some more macros which are also not as per guidelines. |
||
struct zrepl_status_ack { | ||
zvol_status_t state; | ||
zvol_rebuild_status_t rebuild_status; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -228,14 +228,21 @@ uzfs_submit_writes(zvol_info_t *zinfo, zvol_io_cmd_t *zio_cmd) | |
remain -= sizeof (*write_hdr); | ||
if (remain < write_hdr->len) | ||
return (-1); | ||
|
||
rc = uzfs_write_data(zinfo->main_zv, datap, data_offset, | ||
write_hdr->len, &metadata, is_rebuild); | ||
if (rc != 0) | ||
break; | ||
/* | ||
* Write to main_zv when volume is either | ||
* healthy or in REBUILD_AFS state of rebuild | ||
*/ | ||
if (ZVOL_IS_REBUILDING_AFS(zinfo->main_zv) || | ||
ZVOL_IS_HEALTHY(zinfo->main_zv)) { | ||
rc = uzfs_write_data(zinfo->main_zv, datap, data_offset, | ||
write_hdr->len, &metadata, is_rebuild); | ||
if (rc != 0) | ||
break; | ||
} | ||
|
||
/* IO to clone should be sent only when it is from app */ | ||
if (!is_rebuild && (zinfo->clone_zv != NULL)) { | ||
if (!is_rebuild && !ZVOL_IS_HEALTHY(zinfo->main_zv) && | ||
(zinfo->clone_zv != NULL)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we can remove check for clone_zv There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
rc = uzfs_write_data(zinfo->clone_zv, datap, | ||
data_offset, write_hdr->len, &metadata, | ||
is_rebuild); | ||
|
@@ -334,6 +341,12 @@ uzfs_zvol_worker(void *arg) | |
} | ||
} | ||
|
||
/* App IOs should go to cloen_zv */ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we can make this as 'else' for above 'if' without NULL check for clone_zv There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
if (!rebuild_cmd_req && | ||
!ZVOL_IS_HEALTHY(zinfo->main_zv) && | ||
(zinfo->clone_zv != NULL)) | ||
read_zv = zinfo->clone_zv; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we should do the same for the sync also (ZVOL_OPCODE_SYNC) ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done sir. |
||
|
||
rc = uzfs_read_data(read_zv, | ||
(char *)zio_cmd->buf, | ||
hdr->offset, hdr->len, | ||
|
@@ -670,10 +683,31 @@ uzfs_zvol_rebuild_dw_replica(void *arg) | |
* one of them might have changed rebuild state | ||
*/ | ||
if (uzfs_zvol_get_rebuild_status(zinfo->main_zv) != | ||
ZVOL_REBUILDING_AFS) | ||
ZVOL_REBUILDING_AFS) { | ||
uzfs_zvol_set_rebuild_status(zinfo->main_zv, | ||
ZVOL_REBUILDING_AFS); | ||
/* | ||
* Lets ask io_receiver thread to flush | ||
* all outstanding IOs in taskq | ||
*/ | ||
zinfo->quiesce_done = 0; | ||
zinfo->quiesce_requested = 1; | ||
} | ||
mutex_exit(&zinfo->main_zv->rebuild_mtx); | ||
/* | ||
* Wait for all outstanding IOs to be flushed | ||
* to disk before making further progress | ||
*/ | ||
#ifdef DEBUG | ||
if (inject_error.delay.rebuid_io_quiesce_check_by_pass) | ||
continue; | ||
#endif | ||
while (1) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this may need to be executed only in the thread where we had set these flags There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think after discussion this code have no side effect. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes |
||
if (!zinfo->quiesce_done) | ||
sleep(1); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have a doubt. If replica gets disconnected from the target during rebuilding and quiescing was requested then will this thread exit? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. current zfs takes care that - if either mgmt or data conn breaks, any rebuilding related threads also will be exited. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, I is fixed now. |
||
else | ||
break; | ||
} | ||
continue; | ||
} | ||
ASSERT((hdr.opcode == ZVOL_OPCODE_READ) && | ||
|
@@ -1828,6 +1862,19 @@ uzfs_zvol_io_receiver(void *arg) | |
/* Take refcount for uzfs_zvol_worker to work on it */ | ||
uzfs_zinfo_take_refcnt(zinfo); | ||
zio_cmd->zinfo = zinfo; | ||
|
||
/* | ||
* Rebuild want to take consistent snapshot | ||
* so it asked to flush all outstanding IOs | ||
* before taking snapshot on rebuild_clone | ||
*/ | ||
if (zinfo->quiesce_requested) { | ||
ASSERT(ZVOL_IS_REBUILDING_AFS(zinfo->main_zv)); | ||
taskq_wait_outstanding(zinfo->uzfs_zvol_taskq, 0); | ||
zinfo->quiesce_requested = 0; | ||
zinfo->quiesce_done = 1; | ||
} | ||
|
||
taskq_dispatch(zinfo->uzfs_zvol_taskq, uzfs_zvol_worker, | ||
zio_cmd, TQ_SLEEP); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we use these two as bits in 'flags' variable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and create setter/getter macros around these variables
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok.. we can't set them as bits, as there is no lock in reading these variables
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok