Does sync(8) really flush everything? Lost writes with journaled SU after sync+power cycle

Kevin Day toasty at dragondata.com
Fri Apr 12 15:59:47 UTC 2013


On Apr 11, 2013, at 1:30 AM, Bruce Evans <brde at optusnet.com.au> wrote:
> 
> sync(2) only schedules all writing of all modified buffers to disk.  Its
> man page even says this.  It doesn't wait for any of the writes to complete.
> Its man page says that this is a BUG, but it is intentional and sync() has
> always done this.  There is no way for sync() to guarantee that all modified
> buffers have been written to disk when it returns, since even if it waited,
> buffers might be modified while it is returning.  Perhaps even ones that
> would take 8 seconds to complete can be written in the few nanoseconds that
> it takes to return.
> 
> sync(8) is just a wrapper around sync(2).  One that doesn't even check
> for errors.  Not that it could handle sync() failure.  Its man page
> bogusly first claims that it "forces completion".  This is not
> completely wrong, since it doesn't claim that the completion occurs
> before sync(8) exits.  But then it claims that sync(8) is suitable "to
> ensure that all disk writes have been completed in a way not suitably
> done by reboot(8) or halt(8).  This wording is poor, unless it is
> intentionally weaselishly worded so that it doesn't actually claim
> full completion.

And on the flip side, the man page for syncer says:

It is possible on some systems that a sync(2) occurring simultaneously with a crash may cause file system damage.  See fsck(8).


> It only claims more suitable completion than with
> reboot or halt.  Actually, completion is not guaranteed, and what
> sync(8) provides is just less unsuitable than what reboot and halt
> provide.
> 
> To ensure completion, you have to freeze the file systems of interest
> before rebooting.  I don't know of any ways to do this from userland
> except mount -u -o ro or unmount.
> 
> There should be a syscall to cause syncing with waiting.  The kernel
> has a wait option for syncing, but doesn't use it for sync(2).  But
> using this would only reduce the races.
> 
> Bruce

I understand that sync(8) returns immediately, I guess my confusion is that calling sync(8) doesn't seem to cause *any* writes to happen.

I can have the system completely idle (absolutely no processes running that could cause any filesystem activity), call sync(8), and watching gstat(8) can see no write activity happen at all, even waiting 10+ seconds afterwards, where as "mount -u -o ro -f /" causes an instant flurry of writes to happen. My understanding was that even though sync returned immediately, flushing would also start immediately, and leave the system in a safe point, at least until another write happens.

If sync(8) isn't starting the write flush immediately, but does return immediately, I'm having trouble figuring out a situation where calling sync would ever accomplish anything useful, other than possibly creating a window where the filesystem could be damaged if a crash happens.

-- Kevin



More information about the freebsd-fs mailing list