Extend fsync_range(2) to support the FDISKSYNC flag, which requests

that the sync be propogated out through the disk drive caches.
This commit is contained in:
wrstuden 2005-01-25 23:55:20 +00:00
parent d9b6766216
commit e384a44e9d
9 changed files with 83 additions and 25 deletions

View File

@ -1,4 +1,4 @@
.\" $NetBSD: fsync.2,v 1.15 2003/11/18 08:49:18 wiz Exp $
.\" $NetBSD: fsync.2,v 1.16 2005/01/25 23:55:20 wrstuden Exp $
.\"
.\" Copyright (c) 1983, 1993
.\" The Regents of the University of California. All rights reserved.
@ -81,6 +81,16 @@ data for the specified range.
Synchronize all modified file data and meta-data for the specified range.
.El
.Pp
By default,
.Fn fsync_range
does not flush disk caches, assuming that storage media are able to ensure
completed writes are transfered to media.
The
.Fa FDISKSYNC
flag may be included in the
.Fa how
parameter to trigger flushing of all disk caches for the file.
.Pp
If the
.Fa length
parameter is zero,

View File

@ -1,4 +1,4 @@
/* $NetBSD: vfs_syscalls.c,v 1.215 2005/01/24 21:27:02 dbj Exp $ */
/* $NetBSD: vfs_syscalls.c,v 1.216 2005/01/25 23:55:20 wrstuden Exp $ */
/*
* Copyright (c) 1989, 1993
@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: vfs_syscalls.c,v 1.215 2005/01/24 21:27:02 dbj Exp $");
__KERNEL_RCSID(0, "$NetBSD: vfs_syscalls.c,v 1.216 2005/01/25 23:55:20 wrstuden Exp $");
#include "opt_compat_netbsd.h"
#include "opt_compat_43.h"
@ -3025,7 +3025,7 @@ sys_fsync(l, v, retval)
error = VOP_FSYNC(vp, fp->f_cred, FSYNC_WAIT, 0, 0, p);
if (error == 0 && bioops.io_fsync != NULL &&
vp->v_mount && (vp->v_mount->mnt_flag & MNT_SOFTDEP))
(*bioops.io_fsync)(vp);
(*bioops.io_fsync)(vp, 0);
VOP_UNLOCK(vp, 0);
vn_finished_write(mp, 0);
FILE_UNUSE(fp, p);
@ -3078,6 +3078,8 @@ sys_fsync_range(l, v, retval)
nflags = FSYNC_DATAONLY | FSYNC_WAIT;
else
nflags = FSYNC_WAIT;
if (flags & FDISKSYNC)
nflags |= FSYNC_CACHE;
len = SCARG(uap, length);
/* If length == 0, we do the whole file, and s = l = 0 will do that */
@ -3099,7 +3101,7 @@ sys_fsync_range(l, v, retval)
if (error == 0 && bioops.io_fsync != NULL &&
vp->v_mount && (vp->v_mount->mnt_flag & MNT_SOFTDEP))
(*bioops.io_fsync)(vp);
(*bioops.io_fsync)(vp, nflags);
VOP_UNLOCK(vp, 0);
FILE_UNUSE(fp, p);

View File

@ -1,4 +1,4 @@
/* $NetBSD: genfs_vnops.c,v 1.93 2005/01/25 09:50:31 drochner Exp $ */
/* $NetBSD: genfs_vnops.c,v 1.94 2005/01/25 23:55:21 wrstuden Exp $ */
/*
* Copyright (c) 1982, 1986, 1989, 1993
@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: genfs_vnops.c,v 1.93 2005/01/25 09:50:31 drochner Exp $");
__KERNEL_RCSID(0, "$NetBSD: genfs_vnops.c,v 1.94 2005/01/25 23:55:21 wrstuden Exp $");
#if defined(_KERNEL_OPT)
#include "opt_nfsserver.h"
@ -99,15 +99,27 @@ genfs_fsync(void *v)
off_t offhi;
struct proc *a_p;
} */ *ap = v;
struct vnode *vp = ap->a_vp;
struct vnode *vp = ap->a_vp, *dvp;
int wait;
int error;
wait = (ap->a_flags & FSYNC_WAIT) != 0;
vflushbuf(vp, wait);
if ((ap->a_flags & FSYNC_DATAONLY) != 0)
return (0);
error = 0;
else
return (VOP_UPDATE(vp, NULL, NULL, wait ? UPDATE_WAIT : 0));
error = VOP_UPDATE(vp, NULL, NULL, wait ? UPDATE_WAIT : 0);
if (error == 0 && ap->a_flags & FSYNC_CACHE) {
int l = 0;
if (VOP_BMAP(vp, 0, &dvp, NULL, NULL))
error = ENXIO;
else
error = VOP_IOCTL(dvp, DIOCCACHESYNC, &l, FWRITE,
ap->a_p->p_ucred, ap->a_p);
}
return (error);
}
int

