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

隨筆-162  評(píng)論-223  文章-30  trackbacks-0
引言
   在Unix的世界里,萬物皆文件,通過虛擬文件系統(tǒng)VFS,程序可以用標(biāo)準(zhǔn)的Unix系統(tǒng)調(diào)用對(duì)不同的文件系統(tǒng),甚至不同介質(zhì)上的文件系統(tǒng)進(jìn)行讀寫操作。對(duì)于網(wǎng)絡(luò)套接字socket也是如此,除了專屬的Berkeley Sockets API,還支持一些標(biāo)準(zhǔn)的文件IO系統(tǒng)調(diào)用如read(v)、write(v)和close等。那么為什么socket也支持文件IO系統(tǒng)調(diào)用呢?在Linux上,這是通過套接口偽文件系統(tǒng)sockfs來實(shí)現(xiàn)的,因?yàn)閟ockfs實(shí)現(xiàn)了VFS中的4種主要對(duì)象:超級(jí)塊super block、索引節(jié)點(diǎn)inode、目錄項(xiàng)對(duì)象dentry和文件對(duì)象file,當(dāng)執(zhí)行文件IO系統(tǒng)調(diào)用時(shí),VFS就將請(qǐng)求轉(zhuǎn)發(fā)給sockfs,而sockfs就調(diào)用特定的協(xié)議實(shí)現(xiàn),層次結(jié)構(gòu)如下圖:
   本文以linux 2.6.34實(shí)現(xiàn)為基礎(chǔ),本篇闡述初始化和Socket創(chuàng)建兩部分的實(shí)現(xiàn),下篇闡述Socket操作和銷毀兩部分的實(shí)現(xiàn)。

初始化
   在內(nèi)核引導(dǎo)時(shí)初始化網(wǎng)絡(luò)子系統(tǒng),進(jìn)而調(diào)用sock_init,該函數(shù)主要步驟如下:創(chuàng)建inode緩存,注冊(cè)和裝載sockfs,定義在net/socket.c中。
1static int __init sock_init(void)
2{
3    
4    init_inodecache();
5    register_filesystem(&sock_fs_type);
6    sock_mnt = kern_mount(&sock_fs_type);
7    
8}
   
   創(chuàng)建inode緩存
   init_inodecache為socket_alloc對(duì)象創(chuàng)建SLAB緩存,名稱為sock_inode_cachep,socket_alloc定義在include/net/sock.h中。
1struct socket_alloc {
2    struct socket socket;
3    struct inode vfs_inode;
4}
;
   socket_alloc由socket和inode結(jié)構(gòu)2部分組成,這樣就方便了在套接字與inode對(duì)象間雙向定位。

   注冊(cè)sockfs
   調(diào)用VFS的函數(shù)register_filesystem實(shí)現(xiàn)注冊(cè),sock_fs_type定義在net/socket.c中。
1static struct file_system_type sock_fs_type = {
2    .name =        "sockfs",
3    .get_sb =    sockfs_get_sb,
4    .kill_sb =    kill_anon_super,
5}
;
   sock_fs_type包含了文件系統(tǒng)sockfs的名稱、創(chuàng)建和銷毀super block的函數(shù),其中sockfs_get_sb實(shí)現(xiàn)在net/socket.c中。
1static int sockfs_get_sb(struct file_system_type *fs_type,int flags, const char *dev_name, void *data,struct vfsmount *mnt)
2{
3    return get_sb_pseudo(fs_type, "socket:"&sockfs_ops, SOCKFS_MAGIC, mnt);
4}
   它在kern_mount內(nèi)被執(zhí)行,通過調(diào)用get_sb_pseudo創(chuàng)建了一個(gè)super block(包含一個(gè)對(duì)應(yīng)dentry及一個(gè)關(guān)聯(lián)inode):操作對(duì)象為sockfs_ops,根目錄名稱為socket:,對(duì)應(yīng)的根索引節(jié)點(diǎn)編號(hào)為1。
   sockfs_ops定義在net/socket.c中。
