summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authoralfred <alfred@FreeBSD.org>2002-01-14 00:13:45 +0000
committeralfred <alfred@FreeBSD.org>2002-01-14 00:13:45 +0000
commit1f82bc18d1d1e906cd9ed68039acb051fa6e11cf (patch)
treefe7842143c9585ef2ebb793d812ec71cc4488a51 /sys
parentc4988e25d265bba2c63409a8c8b8708c13d8525e (diff)
downloadFreeBSD-src-1f82bc18d1d1e906cd9ed68039acb051fa6e11cf.zip
FreeBSD-src-1f82bc18d1d1e906cd9ed68039acb051fa6e11cf.tar.gz
Replace ffind_* with fget calls.
Make fget MPsafe. Make fgetvp and fgetsock use the fget subsystem to reduce code bloat. Push giant down in fpathconf().
Diffstat (limited to 'sys')
-rw-r--r--sys/alpha/osf1/osf1_misc.c6
-rw-r--r--sys/compat/linux/linux_file.c16
-rw-r--r--sys/compat/linux/linux_ioctl.c26
-rw-r--r--sys/compat/linux/linux_stats.c5
-rw-r--r--sys/compat/svr4/svr4_fcntl.c35
-rw-r--r--sys/compat/svr4/svr4_filio.c3
-rw-r--r--sys/compat/svr4/svr4_ioctl.c5
-rw-r--r--sys/compat/svr4/svr4_stream.c6
-rw-r--r--sys/dev/aac/aac.c5
-rw-r--r--sys/dev/tdfx/tdfx_pci.c5
-rw-r--r--sys/fs/fdescfs/fdesc_vnops.c10
-rw-r--r--sys/fs/portalfs/portal_vnops.c5
-rw-r--r--sys/i386/ibcs2/ibcs2_fcntl.c5
-rw-r--r--sys/i386/ibcs2/ibcs2_ioctl.c3
-rw-r--r--sys/kern/kern_descrip.c187
-rw-r--r--sys/kern/kern_event.c8
-rw-r--r--sys/kern/sys_generic.c10
-rw-r--r--sys/kern/vfs_extattr.c7
-rw-r--r--sys/kern/vfs_syscalls.c7
-rw-r--r--sys/netgraph/ng_socket.c5
-rw-r--r--sys/sys/file.h2
-rw-r--r--sys/vm/vm_mmap.c5
22 files changed, 136 insertions, 230 deletions
diff --git a/sys/alpha/osf1/osf1_misc.c b/sys/alpha/osf1/osf1_misc.c
index 46b20d9..124ba52 100644
--- a/sys/alpha/osf1/osf1_misc.c
+++ b/sys/alpha/osf1/osf1_misc.c
@@ -672,10 +672,8 @@ osf1_fstat(td, uap)
struct osf1_stat oub;
int error;
- fp = ffind_hold(td, uap->fd);
- if (fp == NULL)
- return (EBADF);
-
+ if ((error = fget(td, uap->fd, &fp)) != 0)
+ return (error);
error = fo_stat(fp, &ub, td);
fdrop(fp, td);
cvtstat2osf1(&ub, &oub);
diff --git a/sys/compat/linux/linux_file.c b/sys/compat/linux/linux_file.c
index 54f4584..1dfa4a1 100644
--- a/sys/compat/linux/linux_file.c
+++ b/sys/compat/linux/linux_file.c
@@ -137,11 +137,13 @@ linux_open(struct thread *td, struct linux_open_args *args)
SESS_LEADER(p) && !(p->p_flag & P_CONTROLT)) {
struct file *fp;
- fp = ffind_hold(td, td->td_retval[0]);
+ error = fget(td, td->td_retval[0], &fp);
PROC_UNLOCK(p);
- if (fp->f_type == DTYPE_VNODE)
- fo_ioctl(fp, TIOCSCTTY, (caddr_t) 0, td);
- fdrop(fp, td);
+ if (!error) {
+ if (fp->f_type == DTYPE_VNODE)
+ fo_ioctl(fp, TIOCSCTTY, (caddr_t) 0, td);
+ fdrop(fp, td);
+ }
} else
PROC_UNLOCK(p);
#ifdef DEBUG
@@ -996,9 +998,9 @@ fcntl_common(struct thread *td, struct linux_fcntl64_args *args)
* significant effect for pipes (SIGIO is not delivered for
* pipes under Linux-2.2.35 at least).
*/
- fp = ffind_hold(td, args->fd);
- if (fp == NULL)
- return EBADF;
+ error = fget(td, args->fd, &fp);
+ if (error)
+ return (error);
if (fp->f_type == DTYPE_PIPE) {
fdrop(fp, td);
return (EINVAL);
diff --git a/sys/compat/linux/linux_ioctl.c b/sys/compat/linux/linux_ioctl.c
index baafb5b..acf71d9 100644
--- a/sys/compat/linux/linux_ioctl.c
+++ b/sys/compat/linux/linux_ioctl.c
@@ -109,9 +109,8 @@ linux_ioctl_disk(struct thread *td, struct linux_ioctl_args *args)
int error;
struct disklabel dl;
- fp = ffind_hold(td, args->fd);
- if (fp == NULL)
- return (EBADF);
+ if ((error = fget(td, args->fd, &fp)) != 0)
+ return (error);
switch (args->cmd & 0xffff) {
case LINUX_BLKGETSIZE:
error = fo_ioctl(fp, DIOCGDINFO, (caddr_t)&dl, td);
@@ -555,9 +554,9 @@ linux_ioctl_termio(struct thread *td, struct linux_ioctl_args *args)
struct file *fp;
int error;
- fp = ffind_hold(td, args->fd);
- if (fp == NULL)
- return (EBADF);
+ if ((error = fget(td, args->fd, &fp)) != 0)
+ return (error);
+
switch (args->cmd & 0xffff) {
case LINUX_TCGETS:
@@ -1249,9 +1248,8 @@ linux_ioctl_cdrom(struct thread *td, struct linux_ioctl_args *args)
struct file *fp;
int error;
- fp = ffind_hold(td, args->fd);
- if (fp == NULL)
- return (EBADF);
+ if ((error = fget(td, args->fd, &fp)) != 0)
+ return (error);
switch (args->cmd & 0xffff) {
case LINUX_CDROMPAUSE:
@@ -1706,9 +1704,8 @@ linux_ioctl_console(struct thread *td, struct linux_ioctl_args *args)
struct file *fp;
int error;
- fp = ffind_hold(td, args->fd);
- if (fp == NULL)
- return (EBADF);
+ if ((error = fget(td, args->fd, &fp)) != 0)
+ return (error);
switch (args->cmd & 0xffff) {
case LINUX_KIOCSOUND:
@@ -2259,9 +2256,8 @@ linux_ioctl(struct thread *td, struct linux_ioctl_args *args)
(unsigned long)args->cmd);
#endif
- fp = ffind_hold(td, args->fd);
- if (fp == NULL)
- return (EBADF);
+ if ((error = fget(td, args->fd, &fp)) != 0)
+ return (error);
if ((fp->f_flag & (FREAD|FWRITE)) == 0) {
fdrop(fp, td);
return (EBADF);
diff --git a/sys/compat/linux/linux_stats.c b/sys/compat/linux/linux_stats.c
index 8f1799c..80b1c02 100644
--- a/sys/compat/linux/linux_stats.c
+++ b/sys/compat/linux/linux_stats.c
@@ -160,9 +160,8 @@ linux_newfstat(struct thread *td, struct linux_newfstat_args *args)
printf(ARGS(newfstat, "%d, *"), args->fd);
#endif
- fp = ffind_hold(td, args->fd);
- if (fp == NULL)
- return (EBADF);
+ if ((error = fget(td, args->fd, &fp)) != 0)
+ return (error);
error = fo_stat(fp, &buf, td);
fdrop(fp, td);
diff --git a/sys/compat/svr4/svr4_fcntl.c b/sys/compat/svr4/svr4_fcntl.c
index a13cd23..43a571f 100644
--- a/sys/compat/svr4/svr4_fcntl.c
+++ b/sys/compat/svr4/svr4_fcntl.c
@@ -246,23 +246,14 @@ fd_revoke(td, fd)
struct thread *td;
int fd;
{
- struct file *fp;
struct vnode *vp;
struct mount *mp;
struct vattr vattr;
int error, *retval;
retval = td->td_retval;
- fp = ffind_hold(td, fd);
- if (fp == NULL)
- return EBADF;
-
- if (fp->f_type != DTYPE_VNODE) {
- fdrop(fp, td);
- return EINVAL;
- }
-
- vp = (struct vnode *) fp->f_data;
+ if ((error = fgetvp(td, fd, &vp)) != 0)
+ return (error);
if (vp->v_type != VCHR && vp->v_type != VBLK) {
error = EINVAL;
@@ -283,7 +274,6 @@ fd_revoke(td, fd)
vn_finished_write(mp);
out:
vrele(vp);
- fdrop(fp, td);
return error;
}
@@ -294,7 +284,6 @@ fd_truncate(td, fd, flp)
int fd;
struct flock *flp;
{
- struct file *fp;
off_t start, length;
struct vnode *vp;
struct vattr vattr;
@@ -306,18 +295,16 @@ fd_truncate(td, fd, flp)
/*
* We only support truncating the file.
*/
- fp = ffind_hold(td, fd);
- if (fp == NULL)
- return EBADF;
+ if ((error = fgetvp(td, uap->fd, &vp)) != 0)
+ return (error);
- vp = (struct vnode *)fp->f_data;
- if (fp->f_type != DTYPE_VNODE || vp->v_type == VFIFO) {
- fdrop(fp, td);
+ if (vp->v_type == VFIFO) {
+ vrele(vp);
return ESPIPE;
}
if ((error = VOP_GETATTR(vp, &vattr, td->td_proc->p_ucred, td)) != 0)
- fdrop(fp, td);
+ vrele(vp);
return error;
}
@@ -337,7 +324,7 @@ fd_truncate(td, fd, flp)
break;
default:
- fdrop(fp, td);
+ vrele(vp);
return EINVAL;
}
@@ -351,7 +338,7 @@ fd_truncate(td, fd, flp)
error = ftruncate(td, &ft);
- fdrop(fp, td);
+ vrele(vp);
return (error);
}
@@ -386,13 +373,13 @@ svr4_sys_open(td, uap)
#if defined(NOTYET)
struct file *fp;
- fp = ffind_hold(td, retval);
+ error = fget(td, retval, &fp);
PROC_UNLOCK(p);
/*
* we may have lost a race the above open() and
* another thread issuing a close()
*/
- if (fp == NULL)
+ if (error)
return (EBADF); /* XXX: correct errno? */
/* ignore any error, just give it a try */
if (fp->f_type == DTYPE_VNODE)
diff --git a/sys/compat/svr4/svr4_filio.c b/sys/compat/svr4/svr4_filio.c
index b24a039..0dd6bed 100644
--- a/sys/compat/svr4/svr4_filio.c
+++ b/sys/compat/svr4/svr4_filio.c
@@ -107,8 +107,7 @@ svr4_sys_read(td, uap)
SCARG(&ra, buf) = SCARG(uap, buf);
SCARG(&ra, nbyte) = SCARG(uap, nbyte);
- fp = ffind_hold(td, uap->fd);
- if (fp == NULL) {
+ if (fget(td, uap->fd, &fp) != 0) {
DPRINTF(("Something fishy with the user-supplied file descriptor...\n"));
return EBADF;
}
diff --git a/sys/compat/svr4/svr4_ioctl.c b/sys/compat/svr4/svr4_ioctl.c
index 024c2e5..cbac631 100644
--- a/sys/compat/svr4/svr4_ioctl.c
+++ b/sys/compat/svr4/svr4_ioctl.c
@@ -102,9 +102,8 @@ svr4_sys_ioctl(td, uap)
retval = td->td_retval;
cmd = SCARG(uap, com);
- fp = ffind_hold(td, uap->fd);
- if (fp == NULL)
- return EBADF;
+ if ((error = fget(td, uap->fd, &fp)) != 0)
+ return (error);
if ((fp->f_flag & (FREAD | FWRITE)) == 0) {
fdrop(fp, td);
diff --git a/sys/compat/svr4/svr4_stream.c b/sys/compat/svr4/svr4_stream.c
index 2d8ea84..c0f7134 100644
--- a/sys/compat/svr4/svr4_stream.c
+++ b/sys/compat/svr4/svr4_stream.c
@@ -1717,8 +1717,7 @@ svr4_sys_putmsg(td, uap)
struct file *fp;
int error;
- fp = ffind_hold(td, uap->fd);
- if (fp == NULL) {
+ if ((error = fget(td, uap->fd, &fp)) != 0) {
#ifdef DEBUG_SVR4
uprintf("putmsg: bad fp\n");
#endif
@@ -1905,8 +1904,7 @@ svr4_sys_getmsg(td, uap)
struct file *fp;
int error;
- fp = ffind_hold(td, uap->fd);
- if (fp == NULL) {
+ if ((error = fget(td, uap->fd, &fp)) != 0) {
#ifdef DEBUG_SVR4
uprintf("getmsg: bad fp\n");
#endif
diff --git a/sys/dev/aac/aac.c b/sys/dev/aac/aac.c
index 3a7c063..9d47b64 100644
--- a/sys/dev/aac/aac.c
+++ b/sys/dev/aac/aac.c
@@ -2582,9 +2582,8 @@ aac_linux_ioctl(struct thread *td, struct linux_ioctl_args *args)
debug_called(2);
- fp = ffind_hold(td, args->fd);
- if (fp == NULL)
- return (EBADF);
+ if ((error = fget(td, args->fd, &fp)) != 0)
+ return (error);
cmd = args->cmd;
/*
diff --git a/sys/dev/tdfx/tdfx_pci.c b/sys/dev/tdfx/tdfx_pci.c
index cfbfe18..b94eedf 100644
--- a/sys/dev/tdfx/tdfx_pci.c
+++ b/sys/dev/tdfx/tdfx_pci.c
@@ -844,9 +844,8 @@ linux_ioctl_tdfx(struct thread *td, struct linux_ioctl_args* args)
struct file *fp;
- fp = ffind_hold(td, args->fd);
- if (fp == NULL)
- return (EBADF);
+ if ((error = fget(td, args->fd, &fp)) != 0)
+ return (error);
/* We simply copy the data and send it right to ioctl */
copyin((caddr_t)args->arg, &d_pio, sizeof(d_pio));
error = fo_ioctl(fp, cmd, (caddr_t)&d_pio, td);
diff --git a/sys/fs/fdescfs/fdesc_vnops.c b/sys/fs/fdescfs/fdesc_vnops.c
index 3326375..d3b6bda 100644
--- a/sys/fs/fdescfs/fdesc_vnops.c
+++ b/sys/fs/fdescfs/fdesc_vnops.c
@@ -213,11 +213,8 @@ fdesc_lookup(ap)
fd = 10 * fd + *pname++ - '0';
}
- fp = ffind_hold(td, fd);
- if (fp == NULL) {
- error = EBADF;
+ if ((error = fget(td, fd, &fp)) != 0)
goto bad;
- }
error = fdesc_allocvp(Fdesc, FD_DESC+fd, dvp->v_mount, &fvp, td);
fdrop(fp, td);
@@ -301,9 +298,8 @@ fdesc_getattr(ap)
case Fdesc:
fd = VTOFDESC(vp)->fd_fd;
- fp = ffind_hold(ap->a_td, fd);
- if (fp == NULL)
- return (EBADF);
+ if ((error = fget(ap->a_td, fd, &fp)) != 0)
+ return (error);
bzero(&stb, sizeof(stb));
error = fo_stat(fp, &stb, ap->a_td);
diff --git a/sys/fs/portalfs/portal_vnops.c b/sys/fs/portalfs/portal_vnops.c
index e8feeb1..a7d9832 100644
--- a/sys/fs/portalfs/portal_vnops.c
+++ b/sys/fs/portalfs/portal_vnops.c
@@ -402,11 +402,8 @@ portal_open(ap)
* Check that the mode the file is being opened for is a subset
* of the mode of the existing descriptor.
*/
- fp = ffind_hold(td, fd);
- if (fp == NULL) {
- error = EBADF;
+ if ((error = fget(td, fd, &fp)) != 0)
goto bad;
- }
if (((ap->a_mode & (FREAD|FWRITE)) | fp->f_flag) != fp->f_flag) {
fdrop(fp, td);
portal_closefd(td, fd);
diff --git a/sys/i386/ibcs2/ibcs2_fcntl.c b/sys/i386/ibcs2/ibcs2_fcntl.c
index a54d40a..07b7f41 100644
--- a/sys/i386/ibcs2/ibcs2_fcntl.c
+++ b/sys/i386/ibcs2/ibcs2_fcntl.c
@@ -194,10 +194,11 @@ ibcs2_open(td, uap)
PROC_LOCK(p);
if (!ret && !noctty && SESS_LEADER(p) && !(p->p_flag & P_CONTROLT)) {
struct file *fp;
+ int error;
- fp = ffind_hold(td, td->td_retval[0]);
+ error = fget(td, td->td_retval[0], &fp);
PROC_UNLOCK(p);
- if (fp == NULL)
+ if (error)
return (EBADF);
/* ignore any error, just give it a try */
diff --git a/sys/i386/ibcs2/ibcs2_ioctl.c b/sys/i386/ibcs2/ibcs2_ioctl.c
index a37e116..2755b01 100644
--- a/sys/i386/ibcs2/ibcs2_ioctl.c
+++ b/sys/i386/ibcs2/ibcs2_ioctl.c
@@ -346,8 +346,7 @@ ibcs2_ioctl(td, uap)
struct file *fp;
int error;
- fp = ffind_hold(td, uap->fd);
- if (fp == NULL) {
+ if ((error = fget(td, uap->fd, &fp)) != 0) {
DPRINTF(("ibcs2_ioctl(%d): bad fd %d ", p->p_pid,
SCARG(uap, fd)));
return EBADF;
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index 1adb3e3..c47c3c0 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -843,36 +843,31 @@ fpathconf(td, uap)
struct vnode *vp;
int error;
- fp = ffind_hold(td, uap->fd);
- if (fp == NULL)
- return (EBADF);
- mtx_lock(&Giant);
if ((error = fget(td, uap->fd, &fp)) != 0)
- goto done2;
+ return (error);
switch (fp->f_type) {
case DTYPE_PIPE:
case DTYPE_SOCKET:
if (uap->name != _PC_PIPE_BUF) {
- fdrop(fp, td);
error = EINVAL;
- goto done2;
+ } else {
+ td->td_retval[0] = PIPE_BUF;
+ error = 0;
}
- td->td_retval[0] = PIPE_BUF;
- error = 0;
break;
case DTYPE_FIFO:
case DTYPE_VNODE:
vp = (struct vnode *)fp->f_data;
+ mtx_lock(&Giant);
error = VOP_PATHCONF(vp, uap->name, td->td_retval);
+ mtx_unlock(&Giant);
break;
default:
error = EOPNOTSUPP;
break;
}
fdrop(fp, td);
-done2:
- mtx_unlock(&Giant);
return(error);
}
@@ -1456,50 +1451,6 @@ closef(fp, td)
}
/*
- * Find the struct file 'fd' in process 'p' and bump it's refcount
- * struct file is not locked on return.
- */
-struct file *
-ffind_hold(td, fd)
- struct thread *td;
- int fd;
-{
- struct file *fp;
-
- fp = ffind_lock(td, fd);
- if (fp != NULL)
- FILE_UNLOCK(fp);
- return (fp);
-}
-
-/*
- * Find the struct file 'fd' in process 'p' and bump it's refcount,
- * struct file is locked on return.
- */
-struct file *
-ffind_lock(td, fd)
- struct thread *td;
- int fd;
-{
- struct filedesc *fdp;
- struct file *fp;
-
- if (td == NULL || (fdp = td->td_proc->p_fd) == NULL)
- return (NULL);
- FILEDESC_LOCK(fdp);
- if (fd < 0 || fd >= fdp->fd_nfiles ||
- (fp = fdp->fd_ofiles[fd]) == NULL ||
- fp->f_ops == &badfileops) {
- fp = NULL;
- } else {
- FILE_LOCK(fp);
- fhold_locked(fp);
- }
- FILEDESC_UNLOCK(fdp);
- return (fp);
-}
-
-/*
* Drop reference on struct file passed in, may call closef if the
* reference hits zero.
*/
@@ -1515,29 +1466,38 @@ fdrop(fp, td)
/*
* Extract the file pointer associated with the specified descriptor for
- * the current user process. If no error occured 0 is returned, *fpp
- * will be set to the file pointer, and the file pointer's ref count
- * will be bumped. Use fdrop() to drop it. If an error occured the
- * non-zero error is returned and *fpp is set to NULL.
+ * the current user process.
+ *
+ * If the descriptor doesn't exist, EBADF is returned.
*
- * This routine requires Giant for the moment. Once enough of the
- * system is converted over to this and other encapsulated APIs we
- * will be able to mutex it and call it without Giant.
+ * If the descriptor exists but doesn't match 'flags' then
+ * return EBADF for read attempts and EINVAL for write attempts.
+ *
+ * If 'hold' is set (non-zero) the file's refcount will be bumped on return.
+ * It should be droped with fdrop().
+ * If it is not set, then the refcount will not be bumped however the
+ * thread's filedesc struct will be returned locked (for fgetsock).
+ *
+ * If an error occured the non-zero error is returned and *fpp is set to NULL.
+ * Otherwise *fpp is set and zero is returned.
*/
static __inline
int
-_fget(struct thread *td, int fd, struct file **fpp, int flags)
+_fget(struct thread *td, int fd, struct file **fpp, int flags, int hold)
{
struct filedesc *fdp;
struct file *fp;
- GIANT_REQUIRED;
- fdp = td->td_proc->p_fd;
*fpp = NULL;
- if ((u_int)fd >= fdp->fd_nfiles)
+ if (td == NULL || (fdp = td->td_proc->p_fd) == NULL)
return(EBADF);
- if ((fp = fdp->fd_ofiles[fd]) == NULL)
+ FILEDESC_LOCK(fdp);
+ if (fd < 0 || (u_int)fd >= fdp->fd_nfiles ||
+ (fp = fdp->fd_ofiles[fd]) == NULL ||
+ fp->f_ops == &badfileops) {
+ FILEDESC_UNLOCK(fdp);
return(EBADF);
+ }
/*
* Note: FREAD failures returns EBADF to maintain backwards
@@ -1545,11 +1505,18 @@ _fget(struct thread *td, int fd, struct file **fpp, int flags)
*
* Only one flag, or 0, may be specified.
*/
- if (flags == FREAD && (fp->f_flag & FREAD) == 0)
+ if (flags == FREAD && (fp->f_flag & FREAD) == 0) {
+ FILEDESC_UNLOCK(fdp);
return(EBADF);
- if (flags == FWRITE && (fp->f_flag & FWRITE) == 0)
+ }
+ if (flags == FWRITE && (fp->f_flag & FWRITE) == 0) {
+ FILEDESC_UNLOCK(fdp);
return(EINVAL);
- ++fp->f_count;
+ }
+ if (hold) {
+ fhold(fp);
+ FILEDESC_UNLOCK(fdp);
+ }
*fpp = fp;
return(0);
}
@@ -1557,19 +1524,19 @@ _fget(struct thread *td, int fd, struct file **fpp, int flags)
int
fget(struct thread *td, int fd, struct file **fpp)
{
- return(_fget(td, fd, fpp, 0));
+ return(_fget(td, fd, fpp, 0, 1));
}
int
fget_read(struct thread *td, int fd, struct file **fpp)
{
- return(_fget(td, fd, fpp, FREAD));
+ return(_fget(td, fd, fpp, FREAD, 1));
}
int
fget_write(struct thread *td, int fd, struct file **fpp)
{
- return(_fget(td, fd, fpp, FWRITE));
+ return(_fget(td, fd, fpp, FWRITE, 1));
}
/*
@@ -1583,34 +1550,20 @@ static __inline
int
_fgetvp(struct thread *td, int fd, struct vnode **vpp, int flags)
{
- struct filedesc *fdp;
struct file *fp;
+ int error;
- GIANT_REQUIRED;
- fdp = td->td_proc->p_fd;
*vpp = NULL;
- if ((u_int)fd >= fdp->fd_nfiles)
- return(EBADF);
- if ((fp = fdp->fd_ofiles[fd]) == NULL)
- return(EBADF);
- if (fp->f_type != DTYPE_VNODE && fp->f_type != DTYPE_FIFO)
- return(EINVAL);
- if (fp->f_data == NULL)
- return(EINVAL);
-
- /*
- * Note: FREAD failures returns EBADF to maintain backwards
- * compatibility with what routines returned before.
- *
- * Only one flag, or 0, may be specified.
- */
- if (flags == FREAD && (fp->f_flag & FREAD) == 0)
- return(EBADF);
- if (flags == FWRITE && (fp->f_flag & FWRITE) == 0)
- return(EINVAL);
- *vpp = (struct vnode *)fp->f_data;
- vref(*vpp);
- return(0);
+ if ((error = _fget(td, fd, &fp, 0, 0)) != 0)
+ return (error);
+ if (fp->f_type != DTYPE_VNODE && fp->f_type != DTYPE_FIFO) {
+ error = EINVAL;
+ } else {
+ *vpp = (struct vnode *)fp->f_data;
+ vref(*vpp);
+ }
+ FILEDESC_UNLOCK(td->td_proc->p_fd);
+ return (error);
}
int
@@ -1641,29 +1594,24 @@ fgetvp_write(struct thread *td, int fd, struct vnode **vpp)
int
fgetsock(struct thread *td, int fd, struct socket **spp, u_int *fflagp)
{
- struct filedesc *fdp;
struct file *fp;
- struct socket *so;
+ int error;
- GIANT_REQUIRED;
- fdp = td->td_proc->p_fd;
*spp = NULL;
if (fflagp)
*fflagp = 0;
- if ((u_int)fd >= fdp->fd_nfiles)
- return(EBADF);
- if ((fp = fdp->fd_ofiles[fd]) == NULL)
- return(EBADF);
- if (fp->f_type != DTYPE_SOCKET)
- return(ENOTSOCK);
- if (fp->f_data == NULL)
- return(EINVAL);
- so = (struct socket *)fp->f_data;
- if (fflagp)
- *fflagp = fp->f_flag;
- soref(so);
- *spp = so;
- return(0);
+ if ((error = _fget(td, fd, &fp, 0, 0)) != 0)
+ return (error);
+ if (fp->f_type != DTYPE_SOCKET) {
+ error = ENOTSOCK;
+ } else {
+ *spp = (struct socket *)fp->f_data;
+ if (fflagp)
+ *fflagp = fp->f_flag;
+ soref(*spp);
+ }
+ FILEDESC_UNLOCK(td->td_proc->p_fd);
+ return(error);
}
/*
@@ -1737,14 +1685,13 @@ flock(td, uap)
struct thread *td;
register struct flock_args *uap;
{
- register struct file *fp;
+ struct file *fp;
struct vnode *vp;
struct flock lf;
int error;
- fp = ffind_hold(td, uap->fd);
- if (fp == NULL)
- return (EBADF);
+ if ((error = fget(td, uap->fd, &fp)) != 0)
+ return (error);
if (fp->f_type != DTYPE_VNODE) {
fdrop(fp, td);
return (EOPNOTSUPP);
diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c
index 038b233..bf89043 100644
--- a/sys/kern/kern_event.c
+++ b/sys/kern/kern_event.c
@@ -414,10 +414,10 @@ kevent(struct thread *td, struct kevent_args *uap)
struct timespec ts;
int i, n, nerrors, error;
- fp = ffind_hold(td, uap->fd);
- if (fp == NULL || fp->f_type != DTYPE_KQUEUE) {
- if (fp != NULL)
- fdrop(fp, td);
+ if ((error = fget(td, uap->fd, &fp)) != 0)
+ return (error);
+ if (fp->f_type != DTYPE_KQUEUE) {
+ fdrop(fp, td);
return (EBADF);
}
if (uap->timeout != NULL) {
diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c
index df85cf2..77b843d 100644
--- a/sys/kern/sys_generic.c
+++ b/sys/kern/sys_generic.c
@@ -603,7 +603,7 @@ ioctl(td, uap)
struct thread *td;
register struct ioctl_args *uap;
{
- register struct file *fp;
+ struct file *fp;
register struct filedesc *fdp;
register u_long com;
int error = 0;
@@ -616,9 +616,8 @@ ioctl(td, uap)
long align;
} ubuf;
- fp = ffind_hold(td, uap->fd);
- if (fp == NULL)
- return (EBADF);
+ if ((error = fget(td, uap->fd, &fp)) != 0)
+ return (error);
if ((fp->f_flag & (FREAD | FWRITE)) == 0) {
fdrop(fp, td);
return (EBADF);
@@ -992,8 +991,7 @@ selscan(td, ibits, obits, nfd)
for (fd = i; bits && fd < nfd; fd++, bits >>= 1) {
if (!(bits & 1))
continue;
- fp = ffind_hold(td, fd);
- if (fp == NULL)
+ if (fget(td, fd, &fp))
return (EBADF);
if (fo_poll(fp, flag[msk], fp->f_cred, td)) {
obits[msk][(fd)/NFDBITS] |=
diff --git a/sys/kern/vfs_extattr.c b/sys/kern/vfs_extattr.c
index 75ac3d0..539c418 100644
--- a/sys/kern/vfs_extattr.c
+++ b/sys/kern/vfs_extattr.c
@@ -1704,15 +1704,14 @@ lseek(td, uap)
} */ *uap;
{
struct ucred *cred = td->td_proc->p_ucred;
- register struct file *fp;
+ struct file *fp;
struct vnode *vp;
struct vattr vattr;
off_t offset;
int error, noneg;
- fp = ffind_hold(td, uap->fd);
- if (fp == NULL)
- return (EBADF);
+ if ((error = fget(td, uap->fd, &fp)) != 0)
+ return (error);
if (fp->f_type != DTYPE_VNODE) {
fdrop(fp, td);
return (ESPIPE);
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index 75ac3d0..539c418 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -1704,15 +1704,14 @@ lseek(td, uap)
} */ *uap;
{
struct ucred *cred = td->td_proc->p_ucred;
- register struct file *fp;
+ struct file *fp;
struct vnode *vp;
struct vattr vattr;
off_t offset;
int error, noneg;
- fp = ffind_hold(td, uap->fd);
- if (fp == NULL)
- return (EBADF);
+ if ((error = fget(td, uap->fd, &fp)) != 0)
+ return (error);
if (fp->f_type != DTYPE_VNODE) {
fdrop(fp, td);
return (ESPIPE);
diff --git a/sys/netgraph/ng_socket.c b/sys/netgraph/ng_socket.c
index 09ce2cf..206d752 100644
--- a/sys/netgraph/ng_socket.c
+++ b/sys/netgraph/ng_socket.c
@@ -591,9 +591,8 @@ ng_internalize(struct mbuf *control, struct thread *td)
/* Check that the FD given is legit. and change it to a pointer to a
* struct file. */
fd = CMSG_DATA(cm);
- fp = ffind_hold(td, fd);
- if (fp == NULL)
- return (EBADF);
+ if ((error = fget(td, fd, &fp)) != 0)
+ return (error);
/* Depending on what kind of resource it is, act differently. For
* devices, we treat it as a file. For a AF_NETGRAPH socket,
diff --git a/sys/sys/file.h b/sys/sys/file.h
index d8dbf48..583bfdf 100644
--- a/sys/sys/file.h
+++ b/sys/sys/file.h
@@ -166,8 +166,6 @@ static __inline int fo_stat __P((struct file *fp, struct stat *sb,
static __inline int fo_close __P((struct file *fp, struct thread *td));
static __inline int fo_kqfilter __P((struct file *fp, struct knote *kn));
struct proc;
-struct file *ffind_hold(struct thread *, int fd);
-struct file *ffind_lock(struct thread *, int fd);
static __inline int
fo_read(fp, uio, cred, flags, td)
diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c
index 9bf68c1..47c243f 100644
--- a/sys/vm/vm_mmap.c
+++ b/sys/vm/vm_mmap.c
@@ -292,11 +292,8 @@ mmap(td, uap)
* sure it is of appropriate type.
* don't let the descriptor disappear on us if we block
*/
- fp = ffind_hold(td, uap->fd);
- if (fp == NULL) {
- error = EBADF;
+ if ((error = fget(td, uap->fd, &fp)) != 0)
goto done;
- }
if (fp->f_type != DTYPE_VNODE) {
error = EINVAL;
goto done;
OpenPOWER on IntegriCloud