-
Notifications
You must be signed in to change notification settings - Fork 32
Implement Copy-on-Write (COW) for destructive file operations #88
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
base: master
Are you sure you want to change the base?
Conversation
- Implemented detection of destructive file operations (FILE_OVERWRITE, FILE_SUPERSEDE) in NtCreateFile hook. - Added checks for sensitive file extensions (.ini, .json, .txt, etc.) to target configuration files. - Implemented 'Safety Copy' mechanism: - When a destructive write is detected on a file in 'mods_dir' (and not in 'exclude_mods'), the file is automatically copied to 'overwrite_dir'. - The copy preserves the relative path from the mod root (e.g., 'mods/ModA/SKSE/plugins/foo.ini' -> 'overwrite/SKSE/plugins/foo.ini'). - Updated VFS redirection table immediately after the copy to ensure the file handle and subsequent operations point to the new copy in 'overwrite_dir'. - Enhanced 'LoadSettings' to support dynamic 'overwrite_dir' configuration: - Added 'output_directories' map to 'usvfs::settings'. - Parsed '[Output]' section from 'usvfs_redirect.ini'. - If 'current_process' matches an entry in 'output_directories', 'overwrite_dir' is updated to the specified relative path within 'mods_dir'. - Added comprehensive logging for destructive operation detection, file copying, and VFS rerouting.
|
Is this just doing it for the few file extensions you listed? The reason we've had for not doing the simple thing where we copy files in |
|
Yep, I have some troubles when developing, I don't know when writing happens. So, I decided just CoW a few extensions. The commit is the second time I develop this feature. |
|
ReFS is vaguely positioned to maybe replace NTFS as the default filesystem for Windows, but it's not happening quickly. In 2012, it might have seemed like a safe bet that Windows installs would use ReFS by default in 2025, but 2025 has arrived and that's not the case yet, and Microsoft seem to be pivoting away from making Windows better, so it might never happen. As for specifics of giving USVFS full CoW support, I'm probably not the best person to ask as I've never dealt with its guts, and just know high-level stuff. I did make a CoW-capable USVFS clone for a university project (actually, technically it was a Something I do know, though, is that one of USVFS' strong points is its speed - because the name lookup is done based on stuff in RAM, it doesn't need to touch the disk until a handle is actually opened, and then the application is given a normal handle that works like any other, so USVFS doesn't need to get involved with anything else, so it ends up about the same speed as the native filesystem. If we start hooking all the functions that can actually modify files, there's a risk of undermining that and making things slower, plus there are a lot of unhooked functions we'd have to hook, so the maintenance burden and risk of mistakes would increase significantly. To get CoW support, it might be a better idea to make a fresh filesystem using something easier to work with like Dokany, and then add a toggle to MO2 to pick whether to use the fast, non-CoW one (e.g. for playing games) or the slower CoW one (e.g. for using modding tools). Supposedly, when switching from |
|
After a few times of developing, I'm very sure write operations will be captured by NtWriteFile. |
|
So this is specifically checking for actual file writes before copying the file? If it's still restricted to specific file extensions I think it could be reasonable, but copying something large like a BSA file still seems problematic from a performance perspective. Do you have any specific test cases? It might be necessary to allow passing in allowed extensions for cow. |
|
This CoW has three features, truncated operations will CoW immediately, write operations happens will CoW and upadte vfs mapping, delete file will only remove mappings (I think I should improve it, but how?) Test cases I didn't create yet, for there is still a bug I don't know how to solve. |
|
Regardless of the actual features that this PR is trying to implement, it contains many unrelated changes (e.g., all the rewrite in the workflow file), so these should be moved to another PR if relevant. |
|
Yes, you are right, I should distribute these features into different PR, and I need fork mo2 and adjust usvfs features. |



Actually, this pull request shouldn't be merged now, I just make it a feasible way.
There are many things should be done at mo2 not usvfs:
This Pull request give usvfs an ability to not modify mod source file, possible write will be routed to overwrite_dir
Now this is a true CoW implement.
Truncated operations will redict at NtCreate
Write Access will be redirect at NtWrite