青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

隨筆-162  評(píng)論-223  文章-30  trackbacks-0
   接上篇初始化與創(chuàng)建,本篇闡述Socket操作和銷毀兩部分的實(shí)現(xiàn)。

Socket操作
   系統(tǒng)調(diào)用read(v)、write(v)是用戶空間讀寫socket的一種方法,為了弄清楚它們是怎么通過VFS將請(qǐng)求轉(zhuǎn)發(fā)到特定協(xié)議的實(shí)現(xiàn),下面以read為例(write同理),并假定文件描述符對(duì)應(yīng)的是IPv4 TCP類型的socket,來跟蹤它的執(zhí)行流程。首先來看下sys_read的代碼,定義在fs/read_write.c中。
 1SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count)
 2{
 3    struct file *file;
 4    ssize_t ret = -EBADF;
 5    int fput_needed;
 6
 7    file = fget_light(fd, &fput_needed);
 8    if (file) {
 9        loff_t pos = file_pos_read(file);
10        ret = vfs_read(file, buf, count, &pos);
11        
12    }

13
14    return ret;
15}
   先調(diào)用fget_light得到fd對(duì)應(yīng)的file,再調(diào)用vfs_read。接著跟蹤vfs_read的代碼,定義在fs/read_write.c中。
 1ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos)
 2{
 3    ssize_t ret;
 4    
 5    ret = rw_verify_area(READ, file, pos, count);
 6    if (ret >= 0{
 7        count = ret;
 8        if (file->f_op->read)
 9            ret = file->f_op->read(file, buf, count, pos);
10        else
11            ret = do_sync_read(file, buf, count, pos);
12        
13    }

14
15    return ret;
16}
   在上篇Socket創(chuàng)建一節(jié)已知,因?yàn)閟ockfs_file_ops沒有定義read(即read指針為空),所以這兒實(shí)際調(diào)用了do_sync_read,繼續(xù)跟蹤它的代碼,定義在fs/read_write.c中。
 1ssize_t do_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos)
 2{
 3    struct iovec iov = { .iov_base = buf, .iov_len = len };
 4    struct kiocb kiocb;
 5    ssize_t ret;
 6
 7    
 8    for (;;) {
 9        ret = filp->f_op->aio_read(&kiocb, &iov, 1, kiocb.ki_pos);
10        if (ret != -EIOCBRETRY)
11            break;
12        wait_on_retry_sync_kiocb(&kiocb);
13    }

14
15    if (-EIOCBQUEUED == ret)
16        ret = wait_on_sync_kiocb(&kiocb);
17    *ppos = kiocb.ki_pos;
18    return ret;
19}
   顯而易見,這兒調(diào)用到了f_op->aio_read,使用異步讀來實(shí)現(xiàn)同步讀,若異步讀沒有完成,則調(diào)用wait_on_sync_kiocb等待。由上篇Socket創(chuàng)建一節(jié)可知sockfs_file_ops的aio_read設(shè)為sock_aio_read函數(shù),定義在net/socket.c中,至此sys_read的實(shí)現(xiàn)完成了前一半(操作對(duì)象是file)而進(jìn)入后一半(操作對(duì)象是socket),即socket層的實(shí)現(xiàn)。
   在socket層跟蹤sock_aio_read,可以得到最后調(diào)用的是sock->ops->recvmsg,由于socket類型為IPv4 TCP,因此sock->ops在socket創(chuàng)建過程中被設(shè)為inet_stream_ops,定義在net/ipv4/af_inet.c中。
1const struct proto_ops inet_stream_ops = {
2    .family    =  PF_INET,
3    
4    .release   =  inet_release,
5    
6    .recvmsg  =  sock_common_recvmsg,
7    
8}
;
   從上可知recvmsg設(shè)為sock_common_recvmsg,跟蹤它的代碼,定義在net/core/sock.c中。  
 1int sock_common_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t size, int flags)
 2{
 3    struct sock *sk = sock->sk;
 4    int addr_len = 0;
 5    int err;
 6
 7    err = sk->sk_prot->recvmsg(iocb, sk, msg, size, flags & MSG_DONTWAIT,flags & ~MSG_DONTWAIT, &addr_len);
 8    
 9    return err;
10}
   struct sock表示套接字的網(wǎng)絡(luò)接口層,它的成員sk_prot表示網(wǎng)絡(luò)協(xié)議塊,在這它對(duì)應(yīng)tcp_prot結(jié)構(gòu),定義在net/ipv4/tcp_ipv4.c中,由此可見進(jìn)入到特定協(xié)議的實(shí)現(xiàn)。
