1. 程式人生 > >Linux 核心程式設計之檔案系統(二)

Linux 核心程式設計之檔案系統(二)

1.為了方便查詢,VFS引入了 目錄 項,每個dentry代表路徑中的一個特定部分。目錄項也可包括安裝點。
2.目錄項物件由dentry結構體表示 ,定義在檔案linux/dcache.h 標頭檔案中。
  89struct dentry {
  90        atomic_t d_count;                //使用計數
  91        unsigned int d_flags;           //目錄項標時
  92        spinlock_t d_lock;                //單目錄鎖
  93        int d_mounted;                    //目錄項的安裝點
  94        struct inode *d_inode;        //與該目錄項相關聯的索引節點
  95                                       
  96        /*
  97         * The next three fields are touched by __d_lookup.  Place them here
  98         * so they all fit in a cache line.
  99         */
 100        struct hlist_node d_hash;        //散列表
 101        struct dentry *d_parent;          //父目錄項
 102        struct qstr d_name;                //目錄項名可快速查詢
 103
 104        struct list_head d_lru;            // 未使用目錄以LRU 演算法連結的連結串列
 105        /*
 106         * d_child and d_rcu can share memory
 107         */
 108        union {
 109                struct list_head d_child;       /* child of parent list */
 110                struct rcu_head d_rcu;
 111        } d_u;
 112        struct list_head d_subdirs;     //該目錄項子目錄項所形成的連結串列
 113        struct list_head d_alias;        //索引節點別名連結串列
 114        unsigned long d_time;           //重新生效時間
 115        const struct dentry_operations *d_op;    // 操作目錄項的函式
 116        struct super_block *d_sb;       //目錄項樹的根
 117        void *d_fsdata;                        //具體檔案系統的資料
 118
 119        unsigned char d_iname[DNAME_INLINE_LEN_MIN];    //短檔名
 120};
1>索引節點中的i_dentry指向了它目錄項,目錄項中的d_alias,d_inode又指會了索引節點物件,目錄項中的d_sb又指回了超級塊物件。
2>我們可以看到不同於VFS 中的索引節點物件和超級塊物件,目錄項物件中沒有對應磁碟的資料結構,所以說明目錄項物件並沒有真正標存在磁碟上,那麼它也就沒有髒標誌位。
3>目錄項的狀態(被使用,未被使用和負狀態)
a.它們是靠d_count的值來進行區分的,當d_count為正值說明目錄項處於被使用狀態。當d_count=0時表示該目錄項是一個未被使用的目錄項, 但其d_inode指標仍然指向相關的的索引節點。該目錄項仍然包含有效的資訊,只是當前沒有人引用他。d_count=NULL表示負(negative)狀態,與目錄項相關的inode物件不復存在(相應的磁碟索引節點可能已經被刪除),dentry物件的d_inode 指標為NULL。但這種dentry物件仍然儲存在dcache中,以便後續對同一檔名的查詢能夠快速完成。這種dentry物件在回收記憶體時將首先被釋放。
4> d_subdirs:如果當前目錄項是一個目錄,那麼該目錄下所有的子目錄形成一個連結串列。該欄位是這個連結串列的表頭;
      d_child:如果當前目錄項是一個目錄,那麼該目錄項通過這個欄位加入到父目錄的d_subdirs連結串列當中。這個欄位中的next和prev指標分別 指向父目錄中的另外兩個子目錄;
      d_alias:一個inode可能對應多個目錄項,所有的目錄項形成一個連結串列。inode結構中的i_dentry即為這個連結串列的頭結點。當前目錄項以這個欄位處於i_dentry連結串列中。該欄位中的prev和next指標分別指向與該目錄項同inode的其他兩個(如果有的話)目錄項
3.dentry和inode的區別:
 inode(可理解為ext2 inode)對應於物理磁碟上的具體物件,dentry是一個記憶體實體,其中的d_inode成員指向對應的inode。也就是說,一個inode可以在執行的時候連結多個dentry,而d_count記錄了這個連結的數量。
