diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master index ee633428f1f8..a1d70544cb7b 100644 --- a/sys/kern/syscalls.master +++ b/sys/kern/syscalls.master @@ -1,4 +1,4 @@ - $NetBSD: syscalls.master,v 1.133 2003/09/30 20:36:10 christos Exp $ + $NetBSD: syscalls.master,v 1.134 2003/11/15 01:19:38 thorpej Exp $ ; @(#)syscalls.master 8.2 (Berkeley) 1/13/94 @@ -705,3 +705,6 @@ 351 UNIMPL sys_sched_get_priority_max 352 UNIMPL sys_sched_get_priority_min 353 UNIMPL sys_sched_rr_get_interval + +354 STD { int sys_fsync_range(int fd, int flags, off_t start, \ + off_t length); } diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 5b5f29b888c2..405e0f075479 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -1,4 +1,4 @@ -/* $NetBSD: vfs_syscalls.c,v 1.200 2003/11/09 07:55:38 yamt Exp $ */ +/* $NetBSD: vfs_syscalls.c,v 1.201 2003/11/15 01:19:38 thorpej Exp $ */ /* * Copyright (c) 1989, 1993 @@ -37,7 +37,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: vfs_syscalls.c,v 1.200 2003/11/09 07:55:38 yamt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vfs_syscalls.c,v 1.201 2003/11/15 01:19:38 thorpej Exp $"); #include "opt_compat_netbsd.h" #include "opt_compat_43.h" @@ -3005,6 +3005,80 @@ sys_fsync(l, v, retval) return (error); } +/* + * Sync a range of file data. API modeled after that found in 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 = v; + struct proc *p = l->l_proc; + struct vnode *vp; + struct file *fp; + int flags, nflags; + off_t s, e, len; + int error; + + /* getvnode() will use the descriptor for us */ + if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0) + return (error); + + if ((fp->f_flag & FWRITE) == 0) { + FILE_UNUSE(fp, p); + return (EBADF); + } + + flags = SCARG(uap, flags); + if (((flags & (FDATASYNC | FFILESYNC)) == 0) || + ((~flags & (FDATASYNC | FFILESYNC)) == 0)) { + return (EINVAL); + } + /* Now set up the flags for value(s) to pass to VOP_FSYNC() */ + if (flags & FDATASYNC) + nflags = FSYNC_DATAONLY | FSYNC_WAIT; + else + nflags = FSYNC_WAIT; + + len = SCARG(uap, length); + /* If length == 0, we do the whole file, and s = l = 0 will do that */ + if (len) { + s = SCARG(uap, start); + e = s + len; + if (e < s) { + FILE_UNUSE(fp, p); + return (EINVAL); + } + } else { + e = 0; + s = 0; + } + + vp = (struct vnode *)fp->f_data; + vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); + error = VOP_FSYNC(vp, fp->f_cred, nflags, s, e, p); + + if (error == 0 && bioops.io_fsync != 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. */ diff --git a/sys/sys/unistd.h b/sys/sys/unistd.h index 68e2897153dd..a32c9e1a36e1 100644 --- a/sys/sys/unistd.h +++ b/sys/sys/unistd.h @@ -1,4 +1,4 @@ -/* $NetBSD: unistd.h,v 1.29 2003/08/07 16:34:21 agc Exp $ */ +/* $NetBSD: unistd.h,v 1.30 2003/11/15 01:19:38 thorpej Exp $ */ /* * Copyright (c) 1989, 1993 @@ -112,6 +112,17 @@ #define L_SET SEEK_SET #define L_INCR SEEK_CUR #define L_XTND SEEK_END + +/* + * 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 */ +#define FFILESYNC 0x0020 /* sync data and metadata */ #endif /* configurable pathname variables */ diff --git a/sys/ufs/ffs/ffs_vnops.c b/sys/ufs/ffs/ffs_vnops.c index fa1bc7b00b54..925849bcde3d 100644 --- a/sys/ufs/ffs/ffs_vnops.c +++ b/sys/ufs/ffs/ffs_vnops.c @@ -1,4 +1,4 @@ -/* $NetBSD: ffs_vnops.c,v 1.65 2003/11/08 07:13:57 jdolecek Exp $ */ +/* $NetBSD: ffs_vnops.c,v 1.66 2003/11/15 01:19:38 thorpej Exp $ */ /* * Copyright (c) 1982, 1986, 1989, 1993 @@ -32,7 +32,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ffs_vnops.c,v 1.65 2003/11/08 07:13:57 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ffs_vnops.c,v 1.66 2003/11/15 01:19:38 thorpej Exp $"); #include #include @@ -318,7 +318,8 @@ ffs_fsync(v) splx(s); return (VOP_UPDATE(vp, NULL, NULL, - (ap->a_flags & FSYNC_WAIT) ? UPDATE_WAIT : 0)); + ((ap->a_flags & (FSYNC_WAIT | FSYNC_DATAONLY)) == FSYNC_WAIT) + ? UPDATE_WAIT : 0)); } /*