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

低調(diào)的 Linux 文件系統(tǒng)家族

系統(tǒng) Linux
在 Linux 中,最直觀、最可見的部分就是 文件系統(tǒng)(file system)。下面我們就來一起探討一下關(guān)于 Linux 中國的文件系統(tǒng),系統(tǒng)調(diào)用以及文件系統(tǒng)實現(xiàn)背后的原理和思想。

[[343784]]

在 Linux 中,最直觀、最可見的部分就是 文件系統(tǒng)(file system)。下面我們就來一起探討一下關(guān)于 Linux 中國的文件系統(tǒng),系統(tǒng)調(diào)用以及文件系統(tǒng)實現(xiàn)背后的原理和思想。這些思想中有一些來源于 MULTICS,現(xiàn)在已經(jīng)被 Windows 等其他操作系統(tǒng)使用。Linux 的設(shè)計理念就是 小的就是好的(Small is Beautiful)。雖然 Linux 只是使用了最簡單的機制和少量的系統(tǒng)調(diào)用,但是 Linux 卻提供了強大而優(yōu)雅的文件系統(tǒng)。

Linux 文件系統(tǒng)基本概念

Linux 在最初的設(shè)計是 MINIX1 文件系統(tǒng),它只支持 14 字節(jié)的文件名,它的最大文件只支持到 64 MB。在 MINIX 1 之后的文件系統(tǒng)是 ext 文件系統(tǒng)。ext 系統(tǒng)相較于 MINIX 1 來說,在支持字節(jié)大小和文件大小上均有很大提升,但是 ext 的速度仍沒有 MINIX 1 快,于是,ext 2 被開發(fā)出來,它能夠支持長文件名和大文件,而且具有比 MINIX 1 更好的性能。這使他成為 Linux 的主要文件系統(tǒng)。只不過 Linux 會使用 VFS 曾支持多種文件系統(tǒng)。在 Linux 鏈接時,用戶可以動態(tài)的將不同的文件系統(tǒng)掛載倒 VFS 上。

Linux 中的文件是一個任意長度的字節(jié)序列,Linux 中的文件可以包含任意信息,比如 ASCII 碼、二進(jìn)制文件和其他類型的文件是不加區(qū)分的。

為了方便起見,文件可以被組織在一個目錄中,目錄存儲成文件的形式在很大程度上可以作為文件處理。目錄可以有子目錄,這樣形成有層次的文件系統(tǒng),Linux 系統(tǒng)下面的根目錄是 / ,它通常包含了多個子目錄。字符 / 還用于對目錄名進(jìn)行區(qū)分,例如 「/usr/cxuan」 表示的就是根目錄下面的 usr 目錄,其中有一個叫做 cxuan 的子目錄。

下面我們介紹一下 Linux 系統(tǒng)根目錄下面的目錄名

  • /bin,它是重要的二進(jìn)制應(yīng)用程序,包含二進(jìn)制文件,系統(tǒng)的所有用戶使用的命令都在這里
  • /boot,啟動包含引導(dǎo)加載程序的相關(guān)文件
  • /dev,包含設(shè)備文件,終端文件,USB 或者連接到系統(tǒng)的任何設(shè)備
  • /etc,配置文件,啟動腳本等,包含所有程序所需要的配置文件,也包含了啟動/停止單個應(yīng)用程序的啟動和關(guān)閉 shell 腳本
  • /home,本地主要路徑,所有用戶用 home 目錄存儲個人信息
  • /lib,系統(tǒng)庫文件,包含支持位于 /bin 和 /sbin 下的二進(jìn)制庫文件
  • /lost+found,在根目錄下提供一個遺失+查找系統(tǒng),必須在 root 用戶下才能查看當(dāng)前目錄下的內(nèi)容
  • /media,掛載可移動介質(zhì)
  • /mnt,掛載文件系統(tǒng)
  • /opt,提供一個可選的應(yīng)用程序安裝目錄
  • /proc,特殊的動態(tài)目錄,用于維護系統(tǒng)信息和狀態(tài),包括當(dāng)前運行中進(jìn)程信息
  • /root,root 用戶的主要目錄文件夾
  • /sbin,重要的二進(jìn)制系統(tǒng)文件
  • /tmp, 系統(tǒng)和用戶創(chuàng)建的臨時文件,系統(tǒng)重啟時,這個目錄下的文件都會被刪除
  • /usr,包含絕大多數(shù)用戶都能訪問的應(yīng)用程序和文件
  • /var,經(jīng)常變化的文件,諸如日志文件或數(shù)據(jù)庫等

在 Linux 中,有兩種路徑,一種是 絕對路徑(absolute path) ,絕對路徑告訴你從根目錄下查找文件,絕對路徑的缺點是太長而且不太方便。還有一種是 相對路徑(relative path) ,相對路徑所在的目錄也叫做工作目錄(working directory)。

如果 /usr/local/books 是工作目錄,那么 shell 命令

  1. cp books books-replica  

就表示的是相對路徑,而

  1. cp /usr/local/books/books /usr/local/books/books-replica 

則表示的是絕對路徑。

在 Linux 中經(jīng)常出現(xiàn)一個用戶使用另一個用戶的文件或者使用文件樹結(jié)構(gòu)中的文件。兩個用戶共享同一個文件,這個文件位于某個用戶的目錄結(jié)構(gòu)中,另一個用戶需要使用這個文件時,必須通過絕對路徑才能引用到他。如果絕對路徑很長,那么每次輸入起來會變的非常麻煩,所以 Linux 提供了一種 鏈接(link) 機制。

舉個例子,下面是一個使用鏈接之前的圖

 

以上所示,比如有兩個工作賬戶 jianshe 和 cxuan,jianshe 想要使用 cxuan 賬戶下的 A 目錄,那么它可能會輸入 /usr/cxuan/A ,這是一種未使用鏈接之后的圖。

使用鏈接后的示意如下

 

現(xiàn)在,jianshe 可以創(chuàng)建一個鏈接來使用 cxuan 下面的目錄了。‘

當(dāng)一個目錄被創(chuàng)建出來后,有兩個目錄項也同時被創(chuàng)建出來,它們就是 . 和 .. ,前者代表工作目錄自身,后者代表該目錄的父目錄,也就是該目錄所在的目錄。這樣一來,在 /usr/jianshe 中訪問 cxuan 中的目錄就是 ../cxuan/xxxLinux 文件系統(tǒng)不區(qū)分磁盤的,這是什么意思呢?一般來說,一個磁盤中的文件系統(tǒng)相互之間保持獨立,如果一個文件系統(tǒng)目錄想要訪問另一個磁盤中的文件系統(tǒng),在 Windows 中你可以像下面這樣。

 

兩個文件系統(tǒng)分別在不同的磁盤中,彼此保持獨立。

而在 Linux 中,是支持掛載的,它允許一個磁盤掛在到另外一個磁盤上,那么上面的關(guān)系會變成下面這樣

 

掛在之后,兩個文件系統(tǒng)就不再需要關(guān)心文件系統(tǒng)在哪個磁盤上了,兩個文件系統(tǒng)彼此可見。

Linux 文件系統(tǒng)的另外一個特性是支持 加鎖(locking)。在一些應(yīng)用中會出現(xiàn)兩個或者更多的進(jìn)程同時使用同一個文件的情況,這樣很可能會導(dǎo)致競爭條件(race condition)。一種解決方法是對其進(jìn)行加不同粒度的鎖,就是為了防止某一個進(jìn)程只修改某一行記錄從而導(dǎo)致整個文件都不能使用的情況。

POSIX 提供了一種靈活的、不同粒度級別的鎖機制,允許一個進(jìn)程使用一個不可分割的操作對一個字節(jié)或者整個文件進(jìn)行加鎖。加鎖機制要求嘗試加鎖的進(jìn)程指定其「要加鎖的文件,開始位置以及要加鎖的字節(jié)」

