The close system call socket

close system call to close the file descriptor, which system call is as follows;

 1 /
 2  * Careful here! We test whether the file pointer is NULL before
 3  * releasing the fd. This ensures that one clone task can't release
 4  * an fd while another clone is opening it.
 5  */
 6 SYSCALL_DEFINE1(close, unsigned int, fd)
 7 {
 8     int retval = __close_fd(current->files, fd);
 9 
10     /* can't restart close syscall because file table entry was cleared */
11     if (unlikely(retval == -ERESTARTSYS ||
12              retval == -ERESTARTNOINTR ||
13              retval == -ERESTARTNOHAND ||
14              retval == -ERESTART_RESTARTBLOCK))
15         retval = -EINTR;
16 
17     return retval;
18 }
19 EXPORT_SYMBOL(sys_close);

 

This paper focuses on the analysis of the close portions of the socket, so that outlines the close system call function calls general flow relationship, as follows;

Added: where the focus of attention at fput function, the reference count of -1 will now function will first file, and then determine whether it is 0, 0 of the time will be to continue the process, that is to say when there are multiple references socket only the last one close will trigger the destruction process behind schedule, a different place is close to the shutdown of;

. 1  / * *
 2  * Close the system call function call relationship
 . 3  * __ close_fd
 . 4  * | -> filp_close
 . 5  * | -> fput delayed_fput_list the file is added to the list
 . 6  * | - queue processing list> schedule_delayed_work scheduling delay execution
 7  * | -> delayed_fput
 8  * | -> __ fput
 9  * | -> File-> f_op-> release files operating release call
 10   * /

 

Seen in the close system call invokes the release operation file, so we focus on the analysis of this release socket operation implementation;

Operation of socket file structure shown below, wherein the release function is implemented as discussed herein sock_close;

 1 /* socket文件操作函数 */
 2 static const struct file_operations socket_file_ops = {
 3     .owner =    THIS_MODULE,
 4     .llseek =    no_llseek,
 5     .read_iter =    sock_read_iter,
 6     .write_iter =    sock_write_iter,
 7     .poll =        sock_poll,
 8     .unlocked_ioctl = sock_ioctl,
 9 #ifdef CONFIG_COMPAT
10     .compat_ioctl = compat_sock_ioctl,
11 #endif
12     .mmap =        sock_mmap,
13     .release =    sock_close,
14     .fasync =    sock_fasync,
15     .sendpage =    sock_sendpage,
16     .splice_write = generic_splice_sendpage,
17     .splice_read =    sock_splice_read,
18 };

 

In socket_release function, operation function calls socket release, ipv4 corresponding to inet_release;

1 /* 关闭socket */
2 static int sock_close(struct inode *inode, struct file *filp)
3 {
4     /* socket关闭 */
5     sock_release(SOCKET_I(inode));
6     return 0;
7 }

 

 1 /**
 2  *    sock_release    -    close a socket
 3  *    @sock: socket to close
 4  *
 5  *    The socket is released from the protocol stack if it has a release
 6  *    callback, and the inode is then released if the socket is bound to
 7  *    an inode not a file.
 8  */
 9 
10 void sock_release(struct socket *sock)
11 {
12     if (sock->ops) {
13         struct module *owner = sock->ops->owner;
14 
15         / * Invoke socket operation Release * / 
16          sock-> OPS-> Release (our sock);
 . 17          sock-> OPS = NULL;
 18 is          module_put (owner);
 . 19      }
 20 is  
21 is      IF (rcu_dereference_protected (sock-> WQ, . 1 ) -> fasync_list)
 22 is          pr_err ( " !% S: fasync List Not empty \ n- " , __func__ in);
 23 is  
24      / * reduce the set number of cpu interface * / 
25      this_cpu_sub (sockets_in_use, . 1 );
 26 is  
27      / * fault tolerance * / 
28     IF (sock->! File) {
 29          iput (SOCK_INODE (our sock));
 30          return ;
 31 is      }
 32  
33 is      / * socket closing is completed, continue with other processes close system call * / 
34 is      sock-> File = NULL;
 35 }

 

inet_release responsible leave a multicast group, to set the delay time in accordance with off flag is turned linger, and calls the close function of the transport layer, for tcp, its call is tcp_close;

 1 /*
 2  *    The peer socket should always be NULL (or else). When we call this
 3  *    function we are destroying the object and from then on nobody
 4  *    should refer to it.
 5  */
 6 int inet_release(struct socket *sock)
 7 {
 8     struct sock *sk = sock->sk;
 9 
10     if (sk) {
11         long timeout;
12 
13         /* Applications forget to leave groups before exiting */
14         /* 退出组播组 */
15          ip_mc_drop_socket (SK);
 16  
. 17          / * the If the linger IS SET, WE do Not Close The return an until
 18 is           * IS of The Complete Immediately return the Otherwise WE..
 . 19           * Actually either the closing IS DONE The Same Way.
 20 is           *
 21 is           * the If Due to IS the Close the exiting the process, WE Never
 22 is           * linger ..
 23 is           * / 
24          timeout = 0 ;
 25  
26 is          / *  
27              provided linger flag, the process is not exit
 28              is set off delay time lingertime 
 29          * / 
30          if(sock_flag (SK, SOCK_LINGER) &&
 31 is              (to current-> the flags &! PF_EXITING))
 32              timeout = SK-> sk_lingertime;
 33 is          sock-> SK = NULL;
 34 is  
35          / * calls the close function of the transmission layer * / 
36          SK- > sk_prot-> Close (SK, timeout);
 37 [      }
 38 is      return  0 ;
 39 }

 

tcp_close analysis please move on to another article <TCP layer to achieve close analysis of the system calls>;

Guess you like

Origin www.cnblogs.com/wanpengcoder/p/11749264.html