From 52da2f8e345a7de465e7604b8712493ea0fedebd Mon Sep 17 00:00:00 2001 From: phk Date: Sun, 7 Nov 2004 22:16:07 +0000 Subject: [PATCH] Introduce fdclose() which will clean an entry in a filedesc. Replace homerolled versions with call to fdclose(). Make fdunused() static to kern_descrip.c --- sys/kern/kern_descrip.c | 18 +++++++++++++++- sys/kern/sys_pipe.c | 10 +-------- sys/kern/uipc_syscalls.c | 44 ++++++---------------------------------- sys/kern/vfs_extattr.c | 31 ++++------------------------ sys/kern/vfs_syscalls.c | 31 ++++------------------------ sys/sys/filedesc.h | 2 +- 6 files changed, 33 insertions(+), 103 deletions(-) diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c index 384ca163c5c7..8f5ea75a12e0 100644 --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -99,6 +99,7 @@ static int do_dup(struct thread *td, enum dup_type type, int old, int new, static int fd_first_free(struct filedesc *, int, int); static int fd_last_used(struct filedesc *, int, int); static void fdgrowtable(struct filedesc *, int); +static void fdunused(struct filedesc *fdp, int fd); /* * A process is initially started out with NDFILE descriptors stored within @@ -224,7 +225,7 @@ fdused(struct filedesc *fdp, int fd) /* * Mark a file descriptor as unused. */ -void +static void fdunused(struct filedesc *fdp, int fd) { FILEDESC_LOCK_ASSERT(fdp, MA_OWNED); @@ -1729,6 +1730,21 @@ setugidsafety(td) FILEDESC_UNLOCK(fdp); } +void +fdclose(struct filedesc *fdp, struct file *fp, int idx, struct thread *td) +{ + + FILEDESC_LOCK(fdp); + if (fdp->fd_ofiles[idx] == fp) { + fdp->fd_ofiles[idx] = NULL; + fdunused(fdp, idx); + FILEDESC_UNLOCK(fdp); + fdrop(fp, td); + } else { + FILEDESC_UNLOCK(fdp); + } +} + /* * Close any files on exec? */ diff --git a/sys/kern/sys_pipe.c b/sys/kern/sys_pipe.c index b450cdd8875e..6865546e4053 100644 --- a/sys/kern/sys_pipe.c +++ b/sys/kern/sys_pipe.c @@ -384,15 +384,7 @@ pipe(td, uap) FILE_UNLOCK(rf); error = falloc(td, &wf, &fd); if (error) { - FILEDESC_LOCK(fdp); - if (fdp->fd_ofiles[td->td_retval[0]] == rf) { - fdp->fd_ofiles[td->td_retval[0]] = NULL; - fdunused(fdp, td->td_retval[0]); - FILEDESC_UNLOCK(fdp); - fdrop(rf, td); - } else { - FILEDESC_UNLOCK(fdp); - } + fdclose(fdp, rf, td->td_retval[0], td); fdrop(rf, td); /* rpipe has been closed by fdrop(). */ pipeclose(wpipe); diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c index c2d34863bdfd..9ad7ae002222 100644 --- a/sys/kern/uipc_syscalls.c +++ b/sys/kern/uipc_syscalls.c @@ -167,17 +167,10 @@ socket(td, uap) error = socreate(uap->domain, &so, uap->type, uap->protocol, td->td_ucred, td); NET_UNLOCK_GIANT(); - FILEDESC_LOCK(fdp); if (error) { - if (fdp->fd_ofiles[fd] == fp) { - fdp->fd_ofiles[fd] = NULL; - fdunused(fdp, fd); - FILEDESC_UNLOCK(fdp); - fdrop(fp, td); - } else { - FILEDESC_UNLOCK(fdp); - } + fdclose(fdp, fp, fd, td); } else { + FILEDESC_LOCK(fdp); fp->f_data = so; /* already has ref count */ fp->f_flag = FREAD|FWRITE; fp->f_ops = &socketops; @@ -435,17 +428,8 @@ accept1(td, uap, compat) * close the new descriptor, assuming someone hasn't ripped it * out from under us. */ - if (error) { - FILEDESC_LOCK(fdp); - if (fdp->fd_ofiles[fd] == nfp) { - fdp->fd_ofiles[fd] = NULL; - fdunused(fdp, fd); - FILEDESC_UNLOCK(fdp); - fdrop(nfp, td); - } else { - FILEDESC_UNLOCK(fdp); - } - } + if (error) + fdclose(fdp, nfp, fd, td); /* * Release explicitly held references before returning. @@ -637,26 +621,10 @@ socketpair(td, uap) fdrop(fp2, td); goto done2; free4: - FILEDESC_LOCK(fdp); - if (fdp->fd_ofiles[sv[1]] == fp2) { - fdp->fd_ofiles[sv[1]] = NULL; - fdunused(fdp, sv[1]); - FILEDESC_UNLOCK(fdp); - fdrop(fp2, td); - } else { - FILEDESC_UNLOCK(fdp); - } + fdclose(fdp, fp2, sv[1], td); fdrop(fp2, td); free3: - FILEDESC_LOCK(fdp); - if (fdp->fd_ofiles[sv[0]] == fp1) { - fdp->fd_ofiles[sv[0]] = NULL; - fdunused(fdp, sv[0]); - FILEDESC_UNLOCK(fdp); - fdrop(fp1, td); - } else { - FILEDESC_UNLOCK(fdp); - } + fdclose(fdp, fp1, sv[0], td); fdrop(fp1, td); free2: (void)soclose(so2); diff --git a/sys/kern/vfs_extattr.c b/sys/kern/vfs_extattr.c index 38d6de6480b9..d98a88558a54 100644 --- a/sys/kern/vfs_extattr.c +++ b/sys/kern/vfs_extattr.c @@ -990,15 +990,7 @@ kern_open(struct thread *td, char *path, enum uio_seg pathseg, int flags, * Clean up the descriptor, but only if another thread hadn't * replaced or closed it. */ - FILEDESC_LOCK(fdp); - if (fdp->fd_ofiles[indx] == fp) { - fdp->fd_ofiles[indx] = NULL; - fdunused(fdp, indx); - FILEDESC_UNLOCK(fdp); - fdrop(fp, td); - } else { - FILEDESC_UNLOCK(fdp); - } + fdclose(fdp, fp, indx, td); if (error == ERESTART) error = EINTR; @@ -1091,15 +1083,7 @@ kern_open(struct thread *td, char *path, enum uio_seg pathseg, int flags, return (0); bad: mtx_unlock(&Giant); - FILEDESC_LOCK(fdp); - if (fdp->fd_ofiles[indx] == fp) { - fdp->fd_ofiles[indx] = NULL; - fdunused(fdp, indx); - FILEDESC_UNLOCK(fdp); - fdrop(fp, td); - } else { - FILEDESC_UNLOCK(fdp); - } + fdclose(fdp, fp, indx, td); fdrop(fp, td); return (error); } @@ -4018,15 +4002,8 @@ fhopen(td, uap) * descriptor but handle the case where someone might * have dup()d or close()d it when we weren't looking. */ - FILEDESC_LOCK(fdp); - if (fdp->fd_ofiles[indx] == fp) { - fdp->fd_ofiles[indx] = NULL; - fdunused(fdp, indx); - FILEDESC_UNLOCK(fdp); - fdrop(fp, td); - } else { - FILEDESC_UNLOCK(fdp); - } + fdclose(fdp, fp, indx, td); + /* * release our private reference */ diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 38d6de6480b9..d98a88558a54 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -990,15 +990,7 @@ kern_open(struct thread *td, char *path, enum uio_seg pathseg, int flags, * Clean up the descriptor, but only if another thread hadn't * replaced or closed it. */ - FILEDESC_LOCK(fdp); - if (fdp->fd_ofiles[indx] == fp) { - fdp->fd_ofiles[indx] = NULL; - fdunused(fdp, indx); - FILEDESC_UNLOCK(fdp); - fdrop(fp, td); - } else { - FILEDESC_UNLOCK(fdp); - } + fdclose(fdp, fp, indx, td); if (error == ERESTART) error = EINTR; @@ -1091,15 +1083,7 @@ kern_open(struct thread *td, char *path, enum uio_seg pathseg, int flags, return (0); bad: mtx_unlock(&Giant); - FILEDESC_LOCK(fdp); - if (fdp->fd_ofiles[indx] == fp) { - fdp->fd_ofiles[indx] = NULL; - fdunused(fdp, indx); - FILEDESC_UNLOCK(fdp); - fdrop(fp, td); - } else { - FILEDESC_UNLOCK(fdp); - } + fdclose(fdp, fp, indx, td); fdrop(fp, td); return (error); } @@ -4018,15 +4002,8 @@ fhopen(td, uap) * descriptor but handle the case where someone might * have dup()d or close()d it when we weren't looking. */ - FILEDESC_LOCK(fdp); - if (fdp->fd_ofiles[indx] == fp) { - fdp->fd_ofiles[indx] = NULL; - fdunused(fdp, indx); - FILEDESC_UNLOCK(fdp); - fdrop(fp, td); - } else { - FILEDESC_UNLOCK(fdp); - } + fdclose(fdp, fp, indx, td); + /* * release our private reference */ diff --git a/sys/sys/filedesc.h b/sys/sys/filedesc.h index 729ed8d85916..22ef5bfd5409 100644 --- a/sys/sys/filedesc.h +++ b/sys/sys/filedesc.h @@ -108,12 +108,12 @@ int falloc(struct thread *td, struct file **resultfp, int *resultfd); int fdalloc(struct thread *td, int minfd, int *result); int fdavail(struct thread *td, int n); int fdcheckstd(struct thread *td); +void fdclose(struct filedesc *fdp, struct file *fp, int idx, struct thread *td); void fdcloseexec(struct thread *td); struct filedesc *fdcopy(struct filedesc *fdp); void fdfree(struct thread *td); struct filedesc *fdinit(struct filedesc *fdp); struct filedesc *fdshare(struct filedesc *fdp); -void fdunused(struct filedesc *fdp, int fd); void fdused(struct filedesc *fdp, int fd); void ffree(struct file *fp); struct filedesc_to_leader *