4.dentry與dentry_cache
dentry_cache簡稱dcache,中文名稱是目錄項快取記憶體,是Linux為了提高目錄項物件的處理效率而設計的。它主要由兩個資料結構組成:
1>雜湊連結串列dentry_hashtable:dcache中的所有dentry物件都通過d_hash指標域鏈到相應的dentry雜湊連結串列中。
2>未使用的dentry物件連結串列dentry_unused:dcache中所有處於unused狀態和negative狀態的dentry物件都通過其d_lru指標域鏈入dentry_unused連結串列中。該連結串列也稱為LRU連結串列。
目錄項快取記憶體dcache是索引節點快取icache的主控器(master),也即 dcache中的dentry物件控制著icache中的inode物件的生命期轉換。無論何時,只要一個目錄項物件存在於dcache中(非 negative狀態),則相應的inode就將總是存在,因為 inode的引用計數i_count總是大於0。當dcache中的一個dentry被釋放時,針對相應inode物件的iput()方法就會被呼叫。
5對目錄項進行操作的一組函式叫目錄項操作表,由dentry_operation結構描述。它可以在 include/linux/dcache.h 中查到
 134struct dentry_operations {
 135        int (*d_revalidate)(struct dentry *, struct nameidata *);
 136        int (*d_hash) (struct dentry *, struct qstr *);
 137        int (*d_compare) (struct dentry *, struct qstr *, struct qstr *);
 138        int (*d_delete)(struct dentry *);
 139        void (*d_release)(struct dentry *);
 140        void (*d_iput)(struct dentry *, struct inode *);
 141        char *(*d_dname)(struct dentry *, char *, int);
 142};
a.int d_reavlidate(struct dentry *dentry ,int flags) 該函式判斷目錄物件是否有效。VFS準備從dcache中使用一個目錄項時,會呼叫該函式.
b.int d_hash(struct dentry *dentry ,struct qstr *name):該目錄生成雜湊值,當目錄項要加入到散列表時,VFS要呼叫此函式。
c.int d_compare( struct dentry *dentry, struct qstr *name1, struct qstr *name2) 該函式來比較name1和name2這兩個檔名。使用該函式要加dcache_lock鎖。
d.int d_delete(struct dentry *dentry):當d_count=0時,VFS呼叫次函式。使用該函式要叫 dcache_lock鎖。
e.void d_release(struct dentry *dentry):當該目錄物件將要被釋放時,VFS呼叫該函式。
f.void d_iput(struct dentry *dentry,struct inode *inode)當一個目錄項丟失了其索引節點時,VFS就掉用該函式。
二.VFS中的檔案物件

1.檔案物件表示程序已經開啟的檔案 在記憶體中的表示,該物件不是物理上的檔案。它是由相應的open()系統呼叫建立,由close()系統呼叫銷燬。多個程序可以開啟和操作同一個檔案,所以同一個檔案也可能存在多個對應的檔案物件。
2一個檔案對應的檔案物件不是唯一的,但對應的索引節點和超級塊物件是唯一的。
3.file結構中儲存了檔案位置,此外,還把指向該檔案索引節點的指標也放在其中。file結構形成一個雙鏈表,稱為系統開啟檔案表 。它的定義在 include/linux/fs.h 中可以看到
 909struct file {
 910        /*
 911         * fu_list becomes invalid after file_free is called and queued via
 912         * fu_rcuhead for RCU freeing
 913         */
 914        union {
 915                struct list_head        fu_list;                            //每個檔案系統中被開啟的檔案都會形成一個雙鏈表
 916                struct rcu_head       fu_rcuhead;
 917        } f_u;
 918        struct path                           f_path;                    
 919#define f_dentry                      f_path.dentry            // 與該檔案對應的dentry
 920#define f_vfsmnt                     f_path.mnt
 921        const struct file_operations    *f_op;            //指向檔案操作表的指標
 922        spinlock_t                        f_lock;  /* f_ep_links, f_flags, no IRQ */
 923#ifdef CONFIG_SMP
 924        int                                    f_sb_list_cpu;         
 925#endif
 926        atomic_long_t                 f_count;                     //檔案物件的使用計數
 927        unsigned int                    f_flags;                      //開啟檔案時所指定的標誌
 928        fmode_t                          f_mode;                    //檔案的訪問模式
 929        loff_t                               f_pos;                         //檔案當前的位移量
 930        struct fown_struct           f_owner
 931        const struct cred            *f_cred;                    
 932        struct file_ra_state          f_ra;                          //預讀狀態
 933
 934        u64                                 f_version;                  //版本號
 935#ifdef CONFIG_SECURITY
 936        void                                *f_security;                //安全模組
 937#endif
 938        /* needed for tty driver, and maybe others */
 939        void                                *private_data;           //tty裝置hook
 940
 941#ifdef CONFIG_EPOLL
 942        /* Used by fs/eventpoll.c to link all the hooks to this file */
 943        struct list_head                f_ep_links;                
 944#endif /* #ifdef CONFIG_EPOLL */
 945        struct address_space    *f_mapping;                //頁快取對映
 946#ifdef CONFIG_DEBUG_WRITECOUNT
 947        unsigned long f_mnt_write_state;
 948#endif
 949};