1static const struct super_operations sockfs_ops = {
2    .alloc_inode =    sock_alloc_inode,
3    .destroy_inode = sock_destroy_inode,
4    .statfs =    simple_statfs,
5}
;
   sock_alloc_inode用于分配inode對(duì)象,將在socket創(chuàng)建過程中被調(diào)用;sock_destroy_inode用于釋放inode對(duì)象,將在socket銷毀過程中被調(diào)用;simple_statfs用于獲取sockfs文件系統(tǒng)的狀態(tài)信息。
   
   裝載sockfs
   由kern_mount函數(shù)實(shí)現(xiàn)裝載一個(gè)偽文件系統(tǒng)(當(dāng)然,它沒有裝載點(diǎn)),返回一個(gè)static vfsmount對(duì)象sock_mnt。

   經(jīng)過以上步驟后,所創(chuàng)建的VFS對(duì)象關(guān)系如下圖:
    對(duì)于根目錄項(xiàng),不用進(jìn)行路徑轉(zhuǎn)換,因此dentry的d_op為空(未畫出);對(duì)于偽文件系統(tǒng),操作索引對(duì)象沒有意義,所以inode的i_op為空(未畫出)。

Socket創(chuàng)建


   系統(tǒng)調(diào)用socket、accept和socketpair是用戶空間創(chuàng)建socket的幾種方法,其核心調(diào)用鏈如下圖:
   從上圖可知共同的核心就3個(gè)過程:先構(gòu)造inode,再構(gòu)造對(duì)應(yīng)的file,最后安裝file到當(dāng)前進(jìn)程中(即關(guān)聯(lián)映射到一個(gè)未用的文件描述符),下面就這3個(gè)過程進(jìn)行詳細(xì)說明。

   構(gòu)造inode
   由sock_alloc函數(shù)實(shí)現(xiàn),定義在net/socket.c中。
 1static struct socket *sock_alloc(void)
 2{
 3    struct inode *inode;
 4    struct socket *sock;
 5
 6    inode = new_inode(sock_mnt->mnt_sb);
 7        
 8    sock = SOCKET_I(inode);
 9            
10    inode->i_mode = S_IFSOCK | S_IRWXUGO;
11    inode->i_uid = current_fsuid();
12    inode->i_gid = current_fsgid();
13        
14    return sock;
15}
   先調(diào)用new_inode創(chuàng)建inode對(duì)象,再設(shè)置它的類型為S_IFSOCK,由此可知inode對(duì)應(yīng)的文件類型為套接字。new_inode是文件系統(tǒng)的一個(gè)接口函數(shù),用于創(chuàng)建一個(gè)inode對(duì)象,定義在fs/inode.c中,它調(diào)用了sockfs超級(jí)塊的操作對(duì)象即sockfs_ops的sock_alloc_inode方法,由于sock_alloc_inode實(shí)際創(chuàng)建的是socket_alloc復(fù)合對(duì)象,因此要使用SOCKET_I宏從inode中取出關(guān)聯(lián)的socket對(duì)象用于返回。

   構(gòu)造file
   有了inode對(duì)象后,接下來就要構(gòu)造對(duì)應(yīng)的file對(duì)象了,由sock_alloc_file實(shí)現(xiàn),定義在net/socket.c中。
 1static int sock_alloc_file(struct socket *sock, struct file **f, int flags)
 2{
 3    struct qstr name = { .name = "" };
 4    struct path path;
 5    struct file *file;
 6    int fd;
 7
 8    fd = get_unused_fd_flags(flags);
 9        
10    path.dentry = d_alloc(sock_mnt->mnt_sb->s_root, &name);
11        
12    path.mnt = mntget(sock_mnt);
13
14    path.dentry->d_op = &sockfs_dentry_operations;
15    d_instantiate(path.dentry, SOCK_INODE(sock));
16    SOCK_INODE(sock)->i_fop = &socket_file_ops;
17
18    file = alloc_file(&path, FMODE_READ | FMODE_WRITE, &socket_file_ops);
19    
20    sock->file = file;
21    file->f_flags = O_RDWR | (flags & O_NONBLOCK);
22    file->f_pos = 0;
23    file->private_data = sock;
24
25    *= file;
26    return fd;
27}
   sock為上一過程返回的套接字對(duì)象,該函數(shù)主要做了以下幾件事:
   1)得到空閑的文件描述符fd,實(shí)際上就是fd數(shù)組的索引,準(zhǔn)備作為返回值。
   2)先初始化路徑path:其目錄項(xiàng)的父目錄項(xiàng)為超級(jí)塊對(duì)應(yīng)的根目錄,名稱為空,操作對(duì)象為sockfs_dentry_operations,對(duì)應(yīng)的索引節(jié)點(diǎn)對(duì)象為sock套接字關(guān)聯(lián)的索引節(jié)點(diǎn)對(duì)象,即SOCK_INODE(sock);裝載點(diǎn)為sock_mnt。  
   sockfs_dentry_operations定義在net/socket.c中。
