天天看點

了解xv6——檔案系統

作者:chenleiyfk

The xv6 file system provides data files, which are uninterpreted byte arrays, and directories, which contain named references to data files and other directories. The directories form a tree, starting at a special directory called the root. A path like /a/b/c refers to the file or directory named c inside the directory named b inside the directory named a in the root directory /. Paths that don’t begin with / are evaluated relative to the calling process’s current directory, which can be changed with the chdir system call. Both these code fragments open the same file (assuming all the directories involved exist):

Xv6檔案系統提供資料檔案(包含未解釋的位元組數組)和目錄(包含對資料檔案和其他目錄的命名引用)。這些目錄形成一個樹,從一個叫做根的特殊目錄開始。像/a/b/c這樣的路徑是指在根目錄/下名為a的目錄中名為b的目錄中名為c的檔案或目錄。不以/開始的路徑相對于調用程序的目前工作目錄進行計算,目前工作目錄可以通過chdir系統調用進行更改。下面兩個代碼片段打開相同的檔案(假設所有相關的目錄都存在):

了解xv6——檔案系統

chdir

The first fragment changes the process’s current directory to /a/b; the second neither refers to nor changes the process’s current directory.

上面代碼将程序的目前目錄更改為/a/b;下面代碼既不引用也不更改程序的目前目錄.

There are multiple system calls to create a new file or directory: mkdir creates a new directory, open with the O_CREATE flag creates a new data file, and mknod creates a new device file. This example illustrates all three:

還有建立新檔案和目錄的系統調用:

  • mkdir建立一個新目錄
  • open中若使用O_CREATE标志将會建立一個新的資料檔案
  • mknod建立一個新的裝置檔案

這個例子說明了這三點:

了解xv6——檔案系統

mk

Mknod creates a file in the file system, but the file has no contents. Instead, the file’s metadata marks it as a device file and records the major and minor device numbers (the two arguments to mknod), which uniquely identify a kernel device. When a process later opens the file, the kernel diverts read and write system calls to the kernel device implementation instead of passing them to the file system.

Mknod在檔案系統中建立一個檔案,但該檔案沒有内容。相反,檔案的中繼資料将其标記為裝置檔案,并記錄主裝置号和次裝置号(mknod的兩個參數),它們唯一地辨別核心裝置。當一個程序稍後打開該檔案時,核心将讀寫系統調用轉移到核心裝置實作,而不是将它們傳遞給檔案系統。

A file’s name is distinct from the file itself; the same underlying file, called an inode, can have multiple names, called links.

一個檔案的名字和檔案本身是不同的;同一個底層檔案(叫做inode,索引結點)可以有多個名字(叫做link,連結)。每個連結都由目錄中的一個條目組成;該條目包含一個檔案名和一個inode引用。Inode儲存有關檔案的中繼資料(用于解釋或幫助了解資訊的資料),包括其類型(檔案/目錄/裝置)、長度、檔案内容在磁盤上的位置以及指向檔案的連結數。

fstat retrieves information about the object a file descriptor refers to. It fills in a struct stat, defined in stat.h as:

fstat系統調用從檔案描述符所引用的inode中檢索資訊。它填充一個stat類型的結構體,struct stat在stat.h(kernel/stat.h)中定義為:

了解xv6——檔案系統

stat

The link system call creates another file system name referring to the same inode as an existing file. This fragment creates a new file named both a and b.

link系統調用建立另一個檔案名,該檔案名指向與現有檔案相同的inode。下面的代碼片段建立了一個名字既為a又為b的新檔案

open("a", O_CREATE | O_WRONLY);
link("a", "b");           

Reading from or writing to a is the same as reading from or writing to b. Each inode is identified by a unique inode number. After the code sequence above, it is possible to determine that a and b refer to the same underlying contents by inspecting the result of fstat: both will return the same inode number (ino), and the nlink count will be set to 2.

從a讀取或寫入與從b讀取或寫入是相同的操作。每個inode由唯一的inode編号辨別。在上面的代碼序列之後,可以通過檢查fstat的結果來确定a和b引用相同的底層内容:兩者都将傳回相同的inode号(ino),并且nlink計數将被設定為2。

The unlink system call removes a name from the file system. The file’s inode and the disk space holding its content are only freed when the file’s link count is zero and no file descriptors refer to it. Thus adding

unlink系統調用從檔案系統中删除一個名稱。隻有當檔案的連結數為零且沒有檔案描述符引用時,檔案的inode和包含其内容的磁盤空間才會被釋放,是以添加

unlink("a");           

to the last code sequence leaves the inode and file content accessible as b. Further more,

最後一行代碼序列中會使inode和檔案内容可以作為b通路。此外

fd = open("/tmp/xyz", O_CREATE | O_RDWR);
unlink("/tmp/xyz");           

is an idiomatic way to create a temporary inode that will be cleaned up when the process closes fd or exits.

是建立沒有名稱的臨時inode的慣用方法,該臨時inode将在程序關閉fd或退出時被清理。

Shell commands for file system operations are implemented as user-level programs such as mkdir, ln, rm, etc. This design allows anyone to extend the shell with new user commands by just adding a new user-level program. In hindsight this plan seems obvious, but other systems designed at the time of Unix often built such commands into the shell (and built the shell into the kernel).

Unix以使用者級程式的形式提供了可從shell調用的檔案實用程式,例如mkdir、ln和rm。這種設計允許任何人通過添加新的使用者級程式來擴充指令行接口。事後看來,這個計劃似乎是顯而易見的,但是在Unix時代設計的其他系統經常将這樣的指令建構到shell中(并将shell建構到核心中)

One exception is cd, which is built into the shell (8716) . cd must change the current working directory of the shell itself. If cd were run as a regular command, then the shell would fork a child process, the child process would run cd, and cd would change the child’s working directory. The parent’s (i.e., the shell’s) working directory would not change.

一個例外是cd,它是内置在shell(xv6/sh.c:160)。cd必須更改shell本身的目前工作目錄。如果cd作為正常指令運作,那麼shell将分出一個子程序,子程序将運作cd,cd将更改子程序的工作目錄。父目錄(即shell的)的工作目錄不會改變。