在 Linux 中,最直觀、最可見的部分就是 文件系統(tǒng)(file system)。下面我們就來一起探討一下關于 Linux 中國的文件系統(tǒng),系統(tǒng)調(diào)用以及文件系統(tǒng)實現(xiàn)背后的原理和思想。這些思想中有一些來源于 MULTICS,現(xiàn)在已經(jīng)被 Windows 等其他操作系統(tǒng)使用。Linux 的設計理念就是 小的就是好的(Small is Beautiful) 。雖然 Linux 只是使用了最簡單的機制和少量的系統(tǒng)調(diào)用,但是 Linux 卻提供了強大而優(yōu)雅的文件系統(tǒng)。
Linux 文件系統(tǒng)基本概念
Linux 在最初的設計是 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 碼、二進制文件和其他類型的文件是不加區(qū)分的。
在 Linux 中經(jīng)常出現(xiàn)一個用戶使用另一個用戶的文件或者使用文件樹結構中的文件。兩個用戶共享同一個文件,這個文件位于某個用戶的目錄結構中,另一個用戶需要使用這個文件時,必須通過絕對路徑才能引用到他。如果絕對路徑很長,那么每次輸入起來會變的非常麻煩,所以 Linux 提供了一種 鏈接(link) 機制。
Linux 文件系統(tǒng)的另外一個特性是支持 加鎖(locking)。在一些應用中會出現(xiàn)兩個或者更多的進程同時使用同一個文件的情況,這樣很可能會導致競爭條件(race condition)。一種解決方法是對其進行加不同粒度的鎖,就是為了防止某一個進程只修改某一行記錄從而導致整個文件都不能使用的情況。
creat 系統(tǒng)調(diào)用不僅僅創(chuàng)建了一個名為 aaa 的文件,還會打開這個文件。為了允許后續(xù)的系統(tǒng)調(diào)用訪問這個文件,這個 creat 系統(tǒng)調(diào)用會返回一個 非負整數(shù), 這個就叫做 文件描述符(file descriptor),也就是上面的 fd。
如果在已經(jīng)存在的文件上調(diào)用了 creat 系統(tǒng)調(diào)用,那么該文件中的內(nèi)容會被清除,從 0 開始。通過設置合適的參數(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)
關閉一個打開的文件
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,...)
文件加鎖等其他操作
為了對一個文件進行讀寫的前提是先需要打開文件,必須使用 creat 或者 open 打開,參數(shù)是打開文件的方式,是只讀、可讀寫還是只寫。open 系統(tǒng)調(diào)用也會返回文件描述符。打開文件后,需要使用 close 系統(tǒng)調(diào)用進行關閉。close 和 open 返回的 fd 總是未被使用的最小數(shù)量。