1static const struct dentry_operations sockfs_dentry_operations = {
2    .d_dname  = sockfs_dname,
3}
;
   sockfs_dname會(huì)被d_path調(diào)用,用于計(jì)算socket對(duì)象的目錄項(xiàng)名稱。
   3)設(shè)置索引節(jié)點(diǎn)的文件操作對(duì)象為socket_file_ops,定義在net/socket.c中。
1static const struct file_operations socket_file_ops = {
2    
3    .aio_read =    sock_aio_read,
4    .aio_write =    sock_aio_write,
5    
6    .open =        sock_no_open,    /* special open code to disallow open via /proc */
7    .release =    sock_close,
8    
9}
;
   4)調(diào)用alloc_file,以path和socket_file_ops為輸入?yún)?shù),這樣返回得到的file便與sock的inode關(guān)聯(lián)上了,并且操作對(duì)象為socket_file_ops,最后設(shè)置到輸出參數(shù)f中。
   5)建立file與socket的一一映射關(guān)系。
   
   安裝file
   由fd_install實(shí)現(xiàn),定義在fs/open.c中。
 1void fd_install(unsigned int fd, struct file *file)
 2{
 3    struct files_struct *files = current->files;
 4    struct fdtable *fdt;
 5    spin_lock(&files->file_lock);
 6    fdt = files_fdtable(files);
 7    BUG_ON(fdt->fd[fd] != NULL);
 8    rcu_assign_pointer(fdt->fd[fd], file);
 9    spin_unlock(&files->file_lock);
10}
   fd和file分別為上一過程返回的空閑文件描述符和文件對(duì)象,使RCU技術(shù)來設(shè)置file到當(dāng)前進(jìn)程的fd數(shù)組中。
 
   經(jīng)過以上過程后,所創(chuàng)建的VFS對(duì)象關(guān)系圖如下
   fd為file*數(shù)組的索引而不是成員字段;vfsmount與初始化之VFS對(duì)象關(guān)系圖中的vfsmount是同一個(gè)對(duì)象,即sock_mnt;對(duì)于偽文件系統(tǒng),操作索引對(duì)象沒有意義,所以inode的i_op為空(未畫出)。
