Linux文件系统之VFS(三)
目录项(dentry
)定义于 include/linux/dcache.h
。
目录项对象描述了文件系统的层次结构,一个路径的各个组成部分,不管是目录(VFS
将目录当作文件处理),还是普通文件,都是一个目录项对象。
目录项将路径中的每个部分与其对应的inode
相联系,一旦VFS
得到了所需要的dentry
,同时便也得到了相应的inode
,即可对文件做想要的操作。沿着路径各部分的目录项进行搜索,最终可找到目标文件的inode
。
struct dentry {
/* RCU lookup touched fields */
unsigned int d_flags; /* protected by d_lock */
seqcount_t d_seq; /* per dentry seqlock */
struct hlist_bl_node d_hash; /* lookup hash list */
struct dentry *d_parent; /* parent directory */
struct qstr d_name;
struct inode *d_inode;
/* Where the name belongs to - NULL is
* negative */
unsigned char d_iname[DNAME_INLINE_LEN]; /* small names */
/* Ref lookup also touches following */
struct lockref d_lockref; /* per-dentry lock and refcount */
const struct dentry_operations *d_op;
struct super_block *d_sb; /* The root of the dentry tree */
unsigned long d_time; /* used by d_revalidate */
void *d_fsdata; /* fs-specific data */
struct list_head d_lru; /* LRU list */
struct list_head d_child; /* child of parent list */
struct list_head d_subdirs; /* our children */
/*
* d_alias and d_rcu can share memory
*/
union {
struct hlist_node d_alias; /* inode alias list */
struct rcu_head d_rcu;
} d_u;
};
每个dentry可能处于以下四个状态:
- 空闲状态(free)。处于该状态的dentry不包含有效的信息,且没有被VFS使用。
- 未使用状态(unused)。处于该状态的dentry当前没有被VFS使用,他的引用计数d_count为0,但其d_inodei字段仍然指 向相关连的indoe。这种dentry仍然是一个有效的目录项对象,包含有效的信息,且被保留在内存中以便需要时使用。但是如果需要回收内存时,它们可 能被丢弃。
- 使用状态(in use)。处于该状态的dentry存在一个或多个使用(d_count为正值),它的d_inode字段指向相关联的inode。这种dentry不能被丢弃。
- 负状态(negative)。处于该状态的dentry没有对应有效的inode,即它的d_inode字段为NULL, 这是由于其相关联的inode已经被删除,或者它是通过解析一个不存在的文件路径而创建的,但是该对象仍然保留在目录项高速缓存中,以便后续使用。
struct dentry_operations {
int (*d_revalidate)(struct dentry *, unsigned int);
int (*d_weak_revalidate)(struct dentry *, unsigned int);
int (*d_hash)(const struct dentry *, struct qstr *);
int (*d_compare)(const struct dentry *, const struct dentry *,
unsigned int, const char *, const struct qstr *);
int (*d_delete)(const struct dentry *);
void (*d_release)(struct dentry *);
void (*d_prune)(struct dentry *);
void (*d_iput)(struct dentry *, struct inode *);
char *(*d_dname)(struct dentry *, char *, int);
struct vfsmount *(*d_automount)(struct path *);
int (*d_manage)(struct dentry *, bool);
struct inode *(*d_select_inode)(struct dentry *, unsigned);
};