0.11版linux文件系統(三)

目錄項和超級塊,節點的概念不同,它在設備上沒有對應的磁盤數據結構。相反,它是目錄文 件的一部分。linux中目錄也是一種文件,類型是'd'。但是目錄中的內容和普通文件不同,它是由目錄項組成的。注意目錄項不是目錄。我們經常用路徑名 執行相關操作,目錄項就是爲了查找方便的。
struct dirt_entry{
        unsigned short inode;
        char name[NAME_LEN];
};
可 以看到一個目錄項中包含了文件的i節點號和文件的名稱。路徑有兩種,一種是絕對路徑,一種是相對路徑。比如/home/fish就是絕對路徑,它以根目錄 /爲開頭,而 X11/xorg.conf就是相對路徑,它相對於目錄/etc,也就是說後者的絕對路徑是/etc/X11/xorg.conf。路徑是由目錄項組成 的。拿 /home/fish/fish.c來說,第一個目錄是/,即根目錄。在根目錄文件中有名字爲home的目錄項。然後通過home目錄項中的i節點就可以 找到home文件,通過i節點中的i_mode字段可知它是一個目錄,在這個文件中有名爲fish的目錄項,然後根據這個目錄項中的i節點號找到fish 文件。同樣由fish的inode->i_mode知這也是個目錄。同樣在fish文件中找到名爲fish.c的目錄項,就可以找出fish.c的 i節點,搜索完成。
namei.c 是內核中最長的一個文件,它包含了許多關於目錄的操作,如find_entry(從一個目錄中搜索制定的目錄項),add_entry(往指定的目錄中添 加一個文件目錄項),get_dir(根據路徑名找到指定的目錄),dir_namei(返回指定目錄的i節點指針),還有namei(根據路徑名找到指 定路徑的i節點)等等。我們就先拿find_entry來看一下。
//dir:指定目錄的i節點指針。name:文件名,namelen:文件名長度。
//返回:高速緩衝區指針和相應的目錄項指針。
static struct buffer_head* find_entry(struct m_inode **dir,const char*name,int namelen,struct dir_entry **res_dir)
{
        int entries;
        int block ,i;
        struct buffer_head *bh;
        struct dir_entry *de;
        struct super_blocl *sb;
//如果定義了NO_TRUNCATE,則如果文件名大於最大長度NAME_LEN,返回。       
#ifdef NO_TRUNCATE
        if(namelen >NAME_LEN)
                return NULL;
#else
        if(namelen>NAME_LEN)
                namelen=NAME_LEN;
//計算本目錄中的目錄項數
        entries=(*dir)->i_size/(sizeof(struct dir_entry));
        *res_dir=NULL;
        if(!namelen)
                return NULL;
//如果是目錄'..',對其進行特殊處理.
        if(namelen==2&&get_fs_byte(name)=='.'&&get_fs_byte(name+1)=='.'){
//如果本目錄是進程的根目錄,那麼就將文件名修改爲'.'.
                if((*dir)==current->root)
                        namelen=1;
//如果本目錄是文件系統的根目錄,那麼取出文件系統的超級塊
                else if((*dir)->i_num==ROOT_INO){
                        sb=get_super((*dir)->i_dev);
//如果本文件系統的安裝節點存在,那麼就釋放原i節點,將*dir指向被安裝到的i節點。對於根文件系統來說,就是它的根節點。
                        if(sb->s_imount){
                        iput(*dir);
                        (*dir)=sb->s_imount;
                        (*dir)->i_count++;
                        }
                }
        }
//如果第i節點指向的第一個直接塊號爲0,則返回
        if(!block=(*dir)->i_zone[0]))
                return NULL;
//讀取節點坐在設備的目錄項數據。也就是本目錄文件的內容
        if(!(bh=bread((*dir)->i_dev,block)))
                return NULL;
//在bh中搜索指定的目錄項
        i=0;
        de=(struct dir_entry*)bh->data;
        while(i<entries){
//如果當前的文件塊搜索完畢,則準備搜索下一塊
        if((char*)de>=BLOCK_SIZE+bh->b_data){
                brelse(bh);
               
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章