zfsctl: fix several problems with reference counts
* Remove excessive references on a snapshot mountpoint vnode. zfsctl_snapdir_lookup() called VN_HOLD() on a vnode returned from zfsctl_snapshot_mknode() and the latter also had a call to VN_HOLD() on the same vnode. On top of that gfs_dir_create() already returns the vnode with the use count of 1 (set in getnewvnode). So there was 3 references on the vnode. * mount_snapshot() should keep a reference to a covered vnode. That reference is owned by the mountpoint (mounted snapshot filesystem). * Remove cryptic manipulations of a covered vnode in zfs_umount(). FreeBSD dounmount() already does the right thing and releases the covered vnode. PR: 207464 Reported by: dustinwenz@ebureau.com Tested by: Howard Powell <hpowell@lighthouseinstruments.com> MFC after: 3 weeks
This commit is contained in:
parent
7d4ce67a76
commit
3055925d42
@ -229,7 +229,7 @@ mount_snapshot(kthread_t *td, vnode_t **vpp, const char *fstype, char *fspath,
|
||||
vfs_event_signal(NULL, VQ_MOUNT, 0);
|
||||
if (VFS_ROOT(mp, LK_EXCLUSIVE, &mvp))
|
||||
panic("mount: lost mount");
|
||||
vput(vp);
|
||||
VOP_UNLOCK(vp, 0);
|
||||
vfs_unbusy(mp);
|
||||
*vpp = mvp;
|
||||
return (0);
|
||||
|
@ -1076,7 +1076,6 @@ zfsctl_snapdir_lookup(ap)
|
||||
sep->se_name = kmem_alloc(strlen(nm) + 1, KM_SLEEP);
|
||||
(void) strcpy(sep->se_name, nm);
|
||||
*vpp = sep->se_root = zfsctl_snapshot_mknode(dvp, dmu_objset_id(snap));
|
||||
VN_HOLD(*vpp);
|
||||
avl_insert(&sdp->sd_snaps, sep, where);
|
||||
|
||||
dmu_objset_rele(snap, FTAG);
|
||||
@ -1454,7 +1453,6 @@ zfsctl_snapshot_mknode(vnode_t *pvp, uint64_t objset)
|
||||
|
||||
vp = gfs_dir_create(sizeof (zfsctl_node_t), pvp, pvp->v_vfsp,
|
||||
&zfsctl_ops_snapshot, NULL, NULL, MAXNAMELEN, NULL, NULL);
|
||||
VN_HOLD(vp);
|
||||
zcp = vp->v_data;
|
||||
zcp->zc_id = objset;
|
||||
VOP_UNLOCK(vp, 0);
|
||||
|
@ -2005,12 +2005,6 @@ zfs_umount(vfs_t *vfsp, int fflag)
|
||||
*/
|
||||
if (zfsvfs->z_ctldir != NULL)
|
||||
zfsctl_destroy(zfsvfs);
|
||||
if (zfsvfs->z_issnap) {
|
||||
vnode_t *svp = vfsp->mnt_vnodecovered;
|
||||
|
||||
if (svp->v_count >= 2)
|
||||
VN_RELE(svp);
|
||||
}
|
||||
zfs_freevfs(vfsp);
|
||||
|
||||
return (0);
|
||||
|
Loading…
x
Reference in New Issue
Block a user