svn commit: r196953 - head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs

Pawel Jakub Dawidek pjd at FreeBSD.org
Mon Sep 7 21:46:52 UTC 2009


Author: pjd
Date: Mon Sep  7 21:46:51 2009
New Revision: 196953
URL: http://svn.freebsd.org/changeset/base/196953

Log:
  When snapshot mount point is busy (for example we are still in it)
  we will fail to unmount it, but it won't be removed from the tree,
  so in that case there is no need to reinsert it.
  
  This fixes a panic reproducable in the following steps:
  
  	# zfs create tank/foo
  	# zfs snapshot tank/foo at snap
  	# cd /tank/foo/.zfs/snapshot/snap
  	# umount /tank/foo
  	panic: avl_find() succeeded inside avl_add()
  
  Reported by:	trasz
  MFC after:	3 days

Modified:
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c	Mon Sep  7 20:57:01 2009	(r196952)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c	Mon Sep  7 21:46:51 2009	(r196953)
@@ -1344,7 +1344,15 @@ zfsctl_umount_snapshots(vfs_t *vfsp, int
 		if (vn_ismntpt(sep->se_root)) {
 			error = zfsctl_unmount_snap(sep, fflags, cr);
 			if (error) {
-				avl_add(&sdp->sd_snaps, sep);
+				/*
+				 * Before reinserting snapshot to the tree,
+				 * check if it was actually removed. For example
+				 * when snapshot mount point is busy, we will
+				 * have an error here, but there will be no need
+				 * to reinsert snapshot.
+				 */
+				if (avl_find(&sdp->sd_snaps, sep, NULL) == NULL)
+					avl_add(&sdp->sd_snaps, sep);
 				break;
 			}
 		}


More information about the svn-src-head mailing list