fd: add refcount argument to falloc_noinstall

This lets callers avoid atomic ops by initializing the count to required
value from the get go.

While here add falloc_abort to backpedal from this without having to
fdrop.
This commit is contained in:
Mateusz Guzik 2021-01-13 15:16:38 +01:00
parent 8f54940f01
commit 5753be8e43
3 changed files with 26 additions and 11 deletions

View File

@ -1979,13 +1979,14 @@ falloc_caps(struct thread *td, struct file **resultfp, int *resultfd, int flags,
MPASS(resultfp != NULL);
MPASS(resultfd != NULL);
error = falloc_noinstall(td, &fp);
if (error)
return (error); /* no reference held on error */
error = _falloc_noinstall(td, &fp, 2);
if (__predict_false(error != 0)) {
return (error);
}
error = finstall(td, fp, &fd, flags, fcaps);
if (error) {
fdrop(fp, td); /* one reference (fp only) */
error = finstall_refed(td, fp, &fd, flags, fcaps);
if (__predict_false(error != 0)) {
falloc_abort(td, fp);
return (error);
}
@ -1999,7 +2000,7 @@ falloc_caps(struct thread *td, struct file **resultfp, int *resultfd, int flags,
* Create a new open file structure without allocating a file descriptor.
*/
int
falloc_noinstall(struct thread *td, struct file **resultfp)
_falloc_noinstall(struct thread *td, struct file **resultfp, u_int n)
{
struct file *fp;
int maxuserfiles = maxfiles - (maxfiles / 20);
@ -2008,6 +2009,7 @@ falloc_noinstall(struct thread *td, struct file **resultfp)
static int curfail;
KASSERT(resultfp != NULL, ("%s: resultfp == NULL", __func__));
MPASS(n > 0);
openfiles_new = atomic_fetchadd_int(&openfiles, 1) + 1;
if ((openfiles_new >= maxuserfiles &&
@ -2022,13 +2024,24 @@ falloc_noinstall(struct thread *td, struct file **resultfp)
}
fp = uma_zalloc(file_zone, M_WAITOK);
bzero(fp, sizeof(*fp));
refcount_init(&fp->f_count, 1);
refcount_init(&fp->f_count, n);
fp->f_cred = crhold(td->td_ucred);
fp->f_ops = &badfileops;
*resultfp = fp;
return (0);
}
void
falloc_abort(struct thread *td, struct file *fp)
{
/*
* For assertion purposes.
*/
refcount_init(&fp->f_count, 0);
_fdrop(fp, td);
}
/*
* Install a file in a file descriptor table.
*/

View File

@ -1214,14 +1214,14 @@ success:
}
} else {
filecaps_free(&nd.ni_filecaps);
fdrop_close(fp, td);
falloc_abort(td, fp);
}
td->td_retval[0] = indx;
return (0);
bad:
KASSERT(indx == -1, ("indx=%d, should be -1", indx));
fdrop_close(fp, td);
falloc_abort(td, fp);
return (error);
}

View File

@ -229,7 +229,9 @@ int dupfdopen(struct thread *td, struct filedesc *fdp, int dfd, int mode,
int openerror, int *indxp);
int falloc_caps(struct thread *td, struct file **resultfp, int *resultfd,
int flags, struct filecaps *fcaps);
int falloc_noinstall(struct thread *td, struct file **resultfp);
void falloc_abort(struct thread *td, struct file *fp);
int _falloc_noinstall(struct thread *td, struct file **resultfp, u_int n);
#define falloc_noinstall(td, resultfp) _falloc_noinstall(td, resultfp, 1)
void _finstall(struct filedesc *fdp, struct file *fp, int fd, int flags,
struct filecaps *fcaps);
int finstall(struct thread *td, struct file *fp, int *resultfd, int flags,