Module Name: src Committed By: hannken Date: Wed Feb 20 10:08:38 UTC 2019
Modified Files: src/external/cddl/osnet/dist/uts/common/fs/zfs: zfs_ctldir.c src/sys/kern: vfs_mount.c vfs_trans.c Log Message: Move fstrans_unmount() to vfs_rele(), just before it would free the mount. Don't take a mount reference for fstrans as it gets notified about the release. Defer the final free of the mount to fstrans_mount_dtor() when fstrans has released all references to this mount. Prevents the mount's memory to be reused as a new mount before fstrans released all references. Address PR kern/53928 modules/t_builtin:disable test case randomly fails. To generate a diff of this commit: cvs rdiff -u -r1.5 -r1.6 \ src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_ctldir.c cvs rdiff -u -r1.69 -r1.70 src/sys/kern/vfs_mount.c cvs rdiff -u -r1.52 -r1.53 src/sys/kern/vfs_trans.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_ctldir.c diff -u src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_ctldir.c:1.5 src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_ctldir.c:1.6 --- src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_ctldir.c:1.5 Tue Feb 5 09:55:48 2019 +++ src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_ctldir.c Wed Feb 20 10:08:37 2019 @@ -1261,7 +1261,6 @@ zfsctl_umount_snapshots(vfs_t *vfsp, int #ifdef __NetBSD__ -#include <sys/fstrans.h> #include <sys/malloc.h> #include <sys/pathname.h> #include <miscfs/genfs/genfs.h> @@ -1354,7 +1353,6 @@ sfs_snapshot_mount(vnode_t *vp, const ch out:; if (error && vfsp) { mutex_exit(&vfsp->mnt_updating); - fstrans_unmount(vfsp); vfs_rele(vfsp); } PNBUF_PUT(osname); Index: src/sys/kern/vfs_mount.c diff -u src/sys/kern/vfs_mount.c:1.69 src/sys/kern/vfs_mount.c:1.70 --- src/sys/kern/vfs_mount.c:1.69 Wed Feb 20 10:07:27 2019 +++ src/sys/kern/vfs_mount.c Wed Feb 20 10:08:37 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: vfs_mount.c,v 1.69 2019/02/20 10:07:27 hannken Exp $ */ +/* $NetBSD: vfs_mount.c,v 1.70 2019/02/20 10:08:37 hannken Exp $ */ /*- * Copyright (c) 1997-2011 The NetBSD Foundation, Inc. @@ -67,7 +67,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: vfs_mount.c,v 1.69 2019/02/20 10:07:27 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vfs_mount.c,v 1.70 2019/02/20 10:08:37 hannken Exp $"); #include <sys/param.h> #include <sys/kernel.h> @@ -297,7 +297,13 @@ vfs_rele(struct mount *mp) if (mp->mnt_op != NULL) { vfs_delref(mp->mnt_op); } - kmem_free(mp, sizeof(*mp)); + fstrans_unmount(mp); + /* + * Final free of mp gets done from fstrans_mount_dtor(). + * + * Prevents this memory to be reused as a mount before + * fstrans releases all references to it. + */ } /* @@ -818,7 +824,6 @@ err_mounted: err_unmounted: vp->v_mountedhere = NULL; mutex_exit(&mp->mnt_updating); - fstrans_unmount(mp); vfs_rele(mp); return error; @@ -906,7 +911,6 @@ dounmount(struct mount *mp, int flags, s panic("unmount: dangling vnode"); vfs_hooks_unmount(mp); - fstrans_unmount(mp); vfs_rele(mp); /* reference from mount() */ if (coveredvp != NULLVP) { vrele(coveredvp); Index: src/sys/kern/vfs_trans.c diff -u src/sys/kern/vfs_trans.c:1.52 src/sys/kern/vfs_trans.c:1.53 --- src/sys/kern/vfs_trans.c:1.52 Wed Feb 20 10:07:27 2019 +++ src/sys/kern/vfs_trans.c Wed Feb 20 10:08:37 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: vfs_trans.c,v 1.52 2019/02/20 10:07:27 hannken Exp $ */ +/* $NetBSD: vfs_trans.c,v 1.53 2019/02/20 10:08:37 hannken Exp $ */ /*- * Copyright (c) 2007 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: vfs_trans.c,v 1.52 2019/02/20 10:07:27 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vfs_trans.c,v 1.53 2019/02/20 10:08:37 hannken Exp $"); /* * File system transaction operations. @@ -186,8 +186,8 @@ fstrans_mount_dtor(struct mount *mp) mutex_exit(&fstrans_mount_lock); + kmem_free(mp, sizeof(*mp)); kmem_free(fmi, sizeof(*fmi)); - vfs_rele(mp); } /* @@ -208,8 +208,6 @@ fstrans_mount(struct mount *mp) mp->mnt_transinfo = newfmi; mutex_exit(&fstrans_mount_lock); - vfs_ref(mp); - return 0; } @@ -719,8 +717,11 @@ fscow_establish(struct mount *mp, int (* KASSERT(mp != dead_rootmount); + mutex_enter(&fstrans_mount_lock); fmi = mp->mnt_transinfo; KASSERT(fmi != NULL); + fmi->fmi_ref_cnt += 1; + mutex_exit(&fstrans_mount_lock); newch = kmem_alloc(sizeof(*newch), KM_SLEEP); newch->ch_func = func; @@ -758,6 +759,8 @@ fscow_disestablish(struct mount *mp, int } cow_change_done(mp); + fstrans_mount_dtor(mp); + return hp ? 0 : EINVAL; }