您的位置:首页 > 运维架构 > Linux

linux文件系统与模型【笔记】 surper block/inode/dentry/file

2014-03-03 15:38 856 查看
因为有文件,所以有管理文件的系统=>因为有很多种文件系统,所以有虚拟文件系统对它们进行封装,让上层的程序只需要调用简单的接口。

文件系统是存储和组织信息的机制,它的目的是管理各种存储设备,所谓的管理是指:存储/操作等。

文件系统管理的对象不同,对应的文件就不同:普通文件,socket文件,目录文件,链接文件,设备文件,管道文件。

文件系统分类:磁盘文件系统,如ext3,ext4;网络文件系统,如NFS;特殊文件系统,这类系统不管理本地或者远程的磁盘,如/proc。

linux支持的文件系统可以查看源码中的fs文件夹,如下:

norton@norton-laptop:~/linuxKernel/linux-2.6.34/fs$ ls
9p                  bio.c                dlm            fs_struct.c     Kconfig         notify        select.c
adfs                bio-integrity.c      drop_caches.c  fs-writeback.c  Kconfig.binfmt  ntfs          seq_file.c
affs                block_dev.c          ecryptfs       fuse            libfs.c         ocfs2         signalfd.c
afs                 btrfs                efs            generic_acl.c   lockd           omfs          smbfs
aio.c               buffer.c             eventfd.c      gfs2            locks.c         open.c        splice.c
anon_inodes.c       cachefiles           eventpoll.c    hfs             logfs           openpromfs    squashfs
attr.c              ceph                 exec.c         hfsplus         Makefile        partitions    stack.c
autofs              char_dev.c           exofs          hostfs          mbcache.c       pipe.c        stat.c
autofs4             cifs                 exportfs       hpfs            minix           pnode.c       super.c
bad_inode.c         coda                 ext2           hppfs           mpage.c         pnode.h       sync.c
befs                compat_binfmt_elf.c  ext3           hugetlbfs       namei.c         posix_acl.c   sysfs
bfs                 compat.c             ext4           inode.c         namespace.c     proc          sysv
binfmt_aout.c       compat_ioctl.c       fat            internal.h      ncpfs           qnx4          timerfd.c
binfmt_elf.c        configfs             fcntl.c        ioctl.c         nfs             quota         ubifs
binfmt_elf_fdpic.c  cramfs               fifo.c         ioprio.c        nfs_common      ramfs         udf
binfmt_em86.c       dcache.c             file.c         isofs           nfsctl.c        readdir.c     ufs
binfmt_flat.c       dcookies.c           filesystems.c  jbd             nfsd            read_write.c  utimes.c
binfmt_misc.c       debugfs              file_table.c   jbd2            nilfs2          read_write.h  xattr_acl.c
binfmt_script.c     devpts               freevxfs       jffs2           nls             reiserfs      xattr.c
binfmt_som.c        direct-io.c          fscache        jfs             no-block.c      romfs         xfs


虚拟文件系统VFS

是建立在各个文件系统上的抽象层,屏蔽了不同文件系统的差异。它之所以有这样的功能是因为它提供了一个“通用的文件系统模型”。该通用模型能够表示很多(即它支持的了)的文件系统。它只提供API接口,桥接实际的文件系统和具体的应用,不会做任何处理文件相关的决策。

VFS采用面向对象的设计思路,将一系列概念抽象出来的同时,也包括处理这些对象的方法。

VFS对象模型

1.超级快(struct super_block)
代表一个已经安装的文件系统。如果是基于磁盘的文件系统,则存放在磁盘扇区。如果不是和基于磁盘的文件系统,如sysfs是基于内存的文件系统,则super_block存放在内存中。

2.索引节点(struct inode)

代表存储设备上的一个实际文件,存储文件相关的信息。linux把文件和文件信息分离出来,文件的相关信息又称为文件的“元数据”,文件信息包括:访问权限,大小,创建时间等。inode结构里面有hash链表,因为inode节点很多,查找效率低,需要借助hash表提高效率。相同hash值的inode节点会被放到一起。

3.目录项(struct dentry)

描述文件系统的层次结构,目录和文件(如.c文件)本身也是“目录项”的对象。通过目录项去找inode。它只存在内存中,不存在磁盘里,具体存在directory cache。它的存在是为了提高系统性能。定义在/include/linux/dcache.h中。

4.文件(struct file)

代表已经被打开(open)的文件。主要用于建立“进程”和文件之间的关系。一个物理文件可能对应多个“文件对象”,但只有唯一的对应的inode。file的结构体中有一个union,用了rcu链表,所以我转载了关于rcu机制的文章,不知道是不是这个rcu机制,仅供参考:http://blog.csdn.net/xzongyuan/article/details/20382995。

总结下4个模型的特征:

