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 | |
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
-rw-r--r-- | sys/kern/vfs_extattr.c | 2 | ||||
-rw-r--r-- | sys/kern/vfs_syscalls.c | 2 | ||||
-rw-r--r-- | sys/kern/vfs_vnops.c | 15 |
3 files changed, 11 insertions, 8 deletions
diff --git a/sys/kern/vfs_extattr.c b/sys/kern/vfs_extattr.c index 1d0caa9..bc5a904 100644 --- a/sys/kern/vfs_extattr.c +++ b/sys/kern/vfs_extattr.c @@ -990,7 +990,7 @@ kern_open(struct thread *td, char *path, enum uio_seg pathseg, int flags, /* An extra reference on `nfp' has been held for us by falloc(). */ fp = nfp; cmode = ((mode &~ fdp->fd_cmask) & ALLPERMS) &~ S_ISTXT; - NDINIT(&nd, LOOKUP, FOLLOW | AUDITVNODE1, pathseg, path, td); + NDINIT(&nd, LOOKUP, FOLLOW | AUDITVNODE1 | MPSAFE, pathseg, path, td); td->td_dupfd = -1; /* XXX check for fdopen */ error = vn_open(&nd, &flags, cmode, indx); if (error) { diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 1d0caa9..bc5a904 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -990,7 +990,7 @@ kern_open(struct thread *td, char *path, enum uio_seg pathseg, int flags, /* An extra reference on `nfp' has been held for us by falloc(). */ fp = nfp; cmode = ((mode &~ fdp->fd_cmask) & ALLPERMS) &~ S_ISTXT; - NDINIT(&nd, LOOKUP, FOLLOW | AUDITVNODE1, pathseg, path, td); + NDINIT(&nd, LOOKUP, FOLLOW | AUDITVNODE1 | MPSAFE, pathseg, path, td); td->td_dupfd = -1; /* XXX check for fdopen */ error = vn_open(&nd, &flags, cmode, indx); if (error) { 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: |