BusyBox Bug and Patch Tracking
BusyBox
  

Viewing Issue Simple Details Jump to Notes ] View Advanced ] Issue History ] Print ]
ID Category Severity Reproducibility Date Submitted Last Update
0002944 [BusyBox] Other minor always 04-18-08 11:13 05-03-08 04:36
Reporter kulve View Status public  
Assigned To BusyBox
Priority normal Resolution fixed  
Status closed   Product Version
Summary 0002944: vi truncates the file synchronously in file_write() but does write() asynchronously.
Description Because the file is truncated to zero synchronously for in-place rewriting and written asynchronously it's vulnarable to losing all data on power loss. This is easily reproducable with e.g. UBIFS by editing the file, exiting and then immediately powering the device off (yeah, I should have run sync before just powering off).

The file_write() should probably be done in a way that would lose only the changes, not the original file. With smaller files this could be achieved with e.g. using mv.
Additional Information
Attached Files

- Relationships

- 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.
 

- Issue History
Date Modified Username Field Change
04-18-08 11:13 kulve New Issue
04-18-08 11:13 kulve Status new => assigned
04-18-08 11:13 kulve Assigned To  => BusyBox
04-18-08 14:42 vda Note Added: 0006664
04-19-08 00:40 kulve Note Added: 0006674
04-19-08 12:01 vda Note Added: 0006684
05-03-08 04:36 vda Status assigned => closed
05-03-08 04:36 vda Note Added: 0007434
05-03-08 04:36 vda Resolution open => fixed


Copyright © 2000 - 2006 Mantis Group
Powered by Mantis Bugtracker