Break out in_pcbdetach() into two functions:

- in_pcbdetach(), which removes the link between an inpcb and its
  socket.

- in_pcbfree(), which frees a detached pcb.

Unlike the previous in_pcbdetach(), neither of these functions will
attempt to conditionally free the socket, as they are responsible only
for managing in_pcb memory.  Mirror these changes into in6_pcbdetach()
by breaking it into in6_pcbdetach() and in6_pcbfree().

While here, eliminate undesired checks for NULL inpcb pointers in
sockets, as we will now have as an invariant that sockets will always
have valid so_pcb pointers.

MFC after:	3 months
This commit is contained in:
Robert Watson 2006-04-01 16:04:42 +00:00
parent 0154484bef
commit 4c7c478d0f
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=157373
4 changed files with 34 additions and 31 deletions

View File

@ -676,16 +676,30 @@ in_pcbdisconnect(struct inpcb *inp)
#ifdef IPSEC
ipsec_pcbdisconn(inp->inp_sp);
#endif
if (inp->inp_socket->so_state & SS_NOFDREF)
in_pcbdetach(inp);
}
/*
* In the old world order, in_pcbdetach() served two functions: to detach the
* pcb from the socket/potentially free the socket, and to free the pcb
* itself. In the new world order, the protocol code is responsible for
* managing the relationship with the socket, and this code simply frees the
* pcb.
*/
void
in_pcbdetach(struct inpcb *inp)
{
struct socket *so = inp->inp_socket;
KASSERT(inp->inp_socket != NULL, ("in_pcbdetach: inp_socket == NULL"));
inp->inp_socket->so_pcb = NULL;
inp->inp_socket = NULL;
}
void
in_pcbfree(struct inpcb *inp)
{
struct inpcbinfo *ipi = inp->inp_pcbinfo;
KASSERT(inp->inp_socket == NULL, ("in_pcbfree: inp_socket != NULL"));
INP_INFO_WLOCK_ASSERT(ipi);
INP_LOCK_ASSERT(inp);
@ -694,12 +708,6 @@ in_pcbdetach(struct inpcb *inp)
#endif /*IPSEC*/
inp->inp_gencnt = ++ipi->ipi_gencnt;
in_pcbremlists(inp);
if (so) {
ACCEPT_LOCK();
SOCK_LOCK(so);
so->so_pcb = NULL;
sotryfree(so);
}
if (inp->inp_options)
(void)m_free(inp->inp_options);
ip_freemoptions(inp->inp_moptions);
@ -744,10 +752,7 @@ in_setsockaddr(struct socket *so, struct sockaddr **nam,
INP_INFO_RLOCK(pcbinfo);
inp = sotoinpcb(so);
if (!inp) {
INP_INFO_RUNLOCK(pcbinfo);
return ECONNRESET;
}
KASSERT(inp != NULL, ("in_setsockaddr: so_pcb == NULL"));
INP_LOCK(inp);
port = inp->inp_lport;
addr = inp->inp_laddr;
@ -771,10 +776,7 @@ in_setpeeraddr(struct socket *so, struct sockaddr **nam,
INP_INFO_RLOCK(pcbinfo);
inp = sotoinpcb(so);
if (!inp) {
INP_INFO_RUNLOCK(pcbinfo);
return ECONNRESET;
}
KASSERT(inp != NULL, ("in_setpeeraddr: so_pcb == NULL"));
INP_LOCK(inp);
port = inp->inp_fport;
addr = inp->inp_faddr;
@ -1169,7 +1171,8 @@ in_pcbsosetlabel(struct socket *so)
#ifdef MAC
struct inpcb *inp;
inp = (struct inpcb *)so->so_pcb;
inp = sotoinpcb(so);
KASSERT(inp != NULL, ("in_pcbsosetlabel: so->so_pcb == NULL"));
INP_LOCK(inp);
SOCK_LOCK(so);
mac_inpcb_sosetlabel(so, inp);

View File

@ -352,6 +352,7 @@ int in_pcbconnect_setup(struct inpcb *, struct sockaddr *, in_addr_t *,
struct ucred *);
void in_pcbdetach(struct inpcb *);
void in_pcbdisconnect(struct inpcb *);
void in_pcbfree(struct inpcb *);
int in_pcbinshash(struct inpcb *);
struct inpcb *
in_pcblookup_local(struct inpcbinfo *,

View File

@ -422,17 +422,23 @@ in6_pcbdisconnect(inp)
#ifdef IPSEC
ipsec_pcbdisconn(inp->inp_sp);
#endif
if (inp->inp_socket->so_state & SS_NOFDREF)
in6_pcbdetach(inp);
}
void
in6_pcbdetach(inp)
struct inpcb *inp;
in6_pcbdetach(struct inpcb *inp)
{
KASSERT(inp->inp_socket != NULL, ("in6_pcbdetach: inp_socket == NULL"));
inp->inp_socket->so_pcb = NULL;
inp->inp_socket = NULL;
}
void
in6_pcbfree(struct inpcb *inp)
{
struct socket *so = inp->inp_socket;
struct inpcbinfo *ipi = inp->inp_pcbinfo;
KASSERT(inp->inp_socket == NULL, ("in6_pcbfree: inp_socket != NULL"));
INP_INFO_WLOCK_ASSERT(inp->inp_pcbinfo);
INP_LOCK_ASSERT(inp);
@ -442,14 +448,6 @@ in6_pcbdetach(inp)
#endif /* IPSEC */
inp->inp_gencnt = ++ipi->ipi_gencnt;
in_pcbremlists(inp);
if (so) {
ACCEPT_LOCK();
SOCK_LOCK(so);
so->so_pcb = NULL;
sotryfree(so);
}
ip6_freepcbopts(inp->in6p_outputopts);
ip6_freemoptions(inp->in6p_moptions);
/* Check and free IPv4 related resources in case of mapped addr */

View File

@ -76,6 +76,7 @@ int in6_pcbbind __P((struct inpcb *, struct sockaddr *, struct ucred *));
int in6_pcbconnect __P((struct inpcb *, struct sockaddr *, struct ucred *));
void in6_pcbdetach __P((struct inpcb *));
void in6_pcbdisconnect __P((struct inpcb *));
void in6_pcbfree __P((struct inpcb *));
int in6_pcbladdr __P((struct inpcb *, struct sockaddr *,
struct in6_addr **));
struct inpcb *