diff options
author | jhb <jhb@FreeBSD.org> | 2006-03-28 21:22:08 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2006-03-28 21:22:08 +0000 |
commit | ec112a33cb968a27eba07871f470a198843508fa (patch) | |
tree | 9566f642c0d00ae7cf32fc2d3279be2b603805da /sys/kern/vfs_vnops.c | |
parent | 1e32aa137d72d99922585b4ac33609aa1a09b782 (diff) | |
download | FreeBSD-src-ec112a33cb968a27eba07871f470a198843508fa.zip FreeBSD-src-ec112a33cb968a27eba07871f470a198843508fa.tar.gz |
Change vn_open() to honor the MPSAFE flag in the passed in nameidata object
and use that instead of testing fdidx against -1 to determine if it should
release Giant if Giant was locked due to the requested file residing on a
non-MPSAFE VFS.
Discussed with: jeff
Diffstat (limited to 'sys/kern/vfs_vnops.c')
-rw-r--r-- | sys/kern/vfs_vnops.c | 15 |
1 files changed, 9 insertions, 6 deletions
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index e0a6866..4771c3f 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -111,8 +111,9 @@ vn_open_cred(ndp, flagp, cmode, cred, fdidx) struct vattr vat; struct vattr *vap = &vat; int mode, fmode, error; - int vfslocked; + int vfslocked, mpsafe; + mpsafe = ndp->ni_cnd.cn_flags & MPSAFE; restart: vfslocked = 0; fmode = *flagp; @@ -125,8 +126,9 @@ restart: bwillwrite(); if ((error = namei(ndp)) != 0) return (error); - vfslocked = (ndp->ni_cnd.cn_flags & GIANTHELD) != 0; - ndp->ni_cnd.cn_flags &= ~MPSAFE; + vfslocked = NDHASGIANT(ndp); + if (!mpsafe) + ndp->ni_cnd.cn_flags &= ~MPSAFE; if (ndp->ni_vp == NULL) { VATTR_NULL(vap); vap->va_type = VREG; @@ -182,8 +184,9 @@ restart: LOCKSHARED | LOCKLEAF | MPSAFE | AUDITVNODE1; if ((error = namei(ndp)) != 0) return (error); - ndp->ni_cnd.cn_flags &= ~MPSAFE; - vfslocked = (ndp->ni_cnd.cn_flags & GIANTHELD) != 0; + if (!mpsafe) + ndp->ni_cnd.cn_flags &= ~MPSAFE; + vfslocked = NDHASGIANT(ndp); vp = ndp->ni_vp; } if (vp->v_type == VLNK) { @@ -230,7 +233,7 @@ restart: vp->v_writecount++; *flagp = fmode; ASSERT_VOP_LOCKED(vp, "vn_open_cred"); - if (fdidx == -1) + if (!mpsafe) VFS_UNLOCK_GIANT(vfslocked); return (0); bad: |