-
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
Simplify/fix dnode_move() for dn_zfetch. #11998
Conversation
Previous code tried to keep prefetch streams while moving dnode. But it was at least not updating per-stream zs_fetchback pointers, causing use-after-free on next access. Instead of that I see much easier and cleaner to just drop old prefetch state and start new from scratch. Signed-off-by: Alexander Motin <[email protected]> Sponsored-By: iXsystems, Inc. Closes openzfs#11936
@@ -822,19 +821,14 @@ dnode_move_impl(dnode_t *odn, dnode_t *ndn) | |||
ndn->dn_newgid = odn->dn_newgid; | |||
ndn->dn_newprojid = odn->dn_newprojid; | |||
ndn->dn_id_flags = odn->dn_id_flags; | |||
dmu_zfetch_init(&ndn->dn_zfetch, NULL); | |||
list_move_tail(&ndn->dn_zfetch.zf_stream, &odn->dn_zfetch.zf_stream); | |||
ndn->dn_zfetch.zf_dnode = odn->dn_zfetch.zf_dnode; |
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.
Does this leak the zstream_t's on the zf_stream?
The move callbacks are pretty tricky code to get right. IMO, if we aren't able to maintain the move callbacks, because we can't test them, because they are dead code, we should remove them from the codebase.
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.
dmu_zfetch_fini(&odn->dn_zfetch) below should free the old streams gracefully. I've preferred to drop streams exactly to not complicate this code and avoid new breakages later.
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. I'm fine with integrating this change, but I would welcome a future PR to remove dnode_move_impl() entirely.
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.
it fixed panic. i'll continue to check it in loop
Previous code tried to keep prefetch streams while moving dnode. But it was at least not updating per-stream zs_fetchback pointers, causing use-after-free on next access. Instead of that I see much easier and cleaner to just drop old prefetch state and start new from scratch. Reviewed-by: Matthew Ahrens <[email protected]> Reviewed-by: Igor Kozhukhov <[email protected]> Signed-off-by: Alexander Motin <[email protected]> Sponsored-By: iXsystems, Inc. Closes openzfs#11936 Closes openzfs#11998
Previous code tried to keep prefetch streams while moving dnode. But it was at least not updating per-stream zs_fetchback pointers, causing use-after-free on next access. Instead of that I see much easier and cleaner to just drop old prefetch state and start new from scratch. Reviewed-by: Matthew Ahrens <[email protected]> Reviewed-by: Igor Kozhukhov <[email protected]> Signed-off-by: Alexander Motin <[email protected]> Sponsored-By: iXsystems, Inc. Closes openzfs#11936 Closes openzfs#11998
Previous code tried to keep prefetch streams while moving dnode. But
it was at least not updating per-stream zs_fetchback pointers, causing
use-after-free on next access. Instead of that I see much easier and
cleaner to just drop old prefetch state and start new from scratch.
Closes #11936
How Has This Been Tested?
The code builds on FreeBSD. Unfortunately I can't run test it, since neither FreeBSD nor Linux dnode_move().
Types of changes
Checklist:
Signed-off-by
.