summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoravg <avg@FreeBSD.org>2016-07-13 11:06:37 +0000
committeravg <avg@FreeBSD.org>2016-07-13 11:06:37 +0000
commitb83688d368150a9722e2f214a9f43d6be0c71582 (patch)
tree08d45ec48bf5eef3bb4a7e48b55fa174514452a6
parent138b29be3feb873c440c9051b4f5f8e38a2a58a7 (diff)
downloadFreeBSD-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.c22
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);
}
OpenPOWER on IntegriCloud