View File

@ -1,4 +1,4 @@
/* $NetBSD: buf.h,v 1.78 2004/12/18 03:08:48 christos Exp $ */
/* $NetBSD: buf.h,v 1.79 2005/01/25 23:55:21 wrstuden Exp $ */
/*-
* Copyright (c) 1999, 2000 The NetBSD Foundation, Inc.
@ -102,7 +102,7 @@ struct bio_ops {
void (*io_start)(struct buf *);
void (*io_complete)(struct buf *);
void (*io_deallocate)(struct buf *);
int (*io_fsync)(struct vnode *);
int (*io_fsync)(struct vnode *, int);
int (*io_sync)(struct mount *);
void (*io_movedeps)(struct buf *, struct buf *);
int (*io_countdeps)(struct buf *, int);

View File

@ -1,4 +1,4 @@
/* $NetBSD: unistd.h,v 1.31 2004/11/10 04:02:52 lukem Exp $ */
/* $NetBSD: unistd.h,v 1.32 2005/01/25 23:55:21 wrstuden Exp $ */
/*
* Copyright (c) 1989, 1993
@ -123,6 +123,7 @@
*/
#define FDATASYNC 0x0010 /* sync data and minimal metadata */
#define FFILESYNC 0x0020 /* sync data and metadata */
#define FDISKSYNC 0x0040 /* flush disk caches after sync */
#endif
/* configurable pathname variables; use as argument to pathconf(3) */

View File

@ -1,4 +1,4 @@
/* $NetBSD: vnode.h,v 1.131 2005/01/03 16:33:33 thorpej Exp $ */
/* $NetBSD: vnode.h,v 1.132 2005/01/25 23:55:21 wrstuden Exp $ */
/*
* Copyright (c) 1989, 1993
@ -287,6 +287,7 @@ extern const int vttoif_tab[];
#define FSYNC_DATAONLY 0x0002 /* fsync: hint: sync file data only */
#define FSYNC_RECLAIM 0x0004 /* fsync: hint: vnode is being reclaimed */
#define FSYNC_LAZY 0x0008 /* fsync: lazy sync (trickle) */
#define FSYNC_CACHE 0x0100 /* fsync: flush disk caches too */
#define UPDATE_WAIT 0x0001 /* update: wait for completion */
#define UPDATE_DIROP 0x0002 /* update: hint to fs to wait or not */

View File