1>檔案物件實際上沒有對應的磁碟資料,所以在結構體中沒有代表其物件是否為髒,是否需要寫回磁碟的標誌。檔案物件 通過f_path.dentry指標指向相關的目錄項物件。目錄項會指向相關的索引節點,索引節點會記錄檔案是否是髒的。
2>fu_list:每個檔案系統中以被開啟的檔案都會形成一個雙聯表,這個雙聯表的頭結點存放在超級塊的s_files欄位中。該欄位的prev和next指標分別指向在連結串列中與當前檔案結構體相鄰的前後兩個元素.

相關推薦

Linux 核心程式設計檔案系統

1.為了方便查詢,VFS引入了 目錄 項,每個dentry代表路徑中的一個特定部分。目錄項也可包括安裝點。 2.目錄項物件由dentry結構體表示 ,定義在檔案linux/dcache.h 標頭檔案中。   89struct dentry {  90        atomic_t d_count;     

linux 核心模組程式設計hello word

我們的目的是要編譯個hello.ko的檔案,然後安裝到核心中。 先來看下需要的程式碼,hello.c檔案如下 #include <linux/module.h> #include <linux/init.h> static int hello_init(vo

例說linux核心與應用資料通訊:proc虛擬檔案系統

下面是一個簡單使用proc的示例,應用上面傳入資料,核心經過處理之後,應用再獲取經過處理的資料:#include <linux/init.h> #include <linux/module.h> #include <linux/kernel.h> #include <

Linux 檔案系統與裝置檔案系統 —— sysfs 檔案系統Linux裝置模型

      提到 sysfs 檔案系統 ,必須先需要了解的是Linux裝置模型,什麼是Linux裝置模型呢? 一、Linux 裝置模型 1、裝置模型概述      從2.6版本開始,Linux開發團隊便為核心建立起一個統一的裝置模型。在以前的核心中沒有獨立的資料結構用來讓核

Linux核心原始碼分析--檔案系統五、Inode.c

_bmap()         1、_bmap()函式用於把一個檔案資料塊對映到盤塊的處理操作                  因為一個i節點對應一個檔案,所以上面的i節點對映的邏輯塊號就是檔案資料存放的邏輯塊號;i_zone[0]到i_zone[6]是直接邏輯塊號,i

Java高併發程式設計synchronized關鍵字

上一篇文章講了synchronized的部分關鍵要點,詳見:Java高併發程式設計之synchronized關鍵字(一) 本篇文章接著講synchronized的其他關鍵點。 在使用synchronized關鍵字的時候,不要以字串常量作為鎖定物件。看下面的例子: public class

【Android架構】基於MVP模式的Retrofit2+RXjava封裝檔案下載

上篇中我們介紹了基於MVP的Retrofit2+RXjava封裝,還沒有看的點選這裡,這一篇我們來說說檔案下載的實現。 首先,我們先在ApiServer定義好呼叫的介面 @GET Observable<ResponseBody> downloadFile(@

bash學習檔案系統

linux系統的一個特點就是將所有的內容都看作是檔案。因此至少要了解linux的檔案也是一個重要的內容。下面將介紹一下linux裡面的檔案: 1.按照檔案型別進行劃分 文字檔案: 檔案的組成主要是ASCII碼,也就是能夠直接識別成我能能夠讀懂內容是什麼的檔案(windows的tx

/proc檔案系統:/proc/<pid>/stat

0. 前言 /proc 檔案系統是一個偽檔案系統,它只存在記憶體當中,而不佔用外存空間。 它以檔案系統的方式為核心與程序提供通訊的介面。使用者和應用程式可以通過/proc得到系統的資訊,並可以改變核心的某些引數。 由於系統的資訊,如程序,是動態改變的,所以使用者或應用程式讀取/proc

FastDFS輕量級分散式檔案系統安裝

FastDFS--tracker安裝 在192.168.101.3上安裝tracker。 下載 tracker和storage使用相同的安裝包,下載地址:http://sourceforge.net/projects/FastDFS/ 或https://github

SD卡中的FAT32檔案系統

2.1 FAT檔案系統簡介 FAT(File Allocation Table,檔案分配表)檔案系統是windows作業系統所使用的一種檔案系統,它的發展過程經歷了FAT12、FAT16、FAT32三個階段。FAT檔案系統用“簇”作為資料單元。一個“簇”由一組連續的扇區

C++ COM程式設計QueryInterface函式

前言 在COM程式設計——認識元件中也總結了,COM是一個說明如何建立可動態互變元件的規範,它提供了為保證能夠互操作,客戶和元件應遵循的一些標準。而在實現和使用QueryInterface時,就需要去遵守一些規則,只有遵守了這些規則,才能是一個正確的COM元件;只有瞭解了這些規則,才能會真正的瞭解COM

高併發程式設計基礎概念

  在上一篇中,簡單介紹了一寫執行緒的基礎知識,以及一些概念,本文繼續介紹一些基礎知識以及一些方法。 什麼是執行緒   執行緒,有時被稱為輕量程序,它是程序內的執行單元。執行緒是程序中的一個實體,是被系統獨立排程和分派的基本單位,執行緒自己不擁有系統資源,只擁有一點兒在執行中必不可少的資源,但它可與同屬一

Linux核心--網路棧實現分析--資料包的傳遞過程

本文分析基於Linux Kernel 1.2.13作者:閆明注:標題中的”(上)“,”(下)“表示分析過程基於資料包的傳遞方向:”(上)“表示分析是從底層向上分析、”(下)“表示分析是從上向下分析。上一篇博文中我們從巨集觀上分析了Linux核心中網路棧的初始化過程,這裡我們再

現代作業系統檔案系統

檔案系統的管理和優化 磁碟空間管理 幾乎所有的檔案系統都把檔案分割成固定大小的塊來儲存,各塊之間不一定相鄰。 效能和空間利用率是矛盾的。 跟蹤空閒塊有兩種常用的方法——第一種方法是採用磁碟塊連結串列,那個塊中包含儘可能多的空閒磁碟號。通常情況下,次啊用空閒塊存放空閒表,

現代作業系統檔案系統

程序執行時,可以在他自己的地址空間記憶體儲一定量的資訊,但儲存容量受虛擬地址空間大小的限制。 程序上儲存空間的第二個問題是——當程序終止時,他儲存的資訊也隨之消失。 第三個問題是:經常需要多個程序同事都去同一個資訊(或部分資訊) 檔案鎖程序建立的資訊邏輯單元。一個磁碟一般

PowerShell檔案系統訪問檔案和目錄

原文地址:http://www.pstips.net/accessing-files-and-directories.html PowerShell 檔案系統系列文章: 使用Get-ChildItem列出目錄的內容。預定義的別名為Dir和ls,Get-Chil

Python高階程式設計資料庫sqlite3

import logging import sqlite3 import sys import threading import time logging.basicConfig( level = logging.DEBUG, format = '%(asctime)s (%(threadN

linux核心分析排程演算法

linux排程演算法在2.6.32中採用排程類實現模組式的排程方式。這樣,能夠很好的加入新的排程演算法。 linux排程器是以模組方式提供的,這樣做的目的是允許不同型別的程序可以有針對性地選擇排程演算法。這種模組化結構被稱為排程器類,他允許多種不同哦可動態新增的排程演算法並

[日更-2019.5.22、23] Android 系統的分割槽和檔案系統--Android 檔案系統中的檔案

宣告 Android系統中有很多分割槽,每個分割槽內的檔案系統一般都不同的,使用ADB進入系統/目錄下可發現掛載這很多的目錄,不