Author: pjd
Date: Sat Aug 28 08:57:15 2010
New Revision: 211930
URL: http://svn.freebsd.org/changeset/base/211930

Log:
  There is a bug in vfs_allocate_syncvnode() failure handling in mount code.
  Actually it is hard to properly handle such a failure, especially in 
MNT_UPDATE
  case. The only reason for the vfs_allocate_syncvnode() function to fail is
  getnewvnode() failure. Fortunately it is impossible for current implementation
  of getnewvnode() to fail, so we can assert this and make
  vfs_allocate_syncvnode() void. This in turn free us from handling its failures
  in the mount code.
  
  Reviewed by:  kib
  MFC after:    1 month

Modified:
  head/sys/kern/vfs_mount.c
  head/sys/kern/vfs_subr.c
  head/sys/sys/mount.h

Modified: head/sys/kern/vfs_mount.c
==============================================================================
--- head/sys/kern/vfs_mount.c   Sat Aug 28 08:39:37 2010        (r211929)
+++ head/sys/kern/vfs_mount.c   Sat Aug 28 08:57:15 2010        (r211930)
@@ -1036,7 +1036,7 @@ vfs_domount(
                MNT_IUNLOCK(mp);
                if ((mp->mnt_flag & MNT_RDONLY) == 0) {
                        if (mp->mnt_syncer == NULL)
-                               error = vfs_allocate_syncvnode(mp);
+                               vfs_allocate_syncvnode(mp);
                } else {
                        if (mp->mnt_syncer != NULL)
                                vrele(mp->mnt_syncer);
@@ -1078,10 +1078,8 @@ vfs_domount(
                mountcheckdirs(vp, newdp);
                vrele(newdp);
                if ((mp->mnt_flag & MNT_RDONLY) == 0)
-                       error = vfs_allocate_syncvnode(mp);
+                       vfs_allocate_syncvnode(mp);
                vfs_unbusy(mp);
-               if (error)
-                       vrele(vp);
        } else {
                vfs_unbusy(mp);
                vfs_mount_destroy(mp);
@@ -1311,7 +1309,7 @@ dounmount(mp, flags, td)
                mp->mnt_kern_flag &= ~MNTK_NOINSMNTQ;
                if ((mp->mnt_flag & MNT_RDONLY) == 0 && mp->mnt_syncer == NULL) 
{
                        MNT_IUNLOCK(mp);
-                       (void) vfs_allocate_syncvnode(mp);
+                       vfs_allocate_syncvnode(mp);
                        MNT_ILOCK(mp);
                }
                mp->mnt_kern_flag &= ~(MNTK_UNMOUNT | MNTK_UNMOUNTF);

Modified: head/sys/kern/vfs_subr.c
==============================================================================
--- head/sys/kern/vfs_subr.c    Sat Aug 28 08:39:37 2010        (r211929)
+++ head/sys/kern/vfs_subr.c    Sat Aug 28 08:57:15 2010        (r211930)
@@ -3365,7 +3365,7 @@ static struct vop_vector sync_vnodeops =
 /*
  * Create a new filesystem syncer vnode for the specified mount point.
  */
-int
+void
 vfs_allocate_syncvnode(struct mount *mp)
 {
        struct vnode *vp;
@@ -3374,16 +3374,15 @@ vfs_allocate_syncvnode(struct mount *mp)
        int error;
 
        /* Allocate a new vnode */
-       if ((error = getnewvnode("syncer", mp, &sync_vnodeops, &vp)) != 0) {
-               mp->mnt_syncer = NULL;
-               return (error);
-       }
+       error = getnewvnode("syncer", mp, &sync_vnodeops, &vp);
+       if (error != 0)
+               panic("vfs_allocate_syncvnode: getnewvnode() failed");
        vp->v_type = VNON;
        vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
        vp->v_vflag |= VV_FORCEINSMQ;
        error = insmntque(vp, mp);
        if (error != 0)
-               panic("vfs_allocate_syncvnode: insmntque failed");
+               panic("vfs_allocate_syncvnode: insmntque() failed");
        vp->v_vflag &= ~VV_FORCEINSMQ;
        VOP_UNLOCK(vp, 0);
        /*
@@ -3411,7 +3410,6 @@ vfs_allocate_syncvnode(struct mount *mp)
        mtx_unlock(&sync_mtx);
        BO_UNLOCK(bo);
        mp->mnt_syncer = vp;
-       return (0);
 }
 
 /*

Modified: head/sys/sys/mount.h
==============================================================================
--- head/sys/sys/mount.h        Sat Aug 28 08:39:37 2010        (r211929)
+++ head/sys/sys/mount.h        Sat Aug 28 08:57:15 2010        (r211930)
@@ -730,7 +730,7 @@ void        vfs_msync(struct mount *, int);
 int    vfs_busy(struct mount *, int);
 int    vfs_export                       /* process mount export info */
            (struct mount *, struct export_args *);
-int    vfs_allocate_syncvnode(struct mount *);
+void   vfs_allocate_syncvnode(struct mount *);
 int    vfs_donmount(struct thread *td, int fsflags, struct uio *fsoptions);
 void   vfs_getnewfsid(struct mount *);
 struct cdev *vfs_getrootfsid(struct mount *);
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "[email protected]"

Reply via email to