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: Thu, 16 Apr 2009 23:56:46 -0400

 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