Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/ufs/ffs Cleanup ffs fsync and make devices on wapbl enab...
details: https://anonhg.NetBSD.org/src/rev/be2202b6ee36
branches: trunk
changeset: 764553:be2202b6ee36
user: hannken <hannken%NetBSD.org@localhost>
date: Wed Apr 27 07:24:52 2011 +0000
description:
Cleanup ffs fsync and make devices on wapbl enabled file systems work here:
- Replace the ugly sync loop in ffs_full_fsync() and ffs_vfs_fsync() with
vflushbuf(). This loop is a relic of softdeps and not needed anymore.
- Add ffs_spec_fsync() for device nodes on ffs file systems that calls
spec_fsync() like all other file systems do and then updates the ctime.
Discussed on tech-kern.
Should fix PRs:
PR #41192 wapbl diagnostic panic during cgdconfig
PR #41977 kernel diagnostic assertion "rw_lock_held(&wl->wl_rwlock)" failed
PR #42149 wapbl locking panic if watching DVD
PR #42551 Lockdebug assert in wapbl when running zpool
diffstat:
sys/ufs/ffs/ffs_extern.h | 3 +-
sys/ufs/ffs/ffs_vfsops.c | 85 +----------------------
sys/ufs/ffs/ffs_vnops.c | 166 +++++++++++++++++++---------------------------
3 files changed, 77 insertions(+), 177 deletions(-)
diffs (truncated from 373 to 300 lines):
diff -r 0b50cf82ce42 -r be2202b6ee36 sys/ufs/ffs/ffs_extern.h
--- a/sys/ufs/ffs/ffs_extern.h Wed Apr 27 06:22:11 2011 +0000
+++ b/sys/ufs/ffs/ffs_extern.h Wed Apr 27 07:24:52 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ffs_extern.h,v 1.76 2011/03/06 17:08:38 bouyer Exp $ */
+/* $NetBSD: ffs_extern.h,v 1.77 2011/04/27 07:24:52 hannken Exp $ */
/*-
* Copyright (c) 1991, 1993, 1994
@@ -125,6 +125,7 @@
int ffs_read(void *);
int ffs_write(void *);
int ffs_fsync(void *);
+int ffs_spec_fsync(void *);
int ffs_reclaim(void *);
int ffs_getpages(void *);
void ffs_gop_size(struct vnode *, off_t, off_t *, int);
diff -r 0b50cf82ce42 -r be2202b6ee36 sys/ufs/ffs/ffs_vfsops.c
--- a/sys/ufs/ffs/ffs_vfsops.c Wed Apr 27 06:22:11 2011 +0000
+++ b/sys/ufs/ffs/ffs_vfsops.c Wed Apr 27 07:24:52 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ffs_vfsops.c,v 1.265 2011/03/27 08:04:50 mlelstv Exp $ */
+/* $NetBSD: ffs_vfsops.c,v 1.266 2011/04/27 07:24:53 hannken Exp $ */
/*-
* Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -61,7 +61,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ffs_vfsops.c,v 1.265 2011/03/27 08:04:50 mlelstv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ffs_vfsops.c,v 1.266 2011/04/27 07:24:53 hannken Exp $");
#if defined(_KERNEL_OPT)
#include "opt_ffs.h"
@@ -2071,14 +2071,12 @@
}
/*
- * Synch vnode for a mounted file system. This is called for foreign
- * vnodes, i.e. non-ffs.
+ * Synch vnode for a mounted file system.
*/
static int
ffs_vfs_fsync(vnode_t *vp, int flags)
{
- int error, passes, skipmeta, i, pflags;
- buf_t *bp, *nbp;
+ int error, i, pflags;
#ifdef WAPBL
struct mount *mp;
#endif
@@ -2130,80 +2128,9 @@
}
#endif /* WAPBL */
- /*
- * Write out metadata for non-logging file systems. XXX This block
- * should be simplified now that softdep is gone.
- */
- passes = NIADDR + 1;
- skipmeta = 0;
- if (flags & FSYNC_WAIT)
- skipmeta = 1;
-
-loop:
- mutex_enter(&bufcache_lock);
- LIST_FOREACH(bp, &vp->v_dirtyblkhd, b_vnbufs) {
- bp->b_cflags &= ~BC_SCANNED;
- }
- for (bp = LIST_FIRST(&vp->v_dirtyblkhd); bp; bp = nbp) {
- nbp = LIST_NEXT(bp, b_vnbufs);
- if (bp->b_cflags & (BC_BUSY | BC_SCANNED))
- continue;
- if ((bp->b_oflags & BO_DELWRI) == 0)
- panic("ffs_fsync: not dirty");
- if (skipmeta && bp->b_lblkno < 0)
- continue;
- bp->b_cflags |= BC_BUSY | BC_VFLUSH | BC_SCANNED;
- mutex_exit(&bufcache_lock);
- /*
- * On our final pass through, do all I/O synchronously
- * so that we can find out if our flush is failing
- * because of write errors.
- */
- if (passes > 0 || !(flags & FSYNC_WAIT))
- (void) bawrite(bp);
- else if ((error = bwrite(bp)) != 0)
- return (error);
- /*
- * Since we unlocked during the I/O, we need
- * to start from a known point.
- */
- mutex_enter(&bufcache_lock);
- nbp = LIST_FIRST(&vp->v_dirtyblkhd);
- }
- mutex_exit(&bufcache_lock);
- if (skipmeta) {
- skipmeta = 0;
- goto loop;
- }
-
- if ((flags & FSYNC_WAIT) != 0) {
- mutex_enter(&vp->v_interlock);
- while (vp->v_numoutput) {
- cv_wait(&vp->v_cv, &vp->v_interlock);
- }
- mutex_exit(&vp->v_interlock);
-
- if (!LIST_EMPTY(&vp->v_dirtyblkhd)) {
- /*
- * Block devices associated with filesystems may
- * have new I/O requests posted for them even if
- * the vnode is locked, so no amount of trying will
- * get them clean. Thus we give block devices a
- * good effort, then just give up. For all other file
- * types, go around and try again until it is clean.
- */
- if (passes > 0) {
- passes--;
- goto loop;
- }
-#ifdef DIAGNOSTIC
- if (vp->v_type != VBLK)
- vprint("ffs_fsync: dirty", vp);
-#endif
- }
- }
-
+ error = vflushbuf(vp, (flags & FSYNC_WAIT) != 0);
if (error == 0 && (flags & FSYNC_CACHE) != 0) {
+ i = 1;
(void)VOP_IOCTL(vp, DIOCCACHESYNC, &i, FWRITE,
kauth_cred_get());
}
diff -r 0b50cf82ce42 -r be2202b6ee36 sys/ufs/ffs/ffs_vnops.c
--- a/sys/ufs/ffs/ffs_vnops.c Wed Apr 27 06:22:11 2011 +0000
+++ b/sys/ufs/ffs/ffs_vnops.c Wed Apr 27 07:24:52 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ffs_vnops.c,v 1.117 2011/04/15 15:54:11 hannken Exp $ */
+/* $NetBSD: ffs_vnops.c,v 1.118 2011/04/27 07:24:53 hannken Exp $ */
/*-
* Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -61,7 +61,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ffs_vnops.c,v 1.117 2011/04/15 15:54:11 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ffs_vnops.c,v 1.118 2011/04/27 07:24:53 hannken Exp $");
#if defined(_KERNEL_OPT)
#include "opt_ffs.h"
@@ -175,7 +175,7 @@
{ &vop_kqfilter_desc, spec_kqfilter }, /* kqfilter */
{ &vop_revoke_desc, spec_revoke }, /* revoke */
{ &vop_mmap_desc, spec_mmap }, /* mmap */
- { &vop_fsync_desc, ffs_fsync }, /* fsync */
+ { &vop_fsync_desc, ffs_spec_fsync }, /* fsync */
{ &vop_seek_desc, spec_seek }, /* seek */
{ &vop_remove_desc, spec_remove }, /* remove */
{ &vop_link_desc, spec_link }, /* link */
@@ -266,6 +266,61 @@
#include <ufs/ufs/ufs_readwrite.c>
int
+ffs_spec_fsync(void *v)
+{
+ struct vop_fsync_args /* {
+ struct vnode *a_vp;
+ kauth_cred_t a_cred;
+ int a_flags;
+ off_t a_offlo;
+ off_t a_offhi;
+ struct lwp *a_l;
+ } */ *ap = v;
+ int error, flags, uflags;
+ struct vnode *vp;
+ struct mount *mp;
+
+ flags = ap->a_flags;
+ uflags = UPDATE_CLOSE | ((flags & FSYNC_WAIT) ? UPDATE_WAIT : 0);
+ vp = ap->a_vp;
+ mp = vp->v_mount;
+
+ fstrans_start(mp, FSTRANS_LAZY);
+
+ error = spec_fsync(v);
+ if (error)
+ goto out;
+
+#ifdef WAPBL
+ if (mp && mp->mnt_wapbl) {
+ /*
+ * Don't bother writing out metadata if the syncer is
+ * making the request. We will let the sync vnode
+ * write it out in a single burst through a call to
+ * VFS_SYNC().
+ */
+ if ((flags & (FSYNC_DATAONLY | FSYNC_LAZY)) != 0)
+ goto out;
+ if ((VTOI(vp)->i_flag & (IN_ACCESS | IN_CHANGE | IN_UPDATE
+ | IN_MODIFY | IN_MODIFIED | IN_ACCESSED)) != 0) {
+ error = UFS_WAPBL_BEGIN(mp);
+ if (error != 0)
+ goto out;
+ error = ffs_update(vp, NULL, NULL, uflags);
+ UFS_WAPBL_END(mp);
+ }
+ goto out;
+ }
+#endif /* WAPBL */
+
+ error = ffs_update(vp, NULL, NULL, uflags);
+
+out:
+ fstrans_done(mp);
+ return error;
+}
+
+int
ffs_fsync(void *v)
{
struct vop_fsync_args /* {
@@ -399,32 +454,27 @@
int
ffs_full_fsync(struct vnode *vp, int flags)
{
- struct buf *bp, *nbp;
- int error, passes, skipmeta, waitfor, i;
+ int error, i, uflags;
struct mount *mp;
+ KASSERT(vp->v_tag == VT_UFS);
KASSERT(VTOI(vp) != NULL);
- KASSERT(vp->v_tag == VT_UFS);
+ KASSERT(vp->v_type != VCHR && vp->v_type != VBLK);
error = 0;
+ uflags = UPDATE_CLOSE | ((flags & FSYNC_WAIT) ? UPDATE_WAIT : 0);
mp = vp->v_mount;
- if (vp->v_type == VBLK && vp->v_specmountpoint != NULL) {
- mp = vp->v_specmountpoint;
- } else {
- mp = vp->v_mount;
- }
/*
* Flush all dirty data associated with the vnode.
*/
- if (vp->v_type == VREG || vp->v_type == VBLK) {
+ if (vp->v_type == VREG) {
int pflags = PGO_ALLPAGES | PGO_CLEANIT;
if ((flags & FSYNC_WAIT))
pflags |= PGO_SYNCIO;
- if (vp->v_type == VREG &&
- fstrans_getstate(mp) == FSTRANS_SUSPENDING)
+ if (fstrans_getstate(mp) == FSTRANS_SUSPENDING)
pflags |= PGO_FREE;
mutex_enter(&vp->v_interlock);
error = VOP_PUTPAGES(vp, 0, 0, pflags);
@@ -433,7 +483,6 @@
}
#ifdef WAPBL
- mp = wapbl_vptomp(vp);
if (mp && mp->mnt_wapbl) {
/*
* Don't bother writing out metadata if the syncer is
@@ -449,8 +498,7 @@
error = UFS_WAPBL_BEGIN(mp);
if (error)
return error;
- error = ffs_update(vp, NULL, NULL, UPDATE_CLOSE |
- ((flags & FSYNC_WAIT) ? UPDATE_WAIT : 0));
+ error = ffs_update(vp, NULL, NULL, uflags);
UFS_WAPBL_END(mp);
}
if (error || (flags & FSYNC_NOLOG) != 0)
@@ -477,87 +525,11 @@
}
#endif /* WAPBL */
- /*
- * Write out metadata for non-logging file systems. XXX This block
- * should be simplified now that softdep is gone.
- */
- passes = NIADDR + 1;
- skipmeta = 0;
- if (flags & FSYNC_WAIT)
- skipmeta = 1;
-
-loop:
- mutex_enter(&bufcache_lock);
- LIST_FOREACH(bp, &vp->v_dirtyblkhd, b_vnbufs) {
- bp->b_cflags &= ~BC_SCANNED;
- }
- for (bp = LIST_FIRST(&vp->v_dirtyblkhd); bp; bp = nbp) {
Home |
Main Index |
Thread Index |
Old Index