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

Reply via email to