Kernel portion of the fsync_range(2) system call. Written by Bill

Studenmund, and contributed by Wasabi Systems, Inc.
This commit is contained in:
thorpej 2003-11-15 01:19:38 +00:00
parent bafaeff914
commit 857f24339f
4 changed files with 96 additions and 7 deletions

View File

@ -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); }

View File

@ -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 <sys/cdefs.h>
__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.
*/

View File

@ -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 */

View File

@ -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 <sys/cdefs.h>
__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 <sys/param.h>
#include <sys/systm.h>
@ -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));
}
/*