分类: LINUX
2005-08-27 21:55:04
文件系统分析(从路径到目标节点)
struct fs_struct{
atomic_t count;
rwlock_t lock;
int mask;
struct dentry *root,*pwd,*altroot;
struct vfsmount *rootmnt,*pwdmnt,*altrootmnt;
};
fs_struct结构中的信息都是与文件系统和进程相关 与具体的已打开的文件没有关系
打开的文件表数据结构
struct files_struct{
atomic_t count;
spinlock_t file_lock;
int max_fds;
int max_fdset;
int next fd;
struct file **fd;
fd_set *close_on_exec;
fd_set open_fds;
fd_set close_on_exec_init;
fd_set open_fds_init;
struct file *fd_array[NR_OPEN_DEFAULT];
};
struct ext2_inode 把inode结构的部分信息保存在磁盘的索引节点上。 在内存中对应为inode结构
目录项 (索引节点的数据项) 在内存中对应为 dentry 结构
struct ext2_dir_entry_2{
__u32 inode;
__u16 rec_len;
__u8 name_len;
__u8 file_type;
char name[EXT2_NAME_LEN];
};
每个磁盘分区都有一个超级块
打开文件的过程:
1.系统调用 sys_open
asmlinkage long sys_open(const char __user * filename, int flags, int mode)
{;
...struct file *f = filp_open(tmp, flags, mode); //tmp 文件名
}
2.struct file *filp_open(const char * filename, int flags, int mode)
error = open_namei(filename, namei_flags, mode, &nd);
if (!error)
return dentry_open(nd.dentry, nd.mnt, flags);
3.int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
{ error = path_lookup(pathname, lookup_flags(flag)|LOOKUP_OPEN, nd);
}
4.int fastcall path_lookup(const char *name, unsigned int flags, struct nameidata *nd)
{
retval = link_path_walk(name, nd);
}
5,result = __link_path_walk(name, nd);
{
;err = do_lookup(nd, &this, &next); 进行真正的搜索
}
dentry结构是文件系统的核心数据结构,也是文件访问和为文件访问而做的文件路径搜索的枢纽。
每个dentry 结构都通过队列头d_hash 链入杂凑表 dentry_hashtable中的某个队列里
共享计数为0的dentry 通过d_lru 链入LRU list
dentry的数据结构
struct dentry {
atomic_t d_count;
unsigned int d_flags; /* protected by d_lock */
spinlock_t d_lock; /* per dentry lock */
struct inode *d_inode; /* Where the name belongs to - NULL is
* negative */
/*
* The next three fields are touched by __d_lookup. Place them here
* so they all fit in a 16-byte range, with 16-byte alignment.
*/
struct dentry *d_parent; /* parent directory */
struct qstr d_name;
struct list_head d_lru; /* LRU list */
struct list_head d_child; /* child of parent list */
struct list_head d_subdirs; /* our children */
struct list_head d_alias; /* inode alias list */
unsigned long d_time; /* used by d_revalidate */
struct dentry_operations *d_op;
struct super_block *d_sb; /* The root of the dentry tree */
void *d_fsdata; /* fs-specific data */
struct rcu_head d_rcu;
struct dcookie_struct *d_cookie; /* cookie, if any */
struct hlist_node d_hash; /* lookup hash list */
int d_mounted;
unsigned char d_iname[DNAME_INLINE_LEN_MIN]; /* small names */
};
static int do_lookup(struct nameidata *nd, struct qstr *name,
struct path *path)
{
struct vfsmount *mnt = nd->mnt;
struct dentry *dentry = __d_lookup(nd->dentry, name);
if (!dentry)
goto need_lookup;
if (dentry->d_op && dentry->d_op->d_revalidate)
goto need_revalidate;
done:
path->mnt = mnt;
path->dentry = dentry;
__follow_mount(path);
return 0;
need_lookup:
dentry = real_lookup(nd->dentry, name, nd);
if (IS_ERR(dentry))
goto fail;
goto done;
need_revalidate:
if (dentry->d_op->d_revalidate(dentry, nd))
goto done;
if (d_invalidate(dentry))
goto done;
dput(dentry);
goto need_lookup;
fail:
return PTR_ERR(dentry);
}