1.超级块是磁盘或者内存的抽象,通过超级块,我们可以访问磁盘或内存的具体位置;

2.索引节点,主要是用于找具体某个文件,之所以叫做索引,是因为它不是文件本身,只是文件描述信息的抽象。
3.目录项,它是一个抽象概念的模型,抽象的是文件的层次逻辑关系。它主要用来构建文件系统的层次性,因此它不代表具体某个对象。

4.文件。真正的文件对象,进程需要通过它来处理文件数据。该文件模型使得进程有能力通过目录项/索引节点/超级块来访问磁盘和内存。

/include/linux/fs.h
struct file {
/*
* fu_list becomes invalid after file_free is called and queued via
* fu_rcuhead for RCU freeing
*/
union {
struct list_head	fu_list;
struct rcu_head 	fu_rcuhead;
} f_u;
struct path		f_path;
#define f_dentry	f_path.dentry
#define f_vfsmnt	f_path.mnt
const struct file_operations	*f_op;
spinlock_t		f_lock;  /* f_ep_links, f_flags, no IRQ */
atomic_long_t		f_count;
unsigned int 		f_flags;
fmode_t			f_mode;
loff_t			f_pos;
struct fown_struct	f_owner;
const struct cred	*f_cred;
struct file_ra_state	f_ra;

u64			f_version;
#ifdef CONFIG_SECURITY
void			*f_security;
#endif
/* needed for tty driver, and maybe others */
void			*private_data;

#ifdef CONFIG_EPOLL
/* Used by fs/eventpoll.c to link all the hooks to this file */
struct list_head	f_ep_links;
#endif /* #ifdef CONFIG_EPOLL */
struct address_space	*f_mapping;
#ifdef CONFIG_DEBUG_WRITECOUNT
unsigned long f_mnt_write_state;
#endif
};


5.其它。还有很多VFS对象,如表示文件系统类型的对象file_system_type,表示挂载点的对象vfsmount。不同的文件类型(file_system_type)通过next关联,相同文件类型的superblock通过s_instance(super block实例)字段链接在一起。所有的相同文件类型的vfsmount通过mnt_list连接在一起。



代码在include/linux/fs.h和include/linux/mount.h中。

struct file_system_type {
const char *name;
int fs_flags;
int (*get_sb) (struct file_system_type *, int,
const char *, void *, struct vfsmount *);
void (*kill_sb) (struct super_block *);
struct module *owner;
struct file_system_type * next;
struct list_head fs_supers;

struct lock_class_key s_lock_key;
struct lock_class_key s_umount_key;

struct lock_class_key i_lock_key;
struct lock_class_key i_mutex_key;
struct lock_class_key i_mutex_dir_key;
struct lock_class_key i_alloc_sem_key;
}


struct vfsmount {
struct list_head mnt_hash;
struct vfsmount *mnt_parent;	/* fs we are mounted on */
struct dentry *mnt_mountpoint;	/* dentry of mountpoint */
struct dentry *mnt_root;	/* root of the mounted tree */
struct super_block *mnt_sb;	/* pointer to superblock */
struct list_head mnt_mounts;	/* list of children, anchored here */
struct list_head mnt_child;	/* and going through their mnt_child */
int mnt_flags;
/* 4 bytes hole on 64bits arches */
const char *mnt_devname;	/* Name of device e.g. /dev/dsk/hda1 */
struct list_head mnt_list;
struct list_head mnt_expire;	/* link in fs-specific expiry list */
struct list_head mnt_share;	/* circular list of shared mounts */
struct list_head mnt_slave_list;/* list of slave mounts */
struct list_head mnt_slave;	/* slave list entry */
struct vfsmount *mnt_master;	/* slave is on master->mnt_slave_list */
struct mnt_namespace *mnt_ns;	/* containing namespace */
int mnt_id;			/* mount identifier */
int mnt_group_id;		/* peer group identifier */
/*
* We put mnt_count & mnt_expiry_mark at the end of struct vfsmount
* to let these frequently modified fields in a separate cache line
* (so that reads of mnt_flags wont ping-pong on SMP machines)
*/
atomic_t mnt_count;
int mnt_expiry_mark;		/* true if marked for expiry */
int mnt_pinned;
int mnt_ghosts;
#ifdef CONFIG_SMP
int __percpu *mnt_writers;
#else
int mnt_writers;
#endif
};


VFS对象之间不是孤立的,其关系如下。



进程描述符task_struct的files字段描述了所有打开的文件,存放在fd_array数组里。通过该数组找到file对象(该file对象实际存放在super_block指定的文件系统中),可以找到dentry项,从而找到inode。这件就建立了文件对象和物理文件之间的关联。

Linux以一组通用的对象看待所有文件系统:super block,inode,dentry和file。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: