Subject: fsync_range() system call
To: None <tech-kern@netbsd.org>
From: Bill Studenmund <wrstuden@netbsd.org>
List: tech-kern
Date: 10/24/2003 15:23:35
--GID0FwUMdk1T2AWN
Content-Type: multipart/mixed; boundary="xHFwDpU9dbj6ez1V"
Content-Disposition: inline


--xHFwDpU9dbj6ez1V
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

I'd like to add a new system call, named fsync_range(). The purpose of
this system call is to flush some of the data in a file; it's a kind of
fdatasync for a range.

This implementation copies the AIX system call of the same name. Including=
=20
the requirement that the file descriptor be open for write for this call.=
=20
The call will cause the data in the range to be written, and also cause=20
some file metadata to be written.

This implementation requires FS support to function efficiently. If the
file sytstem doesn't support the range parameters of VOP_FSYNC(), then
this call is equivalent to an fsync() call. Included is a patch to
ffs_fsync() to handle this call in the non-softdep case. I did not feel
qualified to go mucking with the other file systems to add efficient
support for this.

int fsync_range(int fd, int how, off_t start, off_t length)

fd	is the file descriptor to sync. Must be open for write.
how	should be one of FDATASYNC or FFILESYNC.

		FDATASYNC	Flush data and enough meta data to read
				those blocks back in. i.e. data + indirect
				block tables.

		FFILESYNC	Flush data and all file metadata. i.e.
				fsync() but only data in given range must
				have been written.

	The current implementation only looks at FDATASYNC.

start	byte offset at which to start syncing data.

length	length of data to synchronize. The value of 0 will cause the
	whole file to be synchronized, regardless of start.

File systems may (will) round the range of data flushed to cover an
integer number of file system blocks.

Thanks to Jason Thorpe, Nathan Williams, and Darrin Jewell. Jason helped=20
with the concept, Nathan with the pthread handling, and Darrin audited=20
all our file systems to make sure they wouldn't do something bad as a=20
result of this.

Thoughts? Look good?

Oh, the diff has a little fuzz as it is from a tree that has syscalls 354=
=20
& up marked as UNIMPL, while they just aren't listed in the NetBSD source.

Take care,

Bill

--xHFwDpU9dbj6ez1V
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="temp.fsync.diffs"
Content-Transfer-Encoding: quoted-printable

Index: include/unistd.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/wasabisrc/src/include/unistd.h,v
retrieving revision 1.1.1.4
diff -u -r1.1.1.4 unistd.h
--- include/unistd.h	12 May 2003 20:51:02 -0000	1.1.1.4
+++ include/unistd.h	17 Oct 2003 18:29:50 -0000
@@ -197,6 +197,9 @@
     defined(_NETBSD_SOURCE)
 int	 fdatasync __P((int));
 int	 fsync __P((int));
+/*
+ * See also fsync_range() below
+ */
 #endif
=20
=20
@@ -311,6 +314,7 @@
 void	 endusershell __P((void));
 int	 exect __P((const char *, char * const *, char * const *));
 int	 fchroot __P((int));
+int	 fsync_range(int, int, off_t, off_t);
 int	 getdomainname __P((char *, size_t));
 int	 getgrouplist __P((const char *, gid_t, gid_t *, int *));
 mode_t	 getmode __P((const void *, mode_t));
Index: lib/libc/sys/Makefile.inc
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/wasabisrc/src/lib/libc/sys/Makefile.inc,v
retrieving revision 1.1.1.11
diff -u -r1.1.1.11 Makefile.inc
--- lib/libc/sys/Makefile.inc	12 May 2003 21:08:12 -0000	1.1.1.11
+++ lib/libc/sys/Makefile.inc	17 Oct 2003 18:29:54 -0000
@@ -82,8 +82,8 @@
 	timer_create.S timer_delete.S timer_gettime.S timer_getoverrun.S \
 	timer_settime.S
=20
-WEAKASM=3D accept.S close.S connect.S execve.S fcntl.S fsync.S kill.S \
-	msgrcv.S msgsnd.S __msync13.S \
+WEAKASM=3D accept.S close.S connect.S execve.S fcntl.S fsync.S fsync_range=
s.S \
+	kill.S msgrcv.S msgsnd.S __msync13.S \
 	nanosleep.S open.S poll.S read.S readv.S \
 	select.S __sigsuspend14.S sysarch.S wait4.S write.S writev.S
=20
Index: lib/libc/sys/fsync.2
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/wasabisrc/src/lib/libc/sys/fsync.2,v
retrieving revision 1.1.1.4
diff -u -r1.1.1.4 fsync.2
--- lib/libc/sys/fsync.2	17 Apr 2003 05:21:21 -0000	1.1.1.4
+++ lib/libc/sys/fsync.2	17 Oct 2003 18:29:54 -0000
@@ -38,6 +38,7 @@
 .Os
 .Sh NAME
 .Nm fsync
+.Nm fsync_range
 .Nd "synchronize a file's in-core state with that on disk"
 .Sh LIBRARY
 .Lb libc
@@ -45,6 +46,8 @@
 .In unistd.h
 .Ft int
 .Fn fsync "int fd"
+.Ft int
+.Fn fsync_range "int fd" "int how" "off_t start" "off_t length"
 .Sh DESCRIPTION
 .Fn fsync
 causes all modified data and attributes of
@@ -57,13 +60,44 @@
 should be used by programs that require a file to be
 in a known state, for example, in building a simple transaction
 facility.
+.Pp
+.Fn fsync_range
+causes all modified data starting at
+.Fa start
+for length
+.Fa length
+of
+.Fa fd
+to be written to permanent storage. Note that
+.Fn fsync_range
+requires that the file
+.Fa fd
+must be open for writing.
+.Pp
+.Fn fsync_range
+may flush the file data in one of two manners:
+.Bl -tag -width FDATASYNC
+.It Dv FDATASYNC
+synchronize the file data and sufficient meta-data to retrieve the
+data for the specified range.
+.It Dv FFILESYNC
+All modified file data and meta-data for the specified range.
+.El
+.Pp
+If the
+.Fa length
+parameter is zero,=20
+.Fn fsync_range
+will synchronize all of the file data.
 .Sh RETURN VALUES
 A 0 value is returned on success.
 A -1 value indicates an error.
 .Sh ERRORS
 The
 .Fn fsync
-fails if:
+or
+.Fn fsync_range
+fail if:
 .Bl -tag -width Er
 .It Bq Er EBADF
 .Fa fd
@@ -74,6 +108,30 @@
 .It Bq Er EIO
 An I/O error occurred while reading from or writing to the file system.
 .El
+.Pp
+Additionally, the
+.Fn fsync_range
+fails if:
+.Bl -tag -width Er
+.It Bq Er EBADF
+.Fa fd
+is not open for writing.
+.It Bq Er EINVAL
+.Fa start
++
+.Fa length
+is less than
+.Fa start .
+.El
+.Sh NOTES
+For optimal efficienty, the
+.Fn fsync_range
+call requires that the file system containing the file referenced by
+.Fa fd
+support partial synchronization of file data. For file systems which do
+not support partial synchronization, the entire file will be synchronized
+and the call will be the equivalent of calling
+.Fn fsync .
 .Sh SEE ALSO
 .Xr sync 2 ,
 .Xr sync 8
@@ -82,3 +140,9 @@
 .Fn fsync
 function call appeared in
 .Bx 4.2 .
+.Pp
+The
+.Fn fsync_range
+first appeared in
+.Nx 2.0
+and is modeled after the one available in AIX .
Index: lib/libpthread/pthread_cancelstub.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/wasabisrc/src/lib/libpthread/pthread_cancelstub.c,v
retrieving revision 1.1.1.7
diff -u -r1.1.1.7 pthread_cancelstub.c
--- lib/libpthread/pthread_cancelstub.c	11 Mar 2003 02:46:28 -0000	1.1.1.7
+++ lib/libpthread/pthread_cancelstub.c	17 Oct 2003 18:29:56 -0000
@@ -69,6 +69,7 @@
 int	_sys_connect(int, const struct sockaddr *, socklen_t);
 int	_sys_fcntl(int, int, ...);
 int	_sys_fsync(int);
+int	_sys_fsync_range(int, int, off_t, off_t);
 ssize_t	_sys_msgrcv(int, void *, size_t, long, int);
 int	_sys_msgsnd(int, const void *, size_t, int);
 int	_sys___msync13(void *, size_t, int);
@@ -157,6 +158,20 @@
 	return retval;
 }
=20
+int
+_fsync_range(int d, int f, off_t s, off_t e)
+{
+	int retval;
+	pthread_t self;
+
+	self =3D pthread__self();
+	pthread__testcancel(self);
+	retval =3D _sys_fsync(d, f, s, e);
+	pthread__testcancel(self);
+=09
+	return retval;
+}
+
 ssize_t
 msgrcv(int msgid, void *msgp, size_t msgsz, long msgtyp, int msgflg)
 {
@@ -347,6 +362,7 @@
 __strong_alias(_close, close)
 __strong_alias(_fcntl, fcntl)
 __strong_alias(_fsync, fsync)
+__weak_alias(fsync_range, _fsync_range)
 __strong_alias(_msgrcv, msgrcv)
 __strong_alias(_msgsnd, msgsnd)
 __strong_alias(___msync13, __msync13)
Index: lib/libpthread/pthread_testcancel.3
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/wasabisrc/src/lib/libpthread/pthread_testcancel.3,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 pthread_testcancel.3
--- lib/libpthread/pthread_testcancel.3	10 Jun 2003 16:44:36 -0000	1.1.1.1
+++ lib/libpthread/pthread_testcancel.3	17 Oct 2003 18:29:57 -0000
@@ -135,6 +135,7 @@
 .Fn creat ,
 .Fn fcntl ,
 .Fn fsync ,
+.\".Fn fsync_range ,
 .\".Fn getmsg ,
 .\".Fn getpmsg ,
 .\".Fn lockf ,
Index: sys/kern/init_sysent.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/wasabisrc/src/sys/kern/init_sysent.c,v
retrieving revision 1.9
diff -u -r1.9 init_sysent.c
--- sys/kern/init_sysent.c	24 Mar 2003 23:29:37 -0000	1.9
+++ sys/kern/init_sysent.c	17 Oct 2003 18:30:27 -0000
@@ -934,8 +934,8 @@
 	    sys_sched_get_priority_min },	/* 352 =3D sched_get_priority_min */
 	{ 2, s(struct sys_sched_rr_get_interval_args), 0,
 	    sys_sched_rr_get_interval },	/* 353 =3D sched_rr_get_interval */
-	{ 0, 0, 0,
-	    sys_nosys },			/* 354 =3D unimplemented */
+	{ 4, s(struct sys_fsync_range_args), 0,
+	    sys_fsync_range },			/* 354 =3D fsync_range */
 	{ 0, 0, 0,
 	    sys_nosys },			/* 355 =3D unimplemented */
 	{ 0, 0, 0,
Index: sys/kern/syscalls.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/wasabisrc/src/sys/kern/syscalls.c,v
retrieving revision 1.9
diff -u -r1.9 syscalls.c
--- sys/kern/syscalls.c	24 Mar 2003 23:29:37 -0000	1.9
+++ sys/kern/syscalls.c	17 Oct 2003 18:30:28 -0000
@@ -489,7 +489,7 @@
 	"sched_get_priority_max",			/* 351 =3D sched_get_priority_max */
 	"sched_get_priority_min",			/* 352 =3D sched_get_priority_min */
 	"sched_rr_get_interval",			/* 353 =3D sched_rr_get_interval */
-	"#354 (unimplemented)",		/* 354 =3D unimplemented */
+	"fsync_range",			/* 354 =3D fsync_range */
 	"#355 (unimplemented)",		/* 355 =3D unimplemented */
 	"#356 (unimplemented)",		/* 356 =3D unimplemented */
 	"#357 (unimplemented)",		/* 357 =3D unimplemented */
Index: sys/kern/syscalls.master
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/wasabisrc/src/sys/kern/syscalls.master,v
retrieving revision 1.8
diff -u -r1.8 syscalls.master
--- sys/kern/syscalls.master	24 Mar 2003 23:28:34 -0000	1.8
+++ sys/kern/syscalls.master	17 Oct 2003 18:30:28 -0000
@@ -711,5 +711,6 @@
 ;
-354	UNIMPL
+354	STD		{ int sys_fsync_range(int fd, int flags, off_t start, \
+			    off_t length); }
 355	UNIMPL
 356	UNIMPL
 357	UNIMPL
Index: sys/kern/vfs_syscalls.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/wasabisrc/src/sys/kern/vfs_syscalls.c,v
retrieving revision 1.1.1.10
diff -u -r1.1.1.10 vfs_syscalls.c
--- sys/kern/vfs_syscalls.c	24 May 2003 16:16:42 -0000	1.1.1.10
+++ sys/kern/vfs_syscalls.c	17 Oct 2003 18:30:30 -0000
@@ -2867,6 +2867,76 @@
 }
=20
 /*
+ * Sync range of file data, copied from AIX
+ *
+ * FDATASYNC indicates that we need only save enough metadata to be able
+ * to re-read the written data. Note we duplicate AIX's requirement that
+ * the file be open for writing.
+ */
+/* ARGSUSED */
+int
+sys_fsync_range(l, v, retval)
+	struct lwp *l;
+	void *v;
+	register_t *retval;
+{
+	struct sys_fsync_range_args /* {
+		syscallarg(int) fd;
+		syscallarg(int) flags;
+		syscallarg(off_t) start;
+		syscallarg(int) length;
+	} */ *uap =3D v;
+	struct proc *p =3D l->l_proc;
+	struct vnode *vp;
+	struct file *fp;
+	int flags;
+	off_t s;
+	off_t len;
+	int error;
+
+	/* getvnode() will use the descriptor for us */
+	if ((error =3D getvnode(p->p_fd, SCARG(uap, fd), &fp)) !=3D 0)
+		return (error);
+
+	if ((fp->f_flag & FWRITE) =3D=3D 0) {
+		// simple_unlock(&fp->f_slock);
+		FILE_UNUSE(fp, p);
+		return (EBADF);
+	}
+
+	flags =3D SCARG(uap, flags);
+	if ((flags & (FDATASYNC | FFILESYNC)) =3D=3D 0) {
+		/* Do we care? */
+	}
+	if (flags & FDATASYNC)
+		flags =3D FSYNC_DATASYNC | FSYNC_WAIT;
+	else
+		flags =3D FSYNC_WAIT;
+	len =3D SCARG(uap, length);
+	/* If length =3D=3D 0, we do whole file, and s =3D l =3D 0 will do that */
+	if (len) {
+		s =3D SCARG(uap, start);
+		len +=3D s;		/* "len" now holds the end value */
+		if (len < s) {
+			FILE_UNUSE(fp, p);
+			return (EINVAL);
+		}
+	} else
+		s =3D 0;
+	vp =3D (struct vnode *)fp->f_data;
+	vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
+	error =3D VOP_FSYNC(vp, fp->f_cred, flags, s, len, p);
+
+	if (error =3D=3D 0 && bioops.io_fsync !=3D NULL &&
+	    vp->v_mount && (vp->v_mount->mnt_flag & MNT_SOFTDEP))
+		(*bioops.io_fsync)(vp);
+
+	VOP_UNLOCK(vp, 0);
+	FILE_UNUSE(fp, p);
+	return (error);
+}
+
+/*
  * Sync the data of an open file.
  */
 /* ARGSUSED */
Index: sys/sys/syscall.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/wasabisrc/src/sys/sys/syscall.h,v
retrieving revision 1.9
diff -u -r1.9 syscall.h
--- sys/sys/syscall.h	24 Mar 2003 23:29:37 -0000	1.9
+++ sys/sys/syscall.h	17 Oct 2003 18:30:33 -0000
@@ -864,3 +864,6 @@
 /* syscall: "sched_rr_get_interval" ret: "int" args: "pid_t" "struct times=
pec *" */
 #define	SYS_sched_rr_get_interval	353
=20
+/* syscall: "fsync_range" ret: "int" args: "int" "int" "off_t" "off_t" */
+#define	SYS_fsync_range	354
+
Index: sys/sys/syscallargs.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/wasabisrc/src/sys/sys/syscallargs.h,v
retrieving revision 1.9
diff -u -r1.9 syscallargs.h
--- sys/sys/syscallargs.h	24 Mar 2003 23:29:37 -0000	1.9
+++ sys/sys/syscallargs.h	17 Oct 2003 18:30:34 -0000
@@ -1416,6 +1416,13 @@
 	syscallarg(struct timespec *) interval;
 };
=20
+struct sys_fsync_range_args {
+	syscallarg(int) fd;
+	syscallarg(int) flags;
+	syscallarg(off_t) start;
+	syscallarg(off_t) length;
+};
+
 struct sys_wasabi_fprefetch_args {
 	syscallarg(int) fd;
 	syscallarg(int) pad;
@@ -1803,6 +1810,7 @@
 int	sys_sched_get_priority_max(struct lwp *, void *, register_t *);
 int	sys_sched_get_priority_min(struct lwp *, void *, register_t *);
 int	sys_sched_rr_get_interval(struct lwp *, void *, register_t *);
+int	sys_fsync_range(struct lwp *, void *, register_t *);
 int	sys_wasabi_fprefetch(struct lwp *, void *, register_t *);
 int	sys_wasabi_pdonatev(struct lwp *, void *, register_t *);
 int	sys_wasabi_fmlock(struct lwp *, void *, register_t *);
Index: sys/sys/unistd.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/wasabisrc/src/sys/sys/unistd.h,v
retrieving revision 1.1.1.6
diff -u -r1.1.1.6 unistd.h
--- sys/sys/unistd.h	10 Jun 2003 17:58:11 -0000	1.1.1.6
+++ sys/sys/unistd.h	17 Oct 2003 18:30:34 -0000
@@ -118,6 +118,19 @@
 #define	L_XTND		SEEK_END
 #endif
=20
+/*
+ * fsync_range values.
+ *
+ * Note the following flag values were chosen to not overlap
+ * values for SEEK_XXX flags. While not currently implemented,
+ * it is possible to extend this call to respect SEEK_CUR and
+ * SEEK_END offset addressing modes.
+ */
+#define	FDATASYNC		0x0010	/* Sync data and minimal metadata
+					   to reread */
+#define	FFILESYNC		0x0020	/* Sync data and metadata */
+
+
 /* configurable pathname variables */
 #define	_PC_LINK_MAX		 1
 #define	_PC_MAX_CANON		 2
Index: sys/sys/vnode.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/wasabisrc/src/sys/sys/vnode.h,v
retrieving revision 1.1.1.10
diff -u -r1.1.1.10 vnode.h
--- sys/sys/vnode.h	17 Apr 2003 16:06:32 -0000	1.1.1.10
+++ sys/sys/vnode.h	17 Oct 2003 18:30:35 -0000
@@ -267,6 +267,10 @@
 #define	FSYNC_RECLAIM	0x0004		/* fsync: hint: vnode is being reclaimed */
 #define	FSYNC_LAZY	0x0008		/* fsync: lazy sync (trickle) */
=20
+#define	FSYNC_DATASYNC	0x0010		/* fsync: hint: sync file data +
+					   minimal metadata to re-read */
+					/* fsync: same value as FDATASYNC */
+
 #define	UPDATE_WAIT	0x0001		/* update: wait for completion */
 #define	UPDATE_DIROP	0x0002		/* update: hint to fs to wait or not */
=20
Index: sys/ufs/ffs/ffs_vnops.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/wasabisrc/src/sys/ufs/ffs/ffs_vnops.c,v
retrieving revision 1.9
diff -u -r1.9 ffs_vnops.c
--- sys/ufs/ffs/ffs_vnops.c	4 Jun 2003 21:24:53 -0000	1.9
+++ sys/ufs/ffs/ffs_vnops.c	17 Oct 2003 18:30:36 -0000
@@ -327,7 +327,8 @@
 	splx(s);
=20
 	return (VOP_UPDATE(vp, NULL, NULL,
-	    (ap->a_flags & FSYNC_WAIT) ? UPDATE_WAIT : 0));
+	    ((ap->a_flags & (FSYNC_WAIT | FSYNC_DATASYNC)) =3D=3D FSYNC_WAIT)
+	    ? UPDATE_WAIT : 0));
 }
=20
 /*

--xHFwDpU9dbj6ez1V--

--GID0FwUMdk1T2AWN
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.3 (NetBSD)

iD8DBQE/maZnWz+3JHUci9cRAnCxAJ4/OlOKyNAsM+a5zwST5Evs/RUzMgCePRMy
OWLzD/OtfGi7dMw+CGJkOc0=
=M/ZZ
-----END PGP SIGNATURE-----

--GID0FwUMdk1T2AWN--