Using fsync() to synchronize a USB mass storage device failed
From: Christian Neumair
Date: Fri Feb 10 2006 - 11:42:36 EST
I've seen various postings on the lkml on the issue of fsync()ing block
devices and the expected behavior. Some claim that fsync()ing the mount
point of a block device will flush its buffers, a HOWTO I read claims
that one has to apply it to the device node, because it is the
representation of the block device.
The POSIX standard demands :
"The fsync() function shall request that all data for the open file
descriptor named by fildes is to be transferred to the storage device
associated with the file described by fildes."
To my interpretation this means that all buffers of a mass storage
device should be flushed when calling fsync() on its file
representation, i.e. /dev/foo.
I've tried various Ubuntu-packaged kernel releases (2.6.12 and later),
and none of it seems to actually assert that the data is written when
using code like
int fd = open ("/dev/sdb1", O_RDONLY); /* I also tried O_WRONLY */
int fd = open ("/media/usbdisk", O_DIRECTORY | O_RDONLY);
and then doing
Unfortunately, none of the code really blocked until the whole buffer
was written, and a diode on the mass storage indicated that data was
still being written to it after my testing application terminated, while
for a simple sync() call (or "sync" program invocation) the whole
process really blocked until the data was on disk, as proven by the
I haven't investigated the code in detail, but fs/buffer.c suggests that
sync_inodes is invoked on sync() but not on fsync(), and the latter does
not lookup the block device the file refers to, thus not ensuring that
fsync_bdev() is called on it.
If you wonder why this is needed - over at GNOME we're having issues
where USB sticks are unmounted and the users have no clue when it's
ready to be removed . We'd like to fsync() in a thread and tell the
users that an unmount operation is going on and still needs some time.
Because there may be multiple storage device attached, it isn't a good
idea to sync() all devices, but just that one which is about to be
Christian Neumair <chris@xxxxxxxxxxxx>
Description: This is a digitally signed message part