diff options
author | avg <avg@FreeBSD.org> | 2016-07-13 09:40:53 +0000 |
---|---|---|
committer | avg <avg@FreeBSD.org> | 2016-07-13 09:40:53 +0000 |
commit | 39571e4eceeef9408be5ff772014803a167f8f2c (patch) | |
tree | affec798a5afbd339c220feb4373cdf6b2a2480f /sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c | |
parent | 0f651ac9a72ba1b7cd7b5d4ce88dff602cf339bf (diff) | |
download | FreeBSD-src-39571e4eceeef9408be5ff772014803a167f8f2c.zip FreeBSD-src-39571e4eceeef9408be5ff772014803a167f8f2c.tar.gz |
MFC r299902,299938: mount_snapshot: consolidate all error handling
Diffstat (limited to 'sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c')
-rw-r--r-- | sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c | 38 |
1 files changed, 21 insertions, 17 deletions
diff --git a/sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c b/sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c index 03e8e5f..6af1e8b 100644 --- a/sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c +++ b/sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c @@ -121,34 +121,39 @@ mount_snapshot(kthread_t *td, vnode_t **vpp, const char *fstype, char *fspath, struct ucred *cr; int error; + ASSERT_VOP_ELOCKED(*vpp, "mount_snapshot"); + + vp = *vpp; + *vpp = NULL; + error = 0; + /* * Be ultra-paranoid about making sure the type and fspath * variables will fit in our mp buffers, including the * terminating NUL. */ if (strlen(fstype) >= MFSNAMELEN || strlen(fspath) >= MNAMELEN) - return (ENAMETOOLONG); - - vfsp = vfs_byname_kld(fstype, td, &error); - if (vfsp == NULL) - return (ENODEV); - - vp = *vpp; - if (vp->v_type != VDIR) - return (ENOTDIR); + error = ENAMETOOLONG; + if (error == 0 && (vfsp = vfs_byname_kld(fstype, td, &error)) == NULL) + error = ENODEV; + if (error == 0 && vp->v_type != VDIR) + error = ENOTDIR; /* * We need vnode lock to protect v_mountedhere and vnode interlock * to protect v_iflag. */ - vn_lock(vp, LK_SHARED | LK_RETRY); - VI_LOCK(vp); - if ((vp->v_iflag & VI_MOUNT) != 0 || vp->v_mountedhere != NULL) { + if (error == 0) { + VI_LOCK(vp); + if ((vp->v_iflag & VI_MOUNT) == 0 && vp->v_mountedhere == NULL) + vp->v_iflag |= VI_MOUNT; + else + error = EBUSY; VI_UNLOCK(vp); - VOP_UNLOCK(vp, 0); - return (EBUSY); } - vp->v_iflag |= VI_MOUNT; - VI_UNLOCK(vp); + if (error != 0) { + vput(vp); + return (error); + } VOP_UNLOCK(vp, 0); /* @@ -198,7 +203,6 @@ mount_snapshot(kthread_t *td, vnode_t **vpp, const char *fstype, char *fspath, vfs_unbusy(mp); vfs_freeopts(mp->mnt_optnew); vfs_mount_destroy(mp); - *vpp = NULL; return (error); } |