Introduce fdclose() which will clean an entry in a filedesc.

Replace homerolled versions with call to fdclose().

Make fdunused() static to kern_descrip.c
This commit is contained in:
Poul-Henning Kamp 2004-11-07 22:16:07 +00:00
parent e93bd4ef59
commit ef11fbd7c4
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=137355
6 changed files with 33 additions and 103 deletions

View File

@ -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?
*/

View File

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

View File

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

View File

@ -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
*/

View File

@ -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
*/

View File

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