1struct proto tcp_prot = {
2    .name            = "TCP",
3    
4    .close   =  tcp_close,
5    
6    .recvmsg  =  tcp_recvmsg,
7    
8}
;
   recvmsg設(shè)為tcp_recvmsg,至此跟蹤結(jié)束。對(duì)于sys_readv的實(shí)現(xiàn),調(diào)用的是vfs_readv,后面的過程和sys_read相同,總結(jié)核心調(diào)用鏈如下圖:
   由此可知,sockfs_file_ops只須實(shí)現(xiàn)aio_read,就能支持普通和聚集兩種方式的讀操作。為了對(duì)比,這里也給出Berkeley Sockets API中recv的核心調(diào)用鏈如下圖:
   顯而易見,recv內(nèi)部實(shí)現(xiàn)調(diào)用的是sys_recvfrom,它沒有經(jīng)過VFS,而是先調(diào)用sock_lookup_light從fd得到socket,再調(diào)用sock_recvmsg,后面的流程和recv就是一樣的了。

Socket銷毀
   Socket操作既可以調(diào)用文件IO,也可以調(diào)用Berkeley Sockets API。但銷毀不同,系統(tǒng)調(diào)用close是用戶空間銷毀socket的唯一方法,它定義在fs/open.c中。
 1SYSCALL_DEFINE1(close, unsigned int, fd)
 2{
 3    struct file * filp;
 4    struct files_struct *files = current->files;
 5    struct fdtable *fdt;
 6    int retval;
 7
 8    spin_lock(&files->file_lock);
 9    fdt = files_fdtable(files);
10    
11    filp = fdt->fd[fd];
12    
13    rcu_assign_pointer(fdt->fd[fd], NULL);
14    FD_CLR(fd, fdt->close_on_exec);
15    __put_unused_fd(files, fd);
16    spin_unlock(&files->file_lock);
17    retval = filp_close(filp, files);
18    
19}
   首先從fd獲取對(duì)應(yīng)的file,若file非空則設(shè)置進(jìn)程描述符數(shù)組對(duì)應(yīng)項(xiàng)為空,并將fd從exec時(shí)關(guān)閉的文件描述符鏈表和打開的文件描述符鏈表中移除;最后調(diào)用filp_close,跟蹤它的代碼,定義在fs/open.c中。
 1int filp_close(struct file *filp, fl_owner_t id)
 2{
 3    int retval = 0;
 4
 5    if (!file_count(filp)) {
 6        printk(KERN_ERR "VFS: Close: file count is 0\n");
 7        return 0;
 8    }

 9
10    if (filp->f_op && filp->f_op->flush)
11        retval = filp->f_op->flush(filp, id);
12
13    dnotify_flush(filp, id);
14    locks_remove_posix(filp, id);
15    fput(filp);
16    return retval;
17}
   首先判斷file的引用計(jì)數(shù),若為0則打印一個(gè)錯(cuò)誤日志(說明這是一個(gè)bug,因?yàn)閒ile已經(jīng)被釋放)并返回;由于sockfs_file_ops中的flush沒有定義即為空,因此跳過;dnotify_flush用于釋放任何相關(guān)的dnotify(一種文件監(jiān)控機(jī)制)資源,locks_remove_posix用于清除文件鎖相關(guān)的資源,由于socket對(duì)應(yīng)的inode沒有使用文件鎖,因此它什么也沒做。最后調(diào)用fput來釋放file,定義在fs/file_table.c中。
1void fput(struct file *file)
2{
3    if (atomic_long_dec_and_test(&file->f_count))
4        __fput(file);
5}
   先遞減引用計(jì)數(shù),若為0則調(diào)用__fput釋放file,它會(huì)調(diào)用到sockfs_file_ops定義的release函數(shù)即sock_close,它是sock_release的包裝函數(shù),sock_release定義在net/socket.c中。
 1void sock_release(struct socket *sock)
 2{
 3    if (sock->ops) {
 4        struct module *owner = sock->ops->owner;
 5
 6        sock->ops->release(sock);
 7        sock->ops = NULL;
 8        module_put(owner);
 9    }

10    if (sock->fasync_list)
11        printk(KERN_ERR "sock_release: fasync list not empty!\n");
12
13    percpu_sub(sockets_in_use, 1);
14    if (!sock->file) {
15        iput(SOCK_INODE(sock));
16        return;
17    }

18    sock->file = NULL;
19}
          
   先調(diào)用ops->release即特定協(xié)議的釋放操作,對(duì)于IPv4 TCP,就是inet_stream_ops中定義的inet_release函數(shù),它又會(huì)調(diào)用到tcp_prot中定義的close即tcp_close;對(duì)于關(guān)聯(lián)inode的釋放,這里要分2種情況:如果sock->file為空,就調(diào)用iput釋放,否則返回到__fput中,會(huì)調(diào)用dput釋放dentry,而dentry又關(guān)聯(lián)著inode,最終調(diào)用iput釋放inode;當(dāng)最后一個(gè)iput被調(diào)用時(shí),sockfs_ops中定義的sock_destroy_inode就會(huì)被調(diào)用,歸還由sock_alloc_inode分配的struct socket_alloc對(duì)象到SALB緩存中。總結(jié)核心調(diào)用鏈如下圖:
   
   在上篇初始化一節(jié),我們已知sockfs文件系統(tǒng)被裝載,然而實(shí)際上沒有卸載它的方式。由于TCP/IP協(xié)議棧和sockfs被靜態(tài)編譯到內(nèi)核中,而不是一個(gè)內(nèi)核模塊。因此沒必要提供一個(gè)卸載函數(shù),sockfs偽文件系統(tǒng)在啟動(dòng)到關(guān)閉期間,總是被裝載著的。
