NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: kern/41189: kernel panic xen dom0 using mke2fs & WAPBL
The following reply was made to PR kern/41189; it has been noted by GNATS.
From: christos%zoulas.com@localhost (Christos Zoulas)
To: gnats-bugs%NetBSD.org@localhost, kern-bug-people%netbsd.org@localhost,
gnats-admin%netbsd.org@localhost, netbsd-bugs%netbsd.org@localhost,
jdwhite%iastate.edu@localhost
Cc:
Subject: Re: kern/41189: kernel panic xen dom0 using mke2fs & WAPBL
Date: Fri, 17 Apr 2009 16:25:59 -0400
On Apr 17, 7:15pm, jdwhite%iastate.edu@localhost (Jason White) wrote:
-- Subject: Re: kern/41189: kernel panic xen dom0 using mke2fs & WAPBL
| The following reply was made to PR kern/41189; it has been noted by GNATS.
|
| From: Jason White <jdwhite%iastate.edu@localhost>
| To: gnats-bugs%NetBSD.org@localhost
| Cc:
| Subject: Re: kern/41189: kernel panic xen dom0 using mke2fs & WAPBL
| Date: Fri, 17 Apr 2009 14:10:34 -0500
|
| Tried the above patch against today's 5.0RC4 sources:
|
| Right after I invoke mke2fs I get a panic:
Did you run mke2fs on a partition that used to contain an ffs filesystem?
Was that mounted?
| This panic happens when I unmount an ext2 partition:
|
| panic: kernel diagnostic assertion "vp->v_tag == VT_UFS" failed: file
This is my fault, new patch:
Index: ext2fs/ext2fs_vnops.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/ext2fs/ext2fs_vnops.c,v
retrieving revision 1.83
diff -u -u -r1.83 ext2fs_vnops.c
--- ext2fs/ext2fs_vnops.c 23 Nov 2008 10:09:25 -0000 1.83
+++ ext2fs/ext2fs_vnops.c 17 Apr 2009 20:24:10 -0000
@@ -1349,6 +1349,11 @@
int wait;
int error;
+ if ((ap->a_offlo == 0 && ap->a_offhi == 0) || (vp->v_type != VREG)) {
+ error = ufs_full_fsync(vp, ap->a_flags, ext2fs_update,
+ VT_EXT2FS);
+ goto out;
+ }
wait = (ap->a_flags & FSYNC_WAIT) != 0;
if (vp->v_type == VBLK)
@@ -1365,7 +1370,7 @@
error = VOP_IOCTL(VTOI(vp)->i_devvp, DIOCCACHESYNC, &l, FWRITE,
curlwp->l_cred);
}
-
+out:
return error;
}
Index: ffs/ffs_extern.h
===================================================================
RCS file: /cvsroot/src/sys/ufs/ffs/ffs_extern.h,v
retrieving revision 1.75
diff -u -u -r1.75 ffs_extern.h
--- ffs/ffs_extern.h 22 Feb 2009 20:28:06 -0000 1.75
+++ ffs/ffs_extern.h 17 Apr 2009 20:24:10 -0000
@@ -138,7 +138,6 @@
int ffs_lock(void *);
int ffs_unlock(void *);
int ffs_islocked(void *);
-int ffs_full_fsync(struct vnode *, int);
/*
* Snapshot function prototypes.
Index: ffs/ffs_vnops.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/ffs/ffs_vnops.c,v
retrieving revision 1.112
diff -u -u -r1.112 ffs_vnops.c
--- ffs/ffs_vnops.c 29 Mar 2009 10:29:00 -0000 1.112
+++ ffs/ffs_vnops.c 17 Apr 2009 20:24:10 -0000
@@ -290,7 +290,7 @@
fstrans_start(vp->v_mount, FSTRANS_LAZY);
if ((ap->a_offlo == 0 && ap->a_offhi == 0) || (vp->v_type != VREG)) {
- error = ffs_full_fsync(vp, ap->a_flags);
+ error = ufs_full_fsync(vp, ap->a_flags, ffs_update, VT_UFS);
goto out;
}
@@ -394,179 +394,6 @@
}
/*
- * Synch an open file. Called for VOP_FSYNC().
- */
-/* ARGSUSED */
-int
-ffs_full_fsync(struct vnode *vp, int flags)
-{
- struct buf *bp, *nbp;
- int error, passes, skipmeta, waitfor, i;
- struct mount *mp;
-
- KASSERT(VTOI(vp) != NULL);
- KASSERT(vp->v_tag == VT_UFS);
-
- error = 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) {
- int pflags = PGO_ALLPAGES | PGO_CLEANIT;
-
- if ((flags & FSYNC_WAIT))
- pflags |= PGO_SYNCIO;
- if (vp->v_type == VREG &&
- fstrans_getstate(mp) == FSTRANS_SUSPENDING)
- pflags |= PGO_FREE;
- mutex_enter(&vp->v_interlock);
- error = VOP_PUTPAGES(vp, 0, 0, pflags);
- if (error)
- return error;
- }
-
-#ifdef WAPBL
- mp = wapbl_vptomp(vp);
- 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)
- return 0;
-
- 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)
- return error;
- error = ffs_update(vp, NULL, NULL, UPDATE_CLOSE |
- ((flags & FSYNC_WAIT) ? UPDATE_WAIT : 0));
- UFS_WAPBL_END(mp);
- }
- if (error || (flags & FSYNC_NOLOG) != 0)
- return error;
-
- /*
- * Don't flush the log if the vnode being flushed
- * contains no dirty buffers that could be in the log.
- */
- if (!LIST_EMPTY(&vp->v_dirtyblkhd)) {
- error = wapbl_flush(mp->mnt_wapbl, 0);
- if (error)
- return error;
- }
-
- if ((flags & FSYNC_WAIT) != 0) {
- mutex_enter(&vp->v_interlock);
- while (vp->v_numoutput != 0)
- cv_wait(&vp->v_cv, &vp->v_interlock);
- mutex_exit(&vp->v_interlock);
- }
-
- return error;
- }
-#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);
-
- /*
- * Ensure that any filesystem metadata associated
- * with the vnode has been written.
- */
- 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
- }
- }
-
- waitfor = (flags & FSYNC_WAIT) ? UPDATE_WAIT : 0;
- error = ffs_update(vp, NULL, NULL, UPDATE_CLOSE | waitfor);
-
- if (error == 0 && (flags & FSYNC_CACHE) != 0) {
- (void)VOP_IOCTL(VTOI(vp)->i_devvp, DIOCCACHESYNC, &i, FWRITE,
- kauth_cred_get());
- }
-
- return error;
-}
-
-/*
* Reclaim an inode so that it can be used for other purposes.
*/
int
Index: ufs/ufs_extern.h
===================================================================
RCS file: /cvsroot/src/sys/ufs/ufs/ufs_extern.h,v
retrieving revision 1.61
diff -u -u -r1.61 ufs_extern.h
--- ufs/ufs_extern.h 22 Feb 2009 20:28:07 -0000 1.61
+++ ufs/ufs_extern.h 17 Apr 2009 20:24:11 -0000
@@ -165,6 +165,9 @@
struct componentname *);
int ufs_gop_alloc(struct vnode *, off_t, off_t, int, kauth_cred_t);
void ufs_gop_markupdate(struct vnode *, int);
+int ufs_full_fsync(struct vnode *, int, int (*)(struct vnode *,
+ const struct timespec *, const struct timespec *, int), int);
+
/*
* Snapshot function prototypes.
Index: ufs/ufs_vnops.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/ufs/ufs_vnops.c,v
retrieving revision 1.173
diff -u -u -r1.173 ufs_vnops.c
--- ufs/ufs_vnops.c 22 Feb 2009 20:28:07 -0000 1.173
+++ ufs/ufs_vnops.c 17 Apr 2009 20:24:11 -0000
@@ -2332,3 +2332,179 @@
ip->i_flag |= mask;
}
}
+
+/*
+ * Synch an open file. Called for VOP_FSYNC().
+ */
+/* ARGSUSED */
+int
+ufs_full_fsync(struct vnode *vp, int flags, int (*update)(struct vnode *,
+ const struct timespec *, const struct timespec *, int), int vtag)
+{
+ struct buf *bp, *nbp;
+ int error, passes, skipmeta, waitfor, i;
+ struct mount *mp;
+
+ KASSERT(VTOI(vp) != NULL);
+ KASSERT(vp->v_tag == vtag);
+
+ error = 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) {
+ int pflags = PGO_ALLPAGES | PGO_CLEANIT;
+
+ if ((flags & FSYNC_WAIT))
+ pflags |= PGO_SYNCIO;
+ if (vp->v_type == VREG &&
+ fstrans_getstate(mp) == FSTRANS_SUSPENDING)
+ pflags |= PGO_FREE;
+ mutex_enter(&vp->v_interlock);
+ error = VOP_PUTPAGES(vp, 0, 0, pflags);
+ if (error)
+ return error;
+ }
+
+#ifdef WAPBL
+ if (vtag == VT_UFS) {
+ mp = wapbl_vptomp(vp);
+ 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)
+ return 0;
+
+ 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)
+ return error;
+ error = (*update)(vp, NULL, NULL, UPDATE_CLOSE |
+ ((flags & FSYNC_WAIT) ? UPDATE_WAIT : 0));
+ UFS_WAPBL_END(mp);
+ }
+ if (error || (flags & FSYNC_NOLOG) != 0)
+ return error;
+
+ /*
+ * Don't flush the log if the vnode being flushed
+ * contains no dirty buffers that could be in the log.
+ */
+ if (!LIST_EMPTY(&vp->v_dirtyblkhd)) {
+ error = wapbl_flush(mp->mnt_wapbl, 0);
+ if (error)
+ return error;
+ }
+
+ if ((flags & FSYNC_WAIT) != 0) {
+ mutex_enter(&vp->v_interlock);
+ while (vp->v_numoutput != 0)
+ cv_wait(&vp->v_cv, &vp->v_interlock);
+ mutex_exit(&vp->v_interlock);
+ }
+
+ return error;
+ }
+ }
+#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("ufs_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);
+
+ /*
+ * Ensure that any filesystem metadata associated
+ * with the vnode has been written.
+ */
+ 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
+ }
+ }
+
+ waitfor = (flags & FSYNC_WAIT) ? UPDATE_WAIT : 0;
+ error = (*update)(vp, NULL, NULL, UPDATE_CLOSE | waitfor);
+
+ if (error == 0 && (flags & FSYNC_CACHE) != 0) {
+ (void)VOP_IOCTL(VTOI(vp)->i_devvp, DIOCCACHESYNC, &i, FWRITE,
+ kauth_cred_get());
+ }
+
+ return error;
+}
Home |
Main Index |
Thread Index |
Old Index