-
Notifications
You must be signed in to change notification settings - Fork 3.2k
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
Ensure parent node is always updated in rename(), regardless of fs implementation #21964
Ensure parent node is always updated in rename(), regardless of fs implementation #21964
Conversation
Add a fallback update to the parent directory reference in the finally block of the rename function to ensure consistency. This change addresses cases where the node_ops.rename update doesn't propagate across different file systems or mount points, ensuring that the parent directory reference is correctly updated.
Thanks for the PR! Looking at related code, I see that the two backends that fully support emscripten/src/library_memfs.js Line 201 in 1336355
and emscripten/src/library_proxyfs.js Line 111 in 1336355
Which backend are you using in your project? If it's one of those two then we may need to debug to find out why the existing line did not work. Or, if it's a custom one, then this PR may be the right way to go - better to have that logic in a shared place rather than in each backend - but then we'd probably want to document that and remove those lines from MEMFS and PROXYFS. |
@kripken, thank you so much for taking a look at this!
We're using MEMFS and I can confirm an existing call to
Adding the call to the |
Since you are using MEMFS then I think the only difference is that doing it in the What do you mean by "virtual file system" as opposed to local? (All files in MEMFS are in a virtual file system in some sense, and we may call it that in the docs in some places, I'm not sure. But I think you might mean something else?) |
@kripken, apologies, I realised when reading my last comment back that I got mixed up between virtual/local file systems. A colleague, @fluiddot, also pinged me to further clarify some things. We think we were able to get to the bottom of what's happening. Here's an updated explanation:
We were able to get things working on our side by adding emscripten/src/library_nodefs.js Lines 179 to 189 in 68a9f99
However, we're not sure if there's a specific reason I see two ways we could move forward:
Do either of those seem preferable to the other to you, or are there alternatives? |
Thanks! Now I think I understand. I think option 2 is the right one. We can do it in one place in the In fact we can probably also do the same with |
As we're now calling `old_node.parent = new_dir` from the `finally` block in library_fs.js, it's not necessary to duplicate that line in MEMFS or PROXYFS.
…://github.com/SiobhyB/emscripten into fix/ensure-rename-updates-across-file-systems
@kripken, thank you for sticking with me here. I've gone ahead to make those changes now. |
src/library_fs.js
Outdated
@@ -815,6 +815,9 @@ FS.staticInit();` + | |||
} catch (e) { | |||
throw e; | |||
} finally { | |||
// update old node (called here to ensure consistency | |||
// across fs implementations) | |||
old_node.parent = new_dir; |
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.
Reading this again, I don't think we want this to run if an exception happens. Not running it in that case would match the previous behavior - the old places that set the parent were only reached if nothing was thrown. So let's move this to right after the finally. edit: unless that doesn't work in your case for some reason?
For the comment, how about update old node (we do this here to avoid each backend needing to)
- ?
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.
Reading this again, I don't think we want this to run if an exception happens. Not running it in that case would match the previous behavior - the old places that set the parent were only reached if nothing was thrown. So let's move this to right after the finally. edit: unless that doesn't work in your case for some reason?
Nice catch :D I agree that makes sense and everything still worked as expected for our use case, I updated in 631a8bf.
For the comment, how about update old node (we do this here to avoid each backend needing to) - ?
I think that update has a lot more clarity! I applied that change in b555a45.
As per the feedback here, we don't want to reassign the value if an error is thrown: emscripten-core#21964 (comment)
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.
Perfect, thanks! As soon as tests pass we'll merge this in.
Hmm, it looks like a test is failing here, so we must have missed something. To run that test locally you can use Let me know if you get stuck on something (I know running tests in a project for the first time can be annoying). |
Head branch was pushed to by a user without write access
With this change, we ensure the assignment doesn't happen if an error is thrown, while also ensuring it runs before the code in the finally block.
@kripken, my assumption from looking into this is that there are cases where the code in the Lines 820 to 824 in b3b8ffe
In b3b8ffe, I've moved the |
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.
Good point! Yes, the current PR has the right order.
I missed that the FS.hashAddNode
call can actually interact with that line.
Description:
This PR addresses an issue encountered in the WordPress Playground project where the parent node (
old_node.parent
) needs to be explicitly updated in thefinally
block to ensure consistent handling of directory renames across file systems.Problem:
In our use case, we observed that the
rename()
fails when using NODEFS.Solution:
old_node.parent = new_dir
was missing from the NODEFSrename
function, which was leading to failures in our project. As such, this has now been added to thefinally
block in library_fs.js to ensure the parent node is always correctly updated, regardless of fs implementation.The
old_node.parent = new_dir
line has also been removed from the MEMFS and PROXYFS files to remove redundancy.