In kern_linkat(), avoid passing doomed vnode to the VOP.
Tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 2 weeks
This commit is contained in:
parent
2f41c9023e
commit
7b68dd9333
@ -1554,6 +1554,7 @@ kern_linkat(struct thread *td, int fd1, int fd2, char *path1, char *path2,
|
||||
bwillwrite();
|
||||
NDINIT_AT(&nd, LOOKUP, follow | AUDITVNODE1, segflg, path1, fd1, td);
|
||||
|
||||
again:
|
||||
if ((error = namei(&nd)) != 0)
|
||||
return (error);
|
||||
NDFREE(&nd, NDF_ONLY_PNBUF);
|
||||
@ -1576,8 +1577,7 @@ kern_linkat(struct thread *td, int fd1, int fd2, char *path1, char *path2,
|
||||
vput(nd.ni_dvp);
|
||||
vrele(nd.ni_vp);
|
||||
error = EEXIST;
|
||||
} else if ((error = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY))
|
||||
== 0) {
|
||||
} else if ((error = vn_lock(vp, LK_EXCLUSIVE)) == 0) {
|
||||
error = can_hardlink(vp, td->td_ucred);
|
||||
if (error == 0)
|
||||
#ifdef MAC
|
||||
@ -1588,6 +1588,12 @@ kern_linkat(struct thread *td, int fd1, int fd2, char *path1, char *path2,
|
||||
error = VOP_LINK(nd.ni_dvp, vp, &nd.ni_cnd);
|
||||
VOP_UNLOCK(vp, 0);
|
||||
vput(nd.ni_dvp);
|
||||
} else {
|
||||
vput(nd.ni_dvp);
|
||||
NDFREE(&nd, NDF_ONLY_PNBUF);
|
||||
vrele(vp);
|
||||
vn_finished_write(mp);
|
||||
goto again;
|
||||
}
|
||||
NDFREE(&nd, NDF_ONLY_PNBUF);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user