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