Linux 系統(tǒng)提供了兩種鎖:「共享鎖和互斥鎖」。如果文件的一部分已經(jīng)加上了共享鎖,那么再加排他鎖是不會成功的;如果文件系統(tǒng)的一部分已經(jīng)被加了互斥鎖,那么在互斥鎖解除之前的任何加鎖都不會成功。為了成功加鎖、請求加鎖的部分的所有字節(jié)都必須是可用的。

在加鎖階段,進(jìn)程需要設(shè)計好加鎖失敗后的情況,也就是判斷加鎖失敗后是否選擇阻塞,如果選擇阻塞式,那么當(dāng)已經(jīng)加鎖的進(jìn)程中的鎖被刪除時,這個進(jìn)程會解除阻塞并替換鎖。如果進(jìn)程選擇非阻塞式的,那么就不會替換這個鎖,會立刻從系統(tǒng)調(diào)用中返回,標(biāo)記狀態(tài)碼表示是否加鎖成功,然后進(jìn)程會選擇下一個時間再次嘗試。

加鎖區(qū)域是可以重疊的。下面我們演示了三種不同條件的加鎖區(qū)域。

 

如上圖所示,A 的共享鎖在第四字節(jié)到第八字節(jié)進(jìn)行加鎖

 

如上圖所示,進(jìn)程在 A 和 B 上同時加了共享鎖,其中 6 - 8 字節(jié)是重疊鎖

 

如上圖所示,進(jìn)程 A 和 B 和 C 同時加了共享鎖,那么第六字節(jié)和第七字節(jié)是共享鎖。

如果此時一個進(jìn)程嘗試在第 6 個字節(jié)處加鎖,此時會設(shè)置失敗并阻塞,由于該區(qū)域被 A B C 同時加鎖,那么只有等到 A B C 都釋放鎖后,進(jìn)程才能加鎖成功。

Linux 文件系統(tǒng)調(diào)用

許多系統(tǒng)調(diào)用都會和文件與文件系統(tǒng)有關(guān)。我們首先先看一下對單個文件的系統(tǒng)調(diào)用,然后再來看一下對整個目錄和文件的系統(tǒng)調(diào)用。

為了創(chuàng)建一個新的文件,會使用到 creat 方法,注意沒有 e。

❝這里說一個小插曲,曾經(jīng)有人問 UNIX 創(chuàng)始人 Ken Thompson,如果有機會重新寫 UNIX ,你會怎么辦,他回答自己要把 creat 改成 create ,哈哈哈哈。❞

這個系統(tǒng)調(diào)用的兩個參數(shù)是文件名和保護模式

  1. fd = creat("aaa",mode); 

這段命令會創(chuàng)建一個名為 aaa 的文件,并根據(jù) mode 設(shè)置文件的保護位。這些位決定了哪個用戶可能訪問文件、如何訪問。

creat 系統(tǒng)調(diào)用不僅僅創(chuàng)建了一個名為 aaa 的文件,還會打開這個文件。為了允許后續(xù)的系統(tǒng)調(diào)用訪問這個文件,這個 creat 系統(tǒng)調(diào)用會返回一個 非負(fù)整數(shù), 這個就叫做 文件描述符(file descriptor),也就是上面的 fd。

如果在已經(jīng)存在的文件上調(diào)用了 creat 系統(tǒng)調(diào)用,那么該文件中的內(nèi)容會被清除,從 0 開始。通過設(shè)置合適的參數(shù),open 系統(tǒng)調(diào)用也能夠創(chuàng)建文件。

下面讓我們看一看主要的系統(tǒng)調(diào)用,如下表所示

系統(tǒng)調(diào)用 描述
fd = creat(name,mode) 一種創(chuàng)建一個新文件的方式
fd = open(file, ...) 打開文件讀、寫或者讀寫
s = close(fd) 關(guān)閉一個打開的文件
n = read(fd, buffer, nbytes) 從文件中向緩存中讀入數(shù)據(jù)
n = write(fd, buffer, nbytes) 從緩存中向文件中寫入數(shù)據(jù)
position = lseek(fd, offset, whence) 移動文件指針
s = stat(name, &buf) 獲取文件信息
s = fstat(fd, &buf) 獲取文件信息
s = pipe(&fd[0]) 創(chuàng)建一個管道
s = fcntl(fd,...) 文件加鎖等其他操作

為了對一個文件進(jìn)行讀寫的前提是先需要打開文件,必須使用 creat 或者 open 打開,參數(shù)是打開文件的方式,是只讀、可讀寫還是只寫。open 系統(tǒng)調(diào)用也會返回文件描述符。打開文件后,需要使用 close 系統(tǒng)調(diào)用進(jìn)行關(guān)閉。close 和 open 返回的 fd 總是未被使用的最小數(shù)量。

❝什么是文件描述符?文件描述符就是一個數(shù)字,這個數(shù)字標(biāo)示了計算機操作系統(tǒng)中打開的文件。它描述了數(shù)據(jù)資源,以及訪問資源的方式。❞

  • 當(dāng)程序要求打開一個文件時,內(nèi)核會進(jìn)行如下操作
  • 授予訪問權(quán)限
  • 在全局文件表(global file table)中創(chuàng)建一個條目(entry)向軟件提供條目的位置

文件描述符由唯一的非負(fù)整數(shù)組成,系統(tǒng)上每個打開的文件至少存在一個文件描述符。文件描述符最初在 Unix 中使用,并且被包括 Linux,macOS 和 BSD 在內(nèi)的現(xiàn)代操作系統(tǒng)所使用。

當(dāng)一個進(jìn)程成功訪問一個打開的文件時,內(nèi)核會返回一個文件描述符,這個文件描述符指向全局文件表的 entry 項。這個文件表項包含文件的 inode 信息,字節(jié)位移,訪問限制等。例如下圖所示

 

默認(rèn)情況下,前三個文件描述符為 STDIN(標(biāo)準(zhǔn)輸入)、STDOUT(標(biāo)準(zhǔn)輸出)、STDERR(標(biāo)準(zhǔn)錯誤)。

標(biāo)準(zhǔn)輸入的文件描述符是 0 ,在終端中,默認(rèn)為用戶的鍵盤輸入

標(biāo)準(zhǔn)輸出的文件描述符是 1 ,在終端中,默認(rèn)為用戶的屏幕

與錯誤有關(guān)的默認(rèn)數(shù)據(jù)流是 2,在終端中,默認(rèn)為用戶的屏幕。

在簡單聊了一下文件描述符后,我們繼續(xù)回到文件系統(tǒng)調(diào)用的探討。

在文件系統(tǒng)調(diào)用中,開銷最大的就是 read 和 write 了。read 和 write 都有三個參數(shù)

  • 文件描述符:告訴需要對哪一個打開文件進(jìn)行讀取和寫入
  • 緩沖區(qū)地址:告訴數(shù)據(jù)需要從哪里讀取和寫入哪里
  • 統(tǒng)計:告訴需要傳輸多少字節(jié)

這就是所有的參數(shù)了,這個設(shè)計非常簡單輕巧。

雖然幾乎所有程序都按順序讀取和寫入文件,但是某些程序需要能夠隨機訪問文件的任何部分。與每個文件相關(guān)聯(lián)的是一個指針,該指針指示文件中的當(dāng)前位置。順序讀取(或?qū)懭?時,它通常指向要讀取(寫入)的下一個字節(jié)。如果指針在讀取 1024 個字節(jié)之前位于 4096 的位置,則它將在成功讀取系統(tǒng)調(diào)用后自動移至 5120 的位置。

Lseek 系統(tǒng)調(diào)用會更改指針位置的值,以便后續(xù)對 read 或 write 的調(diào)用可以在文件中的任何位置開始,甚至可以超出文件末尾。

