Notes |
(0006664)
vda
04-18-08 14:42
|
What do you mean "written asynchronously"?
It is written this way:
fd = open(fn, (O_WRONLY | O_CREAT | O_TRUNC), 0666);
if (fd < 0)
return -1;
cnt = last - first + 1;
charcnt = full_write(fd, first, cnt);
if (charcnt == cnt) {
// good write
//file_modified = FALSE; // the file has not been modified
} else {
charcnt = 0;
}
close(fd);
How do you propose doing it instead? |
| |
(0006674)
kulve
04-19-08 00:40
|
The write doesn't force (O_SYNC) data to be written to disk but it is left to cache waiting for the OS to write it to disk at some point. This is the normal case when writing.
But because the O_TRUNC is synchronous operation on some filesystems, the file is truncated immediately. I suggest that the open() and write() uses the same method, either synchronous or not.
With smaller files the content could be first written to a temporary file, then synced and then the temporary file could be renamed over the real one. The rename on same filesystem is atomic. This way the file would always be either the old one or the new one, corruption would not be possible.
With this method the temporary file could be left on the filesystem if the power loss happens before the rename. And the method won't work with big files and low free space: if you have 5M free and you try to edit 6M file, you don't have space for the temporary file.
Maybe the file could be opened with O_SYNC when saving? This would slow down the write phase compared to current situation but maybe in most use cases in normal busybox environments this wouldn't be a problem. And the user might even expect a slow write as he asked to write the file to the disk. There would still be a small chance for data corruption if the power loss happens during the write but at least the user wouldn't accidentally power off too early like I did. |
| |
(0006684)
vda
04-19-08 12:01
|
> With smaller files the content could be first written to a temporary file, then synced and then the temporary file could be renamed over the real one. The rename on same filesystem is atomic. This way the file would always be either the old one or the new one, corruption would not be possible.
If what you edit is a symlink, this will trash the symlink (replace it with ordinary file). You probably don't want that to happen.
The same will happen with hardlink, but in even less obvious way.
This can be done with some effort (and in fact passwd applet has some code for that). Care to try to produce a patch? |
| |
(0007434)
vda
05-03-08 04:36
|
Changed to not open with O_TRUNC in rev 21928. |
| |