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 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