精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

Littlefs原理分析--Commit機制(二)

系統 OpenHarmony
本文介紹了Littlefs中的Commit機制,包括Commit、Compact、Split操作的過程,怎樣寫入Tag和數據,怎樣計算CRC,以及相應的異常情況處理等。

??想了解更多關于開源的內容,請訪問:??

??51CTO 開源基礎軟件社區??

??https://ost.51cto.com??

前言

回顧littlefs的存儲結構,其中最為核心的是元數據。元數據以tag為單元進行信息的存儲,以commit的方式進行信息的更新。當littlefs中進行文件、目錄的創建、修改、刪除等一系列操作時,實際上都是通過向元數據中進行commit操作的方式實現。本文將對littlefs中commit機制進行介紹。

一、commit過程

commit具體的過程如下圖所示:

#littlefs原理分析#[二]commit機制-開源基礎軟件社區

每一次commit時都會向元數據對中寫入一系列的tag和數據,并計算CRC。因為在commit時總是會進行CRC計算,并且從元數據中讀取數據時會做校驗,因此一次commit是一次原子操作。

下面以具體的案例對commit過程進行說明:

1、超級塊的創建

當littlefs進行格式化操作時,會進行超級塊的創建。超級塊創建主要是在根目錄對應元數據對的塊中進行commit:

#littlefs原理分析#[二]commit機制-開源基礎軟件社區

如上圖,超級塊創建時調用lfs_dir_commit函數寫入了CREATE、SUPERBLOCK、INLINESTRUCT和CRC類型的tag。lfs_dir_commit函數中進行了commit的實際寫入操作,其主要分為以下兩個步驟:

  1. 將tag和對應的數據依次寫入元數據對應塊中。
  2. 計算CRC,并接著將其tag和CRC數據寫入元數據對應塊中。

超級塊創建相關函數:

lfs_format(lfs_t *lfs, const struct lfs_config *cfg)
|-> lfs_rawformat(lfs_t *lfs, const struct lfs_config *cfg)
| // 1. 分配根目錄,其塊號為0,1
|-> lfs_dir_alloc(lfs, &root);
|
| // 2. 通過commit創建超級塊
|-> lfs_superblock_t superblock = {
| .version = LFS_DISK_VERSION,
| .block_size = lfs->cfg->block_size,
| .block_count = lfs->cfg->block_count,
| .name_max = lfs->name_max,
| .file_max = lfs->file_max,
| .attr_max = lfs->attr_max,
| };
| lfs_dir_commit(lfs, &root, LFS_MKATTRS(
| {LFS_MKTAG(LFS_TYPE_CREATE, 0, 0), NULL},
| {LFS_MKTAG(LFS_TYPE_SUPERBLOCK, 0, 8), "littlefs"},
| {LFS_MKTAG(LFS_TYPE_INLINESTRUCT, 0, sizeof(superblock)),
| &superblock}));

(1)tag和相應數據的寫入

#littlefs原理分析#[二]commit機制-開源基礎軟件社區

如上圖,在commit過程中,ptag用于進行tag的異或運算,其初始化值為0xffffffff。ptag會依次與將要commit的tag(如上圖中的tagA、tagB、tagC)進行異或運算,然后將運算后的結果存儲到塊中。同時每寫一個tag后,將其對應的數據也進行寫入。

相關函數分析:

lfs_dir_commitattr(lfs_t *lfs, struct lfs_commit *commit,
| lfs_tag_t tag, const void *buffer)
| // 1. 將ptag和tag進行異或運算
| // 注:這里將tag的有效位置為了0,表示tag有效,并且tag為大端存儲
|-> lfs_tag_t ntag = lfs_tobe32((tag & 0x7fffffff) ^ commit->ptag);
|
| // 2. 寫入異或后的ntag
|-> lfs_dir_commitprog(lfs, commit, &ntag, sizeof(ntag));
|
| // 3. 寫入對應數據
|-> lfs_dir_commitprog(lfs, commit, buffer, dsize-sizeof(tag));

(2)CRC的寫入