❝lseek = Lseek ,段首大寫。❞

lseek 避免叫做 seek 的原因就是 seek 已經(jīng)在之前 16 位的計算機上用于搜素功能了。

Lseek 有三個參數(shù):第一個是文件的文件描述符,第二個是文件的位置;第三個告訴文件位置是相對于文件的開頭,當(dāng)前位置還是文件的結(jié)尾

  1. lseek(int fildes, off_t offset, int whence); 

lseek 的返回值是更改文件指針后文件中的絕對位置。lseek 是唯一從來不會造成真正磁盤查找的系統(tǒng)調(diào)用,它只是更新當(dāng)前的文件位置,這個文件位置就是內(nèi)存中的數(shù)字。

對于每個文件,Linux 都會跟蹤文件模式(常規(guī),目錄,特殊文件),大小,最后修改時間以及其他信息。程序能夠通過 stat 系統(tǒng)調(diào)用看到這些信息。第一個參數(shù)就是文件名,第二個是指向要放置請求信息結(jié)構(gòu)的指針。這些結(jié)構(gòu)的屬性如下圖所示。

存儲文件的設(shè)備
存儲文件的設(shè)備
i-node 編號
文件模式(包括保護位信息)
文件鏈接的數(shù)量
文件所有者標(biāo)識
文件所屬的組
文件大小(字節(jié))
創(chuàng)建時間
最后一個修改/訪問時間

fstat 調(diào)用和 stat 相同,只有一點區(qū)別,fstat 可以對打開文件進(jìn)行操作,而 stat 只能對路徑進(jìn)行操作。

pipe 文件系統(tǒng)調(diào)用被用來創(chuàng)建 shell 管道。它會創(chuàng)建一系列的偽文件,來緩沖和管道組件之間的數(shù)據(jù),并且返回讀取或者寫入緩沖區(qū)的文件描述符。在管道中,像是如下操作

  1. sort <in | head –40 

sort 進(jìn)程將會輸出到文件描述符1,也就是標(biāo)準(zhǔn)輸出,寫入管道中,而 head 進(jìn)程將從管道中讀入。在這種方式中,sort 只是從文件描述符 0 中讀取并寫入到文件描述符 1 (管道)中,甚至不知道它們已經(jīng)被重定向了。如果沒有重定向的話,sort 會自動的從鍵盤讀入并輸出到屏幕中。

最后一個系統(tǒng)調(diào)用是 fcntl,它用來鎖定和解鎖文件,應(yīng)用共享鎖和互斥鎖,或者是執(zhí)行一些文件相關(guān)的其他操作。

現(xiàn)在我們來關(guān)心一下和整體目錄和文件系統(tǒng)相關(guān)的系統(tǒng)調(diào)用,而不是把精力放在單個的文件上,下面列出了這些系統(tǒng)調(diào)用,我們一起來看一下。

系統(tǒng)調(diào)用 描述
s = mkdir(path,mode) 創(chuàng)建一個新的目錄
s = rmdir(path) 移除一個目錄
s = link(oldpath,newpath) 創(chuàng)建指向已有文件的鏈接
s = unlink(path) 取消文件的鏈接
s = chdir(path) 改變工作目錄
dir = opendir(path) 打開一個目錄讀取
s = closedir(dir) 關(guān)閉一個目錄
dirent = readdir(dir) 讀取一個目錄項
rewinddir(dir) 回轉(zhuǎn)目錄使其在此使用

可以使用 mkdir 和 rmdir 創(chuàng)建和刪除目錄。但是需要注意,只有目錄為空時才可以刪除。

創(chuàng)建一個指向已有文件的鏈接時會創(chuàng)建一個目錄項(directory entry)。系統(tǒng)調(diào)用 link 來創(chuàng)建鏈接,oldpath 代表已有的路徑,newpath 代表需要鏈接的路徑,使用 unlink 可以刪除目錄項。當(dāng)文件的最后一個鏈接被刪除時,這個文件會被自動刪除。

使用 chdir 系統(tǒng)調(diào)用可以改變工作目錄。

最后四個系統(tǒng)調(diào)用是用于讀取目錄的。和普通文件類似,他們可以被打開、關(guān)閉和讀取。每次調(diào)用 readdir 都會以固定的格式返回一個目錄項。用戶不能對目錄執(zhí)行寫操作,但是可以使用 creat 或者 link 在文件夾中創(chuàng)建一個目錄,或使用 unlink 刪除一個目錄。用戶不能在目錄中查找某個特定文件,但是可以使用 rewindir 作用于一個打開的目錄,使他能在此從頭開始讀取。

Linux 文件系統(tǒng)的實現(xiàn)

下面我們主要討論一下 虛擬文件系統(tǒng)(Virtual File System)。VFS 對高層進(jìn)程和應(yīng)用程序隱藏了 Linux 支持的所有文件系統(tǒng)的區(qū)別,以及文件系統(tǒng)是存儲在本地設(shè)備,還是需要通過網(wǎng)絡(luò)訪問遠(yuǎn)程設(shè)備。設(shè)備和其他特殊文件和 VFS 層相關(guān)聯(lián)。接下來,我們就會探討一下第一個 Linux 廣泛傳播的文件系統(tǒng):ext2。隨后,我們就會探討 ext4 文件系統(tǒng)所做的改進(jìn)。各種各樣的其他文件系統(tǒng)也正在使用中。所有 Linux 系統(tǒng)都可以處理多個磁盤分區(qū),每個磁盤分區(qū)上都有不同的文件系統(tǒng)。

Linux 虛擬文件系統(tǒng)

為了能夠使應(yīng)用程序能夠在不同類型的本地或者遠(yuǎn)程設(shè)備上的文件系統(tǒng)進(jìn)行交互,因為在 Linux 當(dāng)中文件系統(tǒng)千奇百種,比較常見的有 EXT3、EXT4,還有基于內(nèi)存的 ramfs、tmpfs 和基于網(wǎng)絡(luò)的 nfs,和基于用戶態(tài)的 fuse,當(dāng)然 fuse 應(yīng)該不能完全的文件系統(tǒng),只能算是一個能把文件系統(tǒng)實現(xiàn)放到用戶態(tài)的模塊,滿足了內(nèi)核文件系統(tǒng)的接口,他們都是文件系統(tǒng)的一種實現(xiàn)。對于這些文件系統(tǒng),Linux 做了一層抽象就是 VFS虛擬文件系統(tǒng),

下表總結(jié)了 VFS 支持的四個主要的文件系統(tǒng)結(jié)構(gòu)。

對象 描述
超級塊 特定的文件系統(tǒng)
Dentry 目錄項,路徑的一個組成部分
I-node 特定的文件
File 跟一個進(jìn)程相關(guān)聯(lián)的打開文件

超級塊(superblock) 包含了有關(guān)文件系統(tǒng)布局的重要信息,超級塊如果遭到破壞那么就會導(dǎo)致整個文件系統(tǒng)不可讀。

i-node 索引節(jié)點,包含了每一個文件的描述符。

❝在 Linux 中,目錄和設(shè)備也表示為文件,因為它們具有對應(yīng)的 i-node❞

超級塊和索引塊所在的文件系統(tǒng)都在磁盤上有對應(yīng)的結(jié)構(gòu)。

