Conditionally acquire Giant around VFS operations.
This commit is contained in:
parent
079c3bb7eb
commit
3f7e224385
@ -2925,7 +2925,7 @@ NdisOpenFile(status, filehandle, filelength, filename, highestaddr)
|
||||
char *afilename = NULL;
|
||||
struct thread *td = curthread;
|
||||
struct nameidata nd;
|
||||
int flags, error;
|
||||
int flags, error, vfslocked;
|
||||
struct vattr vat;
|
||||
struct vattr *vap = &vat;
|
||||
ndis_fh *fh;
|
||||
@ -2998,8 +2998,6 @@ NdisOpenFile(status, filehandle, filelength, filename, highestaddr)
|
||||
|
||||
snprintf(path, MAXPATHLEN, "%s/%s", ndis_filepath, afilename);
|
||||
|
||||
mtx_lock(&Giant);
|
||||
|
||||
/* Some threads don't have a current working directory. */
|
||||
|
||||
if (td->td_proc->p_fd->fd_rdir == NULL)
|
||||
@ -3007,12 +3005,11 @@ NdisOpenFile(status, filehandle, filelength, filename, highestaddr)
|
||||
if (td->td_proc->p_fd->fd_cdir == NULL)
|
||||
td->td_proc->p_fd->fd_cdir = rootvnode;
|
||||
|
||||
NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, path, td);
|
||||
NDINIT(&nd, LOOKUP, FOLLOW | MPSAFE, UIO_SYSSPACE, path, td);
|
||||
|
||||
flags = FREAD;
|
||||
error = vn_open(&nd, &flags, 0, -1);
|
||||
if (error) {
|
||||
mtx_unlock(&Giant);
|
||||
*status = NDIS_STATUS_FILE_NOT_FOUND;
|
||||
ExFreePool(fh);
|
||||
printf("NDIS: open file %s failed: %d\n", path, error);
|
||||
@ -3020,6 +3017,7 @@ NdisOpenFile(status, filehandle, filelength, filename, highestaddr)
|
||||
free(afilename, M_DEVBUF);
|
||||
return;
|
||||
}
|
||||
vfslocked = NDHASGIANT(&nd);
|
||||
|
||||
ExFreePool(path);
|
||||
|
||||
@ -3028,7 +3026,7 @@ NdisOpenFile(status, filehandle, filelength, filename, highestaddr)
|
||||
/* Get the file size. */
|
||||
VOP_GETATTR(nd.ni_vp, vap, td->td_ucred, td);
|
||||
VOP_UNLOCK(nd.ni_vp, 0, td);
|
||||
mtx_unlock(&Giant);
|
||||
VFS_UNLOCK_GIANT(vfslocked);
|
||||
|
||||
fh->nf_vp = nd.ni_vp;
|
||||
fh->nf_map = NULL;
|
||||
@ -3050,7 +3048,8 @@ NdisMapFile(status, mappedbuffer, filehandle)
|
||||
struct thread *td = curthread;
|
||||
linker_file_t lf;
|
||||
caddr_t kldstart;
|
||||
int error, resid;
|
||||
int error, resid, vfslocked;
|
||||
struct vnode *vp;
|
||||
|
||||
if (filehandle == NULL) {
|
||||
*status = NDIS_STATUS_FAILURE;
|
||||
@ -3088,10 +3087,11 @@ NdisMapFile(status, mappedbuffer, filehandle)
|
||||
return;
|
||||
}
|
||||
|
||||
mtx_lock(&Giant);
|
||||
error = vn_rdwr(UIO_READ, fh->nf_vp, fh->nf_map, fh->nf_maplen, 0,
|
||||
vp = fh->nf_vp;
|
||||
vfslocked = VFS_LOCK_GIANT(vp->v_mount);
|
||||
error = vn_rdwr(UIO_READ, vp, fh->nf_map, fh->nf_maplen, 0,
|
||||
UIO_SYSSPACE, 0, td->td_ucred, NOCRED, &resid, td);
|
||||
mtx_unlock(&Giant);
|
||||
VFS_UNLOCK_GIANT(vfslocked);
|
||||
|
||||
if (error)
|
||||
*status = NDIS_STATUS_FAILURE;
|
||||
@ -3126,6 +3126,8 @@ NdisCloseFile(filehandle)
|
||||
{
|
||||
struct thread *td = curthread;
|
||||
ndis_fh *fh;
|
||||
int vfslocked;
|
||||
struct vnode *vp;
|
||||
|
||||
if (filehandle == NULL)
|
||||
return;
|
||||
@ -3141,9 +3143,10 @@ NdisCloseFile(filehandle)
|
||||
return;
|
||||
|
||||
if (fh->nf_type == NDIS_FH_TYPE_VFS) {
|
||||
mtx_lock(&Giant);
|
||||
vn_close(fh->nf_vp, FREAD, td->td_ucred, td);
|
||||
mtx_unlock(&Giant);
|
||||
vp = fh->nf_vp;
|
||||
vfslocked = VFS_LOCK_GIANT(vp->v_mount);
|
||||
vn_close(vp, FREAD, td->td_ucred, td);
|
||||
VFS_UNLOCK_GIANT(vfslocked);
|
||||
}
|
||||
|
||||
fh->nf_vp = NULL;
|
||||
|
@ -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
|
||||
|
@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/mac.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/namei.h>
|
||||
#include <sys/fcntl.h>
|
||||
@ -556,17 +557,19 @@ link_elf_load_file(linker_class_t cls, const char* filename,
|
||||
int symstrindex;
|
||||
int symcnt;
|
||||
int strcnt;
|
||||
int vfslocked;
|
||||
|
||||
GIANT_REQUIRED;
|
||||
|
||||
shdr = NULL;
|
||||
lf = NULL;
|
||||
|
||||
NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, filename, td);
|
||||
NDINIT(&nd, LOOKUP, FOLLOW | MPSAFE, UIO_SYSSPACE, filename, td);
|
||||
flags = FREAD;
|
||||
error = vn_open(&nd, &flags, 0, -1);
|
||||
if (error)
|
||||
return error;
|
||||
vfslocked = NDHASGIANT(&nd);
|
||||
NDFREE(&nd, NDF_ONLY_PNBUF);
|
||||
#ifdef MAC
|
||||
error = mac_check_kld_load(curthread->td_ucred, nd.ni_vp);
|
||||
@ -859,6 +862,7 @@ out:
|
||||
free(firstpage, M_LINKER);
|
||||
VOP_UNLOCK(nd.ni_vp, 0, td);
|
||||
vn_close(nd.ni_vp, FREAD, td->td_ucred, td);
|
||||
VFS_UNLOCK_GIANT(vfslocked);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/mac.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/namei.h>
|
||||
#include <sys/fcntl.h>
|
||||
@ -393,6 +394,7 @@ link_elf_load_file(linker_class_t cls, const char *filename,
|
||||
int nsym;
|
||||
int pb, rl, ra;
|
||||
int alignmask;
|
||||
int vfslocked;
|
||||
|
||||
GIANT_REQUIRED;
|
||||
|
||||
@ -401,11 +403,12 @@ link_elf_load_file(linker_class_t cls, const char *filename,
|
||||
mapsize = 0;
|
||||
hdr = NULL;
|
||||
|
||||
NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, filename, td);
|
||||
NDINIT(&nd, LOOKUP, FOLLOW | MPSAFE, UIO_SYSSPACE, filename, td);
|
||||
flags = FREAD;
|
||||
error = vn_open(&nd, &flags, 0, -1);
|
||||
if (error)
|
||||
return error;
|
||||
vfslocked = NDHASGIANT(&nd);
|
||||
NDFREE(&nd, NDF_ONLY_PNBUF);
|
||||
#ifdef MAC
|
||||
error = mac_check_kld_load(td->td_ucred, nd.ni_vp);
|
||||
@ -788,6 +791,7 @@ out:
|
||||
free(hdr, M_LINKER);
|
||||
VOP_UNLOCK(nd.ni_vp, 0, td);
|
||||
vn_close(nd.ni_vp, FREAD, td->td_ucred, td);
|
||||
VFS_UNLOCK_GIANT(vfslocked);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user