syscall_net: make close non blocking add a callback for reuse
authorAlan Cox <alan@linux.intel.com>
Fri, 30 Mar 2018 23:25:50 +0000 (00:25 +0100)
committerAlan Cox <alan@linux.intel.com>
Fri, 30 Mar 2018 23:25:50 +0000 (00:25 +0100)
The new mode is close() sends a message to ask the stack to clean up. The
socket ends up dead until the stack calls ack into closed() to say that the
resources are now free.

Kernel/include/netdev.h
Kernel/syscall_net.c

index 77b590a..9783e40 100644 (file)
@@ -60,6 +60,8 @@ struct socket
 #define SS_CLOSEWAIT           9       /* Remote has closed */
 #define SS_CLOSING             10      /* Protocol close in progress */
 #define SS_CLOSED              11      /* Protocol layers done, not close()d */
+#define SS_DEAD                        12      /* Closed byuser space but not yet
+                                          free of any stack resources */
        /* FIXME: need state for shutdown handling */
        uint8_t s_data;                 /* Socket we are an accept() for */
        uint8_t s_error;
@@ -77,6 +79,7 @@ struct socket
 #define SI_EOF         8               /* At EOF */
 #define SI_THROTTLE    16              /* Transmit is throttled */
        void *s_priv;                   /* Private pointer for lower layers */
+       inoptr s_ino;                   /* Inode back pointer */
 };
 
 #define NSOCKTYPE 3
@@ -127,3 +130,4 @@ extern struct socket *sock_find(uint8_t type, uint8_t sv, struct sockaddrs *sa);
 extern void sock_init(void);
 extern int sock_error(struct socket *s);
 extern struct netdevice net_dev;
+extern void sock_closed(struct socket *s);
index 76b13fe..2da8a0f 100644 (file)
@@ -130,12 +130,17 @@ void sock_close(inoptr ino)
        /* For the moment */
        struct socket *s = &sockets[ino->c_node.i_nlink];
        net_close(s);
-       sock_wait_enter(s, 0, SS_CLOSED);
+       /* Dead but not unbound from netd activity yet */
+       s->s_state = SS_DEAD;
+}
+
+void sock_closed(struct socket *s)
+{
        s->s_state = SS_UNUSED;
        /* You re-use something you pays the price. Probably should switch
           to using data 0 as devices do ? FIXME */
-       ino->c_node.i_nlink = 0;
-       ino->c_flags |= CDIRTY;
+       s->s_ino->c_node.i_nlink = 0;
+       s->s_ino->c_flags |= CDIRTY;
 }
 
 /*
@@ -331,6 +336,8 @@ arg_t make_socket(struct sockinfo *s, struct socket **np)
        ino->c_readers = 1;
        ino->c_writers = 1;
 
+       n->s_ino = ino;
+
        of_tab[oftindex].o_inode = ino;
        of_tab[oftindex].o_access = O_RDWR;