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
This commit is contained in:
parent
4d02a00a57
commit
c87f1ad43c
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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 *);
|
||||
|
Loading…
x
Reference in New Issue
Block a user