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

小默

【轉】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久久精品国产91久久| 国产日韩欧美高清免费| 欧美午夜影院| 欧美午夜www高清视频| 欧美大片免费| 久久久久久伊人| 欧美中日韩免费视频| 欧美一区二区免费视频| 午夜精品理论片| 欧美有码在线观看视频| 久久精品夜色噜噜亚洲a∨ | 日韩网站在线看片你懂的| 亚洲精品日本| 在线视频一区二区| 亚洲欧美国产不卡| 久久精品国产综合精品| 久久狠狠亚洲综合| 久久er精品视频| 红桃视频成人| 亚洲高清免费| 亚洲麻豆国产自偷在线| 亚洲午夜激情网站| 欧美一区二区三区视频在线| 久久尤物视频| 亚洲片在线资源| 亚洲国产精品www| 一区二区三区久久网| 午夜精品视频| 久久久精品tv| 欧美日韩国产不卡| 国产精品伊人日日| 亚洲三级国产| 久久精品国产999大香线蕉| 奶水喷射视频一区| 亚洲一区二区在线播放| 欧美成人精品1314www| 国产精品日韩久久久| 在线播放一区| 性18欧美另类| 亚洲裸体视频| 久久久青草青青国产亚洲免观| 欧美日本一区二区三区| 在线播放日韩| 久久噜噜噜精品国产亚洲综合| 亚洲精品一区在线观看香蕉| 久久久久久久久一区二区| 国产精品欧美日韩| 99国内精品久久| 蜜臀99久久精品久久久久久软件| 一区二区欧美国产| 欧美国产成人在线| 在线欧美电影| 久久亚洲春色中文字幕| 亚洲婷婷综合久久一本伊一区| 欧美成人亚洲| 亚洲黑丝在线| 女同性一区二区三区人了人一 | 久久久久久国产精品一区| av成人黄色| 欧美区一区二区三区| 在线观看亚洲| 久久中文字幕导航| 久久av二区| 国产一二精品视频| 久久精品人人做人人爽电影蜜月| 一区二区三区国产在线观看| 欧美日本在线一区| 亚洲人成人77777线观看| 狂野欧美激情性xxxx欧美| 日韩天堂在线视频| 欧美精品v日韩精品v韩国精品v | 亚洲韩国一区二区三区| 欧美freesex交免费视频| 久久久久天天天天| 激情懂色av一区av二区av| 久久久久久一区| 新狼窝色av性久久久久久| 国产毛片精品国产一区二区三区| 校园春色综合网| 亚洲欧美一区二区三区久久| 国产精品久久久久三级| 亚洲欧美日韩中文在线制服| 一本到12不卡视频在线dvd | 国产精品一区二区久久| 亚洲综合精品四区| 午夜精品一区二区三区在线播放| 国产精品入口尤物| 久久久久久亚洲精品杨幂换脸| 欧美大片一区| 欧美一级久久久| 老司机免费视频一区二区| 99精品视频免费全部在线| 亚洲一区国产精品| 亚洲第一区中文99精品| 亚洲国产经典视频| 欧美日韩国产一级片| 欧美一区中文字幕| 欧美成人精品1314www| 亚洲男女毛片无遮挡| 久久精品青青大伊人av| 在线中文字幕不卡| 久久综合伊人| 午夜精品久久久久久久久久久久| 久久美女性网| 亚洲欧美日韩国产另类专区| 久久福利电影| 亚洲综合社区| 欧美777四色影视在线| 欧美一区二区视频网站| 亚洲女女做受ⅹxx高潮| 亚洲欧洲午夜| 久久黄金**| 日韩一二三区视频| 午夜视频精品| 久久riav二区三区| 狠狠做深爱婷婷久久综合一区| 欧美国产日本在线| 中文在线资源观看网站视频免费不卡 | 国产视频一区在线观看| 久久国产视频网站| 久久视频一区二区| 亚洲日韩第九十九页| 一本大道久久a久久综合婷婷 | 久久亚洲图片| 亚洲美女av在线播放| 亚洲综合色网站| 亚洲国产欧美一区二区三区同亚洲 | 亚洲欧美日韩综合国产aⅴ| 伊人成人开心激情综合网| 99国产精品私拍| 在线观看欧美视频| 亚洲综合欧美| 欧美与欧洲交xxxx免费观看| 蜜桃精品久久久久久久免费影院| 亚洲综合好骚| 欧美岛国激情| 裸体丰满少妇做受久久99精品 | 亚洲性图久久| 日韩午夜中文字幕| 亚洲特黄一级片| 欧美一区在线视频| 欧美激情五月| 欧美高清日韩| 国产精品亚洲视频| 亚洲美女毛片| 免费亚洲网站| 亚洲精品久久| 曰韩精品一区二区| 久久精品99| 久久综合久久综合这里只有精品| 国产精品乱子久久久久| 99在线观看免费视频精品观看| 亚洲日本在线观看| 久久精品九九| 久久久久国色av免费观看性色| 欧美视频在线免费| 亚洲最黄网站| 久久久久网站| 国产日韩在线一区| 亚洲综合色噜噜狠狠| 欧美一区深夜视频| 国产欧美大片| 亚洲欧美日韩国产综合精品二区 | 欧美不卡三区| 亚洲麻豆av| 亚洲影音先锋| 欧美成人综合在线| 亚洲综合社区| 欧美一区二区视频观看视频| 国产精品综合色区在线观看| 亚洲欧美激情一区| 久久久亚洲成人| 亚洲最新视频在线| 欧美日韩在线一区二区三区| 亚洲一区二区在线观看视频| 亚洲午夜免费福利视频| 国产精品嫩草久久久久| 女人香蕉久久**毛片精品| 亚洲激精日韩激精欧美精品| 制服丝袜亚洲播放| 国产精品婷婷| 久久久一二三| 欧美国产大片| 亚洲视屏一区| 国产在线拍揄自揄视频不卡99 | 毛片一区二区三区| 99精品国产一区二区青青牛奶 | 欧美自拍丝袜亚洲| 亚洲老司机av| 欧美日韩中文字幕日韩欧美| 香蕉成人久久| 亚洲经典一区| 久久精品亚洲一区二区| 亚洲性av在线| 黄色成人av网| 欧美午夜片在线观看|