commit過程中,當寫入tag(異或后的tag)或數據時,均會進行逐字節CRC的計算。最后commit完成后,再寫入相應的CRC tag和對應的CRC值。同時為了寫入對齊,在CRC tag后會設置相應的padding。

CRC計算的范圍為從本次commit起始的tag和數據,一直到CRC tag(包括CRC tag)。

寫入CRC后塊中布局如下圖:

#littlefs原理分析#[二]commit機制-開源基礎軟件社區

相關函數分析:

// 該函數用于寫入tag或數據,每當調用該函數時都會做CRC的計算
lfs_dir_commitprog(lfs_t *lfs, struct lfs_commit *commit,
| const void *buffer, lfs_size_t size)
| // 1. 將傳入的tag或tag對應數據寫入塊中
|-> lfs_bd_prog(lfs,
| &lfs->pcache, &lfs->rcache, false,
| commit->block, commit->off ,
| (const uint8_t*)buffer, size)
|
| // 2. 計算CRC和更新偏移
|-> commit->crc = lfs_crc(commit->crc, buffer, size);
| commit->off += size;

// 該函數用于寫入CRC tag和padding
lfs_dir_commitcrc(lfs_t *lfs, struct lfs_commit *commit)
| // 1. 創建CRC tag,并異或后存儲于footer[0]中
| // 這里tag的size設置為了noff - off,實際上是包含了padding的大小
| // littlefs中沒有通過填充數據的方式來設置padding,而是設置其tag的size進行標記
|-> tag = LFS_MKTAG(LFS_TYPE_CRC + reset, 0x3ff, noff - off);
| uint32_t footer[2];
| footer[0] = lfs_tobe32(tag ^ commit->ptag);
|
| // 2. 計算CRC并將CRC值存入footer[1]中
| // 這里是最后一次計算CRC,前面的tag和數據已經在寫入時計算,只差CRC tag
|-> commit->crc = lfs_crc(commit->crc, &footer[0], sizeof(footer[0]));
| footer[1] = lfs_tole32(commit->crc);
|
| // 3. 寫入CRC tag和CRC值到塊中
|-> lfs_bd_prog(lfs,
| &lfs->pcache, &lfs->rcache, false,
| commit->block, commit->off, &footer, sizeof(footer));

(3)crc的計算

littlefs中crc計算核心函數如下:

uint32_t lfs_crc(uint32_t crc, const void *buffer, size_t size) {
static const uint32_t rtable[16] = {
0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c,
};
const uint8_t *data = buffer;
for (size_t i = 0; i < size; i++) {
crc = (crc >> 4) ^ rtable[(crc ^ (data[i] >> 0)) & 0xf];
crc = (crc >> 4) ^ rtable[(crc ^ (data[i] >> 4)) & 0xf];
}
return crc;
}

本文中不對crc的原理進行具體介紹,有興趣的讀者可參考以下鏈接:

littlefs中crc計算算法的特點是采用了32位的crc結果,輸入數據以4bit為單位進行計算。其中還用到了lookup table進行加速,因為輸入的數據以4bit為單位進行計算,每次有2^4即16種可能的輸入,所以該lookup table的長度為16。從lookup table中還可看出該crc算法對應的多項式值為0x1db71064。

2、tag的遍歷和寫入總結

與遍歷并寫入tag等數據相關的函數為lfs_dir_traverse,該函數被lfs_dir_commit調用。該函數只用于commit等需要寫入tag數據的過程,不用于遍歷獲取數據。其流程如下:

#littlefs原理分析#[二]commit機制-開源基礎軟件社區

代碼分析如下:

static int lfs_dir_traverse(lfs_t *lfs,
| const lfs_mdir_t *dir, lfs_off_t off, lfs_tag_t ptag,
| const struct lfs_mattr *attrs, int attrcount,
| lfs_tag_t tmask, lfs_tag_t ttag,
| uint16_t begin, uint16_t end, int16_t diff,
| int (*cb)(void *data, lfs_tag_t tag, const void *buffer), void *data) {
|-> while (true) {
| // 1. 從磁盤或attrs中獲取下一個tag和相應數據,如果沒有則結束
| // attrs中保存的是將要commit的tag和相應數據
| lfs_tag_t tag;
| const void *buffer;
| struct lfs_diskoff disk;
| // 1.1 如果在磁盤偏移范圍內,則從磁盤中獲取下一個tag和數據
| // 一般進行commit時會將偏移設置到磁盤末尾,不從磁盤中獲取之前的tag
| // 只有如compact等過程中才從磁盤中獲取之前的tag來寫入
|-> if (off+lfs_tag_dsize(ptag) < dir->off) {
| off += lfs_tag_dsize(ptag);
| ...
|
| tag = (lfs_frombe32(tag) ^ ptag) | 0x80000000;
| disk.block = dir->pair[0];
| disk.off = off+sizeof(lfs_tag_t);
| buffer = &disk;
| ptag = tag;
| } else if (attrcount > 0) {
| // 1.2 從attrs中獲取下一個tag和數據
| // attrs中保存的是將要commit的新的tag和數據
|-> tag = attrs[0].tag;
| buffer = attrs[0].buffer;
| attrs += 1;
| attrcount -= 1;
| } else {
| // 1.3 否則結束
|-> return 0;
| }
|
| // 2. 使用tmask和ttag參數過濾掉不想要寫入的tag
|-> lfs_tag_t mask = LFS_MKTAG(0x7ff, 0, 0);
| if ((mask & tmask & tag) != (mask & tmask & ttag)) {
| continue;
| }
|
| // 3. 去除冗余tag等
| if (lfs_tag_id(tmask) != 0) {
| int filter = lfs_dir_traverse(lfs,
| dir, off, ptag, attrs, attrcount,
| 0, 0, 0, 0, 0,
| lfs_dir_traverse_filter, &tag);
| if (filter < 0) {
| return filter;
| }
|
| if (filter) {
| continue;
| }
|
| if (!(lfs_tag_id(tag) >= begin && lfs_tag_id(tag) < end)) {
| continue;
| }
| }
|
| // 4. 處理一些特殊情況
| if (lfs_tag_type3(tag) == ...) {
| ...
| } else {
| // 5. 調用cb回調函數進行寫入
|-> cb(data, tag + LFS_MKTAG(0, diff, 0), buffer);
| ...
| }
| }
}

二、compact過程

當commit時,如果元數據對應塊中的空間不夠,則會嘗試進行compact操作。如下圖:

#littlefs原理分析#[二]commit機制-開源基礎軟件社區

上圖中左邊元數據塊中有兩個commit,其中tag A’是tag A的更新版本。當commit一個tag B’作為tag B的更新版本后,如右圖中右邊的元數據塊,冗余的tag A和tag B被去除,只剩下一個commit。

如果compact后元數據塊中的空間足夠的話,在進行完compact操作之后的元數據塊中就只會剩下一個CRC tag,即只有一個commit。compact的主要過程其實就是篩除冗余的tag和數據之后,將剩下的tag和數據作為一次commit寫入同元數據對中的另一個塊中。

1、compact去除內容

下面對compact過程中具體會去除的tag和相應數據進行說明。

compact過程中調用了lfs_dir_traverse進行去除冗余tag并寫入:

lfs_dir_compact(lfs_t *lfs,
| lfs_mdir_t *dir, const struct lfs_mattr *attrs, int attrcount,
| lfs_mdir_t *source, uint16_t begin, uint16_t end)
|-> ...
|
| // 去重并寫入tag
| // 這里使用了LFS_TYPE_NAME的tag類型進行過濾
|-> lfs_dir_traverse(lfs,
| source, 0, 0xffffffff, attrs, attrcount,
| LFS_MKTAG(0x400, 0x3ff, 0),
| LFS_MKTAG(LFS_TYPE_NAME, 0, 0),
| begin, end, -begin,
| lfs_dir_commit_commit, &(struct lfs_dir_commit_commit){
| lfs, &commit});
|
|-> ...

在lfs_dir_traverse中用下面的邏輯進行篩選tag:

