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;
}