-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
vdev_open_child() race on vdev_parent->vdev_nonrot update? #5162
Conversation
This change is clearer. LGTM. |
b0fd8c8
to
7c0f2e3
Compare
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.
You're absolutely right about this race. In order to resolve the conflict with #4637 I've updated the patch and applied it on top of the other proposed change. Since you're familiar with this code it would be great if you could review and test both fixes so they could be finalized and merged.
@@ -1124,7 +1124,7 @@ vdev_open_child(void *arg) | |||
vd->vdev_open_thread = curthread; | |||
vd->vdev_open_error = vdev_open(vd); | |||
vd->vdev_open_thread = NULL; | |||
vd->vdev_parent->vdev_nonrot &= vd->vdev_nonrot; | |||
/* vd->vdev_parent->vdev_nonrot is updated in vdev_open_children() */ |
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.
This should just be removed.
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.
I updated this patch, such that it could be applied if the CentOS issue of #4637 takes time to resolve. Reason being that condensing the nonrot logic to the end of vdev_open_children()
simplifies some other work.
Updating vd->vdev_parent->vdev_nonrot in vdev_open_child() is a race when vdev_open_child is called for many children from a task queue. vdev_open_child() is only called by vdev_open_children(), let the latter update the parent vdev_nonrot member. The update was already there, so done twice previously. Thus using the same logic at the end in vdev_open_children() to update vdev_nonrot, either we are vdev_uses_zvols() or not.
7c0f2e3
to
70c35e9
Compare
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.
Thanks. Since this is such a straight forward change we may be able to get it in first.
Updating vd->vdev_parent->vdev_nonrot in vdev_open_child() is a race when vdev_open_child is called for many children from a task queue. vdev_open_child() is only called by vdev_open_children(), let the latter update the parent vdev_nonrot member. The update was already there, so done twice previously. Thus using the same logic at the end in vdev_open_children() to update vdev_nonrot, either we are vdev_uses_zvols() or not. Reviewed-by: Richard Elling <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Haakan T Johansson <[email protected]> Closes openzfs#5162
Updating vd->vdev_parent->vdev_nonrot in vdev_open_child() is a race when vdev_open_child is called for many children from a task queue. vdev_open_child() is only called by vdev_open_children(), let the latter update the parent vdev_nonrot member. The update was already there, so done twice previously. Thus using the same logic at the end in vdev_open_children() to update vdev_nonrot, either we are vdev_uses_zvols() or not. Reviewed-by: Richard Elling <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Haakan T Johansson <[email protected]> Closes openzfs#5162
Looking at the vdev_nonrot logic, I think I found a small race condition.
This pull request will conflict with #5117, I'll update either if any is merged. (But please comment on the open questions for #5117 meanwhile).