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:
parent
8f54940f01
commit
5753be8e43
@ -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.
|
||||
*/
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user