@ -1,4 +1,4 @@
/* $NetBSD: ffs_softdep.c,v 1.61 2004/12/15 07:11:51 mycroft Exp $ */
/* $NetBSD: ffs_softdep.c,v 1.62 2005/01/25 23:55:21 wrstuden Exp $ */
/*
* Copyright 1998 Marshall Kirk McKusick. All Rights Reserved.
@ -33,11 +33,12 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ffs_softdep.c,v 1.61 2004/12/15 07:11:51 mycroft Exp $");
__KERNEL_RCSID(0, "$NetBSD: ffs_softdep.c,v 1.62 2005/01/25 23:55:21 wrstuden Exp $");
#include <sys/param.h>
#include <sys/buf.h>
#include <sys/callout.h>
#include <sys/fcntl.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/mount.h>
@ -202,7 +203,7 @@ static void softdep_trackbufs(struct inode *, int, boolean_t);
static void softdep_disk_io_initiation __P((struct buf *));
static void softdep_disk_write_complete __P((struct buf *));
static void softdep_deallocate_dependencies __P((struct buf *));
static int softdep_fsync __P((struct vnode *));
static int softdep_fsync __P((struct vnode *, int));
static int softdep_process_worklist __P((struct mount *));
static void softdep_move_dependencies __P((struct buf *, struct buf *));
static int softdep_count_dependencies __P((struct buf *bp, int));
@ -4663,8 +4664,9 @@ merge_inode_lists(inodedep)
* entries for the inode have been written after the inode gets to disk.
*/
static int
softdep_fsync(vp)
softdep_fsync(vp, f)
struct vnode *vp; /* the "in_core" copy of the inode */
int f; /* Flags */
{
struct diradd *dap;
struct inodedep *inodedep;
@ -4679,6 +4681,7 @@ softdep_fsync(vp)
int error, flushparent;
ino_t parentino;
daddr_t lbn;
int l;
ip = VTOI(vp);
fs = ip->i_fs;
@ -4777,6 +4780,14 @@ softdep_fsync(vp)
break;
}
FREE_LOCK(&lk);
if (f & FSYNC_CACHE) {
/*
* If requested, make sure all of these changes don't
* linger in disk caches
*/
l = 0;
VOP_IOCTL(ip->i_devvp, DIOCCACHESYNC, &l, FWRITE, p->p_ucred, p);
}
return (0);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: ffs_vnops.c,v 1.66 2003/11/15 01:19:38 thorpej Exp $ */
/* $NetBSD: ffs_vnops.c,v 1.67 2005/01/25 23:55:21 wrstuden Exp $ */
/*
* Copyright (c) 1982, 1986, 1989, 1993
@ -32,7 +32,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ffs_vnops.c,v 1.66 2003/11/15 01:19:38 thorpej Exp $");
__KERNEL_RCSID(0, "$NetBSD: ffs_vnops.c,v 1.67 2005/01/25 23:55:21 wrstuden Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -317,9 +317,17 @@ ffs_fsync(v)
}
splx(s);
return (VOP_UPDATE(vp, NULL, NULL,
error = VOP_UPDATE(vp, NULL, NULL,
((ap->a_flags & (FSYNC_WAIT | FSYNC_DATAONLY)) == FSYNC_WAIT)
? UPDATE_WAIT : 0));
? UPDATE_WAIT : 0);
if (error == 0 && ap->a_flags & FSYNC_CACHE) {
int l = 0;
VOP_IOCTL(VTOI(vp)->i_devvp, DIOCCACHESYNC, &l, FWRITE,
ap->a_p->p_ucred, ap->a_p);
}
return error;
}
/*
@ -451,7 +459,15 @@ loop:
waitfor = 0;
else
waitfor = (ap->a_flags & FSYNC_WAIT) ? UPDATE_WAIT : 0;
return (VOP_UPDATE(vp, NULL, NULL, waitfor));
error = VOP_UPDATE(vp, NULL, NULL, waitfor);
if (error == 0 && ap->a_flags & FSYNC_WAIT) {
int i = 0;
VOP_IOCTL(VTOI(vp)->i_devvp, DIOCCACHESYNC, &i, FWRITE,
ap->a_p->p_ucred, ap->a_p);
}
return error;
}
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: lfs_vnops.c,v 1.132 2004/04/22 10:45:00 yamt Exp $ */
/* $NetBSD: lfs_vnops.c,v 1.133 2005/01/25 23:55:21 wrstuden Exp $ */
/*-
* Copyright (c) 1999, 2000, 2001, 2002, 2003 The NetBSD Foundation, Inc.
@ -67,7 +67,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: lfs_vnops.c,v 1.132 2004/04/22 10:45:00 yamt Exp $");
__KERNEL_RCSID(0, "$NetBSD: lfs_vnops.c,v 1.133 2005/01/25 23:55:21 wrstuden Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -317,6 +317,11 @@ lfs_fsync(void *v)
if (error)
return error;
error = VOP_UPDATE(vp, NULL, NULL, wait ? UPDATE_WAIT : 0);
if (error == 0 && ap->a_flags & FSYNC_CACHE) {
int l = 0;
error = VOP_IOCTL(VTOI(vp)->i_devvp, DIOCCACHESYNC, &l, FWRITE,
ap->a_p->p_ucred, ap->a_p);
}
if (wait && !VPISEMPTY(vp))
LFS_SET_UINO(VTOI(vp), IN_MODIFIED);