posted on 2015-05-03 16:31 春秋十二月 閱讀(8709) 評(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>
            久久久视频精品| 亚洲欧美制服中文字幕| 91久久国产综合久久91精品网站| 亚洲一区二区动漫| 亚洲国产精品久久精品怡红院| 亚洲视频狠狠| 日韩一级精品| 亚洲精品资源| 午夜精品福利一区二区蜜股av| 亚洲国产视频直播| 欧美+亚洲+精品+三区| 欧美一区二区日韩一区二区| 亚洲视频欧美视频| 亚洲福利免费| 91久久综合| 亚洲国产小视频在线观看| 国内揄拍国内精品久久| 黄色成人在线| 亚洲大胆av| 最新中文字幕亚洲| 亚洲毛片网站| 亚洲一区视频在线| 亚洲人体大胆视频| 宅男噜噜噜66一区二区66| 正在播放亚洲一区| 亚洲欧美变态国产另类| 午夜视频久久久久久| 亚洲精品中文字幕在线观看| 亚洲伦伦在线| 午夜宅男久久久| 久久精品欧美日韩| 欧美成人精品在线| 亚洲免费高清| 欧美亚洲在线播放| 久久三级视频| 欧美日韩黄色一区二区| 国产精品网曝门| 在线观看视频亚洲| 一本色道久久综合亚洲二区三区 | 亚洲免费一在线| 午夜久久tv| 麻豆91精品91久久久的内涵| 欧美另类一区| 国产婷婷色一区二区三区四区| 影视先锋久久| 一区二区三区 在线观看视| 亚洲国产精品欧美一二99| 夜夜夜久久久| 久久久久www| 国产视频丨精品|在线观看| 一区二区在线观看视频| 99精品热6080yy久久| 午夜日韩在线观看| 亚洲第一区色| 久久亚洲精选| 久久婷婷激情| 日韩亚洲欧美一区| 久久久久久网站| 国产精品第十页| 91久久精品久久国产性色也91| 欧美一区二区三区四区在线观看地址| 亚洲欧美日韩第一区| 美女露胸一区二区三区| 亚洲小视频在线观看| 免费成人你懂的| 国产一区二区三区久久悠悠色av | 国产欧美日韩综合| 91久久久久| 久久久久久伊人| 久久精品日韩欧美| 亚洲第一免费播放区| 欧美高清在线一区| 欧美多人爱爱视频网站| 亚洲乱亚洲高清| 99精品欧美一区二区三区| 欧美日韩亚洲一区二区三区在线 | 欧美视频精品在线| 亚洲字幕一区二区| 性欧美长视频| 亚洲国产精品成人| 91久久精品美女高潮| 欧美日本中文| 欧美中文字幕在线观看| 久久精品国产91精品亚洲| 亚洲欧美国产高清va在线播| 国产精品日产欧美久久久久| 久久国内精品视频| 老色批av在线精品| 亚洲视频第一页| 欧美一级理论性理论a| 黄网站色欧美视频| 亚洲精品视频啊美女在线直播| 国产精品久久久久久亚洲调教| 久久精品国产亚洲精品| 欧美成人精品h版在线观看| 亚洲网站视频福利| 欧美在线不卡| 一区二区三区波多野结衣在线观看| 在线一区观看| **网站欧美大片在线观看| 亚洲精品1区| 国产精品一区毛片| 亚洲国产日韩在线| 国产在线欧美| 一区二区三区蜜桃网| 国内一区二区三区| 亚洲人午夜精品| 黄色成人免费网站| 亚洲午夜成aⅴ人片| 久久人人97超碰国产公开结果| 99在线精品视频在线观看| 午夜亚洲精品| 亚洲一区在线直播| 你懂的国产精品| 久久精品午夜| 国产精品v欧美精品v日韩精品| 裸体一区二区| 国产日韩一区二区| 亚洲调教视频在线观看| 亚洲精选久久| 狂野欧美性猛交xxxx巴西| 西西裸体人体做爰大胆久久久| 欧美激情国产精品| 欧美成人视屏| 亚洲国产成人久久| 久久久久久亚洲综合影院红桃 | 影音先锋中文字幕一区| aa级大片欧美三级| 久久午夜国产精品| 久久久免费精品视频| 国产乱码精品一区二区三区av| 日韩网站在线观看| 亚洲另类黄色| 欧美国产在线观看| 欧美激情第一页xxx| 亚洲电影在线免费观看| 久久久av水蜜桃| 久久人人爽人人爽| 国产视频一区在线观看一区免费| 日韩一区二区福利| 亚洲一区二区久久| 国产精品久久久久9999| 一本色道久久99精品综合 | 欧美a级一区二区| 国内精品视频一区| 久久久99免费视频| 久久噜噜亚洲综合| 国产一区二区三区在线免费观看 | 嫩草伊人久久精品少妇av杨幂| 国产一区二区三区在线免费观看| 午夜精品视频在线| 久久免费黄色| 亚洲国产精品成人综合色在线婷婷| 久久人人爽人人爽爽久久| 欧美国产日韩一区| 在线视频亚洲欧美| 国产精品美女一区二区在线观看| 亚洲视频在线免费观看| 久久精品官网| 亚洲国产成人精品女人久久久 | 久久av一区二区三区| 亚洲国产一区二区三区a毛片| 久久久久久久久伊人| 国产精品一区二区女厕厕| 亚洲欧美制服另类日韩| 麻豆国产精品777777在线| 亚洲精品视频免费观看| 欧美视频成人| 久久精品导航| 亚洲美女中出| 久久午夜电影网| 日韩写真视频在线观看| 国产精品素人视频| 美国十次成人| 亚洲综合色网站| 亚洲高清一区二| 欧美在线影院| 日韩午夜免费视频| 国产婷婷精品| 欧美日韩国产一级片| 欧美中文在线免费| 日韩亚洲精品电影| 免费观看一区| 欧美亚洲在线| 一区二区三区欧美在线| 国内精品久久久久影院薰衣草| 欧美日本高清视频| 久久视频这里只有精品| 亚洲一区二区成人| 亚洲精品系列| 欧美激情第六页| 久久综合中文字幕| 欧美一乱一性一交一视频| 99国产精品久久久久久久| 狠狠色综合日日| 国产欧美日韩免费| 国产精品国产精品国产专区不蜜| 男男成人高潮片免费网站| 欧美一区国产在线| 亚洲综合好骚|