Conditionally acquire Giant around VFS operations.

This commit is contained in:
John Baldwin 2006-06-20 21:31:38 +00:00
parent 690d79381a
commit 62d615d508
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=159808
4 changed files with 36 additions and 18 deletions

View File

@ -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;

View File

@ -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 @@ linker_hints_lookup(const char *path, int pathlen, const char *modname,
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

View File

@ -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 @@ link_elf_load_file(linker_class_t cls, const char* filename,
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;
}

View File

@ -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 @@ link_elf_load_file(linker_class_t cls, const char *filename,
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;
}