為了便于某些目錄操作和路徑遍歷,比如 /usr/local/cxuan,VFS 支持一個 dentry 數(shù)據(jù)結(jié)構(gòu),該數(shù)據(jù)結(jié)構(gòu)代表著目錄項。這個 dentry 數(shù)據(jù)結(jié)構(gòu)有很多東西(http://books.gigatux.nl/mirror/kerneldevelopment/0672327201/ch12lev1sec7.html)這個數(shù)據(jù)結(jié)構(gòu)由文件系統(tǒng)動態(tài)創(chuàng)建。

目錄項被緩存在 dentry_cache 緩存中。例如,緩存條目會緩存 /usr 、 /usr/local 等條目。如果多個進(jìn)程通過硬連接訪問相同的文件,他們的文件對象將指向此緩存中的相同條目。

最后,文件數(shù)據(jù)結(jié)構(gòu)是代表著打開的文件,也代表著內(nèi)存表示,它根據(jù) open 系統(tǒng)調(diào)用創(chuàng)建。它支持 「read、write、sendfile、lock」 和其他在我們之前描述的系統(tǒng)調(diào)用中。

在 VFS 下實現(xiàn)的實際文件系統(tǒng)不需要在內(nèi)部使用完全相同的抽象和操作。但是,它們必須在語義上實現(xiàn)與 VFS 對象指定的文件系統(tǒng)操作相同的文件系統(tǒng)操作。四個 VFS 對象中每個對象的操作數(shù)據(jù)結(jié)構(gòu)的元素都是指向基礎(chǔ)文件系統(tǒng)中功能的指針。

Linux Ext2 文件系統(tǒng)

現(xiàn)在我們一起看一下 Linux 中最流行的一個磁盤文件系統(tǒng),那就是 ext2 。Linux 的第一個版本用于 MINIX1 文件系統(tǒng),它的文件名大小被限制為最大 64 MB。MINIX 1 文件系統(tǒng)被永遠(yuǎn)的被它的擴展系統(tǒng) ext 取代,因為 ext 允許更長的文件名和文件大小。由于 ext 的性能低下,ext 被其替代者 ext2 取代,ext2 目前仍在廣泛使用。

一個 ext2 Linux 磁盤分區(qū)包含了一個文件系統(tǒng),這個文件系統(tǒng)的布局如下所示

 

Boot 塊也就是第 0 塊不是讓 Linux 使用的,而是用來加載和引導(dǎo)計算機啟動代碼的。在塊 0 之后,磁盤分區(qū)被分成多個組,這些組與磁盤柱面邊界所處的位置無關(guān)。

第一個塊是 超級塊(superblock)。它包含有關(guān)文件系統(tǒng)布局的信息,包括 i-node、磁盤塊數(shù)量和以及空閑磁盤塊列表的開始。下一個是 組描述符(group descriptor),其中包含有關(guān)位圖的位置,組中空閑塊和 i-node 的數(shù)量以及組中的目錄數(shù)量的信息。這些信息很重要,因為 ext2 會在磁盤上均勻分布目錄。

圖中的兩個位圖用來記錄空閑塊和空閑 i-node,這是從 MINIX 1文件系統(tǒng)繼承的選擇,大多數(shù) UNIX 文件系統(tǒng)使用位圖而不是空閑列表。每個位圖的大小是一個塊。如果一個塊的大小是 1 KB,那么就限制了塊組的數(shù)量是 8192 個塊和 8192 個 i-node。塊的大小是一個嚴(yán)格的限制,塊組的數(shù)量不固定,在 4KB 的塊中,塊組的數(shù)量增大四倍。

在超級塊之后分布的是 i-node 它們自己,i-node 取值范圍是 1 - 某些最大值。每個 i-node 是 128 字節(jié)的 long ,這些字節(jié)恰好能夠描述一個文件。i-node 包含了統(tǒng)計信息(包含了 stat 系統(tǒng)調(diào)用能獲得的所有者信息,實際上 stat 就是從 i-node 中讀取信息的),以及足夠的信息來查找保存文件數(shù)據(jù)的所有磁盤塊。

在 i-node 之后的是 數(shù)據(jù)塊(data blocks)。所有的文件和目錄都保存在這。如果一個文件或者目錄包含多個塊,那么這些塊在磁盤中的分布不一定是連續(xù)的,也有可能不連續(xù)。事實上,大文件塊可能會被拆分成很多小塊散布在整個磁盤上。

對應(yīng)于目錄的 i-node 分散在整個磁盤組上。如果有足夠的空間,ext2 會把普通文件組織到與父目錄相同的塊組中,而把同一塊上的數(shù)據(jù)文件組織成初始 i-node 節(jié)點。位圖用來快速確定新文件系統(tǒng)數(shù)據(jù)的分配位置。在分配新的文件塊時,ext2 也會給該文件預(yù)分配許多額外的數(shù)據(jù)塊,這樣可以減少將來向文件寫入數(shù)據(jù)時產(chǎn)生的文件碎片。這種策略在整個磁盤上實現(xiàn)了文件系統(tǒng)的 負(fù)載,后續(xù)還有對文件碎片的排列和整理,而且性能也比較好。

為了達(dá)到訪問的目的,需要首先使用 Linux 系統(tǒng)調(diào)用,例如 open,這個系統(tǒng)調(diào)用會確定打開文件的路徑。路徑分為兩種,相對路徑 和 絕對路徑。如果使用相對路徑,那么就會從當(dāng)前目錄開始查找,否則就會從根目錄進(jìn)行查找。

目錄文件的文件名最高不能超過 255 個字符,它的分配如下圖所示

 

每一個目錄都由整數(shù)個磁盤塊組成,這樣目錄就可以整體的寫入磁盤。在一個目錄中,文件和子目錄的目錄項都是未經(jīng)排序的,并且一個挨著一個。目錄項不能跨越磁盤塊,所以通常在每個磁盤塊的尾部會有部分未使用的字節(jié)。

上圖中每個目錄項都由四個固定長度的屬性和一個長度可變的屬性組成。第一個屬性是 i-node 節(jié)點數(shù)量,文件 first 的 i-node 編號是 19 ,文件 second 的編號是 42,目錄 third 的 i-node 編號是 88。緊隨其后的是 rec_len域,表明目錄項大小是多少字節(jié),名稱后面會有一些擴展,當(dāng)名字以未知長度填充時,這個域被用來尋找下一個目錄項,直至最后的未使用。這也是圖中箭頭的含義。緊隨其后的是 類型域:F 表示的是文件,D 表示的是目錄,最后是固定長度的文件名,上面的文件名的長度依次是 5、6、5,最后以文件名結(jié)束。

rec_len 域是如何擴展的呢?如下圖所示

 

我們可以看到,中間的 second 被移除了,所以將其所在的域變?yōu)榈谝粋€目錄項的填充。當(dāng)然,這個填充可以作為后續(xù)的目錄項。

由于目錄是按照線性的順序進(jìn)行查找的,因此可能需要很長時間才能在大文件末尾找到目錄項。因此,系統(tǒng)會為近期的訪問目錄維護一個緩存。這個緩存用文件名來查找,如果緩存命中,那么就會避免線程搜索這樣昂貴的開銷。組成路徑的每個部分都在目錄緩存中保存一個 dentry 對象,并且通過 i-node 找到后續(xù)的路徑元素的目錄項,直到找到真正的文件 i - node。

比如說要使用絕對路徑來尋找一個文件,我們暫定這個路徑是 /usr/local/file,那么需要經(jīng)過如下幾個步驟:

首先,系統(tǒng)會確定根目錄,它通常使用 2 號 i -node ,也就是索引 2 節(jié)點,因為索引節(jié)點 1 是 ext2 /3/4 文件系統(tǒng)上的壞塊索引節(jié)點。系統(tǒng)會將一項放在 dentry 緩存中,以應(yīng)對將來對根目錄的查找。

然后,在根目錄中查找字符串 usr,得到 /usr 目錄的 i - node 節(jié)點號。/usr 的 i - node 同樣也進(jìn)入 dentry 緩存。然后節(jié)點被取出,并從中解析出磁盤塊,這樣就可以讀取 /usr 目錄并查找字符串 local 了。一旦找到這個目錄項,目錄 /usr/local 的 i - node 節(jié)點就可以從中獲得。有了 /usr/local 的 i - node 節(jié)點號,就可以讀取 i - node 并確定目錄所在的磁盤塊。最后,從 /usr/local 目錄查找 file 并確定其 i - node 節(jié)點呢號。