posted on 2015-05-03 16:55 春秋十二月 閱讀(5301) 評(píng)論(0)  編輯 收藏 引用 所屬分類: Network
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            久久精品国产久精国产一老狼| 国产精品亚洲一区| 亚洲电影第三页| 亚洲直播在线一区| 亚洲午夜精品久久久久久浪潮| 亚洲国产精品成人精品| 亚洲国产精品国自产拍av秋霞| 一区二区三区中文在线观看 | 午夜一区不卡| 久久av一区二区三区亚洲| 久久精品亚洲一区二区三区浴池| 久久久噜噜噜久久| 欧美麻豆久久久久久中文| 欧美系列一区| 国产亚洲一区二区三区| 日韩视频免费观看| 性亚洲最疯狂xxxx高清| 久久综合九色综合欧美狠狠| 欧美国产日韩在线| 中文亚洲字幕| 看片网站欧美日韩| 欧美体内谢she精2性欧美| 国产午夜亚洲精品理论片色戒 | 亚洲一区三区电影在线观看| 久久国产精品久久国产精品| 亚洲国产欧美在线人成| 亚洲欧美春色| 欧美日韩免费高清| 狠狠色综合网站久久久久久久| 亚洲精品系列| 精品91视频| 欧美日韩在线一区| 欧美激情在线有限公司| 一区二区三区视频在线播放| 亚洲免费观看高清在线观看| 亚洲一区精彩视频| 久久久久天天天天| 最新国产精品拍自在线播放| 一本大道av伊人久久综合| 午夜亚洲性色福利视频| 男女av一区三区二区色多| 国产精品视频免费一区| 亚洲精品一品区二品区三品区| 欧美一区二区三区在线看 | 久久精品一二三| 亚洲国产精品久久久久久女王| 午夜欧美理论片| 欧美天天综合网| 一区二区三区欧美成人| 亚洲国产精品久久久久婷婷884 | 亚洲国产日韩精品| 久久人人97超碰国产公开结果 | 黄色成人小视频| 久久精品国产一区二区电影| 一级成人国产| 欧美色欧美亚洲另类七区| 亚洲美女毛片| 亚洲精品亚洲人成人网| 欧美成人a∨高清免费观看| 18成人免费观看视频| 欧美暴力喷水在线| 欧美v日韩v国产v| 亚洲国产影院| 亚洲激情第一区| 欧美精品成人| 一区二区电影免费观看| 99日韩精品| 国产精品无人区| 久久精品亚洲| 久久影视精品| 日韩午夜剧场| 亚洲深夜福利在线| 国产一区二区三区在线观看精品| 久久久噜噜噜久久人人看| 久久五月激情| 一本色道久久综合亚洲精品婷婷| 欧美在线一区二区三区| 一级日韩一区在线观看| 欧美视频免费看| 亚洲视频成人| 这里只有精品视频| 国产亚洲欧美色| 亚洲成色www久久网站| 欧美日本亚洲视频| 欧美在线地址| 欧美 亚欧 日韩视频在线| 日韩特黄影片| 午夜在线成人av| 亚洲欧洲一区二区三区久久| 99视频精品免费观看| 国产欧美在线视频| 亚洲高清视频在线| 国产毛片精品国产一区二区三区| 免费观看一区| 欧美三级欧美一级| 久久中文字幕一区| 欧美视频免费看| 欧美成人综合一区| 国产精品一区二区在线| 欧美激情一区二区三区在线视频| 欧美日韩一区二区三区免费| 久久精品欧美| 欧美视频一二三区| 欧美电影免费观看网站| 国产欧美精品一区| 亚洲精品在线一区二区| 红桃视频成人| 午夜精品久久久久久久久 | 亚洲免费人成在线视频观看| 久久深夜福利免费观看| 亚洲你懂的在线视频| 欧美激情1区2区3区| 玖玖国产精品视频| 国产区在线观看成人精品| 日韩一级网站| 亚洲伦伦在线| 免费一级欧美在线大片| 久久在线精品| 国产在线观看91精品一区| 亚洲一区二区精品| 亚洲视频综合| 欧美日本免费一区二区三区| 欧美1区视频| 韩国欧美一区| 欧美一级播放| 欧美专区亚洲专区| 国产精品一区二区三区乱码| 一区二区欧美视频| 一区二区三区黄色| 欧美日本一区二区视频在线观看| 你懂的一区二区| **网站欧美大片在线观看| 欧美制服丝袜第一页| 久久久久一本一区二区青青蜜月| 国产精品久久久久影院亚瑟| 999在线观看精品免费不卡网站| 亚洲精品一区二区三区婷婷月 | 你懂的视频欧美| 欧美激情一区二区三区在线视频观看 | 美女视频黄a大片欧美| 久久天堂成人| 亚洲成人在线观看视频| 免费精品视频| 欧美激情91| 一本色道久久88综合亚洲精品ⅰ | 久久精品亚洲| 禁断一区二区三区在线 | 国产日韩欧美一区二区三区在线观看 | 欧美黄色一级视频| 亚洲伦理在线免费看| 欧美日韩精品一区二区| 亚洲视频1区| 欧美综合二区| 亚洲国产高潮在线观看| 欧美精品一区二区视频| 中文av一区二区| 久久久久久久国产| 亚洲人成在线影院| 国产精品你懂的在线欣赏| 欧美在线关看| 亚洲国产日韩一区| 午夜在线a亚洲v天堂网2018| 精品999在线观看| 欧美日韩不卡视频| 欧美一区二区三区久久精品茉莉花| 免费av成人在线| 亚洲一二三区在线观看| 国产综合色在线| 欧美日韩国产成人在线91| 午夜免费电影一区在线观看| 欧美激情a∨在线视频播放| 亚洲免费综合| 亚洲三级免费观看| 国产欧美一级| 欧美日韩国产精品自在自线| 久久成人免费视频| av不卡免费看| 亚洲高清自拍| 久久精品亚洲热| 亚洲一区日韩在线| 91久久久国产精品| 国产亚洲成精品久久| 欧美日韩视频在线一区二区观看视频| 欧美在线观看视频| 亚洲一区二区精品在线观看| 亚洲高清免费视频| 免费av成人在线| 久久久久综合网| 欧美一区二区三区播放老司机 | 国产伦精品一区二区三区视频黑人| 久久亚洲私人国产精品va媚药 | 欧美大片网址| 欧美在线三区| 亚洲一区二区日本| 亚洲精品视频在线观看网站| 免费在线欧美视频| 久久精品视频99| 欧美一区二区在线免费观看| 亚洲素人在线| 亚洲精品在线观|