Subject: Re: does fsync(2) still ignore some filesystem metadata in 1.6.x?
To: Bill Studenmund <wrstuden@netbsd.org>
From: Greg A. Woods <woods@weird.com>
List: port-i386
Date: 12/29/2004 21:31:12
[ On Wednesday, December 29, 2004 at 14:00:20 (-0800), Bill Studenmund wrote: ]
> Subject: Re: does fsync(2) still ignore some filesystem metadata in 1.6.x?
>
> On Fri, Nov 26, 2004 at 05:38:03PM -0500, Greg A. Woods wrote:
> > The following description of changes to src/sys/ufs/ffs/ffs_vnops.c
> > suggests that in 1.6.x an fsync(2) call will _not_ necessarily cause the
> > inode data to be flushed:
> > 
> > ----------------------------
> > revision 1.61
> > date: 2003/10/25 19:52:21;  author: kleink;  state: Exp;  lines: +5 -8
> > Remove the present incarnation of FSYNC_DATAONLY use from ffs_fsync() and
> > ffs_full_fsync(); while it is supposed to hint that the update of _file_
> > metadata (as in timestamps et al.) may be omitted it doesn't mean the
> > same for _filesystem_ metadata.
> > ----------------------------
> 
> No. Because fsync(2) does not set this flag, thus the previously-incorrect 
> behavior won't be triggered. From my review of the 1.6 branch, only 
> fdatasync(2) sets this flag, thus only it would be impacted by the bug.

Hmmm... yes, I see...  further review in my own source tree confirms
nothing else visibly sets FSYNC_DATAONLY:

$ cd /usr/src/sys
$ find . -type f -print | xargs fgrep FSYNC_DATAONLY 
./kern/vfs_syscalls.c:  error = VOP_FSYNC(vp, fp->f_cred, FSYNC_WAIT|FSYNC_DATAONLY, 0, 0, p);
./miscfs/genfs/genfs_vnops.c:   if ((ap->a_flags & FSYNC_DATAONLY) != 0)
./sys/vnode.h:#define   FSYNC_DATAONLY  0x0002          /* fsync: hint: sync file data only */
./ufs/ffs/ffs_vnops.c:  if (!(ap->a_flags & FSYNC_DATAONLY) && blk_high >= NDADDR) {
./ufs/ffs/ffs_vnops.c:  if (ap->a_flags & (FSYNC_DATAONLY|FSYNC_WAIT))
./ufs/ffs/ffs_vnops.c:  if (skipmeta && !(ap->a_flags & FSYNC_DATAONLY)) {
./ufs/ffs/ffs_vnops.c:          if (ap->a_flags & FSYNC_DATAONLY)


> While the rest of your note indicates there's an issue with -o async, I 
> doubt it's from this bug.

bummer -- that would have seemed to be such an easy fix to the bug!  ;-)

Any other suggestions of where to look?

What about these lines:

        if (ap->a_flags & (FSYNC_DATAONLY|FSYNC_WAIT))
                skipmeta = 1;

The use of FSYNC_WAIT there to set skipmeta seems wrong, though I'm not
sure exactly what's going on in that "goto loop;" part -- it would also
seem that if FSYNC_DATAONLY is not set then the bwrite() will still be
done and so it also wouldn't be the cause of the bug I've demonstrated.

-- 
						Greg A. Woods

H:+1 416 218-0098  W:+1 416 489-5852 x122  VE3TCP  RoboHack <woods@robohack.ca>
Planix, Inc. <woods@planix.com>          Secrets of the Weird <woods@weird.com>