namei() can call underlying nfs_readlink() passing a struct uio pointer

owned by a NULL owner. This will lead consequent VOP_ISLOCKED() present
into nfs_upgrade_vnlock() to panic as it only acquire curthread now.
Fix nfs_upgrade_vnlock() and nfs_downgrade_vnlock() in order to not use
more the struct thread pointer passed as argument (as it is really nomore
required there as vn_lock() and VOP_UNLOCK doesn't get the lock more).
Using curthread, in place, doesn't get ambiguity as LK_EXCLOTHER should
be handled as a "not locked" request by both functions.

Reported by: kris
Tested by: kris
Reviewed by: ups
This commit is contained in:
attilio 2008-02-09 20:13:19 +00:00
parent 969bd2bc47
commit 4274e0aa54
3 changed files with 9 additions and 9 deletions

View File

@ -390,7 +390,7 @@ nfs_bioread_check_cons(struct vnode *vp, struct thread *td, struct ucred *cred)
* XXX - We can make this cheaper later (by acquiring cheaper locks).
* But for now, this suffices.
*/
old_lock = nfs_upgrade_vnlock(vp, td);
old_lock = nfs_upgrade_vnlock(vp);
mtx_lock(&np->n_mtx);
if (np->n_flag & NMODIFIED) {
mtx_unlock(&np->n_mtx);
@ -430,7 +430,7 @@ nfs_bioread_check_cons(struct vnode *vp, struct thread *td, struct ucred *cred)
mtx_unlock(&np->n_mtx);
}
out:
nfs_downgrade_vnlock(vp, td, old_lock);
nfs_downgrade_vnlock(vp, old_lock);
return error;
}
@ -1306,7 +1306,7 @@ nfs_vinvalbuf(struct vnode *vp, int flags, struct thread *td, int intrflg)
slptimeo = 0;
}
old_lock = nfs_upgrade_vnlock(vp, td);
old_lock = nfs_upgrade_vnlock(vp);
/*
* Now, flush as required.
*/
@ -1334,7 +1334,7 @@ nfs_vinvalbuf(struct vnode *vp, int flags, struct thread *td, int intrflg)
np->n_flag &= ~NMODIFIED;
mtx_unlock(&np->n_mtx);
out:
nfs_downgrade_vnlock(vp, td, old_lock);
nfs_downgrade_vnlock(vp, old_lock);
return error;
}

View File

@ -480,11 +480,11 @@ nfs_dircookie_unlock(struct nfsnode *np)
}
int
nfs_upgrade_vnlock(struct vnode *vp, struct thread *td)
nfs_upgrade_vnlock(struct vnode *vp)
{
int old_lock;
if ((old_lock = VOP_ISLOCKED(vp, td)) != LK_EXCLUSIVE) {
if ((old_lock = VOP_ISLOCKED(vp, curthread)) != LK_EXCLUSIVE) {
if (old_lock == LK_SHARED) {
/* Upgrade to exclusive lock, this might block */
vn_lock(vp, LK_UPGRADE | LK_RETRY);
@ -496,7 +496,7 @@ nfs_upgrade_vnlock(struct vnode *vp, struct thread *td)
}
void
nfs_downgrade_vnlock(struct vnode *vp, struct thread *td, int old_lock)
nfs_downgrade_vnlock(struct vnode *vp, int old_lock)
{
if (old_lock != LK_EXCLUSIVE) {
if (old_lock == LK_SHARED) {

View File

@ -205,8 +205,8 @@ nfsuint64 *nfs_getcookie(struct nfsnode *, off_t, int);
uint64_t *nfs4_getcookie(struct nfsnode *, off_t, int);
void nfs_invaldir(struct vnode *);
void nfs4_invaldir(struct vnode *);
int nfs_upgrade_vnlock(struct vnode *vp, struct thread *td);
void nfs_downgrade_vnlock(struct vnode *vp, struct thread *td, int old_lock);
int nfs_upgrade_vnlock(struct vnode *vp);
void nfs_downgrade_vnlock(struct vnode *vp, int old_lock);
void nfs_printf(const char *fmt, ...);
void nfs_dircookie_lock(struct nfsnode *np);