On Thu, Nov 11, 2021 at 12:42:36AM +0300, Vitaliy Makkoveev wrote:
> What about 'SO_DYING' flag? Anyway I want to remove it with the next
> diff.

The so_options are for user flags.  The so_state is for kernel
transitions.  So a SS_DYING would be better, see sys/socketvar.h.

But as we commit the other soclose() diff first, it does not matter
anymore.

> No problem, but I made "if (vp)" without NULL for the consistency with
> "if (unp->unp_vnode)" in this function. Should they have the same
> notation?

mpi@ and I converted the network stack gradually to the pointer ==
NULL or pointer != NULL idiom.  If you change something, go into
this direction.  But there is no need to make bulk conversions.

> OK for updated diff?

OK bluhm@ without the SO_DYING part.

> Index: sys/kern/uipc_socket.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/uipc_socket.c,v
> retrieving revision 1.268
> diff -u -p -r1.268 uipc_socket.c
> --- sys/kern/uipc_socket.c    6 Nov 2021 05:26:33 -0000       1.268
> +++ sys/kern/uipc_socket.c    10 Nov 2021 21:33:01 -0000
> @@ -334,6 +334,8 @@ soclose(struct socket *so, int flags)
>       /* Revoke async IO early. There is a final revocation in sofree(). */
>       sigio_free(&so->so_sigio);
>       if (so->so_options & SO_ACCEPTCONN) {
> +             so->so_options |= SO_DYING;
> +
>               while ((so2 = TAILQ_FIRST(&so->so_q0)) != NULL) {
>                       (void) soqremque(so2, 0);
>                       (void) soabort(so2);
> Index: sys/kern/uipc_usrreq.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/uipc_usrreq.c,v
> retrieving revision 1.154
> diff -u -p -r1.154 uipc_usrreq.c
> --- sys/kern/uipc_usrreq.c    6 Nov 2021 17:35:14 -0000       1.154
> +++ sys/kern/uipc_usrreq.c    10 Nov 2021 21:33:01 -0000
> @@ -485,20 +485,30 @@ void
>  unp_detach(struct unpcb *unp)
>  {
>       struct socket *so = unp->unp_socket;
> -     struct vnode *vp = NULL;
> +     struct vnode *vp = unp->unp_vnode;
>  
>       rw_assert_wrlock(&unp_lock);
>  
>       LIST_REMOVE(unp, unp_link);
> -     if (unp->unp_vnode) {
> +
> +     if (vp != NULL) {
> +             unp->unp_vnode = NULL;
> +
>               /*
> -              * `v_socket' is only read in unp_connect and
> -              * unplock prevents concurrent access.
> +              * Enforce `i_lock' -> `unp_lock' because fifo
> +              * subsystem requires it.
>                */
>  
> -             unp->unp_vnode->v_socket = NULL;
> -             vp = unp->unp_vnode;
> -             unp->unp_vnode = NULL;
> +             sounlock(so, SL_LOCKED);
> +
> +             VOP_LOCK(vp, LK_EXCLUSIVE);
> +             vp->v_socket = NULL;
> +
> +             KERNEL_LOCK();
> +             vput(vp);
> +             KERNEL_UNLOCK();
> +
> +             solock(so);
>       }
>  
>       if (unp->unp_conn)
> @@ -511,21 +521,6 @@ unp_detach(struct unpcb *unp)
>       pool_put(&unpcb_pool, unp);
>       if (unp_rights)
>               task_add(systqmp, &unp_gc_task);
> -
> -     if (vp != NULL) {
> -             /*
> -              * Enforce `i_lock' -> `unplock' because fifo subsystem
> -              * requires it. The socket can't be closed concurrently
> -              * because the file descriptor reference is
> -              * still hold.
> -              */
> -
> -             sounlock(so, SL_LOCKED);
> -             KERNEL_LOCK();
> -             vrele(vp);
> -             KERNEL_UNLOCK();
> -             solock(so);
> -     }
>  }
>  
>  int
> @@ -670,7 +665,8 @@ unp_connect(struct socket *so, struct mb
>               goto put_locked;
>       }
>       if (so->so_proto->pr_flags & PR_CONNREQUIRED) {
> -             if ((so2->so_options & SO_ACCEPTCONN) == 0 ||
> +             if ((so2->so_options & SO_DYING) != 0 ||
> +                 (so2->so_options & SO_ACCEPTCONN) == 0 ||
>                   (so3 = sonewconn(so2, 0)) == NULL) {
>                       error = ECONNREFUSED;
>                       goto put_locked;
> Index: sys/sys/socket.h
> ===================================================================
> RCS file: /cvs/src/sys/sys/socket.h,v
> retrieving revision 1.101
> diff -u -p -r1.101 socket.h
> --- sys/sys/socket.h  7 Nov 2021 12:05:28 -0000       1.101
> +++ sys/sys/socket.h  10 Nov 2021 21:33:01 -0000
> @@ -97,6 +97,7 @@ typedef     __sa_family_t   sa_family_t;    /* so
>  #define SO_TIMESTAMP 0x0800          /* timestamp received dgram traffic */
>  #define SO_BINDANY   0x1000          /* allow bind to any address */
>  #define SO_ZEROIZE   0x2000          /* zero out all mbufs sent over socket 
> */
> +#define SO_DYING     0x4000          /* socket is dying */
>  
>  /*
>   * Additional options, not kept in so_options.

Reply via email to