天天看點

vfs的superblock、inode、dentry、file之間的關系dentry

he common file model consists of the following object types:

<1>The superblock object

Stores information concerning a mounted filesystem. For disk-based filesystems, this object usually corresponds to a filesystem control block stored on disk.

<2>The inode object

Stores general information about a specific file. For disk-based filesystems, this object usually corresponds to a file control block stored on disk. Each inode object is associated with an inode number, which uniquely identifies the file within the filesystem.

<3>The file object

Stores information about the interaction between an open file and a process. This information exists only in kernel memory during the period when a process has the file open.

<4>The dentry object

Stores information about the linking of a directory entry (that is, a particular name of the file) with the corresponding file. Each disk-based filesystem stores this information in its own particular way on disk.

Figure 12-2 illustrates with a simple example how processes interact with files. Three different processes have opened the same file, two of them using the same hard link. In this case, each of the three processes uses its own file object, while only two dentry objects are requiredone for each hard link. Both dentry objects refer to the same inode object, which identifies the superblock object and, together with the latter, the common disk file.

dentry

  一、dentry的定義 

  dentry的中文名稱是目錄項,是Linux檔案系統中某個索引節點(inode)的連結。這個索引節點可以是檔案,也可以是目錄。

  二、dentry的結構:以下是dentry的結構體

  struct dentry {

  atomic_t d_count; 目錄項對象使用計數器

  unsigned int d_flags; 目錄項标志

  struct inode * d_inode; 與檔案名關聯的索引節點

  struct dentry * d_parent; 父目錄的目錄項對象

  struct list_head d_hash; 散清單表項的指針

  struct list_head d_lru; 未使用連結清單的指針

  struct list_head d_child; 父目錄中目錄項對象的連結清單的指針

  struct list_head d_subdirs;對目錄而言,表示子目錄目錄項對象的連結清單

  struct list_head d_alias; 相關索引節點(别名)的連結清單

  int d_mounted; 對于安裝點而言,表示被安裝檔案系統根項

  struct qstr d_name; 檔案名

  unsigned long d_time;

  struct dentry_operations *d_op; 目錄項方法

  struct super_block * d_sb; 檔案的超級塊對象

  vunsigned long d_vfs_flags;

  void * d_fsdata;與檔案系統相關的資料 

  unsigned char d_iname [DNAME_INLINE_LEN]; 存放短檔案名

  }; 

  三、dentry與inode

  inode(可了解為ext2 inode)對應于實體磁盤上的具體對象,dentry是一個記憶體實體,其中的d_inode成員指向對應的inode。也就是說,一個inode可以在運作的時候連結多個dentry,而d_count記錄了這個連結的數量。

  按照d_count的值,dentry分為以下三種狀态:

  1、未使用(unused)狀态:該dentry對象的引用計數d_count的值為0,但其d_inode指針仍然指向相關的的索引節點。該目錄項仍然包含有效的資訊,隻是目前沒有人引用他。這種dentry對象在回收記憶體時可能會被釋放。

  2、正在使用(inuse)狀态:處于該狀态下的dentry對象的引用計數d_count大于0,且其d_inode指向相關的inode對象。這種dentry對象不能被釋放。

  3、負(negative)狀态:與目錄項相關的inode對象不複存在(相應的磁盤索引節點 可能已經被删除),dentry對象的d_inode指針為NULL。但這種dentry對象仍然儲存在dcache中,以便後續對同一檔案名的查找能夠 快速完成。這種dentry對象在回收記憶體時将首先被釋放。

  四、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()方法就會被調用。

  五、dentry_operations *d_op

  struct dentry_operations {

  int (*d_revalidate)(struct dentry *);

  int (*d_hash) (struct dentry *, struct qstr *);

  int (*d_compare) (struct dentry *, struct qstr *, struct qstr *);

  void (*d_delete)(struct dentry *);

  void (*d_release)(struct dentry *);

  void (*d_iput)(struct dentry *, struct inode *);

  };

  d_revalidate:用于VFS使一個dentry重新生效。

  d_hash:用于VFS向哈希表中加入一個dentry。

  d_compare:dentry的最後一個inode被釋放時(d_count等于零),此方法被調用,因為這意味這沒有inode再使用此dentry;當然,此dentry仍然有效,并且仍然在dcache中。

  d_release: 用于清除一個dentry。

  d_iput:用于一個dentry釋放它的inode(d_count不等于零)

  六、d_parent和d_child

  每個dentry都有一個指向其父目錄的指針(d_parent),一個子dentry的哈希清單(d_child)。其中,子dentry基本上就是目錄中的檔案。

  七、怎樣從inode值得到目錄名?

  函數得到目前檔案或目錄的inode值後,進入dcache查找對應的dentry,然後順着父目錄指針d_parent得到父目錄的dentry,這樣逐級向上直到dentry= root,就得到全部目錄名稱。