如果文件存在,那么系統(tǒng)會提取 i - node 節(jié)點號并把它作為索引在 i - node 節(jié)點表中定位相應(yīng)的 i - node 節(jié)點并裝入內(nèi)存。i - node 被存放在 i - node 節(jié)點表(i-node table) 中,節(jié)點表是一個內(nèi)核數(shù)據(jù)結(jié)構(gòu),它會持有當(dāng)前打開文件和目錄的 i - node 節(jié)點號。下面是一些 Linux 文件系統(tǒng)支持的 i - node 數(shù)據(jù)結(jié)構(gòu)。

屬性 字節(jié) 描述
Mode 2 文件屬性、保護位、setuid 和 setgid 位
Nlinks 2 指向 i - node 節(jié)點目錄項的數(shù)目
Uid 2 文件所有者的 UID
Gid 2 文件所有者的 GID
Size 4 文件字節(jié)大小
Addr 60 12 個磁盤塊以及后面 3 個間接塊的地址
Gen 1 每次重復(fù)使用 i - node 時增加的代號
Atime 4 最近訪問文件的時間
Mtime 4 最近修改文件的時間
Ctime 4 最近更改 i - node 的時間

現(xiàn)在我們來一起探討一下文件讀取過程,還記得 read 函數(shù)是如何調(diào)用的嗎?

  1. n = read(fd,buffer,nbytes); 

當(dāng)內(nèi)核接管后,它會從這三個參數(shù)以及內(nèi)部表與用戶有關(guān)的信息開始。內(nèi)部表的其中一項是文件描述符數(shù)組。文件描述符數(shù)組用文件描述符 作為索引并為每一個打開文件保存一個表項。

文件是和 i - node 節(jié)點號相關(guān)的。那么如何通過一個文件描述符找到文件對應(yīng)的 i - node 節(jié)點呢?

這里使用的一種設(shè)計思想是在文件描述符表和 i - node 節(jié)點表之間插入一個新的表,叫做 打開文件描述符(open-file-description table)。文件的讀寫位置會在打開文件描述符表中存在,如下圖所示

 

我們使用 shell 、P1 和 P2 來描述一下父進(jìn)程、子進(jìn)程、子進(jìn)程的關(guān)系。Shell 首先生成 P1,P1 的數(shù)據(jù)結(jié)構(gòu)就是 Shell 的一個副本,因此兩者都指向相同的打開文件描述符的表項。當(dāng) P1 運行完成后,Shell 的文件描述符仍會指向 P1 文件位置的打開文件描述。然后 Shell 生成了 P2,新的子進(jìn)程自動繼承文件的讀寫位置,甚至 P2 和 Shell 都不知道文件具體的讀寫位置。

上面描述的是父進(jìn)程和子進(jìn)程這兩個 相關(guān) 進(jìn)程,如果是一個不相關(guān)進(jìn)程打開文件時,它將得到自己的打開文件描述符表項,以及自己的文件讀寫位置,這是我們需要的。

❝因此,打開文件描述符相當(dāng)于是給相關(guān)進(jìn)程提供同一個讀寫位置,而給不相關(guān)進(jìn)程提供各自私有的位置。❞

i - node 包含三個間接塊的磁盤地址,它們每個指向磁盤塊的地址所能夠存儲的大小不一樣。

Linux Ext4 文件系統(tǒng)

為了防止由于系統(tǒng)崩潰和電源故障造成的數(shù)據(jù)丟失,ext2 系統(tǒng)必須在每個數(shù)據(jù)塊創(chuàng)建之后立即將其寫入到磁盤上,磁盤磁頭尋道操作導(dǎo)致的延遲是無法讓人忍受的。為了增強文件系統(tǒng)的健壯性,Linux 依靠日志文件系統(tǒng),ext3 是一個日志文件系統(tǒng),它在 ext2 文件系統(tǒng)的基礎(chǔ)之上做了改進(jìn),ext4 也是 ext3 的改進(jìn),ext4 也是一個日志文件系統(tǒng)。ext4 改變了 ext3 的塊尋址方案,從而支持更大的文件和更大的文件系統(tǒng)大小。下面我們就來描述一下 ext4 文件系統(tǒng)的特性。

具有記錄的文件系統(tǒng)最基本的功能就是記錄日志,這個日志記錄了按照順序描述所有文件系統(tǒng)的操作。通過順序?qū)懗鑫募到y(tǒng)數(shù)據(jù)或元數(shù)據(jù)的更改,操作不受磁盤訪問期間磁盤頭移動的開銷。最終,這個變更會寫入并提交到合適的磁盤位置上。如果這個變更在提交到磁盤前文件系統(tǒng)宕機了,那么在重啟期間,系統(tǒng)會檢測到文件系統(tǒng)未正確卸載,那么就會遍歷日志并應(yīng)用日志的記錄來對文件系統(tǒng)進(jìn)行更改。

Ext4 文件系統(tǒng)被設(shè)計用來高度匹配 ext2 和 ext3 文件系統(tǒng)的,盡管 ext4 文件系統(tǒng)在內(nèi)核數(shù)據(jù)結(jié)構(gòu)和磁盤布局上都做了變更。盡管如此,一個文件系統(tǒng)能夠從 ext2 文件系統(tǒng)上卸載后成功的掛載到 ext4 文件系統(tǒng)上,并提供合適的日志記錄。

日志是作為循環(huán)緩沖區(qū)管理的文件。日志可以存儲在與主文件系統(tǒng)相同或者不同的設(shè)備上。日志記錄的讀寫操作會由單獨的 JBD(Journaling Block Device) 來扮演。

JBD 中有三個主要的數(shù)據(jù)結(jié)構(gòu),分別是 「log record(日志記錄)、原子操作和事務(wù)」。一個日志記錄描述了一個低級別的文件系統(tǒng)操作,這個操作通常導(dǎo)致塊內(nèi)的變化。因為像是 write 這種系統(tǒng)調(diào)用會包含多個地方的改動 --- i - node 節(jié)點,現(xiàn)有的文件塊,新的文件塊和空閑列表等。相關(guān)的日志記錄會以原子性的方式分組。ext4 會通知系統(tǒng)調(diào)用進(jìn)程的開始和結(jié)束,以此使 JBD 能夠確保原子操作的記錄都能被應(yīng)用,或者一個也不被應(yīng)用。最后,主要從效率方面考慮,JBD 會視原子操作的集合為事務(wù)。一個事務(wù)中的日志記錄是連續(xù)存儲的。只有在所有的變更一起應(yīng)用到磁盤后,日志記錄才能夠被丟棄。

由于為每個磁盤寫出日志的開銷會很大,所以 ext4 可以配置為保留所有磁盤更改的日志,或者僅僅保留與文件系統(tǒng)元數(shù)據(jù)相關(guān)的日志更改。僅僅記錄元數(shù)據(jù)可以減少系統(tǒng)開銷,提升性能,但不能保證不會損壞文件數(shù)據(jù)。其他的幾個日志系統(tǒng)維護著一系列元數(shù)據(jù)操作的日志,例如 SGI 的 XFS。

/proc 文件系統(tǒng)

另外一個 Linux 文件系統(tǒng)是 /proc (process) 文件系統(tǒng)

❝它的主要思想來源于貝爾實驗室開發(fā)的第 8 版的 UNIX,后來被 BSD 和 System V 采用。❞

