summaryrefslogtreecommitdiffstats
path: root/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c
diff options
context:
space:
mode:
authorpjd <pjd@FreeBSD.org>2009-09-07 21:46:51 +0000
committerpjd <pjd@FreeBSD.org>2009-09-07 21:46:51 +0000
commita72e4e5b626034fcb1d56c7b5856d1768f18a16a (patch)
tree7a0f299356a447b98485d1349d76256094832818 /sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c
parent7761ee5e271ffbe5df4b67f56171d6ed5ad13c86 (diff)
downloadFreeBSD-src-a72e4e5b626034fcb1d56c7b5856d1768f18a16a.zip
FreeBSD-src-a72e4e5b626034fcb1d56c7b5856d1768f18a16a.tar.gz
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@snap # cd /tank/foo/.zfs/snapshot/snap # umount /tank/foo panic: avl_find() succeeded inside avl_add() Reported by: trasz MFC after: 3 days
Diffstat (limited to 'sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c')
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c
index cf99d68..7430c83 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c
@@ -1344,7 +1344,15 @@ zfsctl_umount_snapshots(vfs_t *vfsp, int fflags, cred_t *cr)
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;
}
}
OpenPOWER on IntegriCloud