static int lfs_dir_traverse(lfs_t *lfs,
| const lfs_mdir_t *dir, lfs_off_t off, lfs_tag_t ptag,
| const struct lfs_mattr *attrs, int attrcount,
| lfs_tag_t tmask, lfs_tag_t ttag,
| uint16_t begin, uint16_t end, int16_t diff,
| int (*cb)(void *data, lfs_tag_t tag, const void *buffer), void *data) {
|-> ...
|
|-> lfs_tag_t mask = LFS_MKTAG(0x7ff, 0, 0);
| if ((mask & tmask & tag) != (mask & tmask & ttag)) {
| continue;
| }
|-> ...

其中,mask為LFS_MKTAG(0x7ff, 0, 0),tmask為LFS_MKTAG(0x400, 3ff, 0),ttag為LFS_MKTAG(LFS_TYPE_NAME, 0, 0)即LFS_MKTAG(0, 0, 0),則篩選邏輯可簡化為:

if ((LFS_MKTAG(400, 0, 0) & tag) != LFS_MKTAG(0, 0, 0)) {
continue;
}

總結有以下類型的tag會被去除:

  • LFS_TYPE_SPLICE:包括CREATE和DELETE
  • LFS_TYPE_TAIL:包括SOFTTAIL和HARDTAIL
  • LFS_TYPE_GLOBALS:即MOVESTATE
  • LFS_TYPE_CRC

2、compact寫入過程

與commit中tag和數據的寫入過程類似,compact中的寫入過程包括:

  1. 寫入更新后的revision count。
  2. 寫入去除冗余后的tag和數據。
  3. 如果原來有SOFTTAIL或HARDTAIL,則將原來最后一個TAIL補充寫入。因此,compact過程對目錄的遍歷方式無影響,具體目錄的遍歷見后面的文章。
  4. 如果原來有MOVESTATE且進行異或之后不為0,則將異或后的gstate作為MOVESTATE tag補充寫入。gstate相關機制見后面的文章。
  5. 寫入CRC。

相關函數分析:

lfs_dir_compact(lfs_t *lfs,
| lfs_mdir_t *dir, const struct lfs_mattr *attrs, int attrcount,
| lfs_mdir_t *source, uint16_t begin, uint16_t end)
| // 1. 檢查剩余空間,如果不夠則進行split操作
|-> lfs_dir_split(lfs, dir, attrs, attrcount,
| source, begin+split, end)
|
| // 2. revision count + 1,并寫入
|-> dir->rev += 1;
| lfs_bd_erase(lfs, dir->pair[1]);
| lfs_dir_commitprog(lfs, &commit,
| &dir->rev, sizeof(dir->rev));
|
| // 3. 去重并寫入tag
|-> lfs_dir_traverse(lfs,
| source, 0, 0xffffffff, attrs, attrcount,
| LFS_MKTAG(0x400, 0x3ff, 0),
| LFS_MKTAG(LFS_TYPE_NAME, 0, 0),
| begin, end, -begin,
| lfs_dir_commit_commit, &(struct lfs_dir_commit_commit){
| lfs, &commit});
|
| // 4. 補充寫入tail
|-> if (!lfs_pair_isnull(dir->tail)) {
| ...
| lfs_dir_commitattr(lfs, &commit,
| LFS_MKTAG(LFS_TYPE_TAIL + dir->split, 0x3ff, 8),
| dir->tail);
| ...
| }
|
| // 5. 補充寫入move state
|-> if (!lfs_gstate_iszero(&delta)) {
| ...
| lfs_dir_commitattr(lfs, &commit,
| LFS_MKTAG(LFS_TYPE_MOVESTATE, 0x3ff,
| sizeof(delta)), &delta);
| ...
| }
|
| // 6. 計算CRC
|-> lfs_dir_commitcrc(lfs, &commit);

三、split過程

當commit時,進行compact操作后仍空間不足,則會進行split操作,將元數據對劃分為多個塊進行存儲:

#littlefs原理分析#[二]commit機制-開源基礎軟件社區

如上圖,左圖中右邊的元數據塊為最新的元數據塊,其中包含一個commit的內容,即tag A’和tag B’。當再次commit tag C和tag D時,一個元數據塊裝不下,就會進行split操作。split操作在第一個元數據塊commit的末尾加入一個HARDTAIL類型的tag,指向一個新的元數據塊。新的元數據塊中再裝入剩下的tag和數據。

split操作中會遞歸調用compact和split,使得在一次split的容量無法滿足commit需求的時候,進行多次split。

相關函數分析:

lfs_dir_split(lfs_t *lfs,
| lfs_mdir_t *dir, const struct lfs_mattr *attrs, int attrcount,
| lfs_mdir_t *source, uint16_t split, uint16_t end)
| // 1. 重新分配新的塊,用來存儲split后的數據
|-> lfs_dir_alloc(lfs, &tail);
|
| // 2. 將split部分數據再進行compact操作
| // 該調用會遞歸調用compact和split操作直到commit完成或失敗
|-> lfs_dir_compact(lfs, &tail, attrs, attrcount, source, split, end);
|
| // 3. 更新目錄信息
|-> dir->tail[0] = tail.pair[0];
| dir->tail[1] = tail.pair[1];
| dir->split = true;

四、異常情況

前文中提到每次commit之后,都會寫入計算的CRC tag,用于校驗。commit過程因此也是一次原子操作。當commit過程中發生掉電等情況導致commit過程失敗時,磁盤中元數據末尾雖然有寫入的部分tag和數據,但沒有最終的CRC tag,因此當進行tag的遍歷等操作時并不會將這次commit視為有效。compact過程和split過程中也類似,只要沒有最終寫入CRC tag,便不會被視為完成一次commit。如下圖:

#littlefs原理分析#[二]commit機制-開源基礎軟件社區

另外,當split為多個塊時,由前文中相關分析,compact和split會遞歸調用,并提前檢查塊大小是否滿足需求和分配相應塊,最終寫入多個塊。split過程時若沒有足夠的塊,則會報錯,且并不寫入實際內容。split過程時若中途commit失敗,則會導致上一個元數據塊末尾的HARDTAIL指向的塊中沒有有效的CRC tag,進行遍歷時會直接返回錯誤,如下圖:

#littlefs原理分析#[二]commit機制-開源基礎軟件社區

總結

本文介紹了littlefs中的commit機制,包括commit、compact、split操作的過程,怎樣寫入tag和數據,怎樣計算CRC,以及相應的異常情況處理等。commit是一個寫入元數據的過程,后面的文章將會介紹怎樣讀取元數據,從tag中獲取目標信息。

??想了解更多關于開源的內容,請訪問:??

??51CTO 開源基礎軟件社區??

??https://ost.51cto.com??。

責任編輯:jianghua 來源: 51CTO開源基礎軟件社區
相關推薦

2022-11-07 15:27:07

LittlefsFetch操作

2022-11-15 09:24:16

littlefs文件讀寫

2022-11-22 15:21:55

littlefs磨損均衡

2022-11-09 08:52:57

littlefs目錄操作

2022-10-27 16:07:24

littlefs存儲結構

2012-12-03 16:57:37

HDFS

2021-12-06 14:52:08

動畫Android補間動畫

2021-12-08 06:53:28

Choreograph屏幕機制

2009-11-13 17:20:35

ADO.NET數據集工

2023-10-30 01:02:56

Java類類加載器雙親委派

2025-08-22 14:05:00

RSTP網絡端口

2011-07-18 14:08:08

2021-11-11 17:40:08

WatchdogAndroid源碼分析

2010-05-19 13:29:59

2016-11-11 00:39:59

Java可見性機制

2023-06-07 15:25:19

Kafka版本日志

2025-05-27 01:00:00

2023-10-31 16:00:51

類加載機制Java

2014-07-18 11:11:16

SEAndroid

2025-08-27 06:25:00

MSTP網絡端口
點贊
收藏

51CTO技術棧公眾號

在线视频一二三区| 亚洲国产精久久久久久| 亚洲人成人77777线观看| 97人妻人人澡人人爽人人精品 | 国产精品成人一区二区三区夜夜夜 | 国产精品视频自拍| 欧美老女人性生活视频| 久久伊人久久| 狠狠干狠狠久久| 国产91av视频在线观看| 香蕉av一区二区三区| 男女视频一区二区| 97免费视频在线播放| 久久视频一区二区三区| 伦理一区二区| 91麻豆精品国产91久久久更新时间 | 中国1级黄色片| 欧美成人基地| 日韩一区二区免费视频| 日本va中文字幕| 大桥未久在线播放| 国产精品福利影院| 欧美精品一区二区三区在线看午夜 | 日本亚洲一区二区| 97精品欧美一区二区三区| 中文字幕观看av| 欧美美乳视频| 亚洲丁香久久久| 性xxxxxxxxx| 亚洲a成人v| 日本精品一区二区三区高清| 免费超爽大片黄| av毛片在线播放| 中文字幕一区二区三区在线播放| 日本一区视频在线| 午夜影院免费视频| 成人的网站免费观看| 欧美不卡在线视频| 成人h猎奇视频网站| 日产精品久久久久| 天天做天天爱天天爽综合网| 亚洲精品视频在线播放| 91精品人妻一区二区三区蜜桃2 | 日韩精品影视| 337p亚洲精品色噜噜狠狠| 欧美日韩午夜在线| 经典三级在线视频| aⅴ在线视频男人的天堂| 97久久超碰国产精品| 国产亚洲精品中文字幕| 欧美日韩国产另类一区| 97成人在线观看视频| 岛国毛片av在线| 亚洲一区在线免费观看| 久久亚洲国产成人精品无码区| a黄色片在线观看| 亚洲丝袜美腿综合| 青青视频免费在线观看| 在线观看h网| 亚洲一区免费观看| 18禁网站免费无遮挡无码中文| 蜜臀av在线| 亚洲成人tv网| 777久久久精品一区二区三区| 美女91在线看| 色偷偷久久人人79超碰人人澡| 国产精品丝袜久久久久久消防器材 | 国产绿帽一区二区三区| 亚洲男女自偷自拍| 国内外成人免费激情在线视频网站| 国产盗摄x88av| 精品动漫3d一区二区三区免费| 国产欧美一区二区三区鸳鸯浴| 久久婷婷开心| 欧美少妇另类| 欧美韩日一区二区三区| 一本一道久久a久久精品综合 | 久久久久欧美精品| 欧洲亚洲免费视频| 欧美www视频在线观看| 丁香激情综合国产| 国产成人精品免费视频大全最热 | 欧美成人自拍| 美日韩精品免费观看视频| 九九视频在线观看| 亚洲欧美日韩国产| 国产精品一二三在线| av网站在线观看免费| 97se亚洲国产综合自在线 | 亚洲第一偷拍| 97在线观看免费高清| 夜夜躁日日躁狠狠久久av| 极品少妇xxxx精品少妇| 国产精品久久久久久免费观看| 九九在线视频| 亚洲欧美自拍偷拍| 欧美视频在线观看网站 | 91黄在线观看| 欧美精品久久久久久久久久丰满| 中文字幕永久在线不卡| 欧美精品自拍视频| 日本一区二区中文字幕| 欧美精品一区二区三区视频| xxxx日本黄色| 亚洲高清自拍| 国产乱肥老妇国产一区二| 狠狠躁日日躁夜夜躁av| 国产精品久久久久久久久免费樱桃| 日韩在线观看a| 韩国美女久久| 日韩三级视频在线观看| 亚洲一级黄色录像| 亚洲三级国产| 97碰碰视频| 91社区在线高清| 婷婷开心激情综合| 久久久久久久久久久影视| 日本精品黄色| 欧美一级电影免费在线观看| 国产绿帽一区二区三区| 国产精品水嫩水嫩| 欧美日本视频在线观看| 久久免费福利| 色久欧美在线视频观看| 欧美一区二区激情视频| 国产盗摄视频一区二区三区| 亚洲欧洲精品在线| 美脚恋feet久草欧美| 欧美不卡视频一区| 成人高潮免费视频| 美女视频网站久久| 视频一区二区三区免费观看| 成人观看网址| 亚洲白虎美女被爆操| 黄色一级片在线免费观看| 麻豆精品精品国产自在97香蕉| 欧美极品日韩| 欧美xxxhd| 亚洲国产高潮在线观看| 99免费在线观看| 国产精品亚洲第一区在线暖暖韩国 | 性欧美xxxx交| 蜜桃视频久久一区免费观看入口| 亚洲日穴在线视频| 亚洲精品第三页| 欧美高清视频在线观看mv| 国产精品99一区| 国产视频精品久久| 在线免费不卡视频| 日本美女xxx| 全部av―极品视觉盛宴亚洲| 欧美日韩精品综合| 欧美xx视频| 国产一区二区三区毛片| a片在线免费观看| 欧美极品aⅴ影院| 中文av一区二区三区| 日韩精品二区| 91免费版网站入口| 综合久久2o19| 亚洲黄色av网站| 久久久免费高清视频| 久久精子c满五个校花| 日韩一级片播放| 国产精品久久久久久| 亚洲自拍偷拍福利| 日本少妇色视频| 成年午夜在线| 欧洲精品一区二区三区在线观看| 国产伦精品一区二区三区视频女| 久久99精品久久久| 久草这里只有精品视频| 91精品国产91久久久久| 深夜福利免费在线观看| 亚洲欧美日本国产| 在线精品视频视频中文字幕| 中文字幕永久免费视频| 亚洲欧洲成人av每日更新| 中文字幕久久久久久久| 亚洲精品精选| 亚洲高清在线观看一区| 99久久这里有精品| 久久久视频精品| 国产在线观看高清视频| 欧美精品一二三| 国产一国产二国产三| 久久婷婷久久一区二区三区| 无遮挡又爽又刺激的视频| 欧美国产美女| 精品视频一区二区三区四区| 日韩av超清在线观看| 欧美猛男性生活免费| 日本一区二区三区在线观看视频| 欧美日韩在线免费视频| 国产精品99无码一区二区| 国产亚洲精品7777| 9191在线视频| 日韩高清不卡一区二区三区| 日本精品福利视频| 国产剧情在线观看一区| 97超碰人人看人人| 国产精品诱惑| 97超级碰在线看视频免费在线看 | 69xxx免费视频| 中文在线不卡| 亚洲免费视频播放| 国产91精品对白在线播放| 97中文在线| 国产人妖一区| 日韩av片永久免费网站| 欧美日韩色网| 中文字幕在线亚洲| 亚洲av片在线观看| 日韩精品中午字幕| 一级做a爱片性色毛片| 色94色欧美sute亚洲线路一久| 欧美日韩国产精品一区二区三区| 中文字幕欧美日本乱码一线二线| 尤物网站在线观看| 国产99久久久国产精品免费看| 欧美特级aaa| 久久久久久久高潮| 欧美亚洲日本一区二区三区| 欧美成人一区二免费视频软件| 亚洲欧美精品| 精品国产成人| 青青草成人网| 在线亚洲a色| 精品免费视频123区| 99国产精品久久一区二区三区| 成人女保姆的销魂服务| 91另类视频| 国产精品极品在线| 在线精品亚洲欧美日韩国产| 久久久亚洲精品视频| 日韩av官网| 欧美国产视频日韩| 国产蜜臀av在线播放| 久久91精品国产91久久跳| 国产视频中文字幕在线观看| www.久久撸.com| 免费a级人成a大片在线观看| 中文字幕国产日韩| 色欧美激情视频在线| 深夜福利国产精品| 欧美精品日韩少妇| 久久九九热免费视频| 国产原厂视频在线观看| 久热爱精品视频线路一| 污污的网站在线看| 欧美国产日韩xxxxx| 免费影视亚洲| 97超碰国产精品女人人人爽| 九色porny丨国产首页在线| 91国产精品电影| 成人影院av| 国产精品视频导航| 成人在线爆射| 国产精品一区二区三区久久| 欧美激情三区| 99理论电影网| 四虎884aa成人精品最新| 日本免费高清一区二区| 日韩精品免费| 粉嫩av一区二区三区天美传媒| 伊人成年综合电影网| 欧美成人xxxxx| 日韩vs国产vs欧美| 黄色片子免费看| 97超碰欧美中文字幕| 国精产品一区二区三区| 成人欧美一区二区三区视频网页| 国产一区二区视频在线观看免费| 亚洲国产中文字幕| 成人公开免费视频| 在线电影院国产精品| 少妇av一区二区| 一区二区三区日韩在线| av片在线观看| 欧美亚洲视频在线观看| 欧美成人福利| 国产精品一区二区欧美黑人喷潮水| 日韩三级视频| 国产大尺度在线观看| 国产视频欧美| 天天操狠狠操夜夜操| 波多野结衣中文字幕一区二区三区 | 最近中文字幕免费观看| 日韩欧美一二区| 久久这里精品| 久久久久国产精品一区| 播放一区二区| 国产精品久久久一区二区三区| 精品国产一区探花在线观看| 大荫蒂性生交片| 日本不卡中文字幕| 精品一区二区三区四区五区六区| 中文字幕精品一区二区三区精品| 国产一级一级片| 欧美日韩你懂得| 亚洲av毛片成人精品| 九九精品在线播放| 日本一区免费网站| 国内不卡一区二区三区| 天天插综合网| 成人精品小视频| 成人白浆超碰人人人人| 精品国产国产综合精品| 一本色道综合亚洲| 你懂的网站在线| 久久久www成人免费精品张筱雨| 神马久久午夜| 国产精品v欧美精品v日韩精品 | 26uuu亚洲综合色欧美| h色网站在线观看| 在线观看一区二区精品视频| 蜜臀av中文字幕| 久久亚洲一区二区三区四区五区高| 在线精品亚洲欧美日韩国产| 国产欧美日韩综合一区在线观看 | 97人妻人人澡人人爽人人精品| 亚洲欧美日韩第一区| 成人免费网站观看| 成人9ⅰ免费影视网站| 欧美黄色录像片| www.日本xxxx| 久久综合色之久久综合| 一区二区三区视频免费看| 日韩精品在线一区| 97超碰在线公开在线看免费| 国产精品视频免费在线| 国内精品视频在线观看 | 国产精品一区二区久久精品爱涩| 国产精品久久久久久久av| 日韩欧美在线免费| 亚洲区小说区图片区| 97国产一区二区精品久久呦| 国产精品一区二区三区美女| 免费在线黄网站| 国产成人啪午夜精品网站男同| 欧产日产国产v| 日韩欧美中文字幕制服| 在线中文字幕电影| 91情侣在线视频| 午夜日韩福利| 丰满人妻一区二区三区53视频| 亚洲日本青草视频在线怡红院 | 北岛玲heyzo一区二区| 久久精品国产美女| 另类av一区二区| 欧美成人国产精品一区二区| 欧美性猛交xxxxx免费看| 久久精品蜜桃| 国产精品高潮粉嫩av| 成人三级视频| 91在线第一页| 亚洲午夜在线电影| 亚洲 国产 欧美 日韩| 庆余年2免费日韩剧观看大牛| 久久99久久人婷婷精品综合| 精品www久久久久奶水| 国产精品三级电影| aaa一区二区三区| 久久久视频在线| 九九久久成人| 国产亚洲视频一区| 洋洋成人永久网站入口| 神马午夜在线观看| 国产国语videosex另类| 婷婷六月综合| 免费观看污网站| 色偷偷久久人人79超碰人人澡| 嫩草香蕉在线91一二三区| 91久久精品www人人做人人爽 | 欧美一级bbbbb性bbbb喷潮片| 国产一区网站| 日本xxxx免费| 色综合久久久网| 黄色免费在线看| 激情小说网站亚洲综合网| 日韩高清不卡一区二区三区| 成人在线观看免费完整| 亚洲国产天堂久久综合| 五月激情久久| 狠狠精品干练久久久无码中文字幕 | 人妻一区二区视频| 91精品国产麻豆| 一区二区三区电影大全| 免费看啪啪网站| 久久综合久久鬼色中文字| 91久久久久国产一区二区| 久久久久久亚洲精品| 日韩精品影视| 亚洲一区二区三区无码久久| 欧美性生活一区| 成人影院在线视频| 9色视频在线观看| 国产欧美日韩麻豆91| 丰满人妻熟女aⅴ一区| 国产精品视频白浆免费视频|