然而,Linux 在一些方面上對這個想法進(jìn)行了擴充。它的基本概念是為系統(tǒng)中的每個進(jìn)程在 /proc 中創(chuàng)建一個目錄。目錄的名字就是進(jìn)程 PID,以十進(jìn)制數(shù)進(jìn)行表示。例如,/proc/1024 就是一個進(jìn)程號為 1024 的目錄。在該目錄下是進(jìn)程信息相關(guān)的文件,比如進(jìn)程的命令行、環(huán)境變量和信號掩碼等。事實上,這些文件在磁盤上并不存在磁盤中。當(dāng)需要這些信息的時候,系統(tǒng)會按需從進(jìn)程中讀取,并以標(biāo)準(zhǔn)格式返回給用戶。

許多 Linux 擴展與 /proc 中的其他文件和目錄有關(guān)。它們包含各種各樣的關(guān)于 CPU、磁盤分區(qū)、設(shè)備、中斷向量、內(nèi)核計數(shù)器、文件系統(tǒng)、已加載模塊等信息。非特權(quán)用戶可以讀取很多這樣的信息,于是就可以通過一種安全的方式了解系統(tǒng)情況。

NFS 網(wǎng)絡(luò)文件系統(tǒng)

從一開始,網(wǎng)絡(luò)就在 Linux 中扮演了很重要的作用。下面我們會探討一下 NFS(Network File System) 網(wǎng)絡(luò)文件系統(tǒng),它在現(xiàn)代 Linux 操作系統(tǒng)的作用是將不同計算機上的不同文件系統(tǒng)鏈接成一個邏輯整體。

NFS 架構(gòu)NFS 最基本的思想是允許任意選定的一些客戶端和服務(wù)器共享一個公共文件系統(tǒng)。在許多情況下,所有的客戶端和服務(wù)器都會在同一個 LAN(Local Area Network) 局域網(wǎng)內(nèi)共享,但是這并不是必須的。也可能是下面這樣的情況:如果客戶端和服務(wù)器距離較遠(yuǎn),那么它們也可以在廣域網(wǎng)上運行。客戶端可以是服務(wù)器,服務(wù)器可以是客戶端,但是為了簡單起見,我們說的客戶端就是消費服務(wù),而服務(wù)器就是提供服務(wù)的角度來聊。

每一個 NFS 服務(wù)都會導(dǎo)出一個或者多個目錄供遠(yuǎn)程客戶端訪問。當(dāng)一個目錄可用時,它的所有子目錄也可用。因此,通常整個目錄樹都會作為一個整體導(dǎo)出。服務(wù)器導(dǎo)出的目錄列表會用一個文件來維護,這個文件是 /etc/exports,當(dāng)服務(wù)器啟動后,這些目錄可以自動的被導(dǎo)出??蛻舳送ㄟ^掛載這些導(dǎo)出的目錄來訪問它們。當(dāng)一個客戶端掛載了一個遠(yuǎn)程目錄,這個目錄就成為客戶端目錄層次的一部分,如下圖所示。

 

在這個示例中,一號客戶機掛載到服務(wù)器的 bin 目錄下,因此它現(xiàn)在可以使用 shell 訪問 /bin/cat 或者其他任何一個目錄。同樣,客戶機 1 也可以掛載到 二號服務(wù)器上從而訪問 /usr/local/projects/proj1 或者其他目錄。二號客戶機同樣可以掛載到二號服務(wù)器上,訪問路徑是 /mnt/projects/proj2。

從上面可以看到,由于不同的客戶端將文件掛載到各自目錄樹的不同位置,同一個文件在不同的客戶端有不同的訪問路徑和不同的名字。掛載點一般通常在客戶端本地,服務(wù)器不知道任何一個掛載點的存在。

NFS 協(xié)議

由于 NFS 的協(xié)議之一是支持 異構(gòu) 系統(tǒng),客戶端和服務(wù)器可能在不同的硬件上運行不同的操作系統(tǒng),因此有必要在服務(wù)器和客戶端之間進(jìn)行接口定義。這樣才能讓任何寫一個新客戶端能夠和現(xiàn)有的服務(wù)器一起正常工作,反之亦然。

NFS 就通過定義兩個客戶端 - 服務(wù)器協(xié)議從而實現(xiàn)了這個目標(biāo)。協(xié)議就是客戶端發(fā)送給服務(wù)器的一連串的請求,以及服務(wù)器發(fā)送回客戶端的相應(yīng)答復(fù)。

第一個 NFS 協(xié)議是處理掛載??蛻舳丝梢韵蚍?wù)器發(fā)送路徑名并且請求服務(wù)器是否能夠?qū)⒎?wù)器的目錄掛載到自己目錄層次上。因為服務(wù)器不關(guān)心掛載到哪里,因此請求不會包含掛載地址。如果路徑名是合法的并且指定的目錄已經(jīng)被導(dǎo)出,那么服務(wù)器會將文件 句柄 返回給客戶端。

❝文件句柄包含唯一標(biāo)識文件系統(tǒng)類型,磁盤,目錄的i節(jié)點號和安全性信息的字段。❞

隨后調(diào)用讀取和寫入已安裝目錄或其任何子目錄中的文件,都將使用文件句柄。

當(dāng) Linux 啟動時會在多用戶之前運行 shell 腳本 /etc/rc ??梢詫燧d遠(yuǎn)程文件系統(tǒng)的命令寫入該腳本中,這樣就可以在允許用戶登陸之前自動掛載必要的遠(yuǎn)程文件系統(tǒng)。大部分 Linux 版本是支持自動掛載的。這個特性會支持將遠(yuǎn)程目錄和本地目錄進(jìn)行關(guān)聯(lián)。

相對于手動掛載到 /etc/rc 目錄下,自動掛載具有以下優(yōu)勢

  • 如果列出的 /etc/rc 目錄下出現(xiàn)了某種故障,那么客戶端將無法啟動,或者啟動會很困難、延遲或者伴隨一些出錯信息,如果客戶根本不需要這個服務(wù)器,那么手動做了這些工作就白費了。
  • 允許客戶端并行的嘗試一組服務(wù)器,可以實現(xiàn)一定程度的容錯率,并且性能也可以得到提高。

另一方面,我們默認(rèn)在自動掛載時所有可選的文件系統(tǒng)都是相同的。由于 NFS 不提供對文件或目錄復(fù)制的支持,用戶需要自己確保這些所有的文件系統(tǒng)都是相同的。因此,大部分的自動掛載都只應(yīng)用于二進(jìn)制文件和很少改動的只讀的文件系統(tǒng)。

第二個 NFS 協(xié)議是為文件和目錄的訪問而設(shè)計的??蛻舳四軌蛲ㄟ^向服務(wù)器發(fā)送消息來操作目錄和讀寫文件??蛻舳艘部梢栽L問文件屬性,比如文件模式、大小、上次修改時間。NFS 支持大多數(shù)的 Linux 系統(tǒng)調(diào)用,但是 open 和 close 系統(tǒng)調(diào)用卻不支持。

❝不支持 open 和 close 并不是一種疏忽,而是一種刻意的設(shè)計,完全沒有必要在讀一個文件之前對其進(jìn)行打開,也沒有必要在讀完時對其進(jìn)行關(guān)閉。❞

NFS 使用了標(biāo)準(zhǔn)的 UNIX 保護機制,使用 rwx 位來標(biāo)示所有者(owner)、組(groups)、其他用戶 。最初,每個請求消息都會攜帶調(diào)用者的 groupId 和 userId,NFS 會對其進(jìn)行驗證。事實上,它會信任客戶端不會發(fā)生欺騙行為??梢允褂霉€密碼來創(chuàng)建一個安全密鑰,在每次請求和應(yīng)答中使用它驗證客戶端和服務(wù)器。

NFS 實現(xiàn)

