diff options
| author | John Baldwin <jhb@FreeBSD.org> | 2006-06-20 21:31:38 +0000 |
|---|---|---|
| committer | John Baldwin <jhb@FreeBSD.org> | 2006-06-20 21:31:38 +0000 |
| commit | 62d615d50844083e4b9cc1406ee92afa4e84aef3 (patch) | |
| tree | ff143f7dfd89e19ee50e276b610ffb2807cc1964 /sys/kern/kern_linker.c | |
| parent | 690d79381af2aaa73d538b5d7c65da77a4996287 (diff) | |
Notes
Diffstat (limited to 'sys/kern/kern_linker.c')
| -rw-r--r-- | sys/kern/kern_linker.c | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/sys/kern/kern_linker.c b/sys/kern/kern_linker.c index 6eb62b6cfda5..986f34a0413d 100644 --- a/sys/kern/kern_linker.c +++ b/sys/kern/kern_linker.c @@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$"); #include <sys/sx.h> #include <sys/mac.h> #include <sys/module.h> +#include <sys/mount.h> #include <sys/linker.h> #include <sys/fcntl.h> #include <sys/libkern.h> @@ -1483,7 +1484,7 @@ linker_lookup_file(const char *path, int pathlen, const char *name, struct nameidata nd; struct thread *td = curthread; /* XXX */ char *result, **cpp, *sep; - int error, len, extlen, reclen, flags; + int error, len, extlen, reclen, flags, vfslocked; enum vtype type; extlen = 0; @@ -1504,16 +1505,18 @@ linker_lookup_file(const char *path, int pathlen, const char *name, * Attempt to open the file, and return the path if * we succeed and it's a regular file. */ - NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, result, td); + NDINIT(&nd, LOOKUP, FOLLOW | MPSAFE, UIO_SYSSPACE, result, td); flags = FREAD; error = vn_open(&nd, &flags, 0, -1); if (error == 0) { + vfslocked = NDHASGIANT(&nd); NDFREE(&nd, NDF_ONLY_PNBUF); type = nd.ni_vp->v_type; if (vap) VOP_GETATTR(nd.ni_vp, vap, td->td_ucred, td); VOP_UNLOCK(nd.ni_vp, 0, td); vn_close(nd.ni_vp, FREAD, td->td_ucred, td); + VFS_UNLOCK_GIANT(vfslocked); if (type == VREG) return (result); } @@ -1541,6 +1544,7 @@ linker_hints_lookup(const char *path, int pathlen, const char *modname, u_char *hints = NULL; u_char *cp, *recptr, *bufend, *result, *best, *pathbuf, *sep; int error, ival, bestver, *intp, reclen, found, flags, clen, blen; + int vfslocked = 0; result = NULL; bestver = found = 0; @@ -1552,11 +1556,12 @@ linker_hints_lookup(const char *path, int pathlen, const char *modname, snprintf(pathbuf, reclen, "%.*s%s%s", pathlen, path, sep, linker_hintfile); - NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_SYSSPACE, pathbuf, td); + NDINIT(&nd, LOOKUP, NOFOLLOW | MPSAFE, UIO_SYSSPACE, pathbuf, td); flags = FREAD; error = vn_open(&nd, &flags, 0, -1); if (error) goto bad; + vfslocked = NDHASGIANT(&nd); NDFREE(&nd, NDF_ONLY_PNBUF); if (nd.ni_vp->v_type != VREG) goto bad; @@ -1580,6 +1585,7 @@ linker_hints_lookup(const char *path, int pathlen, const char *modname, goto bad; VOP_UNLOCK(nd.ni_vp, 0, td); vn_close(nd.ni_vp, FREAD, cred, td); + VFS_UNLOCK_GIANT(vfslocked); nd.ni_vp = NULL; if (reclen != 0) { printf("can't read %d\n", reclen); @@ -1648,6 +1654,7 @@ bad: if (nd.ni_vp != NULL) { VOP_UNLOCK(nd.ni_vp, 0, td); vn_close(nd.ni_vp, FREAD, cred, td); + VFS_UNLOCK_GIANT(vfslocked); } /* * If nothing found or hints is absent - fallback to the old |
