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
On Apr 16, 10:10pm, 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: Thu, 16 Apr 2009 17:09:50 -0500
|
| # uname -a
| NetBSD xen-2.its.iastate.edu 5.0_RC4 NetBSD 5.0_RC4 (XEN3_DOM0) #0: Wed Apr
15 23:03:24 PDT 2009
builds@wb28:/home/builds/ab/netbsd-5/amd64/200904150002Z-obj/home/builds/ab/netbsd-5/src/sys/arch/amd64/compile/XEN3_DOM0
amd64
|
| Another panic. This time I was unmounting an ext2 filesystem, so the
| problem isn't with mke2fs, but seemingly with ext2 filesystems in
| general.
|
| panic: kernel diagnostic assertion "LIST_EMPTY(&vp->v_dirtyblkhd)"
| failed: file "/home/builds/ab/netbsd-5/src/sys/kern/vfs_subr.c", line 872
| fatal breakpoint trap in supervisor mode
| trap type 1 code 0 rip ffffffff804bfded cs e030 rflags 246 cr2
| 7f7ffda04000 cpl 0 rsp ffffa0001e8c7900
| Stopped in pid 752.1 (umount) at netbsd:breakpoint+0x5: leave
| breakpoint() at netbsd:breakpoint+0x5
| panic() at netbsd:panic+0x242
| __kernassert() at netbsd:__kernassert+0x2d
| vinvalbuf() at netbsd:vinvalbuf+0x206
| spec_close() at netbsd:spec_close+0x8a
| VOP_CLOSE() at netbsd:VOP_CLOSE+0x29
| ext2fs_unmount() at netbsd:ext2fs_unmount+0xa3
| dounmount() at netbsd:dounmount+0xd5
| sys_unmount() at netbsd:sys_unmount+0x11c
| syscall() at netbsd:syscall+0xb4
| ds 0x7910
| es 0x121c
| fs 0x7910
| gs 0x12f7
| rdi 0
| rsi 0x1
| rbp 0xffffa0001e8c7900
| rbx 0xffffa0001e8c7910
| rdx 0
| rcx 0
| rax 0x1
| r8 0xffffffff80b56000 cpu_info_primary
| r9 0x1
| r10 0xffffa0001e8c7820
| r11 0xffffffff804fd2b0 xenconscn_putc
| r12 0x104
| r13 0xffffffff809f62d8
| r14 0xffffa0001e8c7ac0
| r15 0
| rip 0xffffffff804bfded breakpoint+0x5
| cs 0xe030
| rflags 0x246
| rsp 0xffffa0001e8c7900
| ss 0xe02b
| netbsd:breakpoint+0x5: leave
I don't know what I am talking about perhaps, but could something like this
be the issue?
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 03:54:58 -0000
@@ -1349,6 +1349,10 @@
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);
+ goto out;
+ }
wait = (ap->a_flags & FSYNC_WAIT) != 0;
if (vp->v_type == VBLK)
@@ -1365,7 +1369,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 03:54:58 -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 03:54:58 -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);
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 03:54:58 -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));
+
/*
* 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 03:54:59 -0000
@@ -2332,3 +2332,177 @@
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))
+{
+ 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 = (*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