即使客戶端和服務(wù)器的代碼實現(xiàn)是獨立于 NFS 協(xié)議的,大部分的 Linux 系統(tǒng)會使用一個下圖的三層實現(xiàn),頂層是系統(tǒng)調(diào)用層,系統(tǒng)調(diào)用層能夠處理 open 、 read 、 close 這類的系統(tǒng)調(diào)用。在解析和參數(shù)檢查結(jié)束后調(diào)用第二層,虛擬文件系統(tǒng) (VFS) 層。

 

 

VFS 層的任務(wù)是維護一個表,每個已經(jīng)打開的文件都在表中有一個表項。VFS 層為每一個打開的文件維護著一個虛擬i節(jié)點,簡稱為 v - node。v 節(jié)點用來說明文件是本地文件還是遠(yuǎn)程文件。如果是遠(yuǎn)程文件的話,那么 v - node 會提供足夠的信息使客戶端能夠訪問它們。對于本地文件,會記錄其所在的文件系統(tǒng)和文件的 i-node ,因為現(xiàn)代操作系統(tǒng)能夠支持多文件系統(tǒng)。雖然 VFS 是為了支持 NFS 而設(shè)計的,但是現(xiàn)代操作系統(tǒng)都會使用 VFS,而不管有沒有 NFS。

本文轉(zhuǎn)載自微信公眾號「Java建設(shè)者」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系Java建設(shè)者公眾號。

 

責(zé)任編輯:武曉燕 來源: Java建設(shè)者
相關(guān)推薦

2011-01-13 14:10:30

Linux文件系統(tǒng)

2020-07-22 14:53:06

Linux系統(tǒng)虛擬文件

2021-04-12 05:44:44

Linux文件系統(tǒng)

2021-06-06 16:55:22

Linux文件系統(tǒng)

2012-05-10 13:49:44

Linux文件系統(tǒng)

2011-01-11 10:29:35

Linux文件

2009-12-25 09:58:46

linux劃分文件系統(tǒng)

2009-12-22 15:12:33

Linux擴展文件系統(tǒng)

2021-11-01 13:38:55

Linux文件系統(tǒng)

2011-01-13 13:18:38

Linux網(wǎng)絡(luò)文件

2009-12-14 13:14:57

2019-09-20 10:04:45

Linux系統(tǒng)虛擬文件

2018-08-24 10:10:25

Linux文件系統(tǒng)技術(shù)

2020-01-15 09:10:13

LinuxWindowsmacOS

2021-05-31 07:50:59

Linux文件系統(tǒng)

2017-02-28 20:00:17

Linux文件系統(tǒng)對比

2017-12-04 13:30:12

Linux文件系統(tǒng)鏈接

2017-03-30 10:13:11

Linux內(nèi)核文件系統(tǒng)

2010-12-20 10:42:59

Linux文件系統(tǒng)

2009-12-22 11:30:38

Linux操作系統(tǒng)
點贊
收藏

51CTO技術(shù)棧公眾號

