diff options
author | avg <avg@FreeBSD.org> | 2016-07-13 11:06:37 +0000 |
---|---|---|
committer | avg <avg@FreeBSD.org> | 2016-07-13 11:06:37 +0000 |
commit | b83688d368150a9722e2f214a9f43d6be0c71582 (patch) | |
tree | 08d45ec48bf5eef3bb4a7e48b55fa174514452a6 | |
parent | 138b29be3feb873c440c9051b4f5f8e38a2a58a7 (diff) | |
download | FreeBSD-src-b83688d368150a9722e2f214a9f43d6be0c71582.zip FreeBSD-src-b83688d368150a9722e2f214a9f43d6be0c71582.tar.gz |
MFC r300130: zfsctl_freebsd_root_lookup: gfs_vop_lookup may return a
doomed vnode
-rw-r--r-- | sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c | 22 |
1 files changed, 14 insertions, 8 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 5ee6127..5446208 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 @@ -628,19 +628,25 @@ zfsctl_freebsd_root_lookup(ap) ASSERT(ap->a_cnp->cn_namelen < sizeof(nm)); strlcpy(nm, ap->a_cnp->cn_nameptr, ap->a_cnp->cn_namelen + 1); +relookup: err = zfsctl_root_lookup(dvp, nm, vpp, NULL, 0, NULL, cr, NULL, NULL, NULL); if (err == 0 && (nm[0] != '.' || nm[1] != '\0')) { - if (flags & ISDOTDOT) + if (flags & ISDOTDOT) { VOP_UNLOCK(dvp, 0); - err = vn_lock(*vpp, lkflags); - if (err != 0) { - vrele(*vpp); - *vpp = NULL; - } - if (flags & ISDOTDOT) + err = vn_lock(*vpp, lkflags); + if (err != 0) { + vrele(*vpp); + *vpp = NULL; + } vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY); + } else { + err = vn_lock(*vpp, LK_EXCLUSIVE); + if (err != 0) { + VERIFY3S(err, ==, ENOENT); + goto relookup; + } + } } - return (err); } |