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

小默

【轉】proc文件系統分析(四)

(六) 對proc文件默認操作的分析 
現在,我們已經基本清楚了proc文件系統對自己proc_dir_entry結構的管理了。下面我們回過頭來,再看一下在文件注冊函數中的一段代碼: 
if (S_ISDIR(dp->mode)) { 
if (dp->proc_iops == NULL) { 
dp->proc_fops = &proc_dir_operations; 
dp->proc_iops = &proc_dir_inode_operations; 
} 
dir->nlink++; 
} else if (S_ISLNK(dp->mode)) { 
if (dp->proc_iops == NULL) 
dp->proc_iops = &proc_link_inode_operations; 
} else if (S_ISREG(dp->mode)) { 
if (dp->proc_fops == NULL) 
dp->proc_fops = &proc_file_operations; 
} 
我在前面已經提過,這段代碼根據注冊的proc文件類型的不同,為proc_dir_entry結構設置了不同的操作函數集。也就是說,我們使用封裝的create_proc_entry函數在proc文件系統中注冊文件時,可以不用去管這些操作函數集,因為該結構總是自動地設置了相應的proc_iops和proc_fops操作函數。下面我們就對這些默認的操作進行一個分析,因為這對我們了解proc文件系統和VFS的結構非常重要。 
1 對普通文件的操作 
我們首先看一下普通proc文件的函數集,根據代碼段: 
if (S_ISREG(dp->mode)) { 
if (dp->proc_fops == NULL) 
dp->proc_fops = &proc_file_operations; 
} 
我們可以看到,對于普通的proc文件,只設置了文件操作,即proc_file_operations,從這一點上可以看出,對于普通的proc文件,只缺省提供了文件操作,因此,在必要的時候,我們必須手工設置需要的索引節點操作函數集,比如inode_operations中的權限檢查函數permission等等。 
對于proc_file_operations,我們可以看到,只實現了三個函數: 
static struct file_operations proc_file_operations = { 
llseek: proc_file_lseek, 
read: proc_file_read, 
write: proc_file_write, 
}; 
下面我們簡單的看一下它們實現的功能: 
(1)llseek: proc_file_lseek 
這個函數,用來實現lseek系統調用,其功能是設置file結構的->f_pos域,因此,根據第三個參數orig的不同,將f_pos設置為相應的值,該函數非常簡單,因此不作過多的介紹。 
(2)read: proc_file_read 
這個函數是file_operations結構中的成員,在后面我們將看到,在proc_dir_entry結構中實現的file_operations和inode_operations將鏈接至VFS的inode中,因此,該函數將用來實現read系統調用。在這個函數中,首先根據file結構,得到相應的inode,然后由 
struct proc_dir_entry * dp; 
dp = (struct proc_dir_entry *) inode->u.generic_ip; 
而得到proc_dir_entry結構,然后,開始調用該proc_dir_entry結構中的函數,向用戶空間返回指定大小的數據,我們看一下下面的代碼片斷: 
if (dp->get_info) { 
/* 
* Handle backwards compatibility with the old net 
* routines. 
*/ 
n = dp->get_info(page, &start, *ppos, count); 
if (n read_proc) { 
n = dp->read_proc(page, &start, *ppos, 
count, &eof, dp->data); 
} else 
break; 
由此我們看出,該函數的實現依賴于proc_dir_entry結構中的get_info和read_proc函數,因此,如果我們要注冊自己的proc文件,在不設置自己的proc_fops操作函數集的時候,必須實現上面兩個函數中的一個,否則,這個缺省的proc_file_read函數將做不了任何工作。示意圖如下: 
在這個函數中,實現了從內核空間向用戶空間傳遞數據的功能,其中使用了許多技巧,在這里就不作討論了,具體實現可以參考源碼。 
(3)write: proc_file_write 
與上面的函數類似,我們可以看到proc_file_write函數同樣依賴于proc_dir_entry中的write_proc(file, buffer, count, dp->data)函數,它的實現非常簡單: 
static ssize_t 
proc_file_write(struct file * file, const char * buffer, 
size_t count, loff_t *ppos) 
{ 
struct inode *inode = file->f_dentry->d_inode; 
struct proc_dir_entry * dp; 
dp = (struct proc_dir_entry *) inode->u.generic_ip; 
if (!dp->write_proc) 
return -EIO; 
/* FIXME: does this routine need ppos? probably... */ 
return dp->write_proc(file, buffer, count, dp->data); 
} 
我們看到,它只是簡單地檢測了->write_proc函數是否存在,如果我們在proc_dir_entry結構中實現了這個函數,那么就調用它,否則,就退出。 
根據上面的討論,我們看到,對于普通文件的操作函數,proc文件系統為我們提供了一個簡單的封裝,因此,我們只要在proc_dir_entry中實現相關的讀寫操作即可。 
但是,如果我們想提供讀寫操作之外的函數,那么我們就可以定義自己的file_operations函數集,并且在proc文件注冊后,將它鏈接到proc_dir_entry的proc_fops上,這樣,就可以使用自己的函數集了。 
2 對鏈接文件的操作 
根據代碼段: 
else if (S_ISLNK(dp->mode)) { 
if (dp->proc_iops == NULL) 
dp->proc_iops = &proc_link_inode_operations; 
我們可以看出,對于鏈接文件,proc文件系統為它設置了索引節點操作proc_iops。因為我們知道,一個符號鏈接,只擁有inode結構,而沒有文件結構,所以,為它提供proc_link_inode_operations函數集就可以了。 
下面我們看一下,這個函數集的內容: 
static struct inode_operations proc_link_inode_operations = { 
readlink: proc_readlink, 
follow_link: proc_follow_link, 
}; 
這個函數集實現了和鏈接相關的兩個函數,我們分別來看一下: 
(1)readlink: proc_readlink 
該函數用來實現readlink系統調用,它的功能是獲得目標文件的文件名,我們在前面看到,對于一個鏈接文件,在注冊時已經將鏈接目標的文件放在了proc_dir_entry結構的->data域中(參考前面介紹的函數proc_symlink),因此,我們只要將->data中的數據返回就可以了,它的代碼如下: 
static int proc_readlink(struct dentry *dentry, char *buffer, int buflen) 
{ 
char *s= 
((struct proc_dir_entry *)dentry->d_inode->u.generic_ip)->data; 
return vfs_readlink(dentry, buffer, buflen, s); 
} 
我們看到,這個函數使用一個指針指向->data,然后,使用VFS函數vfs_readlink將數據返回到用戶空間,非常的簡單。 
(2)follow_link: proc_follow_link 
這個函數代碼如下: 
static int proc_follow_link(struct dentry *dentry, struct nameidata *nd) 
{ 
char *s= 
((struct proc_dir_entry *)dentry->d_inode->u.generic_ip)->data; 
return vfs_follow_link(nd, s); 
} 
和上面介紹的函數類似,它同樣利用VFS的函數實現其功能,對于vfs_follow_link,可以參考fs/namei.c文件。其結構如下圖所示: 
3 對目錄文件的操作 
最后我們看一下proc文件系統對目錄文件的操作函數集,在文件注冊的時候,有如下代碼: 
if (S_ISDIR(dp->mode)) { 
if (dp->proc_iops == NULL) { 
dp->proc_fops = &proc_dir_operations; 
dp->proc_iops = &proc_dir_inode_operations; 
} 
dir->nlink++; 
} 
從中我們可以看到,在proc文件系統中注冊目錄文件的時候,它會檢查是否該proc_dir_entry結構已經注冊了proc_iops函數集,如果沒有,那么就為proc_fops和proc_iops設置相應的缺省函數集。下面我們對它們分別進行討論: 
1.對目錄的文件操作proc_dir_operations: 
static struct file_operations proc_dir_operations = { 
read: generic_read_dir, 
readdir: proc_readdir, 
}; 
這個函數集的主要功能,是在由proc_dir_entry結構構成的proc文件樹中解析目錄。下面我們對這兩個函數進行一個簡單的分析: 
(1)read: generic_read_dir 
我們知道,對于read系統調用,當其參數文件句柄指向目錄的時候,將返回EISDIR錯誤。因此,目錄文件的read函數將完成這個工作。generic_read_dir函數是VFS提供的通用函數,可以參考fs/read_write.c文件: 
ssize_t generic_read_dir(struct file *filp, char *buf, size_t siz, loff_t *ppos){ 
return –EISDIR; 
} 
這個函數很簡單,只要返回錯誤碼就可以了。 
(2)readdir: proc_readdir 
這個函數用來實現readdir系統調用,它從目錄文件中讀出dirent結構到內存中。我們可以參考fs/readdir.c中的filldir()函數。 
2.對目錄文件索引節點的操作函數:proc_dir_inode_operations 
首先,我們看一下proc_dir_inode_operations的定義: 
/* 
* proc directories can do almost nothing.. 
*/ 
static struct inode_operations proc_dir_inode_operations = { 
lookup: proc_lookup, 
}; 
我們看到,對于目錄文件的索引節點,只定義了一個函數lookup。因為我們在前面對VFS進行分析的時候知道,以下操作,是只在目錄節點中定義的: 
int (*create) (struct inode *,struct dentry *,int); 
struct dentry * (*lookup) (struct inode *,struct dentry *); 
int (*link) (struct dentry *,struct inode *,struct dentry *); 
int (*unlink) (struct inode *,struct dentry *); 
int (*symlink) (struct inode *,struct dentry *,const char *); 
int (*mkdir) (struct inode *,struct dentry *,int); 
int (*rmdir) (struct inode *,struct dentry *); 
int (*mknod) (struct inode *,struct dentry *,int,int); 
int (*rename) (struct inode *, struct dentry *, 
struct inode *, struct dentry *); 
但是經過我們對proc文件系統的分析,我們知道,proc文件系統中的文件都是在內核代碼中通過proc_dir_entry實現的,因此,它不提供目錄索引節點的create,link,unlink,symlink,mkdir,rmdir,mknod,rename方法,也就是說,用戶是不能通過shell命令在/proc目錄中對proc文件進行改名,刪除,建子目錄等操作的。這也算是proc文件系統的一種保護策略。 
而在內核中,則使用proc_mkdir,proc_mknod等函數,在核心內通過代碼來維護proc文件樹。由此可以看出虛擬文件系統的一些特性。對目錄文件的默認操作,可以參見下面的示意圖: 
下面我們就來看一下唯一定義的函數lookup: proc_lookup,到底實現了什么功能。 
在進行具體分析之前,我們先考慮一個問題,我們知道,proc文件系統維護了自己的proc_dir_entry結構,因此提供了create_proc_entry,remove_proc_entry等等函數,并且為了方便實現對proc文件的讀寫功能,特意在proc_dir_entry結構中設置了get_info,read_proc和write_proc函數指針(我們在前面介紹過,這三個函數被封裝在proc_file_operations中),并且,提供了自己的inode_operations和file_operations,分別是proc_iops 和proc_fops。也就是說,我們在建立proc文件以及為proc文件建立操作函數的時候,似乎可以不用考慮VFS的實現,只要建立并注冊該proc_dir_entry結構,然后實現其proc_iops 和proc_fops(或者get_info,read_proc和write_proc)就可以了。 
但是我們知道,在linux系統中,所有的子系統都是與VFS層交互,而VFS是通過inode結構進行管理的,并且在其上的操作(文件和索引節點的操作)也是通過該inode結構的inode_operations和file_operations實現的。因此,proc文件系統必須將自己的文件與VFS的inode鏈接起來。 
那么proc文件系統是在何時,通過何種方法將自己的proc_dir_entry結構和VFS的inode聯系在一起的,并且將對inode的inode_operations和file_operations操作定位到自己結構中的proc_iops 和proc_fops上呢?通過我們對lookup: proc_lookup的分析,就會明白這一過程。 
我們先看一下它的代碼: 
struct dentry *proc_lookup(struct inode * dir, struct dentry *dentry) 
{ 
struct inode *inode; 
struct proc_dir_entry * de; 
int error; 
error = -ENOENT; 
inode = NULL; 
de = (struct proc_dir_entry *) dir->u.generic_ip; 
if (de) { 
for (de = de->subdir; de ; de = de->next) { 
if (!de || !de->low_ino) 
continue; 
if (de->namelen != dentry->d_name.len) 
continue; 
if (!memcmp(dentry->d_name.name, 
de->name, de->namelen)) { 
int ino = de->low_ino; 
error = -EINVAL; 
inode = proc_get_inode(dir->i_sb, ino, de); 
break; 
} 
} 
} 
if (inode) { 
dentry->d_op = &proc_dentry_operations; 
d_add(dentry, inode); 
return NULL; 
} 
return ERR_PTR(error); 
} 
這個函數的參數是struct inode * dir和struct dentry *dentry,它的功能是查找由dentry指定的文件,是否在由dir指定的目錄中。 
我們知道,proc文件系統通過proc_dir_entry結構維護文件信息,并且該結構與相應的inode->u.generic_ip聯系,因此,這個函數首先通過struct inode * dir得到了相應目錄文件的proc_dir_entry結構,并使用指針de指向它,然后,開始在該結構的孩子中查找指定的dentry。 
判斷是否找到的條件很簡單,就是de->namelen等于 dentry->d_name.len,并且dentry->d_name.name等于de->name,根據程序流程,如果沒有找到,那么將返回-ENOENT錯誤(使用inode指針作為判斷條件),如果找到該文件,那么就根據ino = de->low_ino(要注意的是,這時候的de已經指向由dentry確定的proc_dir_entry結構了。)調用函數: 
inode = proc_get_inode(dir->i_sb, ino, de); 
這個proc_get_inode的功能很容易猜到,就是從由超級塊i_sb確定的文件系統中,得到索引節點號為ino的inode。因此考慮兩種情況,第一種情況,這個索引節點已經被讀入緩存了,那么直接返回該inode即可。第二種情況是,指定ino的索引節點不在緩存中,那么就需要調用相應的函數,將該索引節點從邏輯文件系統中讀入inode中。 
下面我們就來分析一下proc_get_inode函數,尤其注意上面所說的第二種情況,因為這正是inode和proc_dir_entry建立聯系并重定位操作函數集的時機。先看一下源碼: 
struct inode * proc_get_inode(struct super_block * sb, int ino, 
struct proc_dir_entry * de) 
{ 
struct inode * inode; 
/* 
* Increment the use count so the dir entry can't disappear. 
*/ 
de_get(de); 
#if 1 
/* shouldn't ever happen */ 
if (de && de->deleted) 
printk("proc_iget: using deleted entry %s, count=%d\n", de->name, atomic_read(&de->count)); 
#endif 
inode = iget(sb, ino); 
if (!inode) 
goto out_fail; 
inode->u.generic_ip = (void *) de; /* link the proc_dir_entry to inode */ 
/* 
* set up other fields in the inode 
*/ 
if (de) { 
if (de->mode) { 
inode->i_mode = de->mode; 
inode->i_uid = de->uid; 
inode->i_gid = de->gid; 
} 
if (de->size) 
inode->i_size = de->size; 
if (de->nlink) 
inode->i_nlink = de->nlink; 
if (de->owner) 
__MOD_INC_USE_COUNT(de->owner); 
if (S_ISBLK(de->mode)||S_ISCHR(de->mode)||S_ISFIFO(de->mode)) 
init_special_inode(inode,de->mode,kdev_t_to_nr(de->rdev)); 
else { 
if (de->proc_iops) 
inode->i_op = de->proc_iops; 
if (de->proc_fops) 
inode->i_fop = de->proc_fops; 
} 
} 
out: 
return inode; 
out_fail: 
de_put(de); 
goto out; 
} 
我們根據程序流程,分析它的功能: 
1.使用de_get(de)增加proc_dir_entry結構de的引用計數。 
2.使用VFS的iget(sb, ino)函數,從sb指定的文件系統中得到節點號為ino的索引節點,并使用指針inode指向它。如果沒有得到,則直接跳到標號out_fail,減少de的引用計數后退出。 
因此我們要了解一下iget,這個函數由VFS提供,可以參考源文件fs/inode.c和頭文件include/linux/fs.h,在fs.h頭文件中,有如下定義: 
static inline struct inode *iget(struct super_block *sb, unsigned long ino) 
{ 
return iget4(sb, ino, NULL, NULL); 
} 
因此該函數是由fs/inode.c中的iget4實現的。主要步驟是,首先根據sb和ino得到要查找的索引節點的哈希鏈表,然后調用find_inode函數在該鏈表中查找該索引節點。如果找到了,那么就增加該索引節點的引用計數,并將其返回;否則,調用get_new_inode函數,以便從邏輯文件系統中讀出該索引節點。 
而get_new_inode函數也很簡單,它分配一個inode結構,并試圖重新查找指定的索引節點,如果還是沒有找到,那么就給新分配的索引節點加入到哈希鏈表和使用鏈表中,并設置一些基本信息,如i_ino,i_sb,i_dev等,并且,將其引用計數i_count初始化為1。然后,調用超級塊sb的read_inode函數,來作邏輯文件系統自己特定的工作,但對于proc文件系統來說,read_inode函數基本沒有實質性的功能,可參考前文對該函數的分析。最后,返回這個新建的索引節點。 
3.這時,我們已經得到了指定的inode(或者是從緩存中返回,或者是利用get_new_inode函數剛剛創建),那么就使用語句 
inode->u.generic_ip = (void *) de; 
將proc_dir_entry結構de與相應的索引節點鏈接起來。因此,我們就可以在其他時刻,利用proc文件索引節點的->u.generic_ip得到相應的proc_dir_entry結構了。 
對于新創建的inode來說,將其->u.generic_ip域指向(void *) de沒什么問題,因為該域還沒有被賦值,但是如果這個inode是從緩存中得到的,那么,說明該域已經指向了一個proc_dir_entry結構,這樣直接賦值,會不會引起問題呢? 
這有兩種情況,第一種情況,它指向的proc_dir_entry結構沒有發生過變化,那么,由于索引節點是由ino確定的,而且在一個文件系統中,確保了索引節點號ino的唯一性,因此,使用inode->u.generic_ip = (void *) de語句對其重新進行賦值,不會發生任何問題。 
另一種情況是在這之前,程序曾調用remove_proc_entry要將該proc_dir_entry結構刪除,那么由于它的引用計數count不等于零,因此,該結構不會被釋放,而只是打上了刪除標記。所以這種情況下,該賦值語句也不會引起問題。 
我們知道,當inode的i_count變為0的時候,會調用sb的proc_delete_inode函數,這個函數將inode的i_state設置為I_CLEAR,這可以理解為將該inode刪除了,并調用de_put,減少并檢查proc_dir_entry的引用計數,如果到零,也將其釋放。因此我們看到,引用計數的機制使得VFS的inode結構和proc的proc_dir_entry結構能夠保持同步,也就是說,對于一個存在于緩存中的的inode,必有一個proc_dir_entry結構存在。 
4.這時,我們已經得到了inode結構,并且將相應的proc_dir_entry結構de與inode鏈接在了一起。因此,就可以根據de的信息,對inode的一些域進行填充了。其中最重要的是使用語句: 
if (de->proc_iops) 
inode->i_op = de->proc_iops; 
if (de->proc_fops) 
inode->i_fop = de->proc_fops; 
將inode的操作函數集重定向到proc_dir_entry結構提供的函數集上。這是因為我們可以通過proc_dir_entry結構進行方便的設置和調整,但最終要將文件提交至VFS進行管理。正是在這種思想下,proc文件系統提供提供了一套封裝函數,使得我們可以只對proc_dir_entry結構進行操作,而忽略與VFS的inode的聯系。 
5.最后,成功地返回所要的inode結構。 
(七) 小結 
至此,已經對proc文件系統進行了一個粗略的分析,從文件系統的注冊,到proc_dir_entry結構的管理,以及與VFS的聯系等等。下面我們對proc文件系統的整體結構作一個總結。 
proc文件系統使用VFS接口,注冊自己的文件類型,并且通過注冊時提供的proc_read_super函數,創建自己的超級塊,然后裝載vfsmount結構。在proc文件系統內部,則使用proc_dir_entry結構來維護自己的文件樹,并且通過目錄文件的lookup函數,將proc_dir_entry結構與VFS的inode結構建立聯系。 


本文來自ChinaUnix博客,如果查看原文請點:http://blog.chinaunix.net/u2/74524/showart_1129842.html

posted on 2010-06-23 06:10 小默 閱讀(596) 評論(0)  編輯 收藏 引用 所屬分類: Linux

導航

統計

留言簿(13)

隨筆分類(287)

隨筆檔案(289)

漏洞

搜索

積分與排名

最新評論

閱讀排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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成人网| 欧美大色视频| 欧美~级网站不卡| 欧美刺激性大交免费视频| 亚洲综合三区| 亚洲国产精品va在线看黑人| 91久久线看在观草草青青| 狠狠色狠色综合曰曰| 在线观看欧美亚洲| 亚洲精品国产精品国产自| 亚洲伦理一区| 欧美亚洲视频一区二区| 免费永久网站黄欧美| 亚洲激情视频在线观看| 99精品国产福利在线观看免费| 亚洲网站视频| 久久婷婷综合激情| 欧美日韩亚洲精品内裤| 国产一区二区三区高清在线观看 | 亚洲女与黑人做爰| 午夜精品在线视频| 欧美黄色影院| 亚洲在线观看免费| 麻豆精品在线观看| 国产日韩精品在线播放| 亚洲国产高清一区| 欧美一区二区三区四区在线| 欧美成人午夜免费视在线看片| 99在线|亚洲一区二区| 久久激情视频免费观看| 欧美午夜激情视频| 亚洲国产精品热久久| 欧美一区二区黄| 亚洲国产一区在线| 久久久免费精品视频| 国产精品视频99| 亚洲毛片在线观看| 久热re这里精品视频在线6| 日韩视频在线观看| 欧美aⅴ一区二区三区视频| 国产人成一区二区三区影院| 夜夜爽夜夜爽精品视频| 欧美成人一区在线| 久久国产婷婷国产香蕉| 欧美视频在线观看视频极品 | 国产欧美日韩在线观看| 在线一区日本视频| 最新中文字幕一区二区三区| 美女精品在线观看| 一区视频在线| 久久精品最新地址| 午夜精品视频网站| 国产麻豆精品theporn| 国产精品揄拍500视频| 亚洲第一福利视频| 亚洲电影天堂av| 久久xxxx精品视频| 毛片一区二区三区| 国产精品免费电影| 亚洲男人的天堂在线观看 | 一本色道**综合亚洲精品蜜桃冫| 欧美国产在线视频| 欧美一区二区三区视频在线观看| 久久久免费精品视频| 国产在线视频欧美一区二区三区| 亚洲精品四区| 亚洲少妇诱惑| 奶水喷射视频一区| 国产精品欧美一区喷水| 国产精品99久久久久久www| 亚洲国产老妈| 亚洲一区二区三区精品在线观看 | 欧美三区美女| 亚洲综合丁香| 欧美在线视频a| 精品51国产黑色丝袜高跟鞋| 裸体歌舞表演一区二区| 另类av导航| 亚洲午夜激情网页| 午夜精品www| 伊人婷婷欧美激情| 亚洲激情黄色| 国产精品影片在线观看| 久久久久久久一区二区| 免费观看成人www动漫视频| 99xxxx成人网| 亚洲综合色噜噜狠狠| 国内偷自视频区视频综合| 欧美激情视频给我| 国产精品免费aⅴ片在线观看| 久久亚洲综合色| 欧美日韩国产电影| 久久久久久高潮国产精品视| 久久婷婷激情| 一本色道88久久加勒比精品 | 亚洲精品一区在线| 亚洲高清二区| 亚洲精品久久久久久下一站| 国产精品高清在线观看| 欧美在线不卡| 久久久久国产精品麻豆ai换脸| 亚洲另类在线一区| 欧美一区激情视频在线观看| 亚洲国产精品一区二区www| 一二三四社区欧美黄| 在线看日韩欧美| 99热精品在线| 最新国产成人在线观看| 亚洲午夜黄色| 亚洲精品一区二区三区四区高清| 亚洲欧美综合v| 宅男精品视频| 欧美国产91| 欧美成人按摩| 国内自拍亚洲| 亚洲欧美一区二区原创| 亚洲精品免费网站| 欧美一二三区精品| 亚洲欧美日韩国产综合| 农村妇女精品| 亚洲综合色激情五月| 欧美高清在线视频| 久久超碰97人人做人人爱| 欧美在线国产| 欧美成人伊人久久综合网| 欧美一区1区三区3区公司| 欧美国产精品专区| 鲁大师成人一区二区三区| 国产欧美日韩在线| 在线午夜精品| 亚洲主播在线播放| 欧美日韩专区| 99精品国产99久久久久久福利| 亚洲激情国产| 蜜桃精品一区二区三区| 美女日韩欧美| 亚洲国产三级网| 国产精品久久一区主播| 亚洲精品影视在线观看| 亚洲精品国产日韩| 嫩草国产精品入口| 亚洲国产毛片完整版 | 欧美片在线播放| 亚洲精品美女久久久久| 亚洲伦伦在线| 欧美日韩一区二区免费在线观看| 亚洲乱码日产精品bd| 亚洲网站视频福利| 国产精品久久久久久久一区探花 | 欧美日韩亚洲天堂| 99精品久久免费看蜜臀剧情介绍| 欧美日韩一区二区三区高清| 亚洲精品日本| 亚洲一区二区在线免费观看视频 | 亚洲欧美在线视频观看| 久久av资源网站| 黄色一区二区在线观看| 久久综合电影| avtt综合网| 久久久久这里只有精品| 91久久国产自产拍夜夜嗨| 欧美日韩国产首页在线观看| 亚洲视频一区二区在线观看| 久久久久久电影| 亚洲乱码一区二区| 国产午夜精品在线| 欧美高清在线视频观看不卡| 亚洲——在线| 欧美激情aⅴ一区二区三区| 一区二区日韩免费看| 国产视频自拍一区| 欧美福利视频在线| 亚洲欧美另类中文字幕| 欧美激情亚洲激情| 久久9热精品视频| 亚洲欧洲在线视频| 国产欧美日韩专区发布| 欧美极品欧美精品欧美视频| 亚洲欧美制服中文字幕| 亚洲日本理论电影| 久久久久久久久伊人| 这里是久久伊人| 最新精品在线| 狠狠色综合网| 欧美午夜电影一区| 男女视频一区二区| 羞羞漫画18久久大片| 99re66热这里只有精品3直播| 久久综合伊人77777麻豆| 午夜精品国产更新| 亚洲美女色禁图| 在线电影院国产精品| 国产精品夜色7777狼人| 欧美日韩ab片| 免费在线成人| 久久偷看各类wc女厕嘘嘘偷窃| 亚洲一区二区三区四区五区午夜| 亚洲国产精品精华液2区45| 久久偷窥视频|