Closed Bug 231300 Opened 21 years ago Closed 20 years ago

nsLocalFile::MoveTo is very slow to move directories [Cause of disk trashing (on NT) when clearing cache?]

Categories

(Core :: XPCOM, defect, P2)

x86
Windows NT
defect

Tracking

()

RESOLVED FIXED
mozilla1.8beta2

People

(Reporter: jo.hermans, Assigned: darin.moz)

References

Details

(Keywords: perf)

Attachments

(1 file, 1 obsolete file)

Build 2004011605 on Windows NT I noticed that clearing the disk cache was a lot faster on Mac OS X 10.2.8 (about a second), than on Windows NT (can take up to half a minute or more). When investigating why, I found that all cache-files are moved to Cache.Trash, and are then deleted in a background thread. The deletion itself is more than fast enough (esp. because it's on a separate thread), but it's the move that is the bottleneck. You can hear the disk trashing like crazy. Hence the name of the folder, I suppose :-) Mac OS X handles the move of an entire directoy very fast (see nsLocalFile::MoveToNative, which ends up calling nsLocalFile::MoveCopy at <http://lxr.mozilla.org/seamonkey/source/xpcom/io/nsLocalFileOSX.cpp#1917>), but the same code in Windows is a mess (see nsLocalFile::MoveToNative, which ends up calling nsLocalFile::CopySingleFile at <http://lxr.mozilla.org/seamonkey/source/xpcom/io/nsLocalFileWin.cpp#980>). From what I can see, the code is creating a backupfile first (.moztmp extension), before the real MoveFile is called. Isn't that a bit too much ? Shouldn't nsLocalfile::CopyMove call MoveFile directly, instead of passing through CopySingleFile ? And can we avoid the backupfile in this case ? See also bug 179641. (filed in Browser/Xpcom, just like bug 179641)
have you measured this or is this speculation? creating the moztmp files is to prevent data loss when a move fails. osX may do this for you auto-magically.
I found the code while I was on IRC at home (on Mac OS X). Tomorrow, in the office, I'll try to see if I can find it back on Windows NT. The difference between clearing the disk cache on Mac OS X and Windows NT is enormous : the Mac does it in 1 or 2 seconds (even on an old 300 MHz iBook), while Windows will keep trashing the disk for half a minute or more (400 MHz desktop). It's very audible and blocks the GUI for a long time.
Note that I can't see the problem anymore on Windows 2000, on exactly the same hardware (and same software - currently Firefox 0.9.1). I think that the filesystem code in Windooze has improved a lot. Those .moztmp files are only created for a very short time, so they might never be written to disk. Oh well, if nobody has any complaints about it, we can close this bug (and 179641 too). It might still be very inefficient code (we're deleting files, so those backup files are overkill), but the OS can easily help in this case. Note that you also are deleting the entire cache after a crash. On my old NT setup, I also had to wait +/- 30 sec before the browser loaded, both in Mozilla and Firefox.
the cache deletion is intentional/by design. cache does not do any work to maintain its integrity in the case when the app crashes, so its only recovery mechanism is to start from scratch.
(In reply to comment #4) > the cache deletion is intentional/by design. cache does not do any work to > maintain its integrity in the case when the app crashes, so its only recovery > mechanism is to start from scratch. I know, you have to read the other comments too. I was only commenting that because of the slow delete (b/c every delete creates a backup file first !), it is slower than it needs to be. I don't have anything against the delete itself.
see also new bug 287827 (dupe?)
*** Bug 287827 has been marked as a duplicate of this bug. ***
Bug 287827 has more analysis on this problem. It is very clear that iterating the directory and moving individual files is killing performance. We should only do that if MoveFile fails (due to crossing filesystem volumes or something like that).
Summary: cause of disk trashing (on NT) when clearing cache ? → nsLocalFile::MoveTo is very slow to move directories [Cause of disk trashing (on NT) when clearing cache?]
I create authoring applications for web based trainings using the Mozilla Framework. Such a project could have a lot of media files and pages. More then 1000 Files with more than 500 MB in total are pretty common. When I want to just rename a folder it takes up to several minutes as the whole folder will be moved instead of just renamed. As a nsIFile.moveTo(null,newName) seems to be the only way to rename a file or directory (using JavaScript), this is pretty unsatisfying. Hope to see this fixed in one of the next releases.
adding to my 1.8 bucket... help would still be very much appreciated!
Assignee: dougt → darin
Severity: normal → major
Priority: -- → P2
Target Milestone: --- → mozilla1.8beta2
From comparing: http://lxr.mozilla.org/seamonkey/source/xpcom/io/nsLocalFileWin.cpp#1427 with: http://lxr.mozilla.org/seamonkey/source/xpcom/io/nsLocalFileUnix.cpp#861 one can see that the Unix version of MoveToNative first just tries to 'rename' the file or directory, whilst the Win version always CopyMove's it. Copying the code from the Unix version could do the trick, replacing 'rename' with the windows 'MoveFile' call. P.s. same applies also to OS/2: http://lxr.mozilla.org/seamonkey/source/xpcom/io/nsLocalFileOS2.cpp#800
Yeah, I agree. That sounds like the right solution. Do you have time to put together a patch?
Instead of always enumerating directories to move it, first try to move the directory as a single 'file' to the new location. If this fails, fallback to the usual iterative move/copy. This speeds up the move/delete operation of a dirty cache enormously, as the move is now a single file op, and delete is a separate nonblocking thread. This patch also does the same trick of OS/2, but I cannot compile and test OS/2. Any volunteers do the testing for this patch?
Comment on attachment 181040 [details] [diff] [review] Version 1: patch for Windows and OS/2 This patch looks like it should do the trick (and I'll help test it), but it's interesting that it may call CopySingleFile more than once in the failure case for normal files.
This version only tries to call CopySingleFile for copy of single files (or non-followed symlinks), and for move of a single file or a directory. Only when the CopySingleFile for move of a directory fails, fallback to the enumeration code (which is also used for normal copy of directories and followed symlinks)).
Attachment #181040 - Attachment is obsolete: true
Attachment #181068 - Flags: review?(darin)
Comment on attachment 181068 [details] [diff] [review] Version 2: Improved logic for trying CopySingleFile for copy file and/or move file/directories r=darin
Attachment #181068 - Flags: superreview?(dougt)
Attachment #181068 - Flags: review?(darin)
Attachment #181068 - Flags: review+
Comment on attachment 181068 [details] [diff] [review] Version 2: Improved logic for trying CopySingleFile for copy file and/or move file/directories xpcom/io only needs your review darin. Since I am here: the comment: // Ignore failure in case of move of a directory, then we fallback to enumeration Doesn't read well, try: // If we are moving a directory and that fails, fallback on directory enumberation. See bug 231300 for details. Also, if you really wanted to you could make CopySingleFile not make a backup while doing the move. Probably just removing that will will you a ~40% speed inprovement over what we do currently. However, doing this will result in data loss if the move files for whatever reason. Maybe there isn't ever a failure case we care about?
I would be carefull about removing the backup because MoveFile is mostly used for things like cookies.txt, prefs.js, bookmarks.html. Losing these files in case of failure is not so nice...
Actually the renamve, movefile, delete operation could also be replaced by 'ReplaceFile' (see bug 179641). Problem is that the HandleFile function is only supported on W2K and WXP (and higher I guess). Note that on OS/2 we don't create a backup first, so failure is failure there...
The backup business in CopySingleFile is only done for single files. Moreover, it is only done in the case where we are moving a file on top of an existing file. So, for directories there is nothing to worry about.
Comment on attachment 181068 [details] [diff] [review] Version 2: Improved logic for trying CopySingleFile for copy file and/or move file/directories I like dougt's suggested wording of that comment -- without the 'b' of course ;-) I'd like to get some testing of this fix in 1.8b2. It solves the very real problem of firefox thrashing the harddrive madly after a firefox or OS crash.
Attachment #181068 - Flags: superreview?(dougt)
Attachment #181068 - Flags: superreview+
Attachment #181068 - Flags: approval1.8b2?
Comment on attachment 181068 [details] [diff] [review] Version 2: Improved logic for trying CopySingleFile for copy file and/or move file/directories a=asa
Attachment #181068 - Flags: approval1.8b2? → approval1.8b2+
fixed-on-trunk thanks again Alfred!
Status: NEW → RESOLVED
Closed: 20 years ago
Resolution: --- → FIXED
*** Bug 300035 has been marked as a duplicate of this bug. ***
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: