mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-19 15:33:56 +00:00
Extend getsock() to return the struct file flags read while holding the
file lock, in the style of fgetsock(). Modify accept1() to use getsock() instead of fgetsock(), relying on the file descriptor reference rather than an acquired socket reference to prevent the listen socket from being destroyed during accept(). This avoids additional reference count operations, which should improve performance, and also avoids accept1() operating on a socket whose file descriptor has been torn down, which may have resulted in protocol shutdown starting. MFC after: 3 months
This commit is contained in:
parent
10702a2840
commit
102ea03373
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=158010
@ -105,10 +105,11 @@ SYSCTL_INT(_kern_ipc, OID_AUTO, nsfbufsused, CTLFLAG_RD, &nsfbufsused, 0,
|
||||
* file entry is held upon returning. This is lighter weight than
|
||||
* fgetsock(), which bumps the socket reference drops the file reference
|
||||
* count instead, as this approach avoids several additional mutex operations
|
||||
* associated with the additional reference count.
|
||||
* associated with the additional reference count. If requested, return the
|
||||
* open file flags.
|
||||
*/
|
||||
static int
|
||||
getsock(struct filedesc *fdp, int fd, struct file **fpp)
|
||||
getsock(struct filedesc *fdp, int fd, struct file **fpp, u_int *fflagp)
|
||||
{
|
||||
struct file *fp;
|
||||
int error;
|
||||
@ -126,6 +127,8 @@ getsock(struct filedesc *fdp, int fd, struct file **fpp)
|
||||
error = ENOTSOCK;
|
||||
} else {
|
||||
fhold(fp);
|
||||
if (fflagp != NULL)
|
||||
*fflagp = fp->f_flag;
|
||||
error = 0;
|
||||
}
|
||||
FILEDESC_UNLOCK_FAST(fdp);
|
||||
@ -221,7 +224,7 @@ kern_bind(td, fd, sa)
|
||||
int error;
|
||||
|
||||
NET_LOCK_GIANT();
|
||||
error = getsock(td->td_proc->p_fd, fd, &fp);
|
||||
error = getsock(td->td_proc->p_fd, fd, &fp, NULL);
|
||||
if (error)
|
||||
goto done2;
|
||||
so = fp->f_data;
|
||||
@ -260,7 +263,7 @@ listen(td, uap)
|
||||
int error;
|
||||
|
||||
NET_LOCK_GIANT();
|
||||
error = getsock(td->td_proc->p_fd, uap->s, &fp);
|
||||
error = getsock(td->td_proc->p_fd, uap->s, &fp, NULL);
|
||||
if (error == 0) {
|
||||
so = fp->f_data;
|
||||
#ifdef MAC
|
||||
@ -283,9 +286,6 @@ listen(td, uap)
|
||||
/*
|
||||
* accept1()
|
||||
* MPSAFE
|
||||
*
|
||||
* XXXRW: Use getsock() instead of fgetsock() here to avoid additional mutex
|
||||
* operations due to soref()/sorele().
|
||||
*/
|
||||
static int
|
||||
accept1(td, uap, compat)
|
||||
@ -298,7 +298,7 @@ accept1(td, uap, compat)
|
||||
int compat;
|
||||
{
|
||||
struct filedesc *fdp;
|
||||
struct file *nfp = NULL;
|
||||
struct file *headfp, *nfp = NULL;
|
||||
struct sockaddr *sa = NULL;
|
||||
socklen_t namelen;
|
||||
int error;
|
||||
@ -317,9 +317,10 @@ accept1(td, uap, compat)
|
||||
return (EINVAL);
|
||||
}
|
||||
NET_LOCK_GIANT();
|
||||
error = fgetsock(td, uap->s, &head, &fflag);
|
||||
error = getsock(fdp, uap->s, &headfp, &fflag);
|
||||
if (error)
|
||||
goto done2;
|
||||
head = headfp->f_data;
|
||||
if ((head->so_options & SO_ACCEPTCONN) == 0) {
|
||||
error = EINVAL;
|
||||
goto done;
|
||||
@ -453,7 +454,7 @@ accept1(td, uap, compat)
|
||||
done:
|
||||
if (nfp != NULL)
|
||||
fdrop(nfp, td);
|
||||
fputsock(head);
|
||||
fdrop(headfp, td);
|
||||
done2:
|
||||
NET_UNLOCK_GIANT();
|
||||
return (error);
|
||||
@ -521,7 +522,7 @@ kern_connect(td, fd, sa)
|
||||
int interrupted = 0;
|
||||
|
||||
NET_LOCK_GIANT();
|
||||
error = getsock(td->td_proc->p_fd, fd, &fp);
|
||||
error = getsock(td->td_proc->p_fd, fd, &fp, NULL);
|
||||
if (error)
|
||||
goto done2;
|
||||
so = fp->f_data;
|
||||
@ -740,7 +741,7 @@ kern_sendit(td, s, mp, flags, control, segflg)
|
||||
#endif
|
||||
|
||||
NET_LOCK_GIANT();
|
||||
error = getsock(td->td_proc->p_fd, s, &fp);
|
||||
error = getsock(td->td_proc->p_fd, s, &fp, NULL);
|
||||
if (error)
|
||||
goto bad2;
|
||||
so = (struct socket *)fp->f_data;
|
||||
@ -952,7 +953,7 @@ kern_recvit(td, s, mp, namelenp, segflg, controlp)
|
||||
*controlp = 0;
|
||||
|
||||
NET_LOCK_GIANT();
|
||||
error = getsock(td->td_proc->p_fd, s, &fp);
|
||||
error = getsock(td->td_proc->p_fd, s, &fp, NULL);
|
||||
if (error) {
|
||||
NET_UNLOCK_GIANT();
|
||||
return (error);
|
||||
@ -1282,7 +1283,7 @@ shutdown(td, uap)
|
||||
int error;
|
||||
|
||||
NET_LOCK_GIANT();
|
||||
error = getsock(td->td_proc->p_fd, uap->s, &fp);
|
||||
error = getsock(td->td_proc->p_fd, uap->s, &fp, NULL);
|
||||
if (error == 0) {
|
||||
so = fp->f_data;
|
||||
error = soshutdown(so, uap->how);
|
||||
@ -1349,7 +1350,7 @@ kern_setsockopt(td, s, level, name, val, valseg, valsize)
|
||||
}
|
||||
|
||||
NET_LOCK_GIANT();
|
||||
error = getsock(td->td_proc->p_fd, s, &fp);
|
||||
error = getsock(td->td_proc->p_fd, s, &fp, NULL);
|
||||
if (error == 0) {
|
||||
so = fp->f_data;
|
||||
error = sosetopt(so, &sopt);
|
||||
@ -1432,7 +1433,7 @@ kern_getsockopt(td, s, level, name, val, valseg, valsize)
|
||||
}
|
||||
|
||||
NET_LOCK_GIANT();
|
||||
error = getsock(td->td_proc->p_fd, s, &fp);
|
||||
error = getsock(td->td_proc->p_fd, s, &fp, NULL);
|
||||
if (error == 0) {
|
||||
so = fp->f_data;
|
||||
error = sogetopt(so, &sopt);
|
||||
@ -1466,7 +1467,7 @@ getsockname1(td, uap, compat)
|
||||
int error;
|
||||
|
||||
NET_LOCK_GIANT();
|
||||
error = getsock(td->td_proc->p_fd, uap->fdes, &fp);
|
||||
error = getsock(td->td_proc->p_fd, uap->fdes, &fp, NULL);
|
||||
if (error)
|
||||
goto done2;
|
||||
so = fp->f_data;
|
||||
@ -1554,7 +1555,7 @@ getpeername1(td, uap, compat)
|
||||
int error;
|
||||
|
||||
NET_LOCK_GIANT();
|
||||
error = getsock(td->td_proc->p_fd, uap->fdes, &fp);
|
||||
error = getsock(td->td_proc->p_fd, uap->fdes, &fp, NULL);
|
||||
if (error)
|
||||
goto done2;
|
||||
so = fp->f_data;
|
||||
|
Loading…
Reference in New Issue
Block a user