国产在线观看福利| 国产欧美日韩专区发布| 国产麻豆剧传媒精品国产av| 人成在线免费网站| 国产亚洲精品超碰| 亚洲aaaaaa| 国产成人精品一区二三区| 国内精品伊人久久久| 91精品麻豆日日躁夜夜躁| 妞干网在线观看视频| 在线日本中文字幕| 国产.欧美.日韩| 国产精品嫩草视频| 久久精品国产亚洲av香蕉| 欧美色图一区| 亚洲精品一区在线观看| 亚洲高清在线免费观看| 伦理在线一区| 中文字幕在线一区| 久久香蕉综合色| 精品人妻一区二区三区换脸明星| 免费看的黄色欧美网站| 久久视频国产精品免费视频在线| 久久久久久久无码| 国产精品视频一区二区三区| 欧美日韩亚洲一区二区| 一区二区不卡在线观看| 人成在线免费视频| 丁香激情综合五月| 亚洲在线视频观看| 伊人网综合在线| 西西裸体人体做爰大胆久久久| 色综合导航网站| 国产精品麻豆一区| 欧美日韩国产免费观看视频| 亚洲大胆人体在线| 91成人在线观看喷潮蘑菇| 天天综合91| 在线观看日韩国产| 午夜精品久久久内射近拍高清| 国产网红在线观看| 一区二区三区视频在线看| 亚洲三区在线| а√天堂中文在线资源bt在线 | 色七七在线观看| 2021中文字幕在线| 一区二区三区在线看| www亚洲国产| 久久精品视频观看| 中文字幕日韩一区| 亚洲精品在线免费看| 国产免费a∨片在线观看不卡| 26uuu亚洲| 欧美久久在线| 美国一级片在线免费观看视频| 91原创在线视频| 国产一区国产精品| 黑人操亚洲女人| 成人免费视频免费观看| 国产精品久久久久久久天堂第1集 国产精品久久久久久久免费大片 国产精品久久久久久久久婷婷 | 欧美一区二区三区四区视频| 欧美精品久久久久久久久25p| 电影天堂国产精品| 欧美性淫爽ww久久久久无| 国产真人无码作爱视频免费| 99re久久| 9191久久久久久久久久久| 色18美女社区| 97成人在线| 日韩成人在线观看| www.黄色在线| 91青青国产在线观看精品| 俺去亚洲欧洲欧美日韩| 澳门黄色一级片| 黄色国产精品| 欧美一区第一页| 超碰在线免费97| 久久99国产乱子伦精品免费| 亚洲一区久久久| 欧美一级一区二区三区| 久久久久久亚洲综合影院红桃| 日韩精品欧美在线| 黄色成人影院| 亚洲aⅴ怡春院| 国产免费视频传媒| 91麻豆精品国产综合久久久| 欧美不卡一区二区三区| 精品人妻一区二区三区日产乱码卜| 国产一区二区三区网| 精品国产一区二区三区四区在线观看 | 日韩毛片免费看| 欧美成人免费网站| 一级片视频免费看| 亚洲视频电影在线| 欧美中文字幕视频在线观看| 亚洲系列在线观看| www.欧美色图| 在线码字幕一区| а√天堂中文资源在线bt| 欧洲生活片亚洲生活在线观看| 91免费视频污| 欧美美女在线| 欧美日韩xxxxx| 91丨九色丨海角社区| 国产精品一二一区| 日日夜夜精品网站| 91九色porn在线资源| 欧美日韩国产免费一区二区 | 国产3级在线观看| 久久久久久久久久久久久久久久av| 亚洲欧美综合图区| 天堂av在线网站| 人人爱人人干婷婷丁香亚洲| 日韩成人av网址| 日韩欧美中文字幕视频| 视频在线观看91| 国产精品美女黄网| 麻豆传媒视频在线| 色老汉一区二区三区| 亚洲一区二区三区四区av| 日韩精品午夜| 奇米成人av国产一区二区三区| 精品人妻伦一区二区三区久久| 国产欧美一区二区三区鸳鸯浴| 欧美日韩福利在线| 另类视频一区二区三区| 伊人伊人伊人久久| 国产乱国产乱老熟| k8久久久一区二区三区| 在线观看17c| av在线国产精品| 中文字幕精品久久| 亚洲成熟少妇视频在线观看| 99精品欧美一区二区三区综合在线| 欧美aaa在线观看| 国产香蕉久久| 伊人亚洲福利一区二区三区| 中文字幕免费高清网站| 91视视频在线观看入口直接观看www| 久久精品在线免费视频| 四虎永久精品在线| 爽爽爽爽爽爽爽成人免费观看| aaaaaa毛片| ww亚洲ww在线观看国产| 91精品91久久久中77777老牛| 国产图片一区| 久久免费国产视频| 免费av网站观看| 亚洲国产裸拍裸体视频在线观看乱了| av在线免费观看不卡| 亚洲精品网址| 99精品在线直播| 欧美v亚洲v| 亚洲精品一区在线观看| 五月天婷婷综合网| 91丨porny丨蝌蚪视频| 日韩久久一级片| 欧美色图在线播放| 成人精品视频在线| 欧洲性视频在线播放| 欧美精品一区二区三区蜜桃 | 亚洲欧美成人一区二区三区| 肉色超薄丝袜脚交| 精品9999| 欧美精品一区在线发布| 日韩三区在线| 中文字幕亚洲无线码在线一区| 中文字字幕在线观看| 中文字幕欧美一| 少妇极品熟妇人妻无码| 伊人久久成人| 区一区二区三区中文字幕| 影音成人av| 久久亚洲精品中文字幕冲田杏梨| www.com欧美| 欧美日韩免费看| 貂蝉被到爽流白浆在线观看| 韩国三级中文字幕hd久久精品| 国产女教师bbwbbwbbw| 秋霞蜜臀av久久电影网免费| 国产精品久久99久久| av文字幕在线观看| 日韩电影大全免费观看2023年上| 无码人妻精品一区二区| 亚洲欧美另类图片小说| 日本丰满少妇裸体自慰| 美女久久久精品| 特大黑人娇小亚洲女mp4| 亚洲欧美成人vr| 国产一区二区在线播放| 51漫画成人app入口| 综合国产在线观看| 蜜桃av鲁一鲁一鲁一鲁俄罗斯的| 一本到不卡精品视频在线观看 | 熟妇人妻系列aⅴ无码专区友真希| 日韩欧美在线国产| 男的操女的网站| 久久久噜噜噜久久中文字幕色伊伊 | 在线观看日韩精品视频| 精品影院一区二区久久久| 国产精品国产亚洲精品看不卡| 欧美日韩国产在线观看网站| www.成人av.com| 日本免费成人| 欧美一区二区三区免费观看| dy888亚洲精品一区二区三区| 亚洲男人的天堂网站| www.激情五月.com| 欧美日韩一区不卡| 波多野结衣国产| 亚洲综合免费观看高清完整版在线| 亚洲日本精品视频| av一本久道久久综合久久鬼色| 国产无色aaa| 日本不卡一二三区黄网| 黄色国产一级视频| 欧美日一区二区在线观看 | 精品一区二区三区四区五区六区| 久久精品国产秦先生| 久章草在线视频| 亚洲大胆视频| 青青草视频在线视频| 久久一级电影| 日韩国产在线一区| 亚洲涩涩av| 久久99精品久久久久久青青日本| 日韩中文字幕无砖| 亚洲精品欧美极品| 四虎视频在线精品免费网址| 国产精品流白浆视频| 美女福利一区二区| 日本欧美黄网站| 色戒汤唯在线观看| 97在线视频一区| 超碰在线最新网址| 欧美激情亚洲综合一区| 亚洲综合影视| 欧美另类极品videosbest最新版本| 在线毛片网站| 中文字幕亚洲自拍| 在线中文资源天堂| 色小说视频一区| 91xxx在线观看| 色天天综合狠狠色| 米奇精品一区二区三区| xxav国产精品美女主播| 麻豆av在线导航| 久久精品国产综合| 黄色av电影在线播放| 欧美刺激性大交免费视频| www国产在线观看| 欧美激情区在线播放| 91豆花视频在线播放| 91精品国产精品| 亚洲伊人av| 国产精品久久久久久久久久久久久久| 日韩免费小视频| 国产精品视频中文字幕91| 青草综合视频| 91黄在线观看| 精品资源在线| 日本不卡二区| 色999国产精品| 九一免费在线观看| 一本一道久久综合狠狠老精东影业| 国产精品自拍片| 老司机午夜精品视频| 在线观看av网页| 国产精品99久| 亚洲视频在线播放免费| 久久色视频免费观看| 免费在线观看a视频| 成人免费一区二区三区在线观看| 青青青在线视频| 欧美日韩免费一区| 亚洲一区二区视频在线播放| 欧美一二三在线| 三级国产在线观看| 色偷偷av一区二区三区乱| 四虎av在线| 日本精品中文字幕| www一区二区三区| 久久伊人一区| 我不卡影院28| 欧美成人免费在线观看视频| 男女男精品视频| 在线播放av网址| 国产亚洲成aⅴ人片在线观看| 欧美精品久久久久久久久46p| 亚洲午夜一二三区视频| 中文字幕精品视频在线观看| 在线播放视频一区| 天堂av在线资源| 久久久精品日本| 伊人网在线播放| 亚洲影院污污.| 精品国产一区二区三区四区 | 波多野结衣一二三四区| 亚洲精品第1页| 无码人妻丰满熟妇精品区| 精品久久久久久久久久久久包黑料 | 亚洲精品综合久久中文字幕| 国产视频中文字幕在线观看| 欧美最顶级丰满的aⅴ艳星| 欧美日本三级| 午夜视频久久久| 国产免费成人| 日本一区二区三区在线免费观看| 久久精品夜夜夜夜久久| 久久精品国产亚洲av无码娇色| 欧美欧美午夜aⅴ在线观看| 午夜视频免费在线| 欧美大片va欧美在线播放| 成人精品国产| 久久国产精品高清| 国产精品av一区二区| 超碰超碰在线观看| 久久久精品免费观看| 日本午夜精品理论片a级app发布| 欧美日韩国产综合久久| 加勒比一区二区三区在线| 国内精品久久影院| 一区二区三区亚洲变态调教大结局 | 亚洲色图欧美自拍| 中文字幕av不卡| 狠狠狠狠狠狠狠| 日韩精品中文字幕在线| av成人 com a| 国产高清精品一区二区| 亚洲a在线视频| 久久久久xxxx| 一区免费观看视频| 亚洲综合视频在线播放| 一区二区亚洲欧洲国产日韩| 中文字幕在线视频网站| 好吊色欧美一区二区三区视频| 国产一区视频在线观看免费| 伊人精品视频在线观看| 亚洲人成网站色在线观看| 亚洲无码精品在线播放| 精品国模在线视频| 日韩亚洲国产免费| 不卡中文字幕在线| 激情另类小说区图片区视频区| 中文字幕资源站| 欧美日韩成人激情| 欧美激情二区| 92国产精品视频| 午夜电影亚洲| 丰满熟女人妻一区二区三区| 亚洲一区在线电影| 熟妇高潮一区二区三区| 日本精品视频在线观看| 欧美日韩在线观看视频小说| 亚洲36d大奶网| 亚洲天堂精品在线观看| 国产激情无套内精对白视频| 欧美日本高清一区| 老司机aⅴ在线精品导航| 少妇高潮喷水久久久久久久久久| 久久免费电影网| 波多野结衣视频观看| 日韩中文理论片| 欧美不卡在线观看| 亚洲国产精品无码观看久久| 99久久夜色精品国产网站| 丁香社区五月天| 久久国产一区二区三区| 91久久精品无嫩草影院 | xxxcom在线观看| 久久伊人一区| 久久成人免费电影| 免费在线视频观看| 国产午夜精品理论片a级探花| 日韩精品麻豆| 国产精品视频一二三四区| 99精品久久久久久| 中文字幕777| 欧美高清视频在线| 亚洲免费观看高清完整版在线观| 91插插插插插插插插| 一区二区三区91| 九色蝌蚪在线| 亚洲mm色国产网站| 久久精品91| 加勒比婷婷色综合久久| 亚洲精品按摩视频| 少妇高潮一区二区三区99| 久久精品xxx| 中文字幕av在线一区二区三区| 精品国产无码一区二区| 日韩美女免费观看| 91精品蜜臀一区二区三区在线| 精品人妻一区二区免费视频| 欧美性xxxxx极品少妇| 国产精品69xx| 亚洲精品中文字幕乱码三区不卡| 不卡av在线免费观看| 一级黄色大毛片| 欧美一级免费视频|