此篇文章主要介绍下linux 文件系统下的主要对象及他们之间的关系。
1 inode
inode结构中主要包含对文件或者目录原信息的描述,原信息包括但不限于文件大小、文件在磁盘块中的位置信息、权限位、文件属性等。文件系统主要通过查找内存中是否有对应的inode来判断一个文件是否存在。
inode本质上分为两种,一种是磁盘文件系统确实存在的inode信息,这里暂叫disk_inode,另一种是内存中的inode,是根据disk_inode生成的,这里暂叫mm_inode。mm_inode中包含文件文件系统特殊管理的复杂数据信息,比对应disk_inode信息量大的多。这里注意,disk_inode并非每个磁盘文件系统都包含,但如前文所述,若想被挂载使用,必须模拟出对应的disk_inode(最终目的是mm_inode)。
inode 结构体定义:
/include/linux/fs.h struct inode { struct hlist_node i_hash; struct list_head i_list; struct list_head i_dentry;//All the dentrys which point to this inode list together. unsigned long i_ino;//The inode id, unique in a certain fils system.Sometimes kernel use the i_ino to locate the inode structure atomic_t i_count; umode_t i_mode; unsigned int i_nlink;//How many dentrys points to this same inode. uid_t i_uid; gid_t i_gid; dev_t i_rdev;//if this inode standard for a specific device file, the region include major/minor device number. loff_t i_size;//The size of the data in this inode. struct timespec i_atime; struct timespec i_mtime; struct timespec i_ctime; unsigned int i_blkbits; unsigned long i_blksize; unsigned long i_version; unsigned long i_blocks; unsigned short i_bytes; unsigned char i_sock; spinlock_t i_lock; /* i_blocks, i_bytes, maybe i_size */ struct semaphore i_sem; struct rw_semaphore i_alloc_sem; struct inode_operations *i_op; struct file_operations *i_fop; /* former ->i_op->default_file_ops */ struct super_block *i_sb; struct file_lock *i_flock; struct address_space *i_mapping; struct address_space i_data; #ifdef CONFIG_QUOTA struct dquot *i_dquot[MAXQUOTAS]; #endif /* These three should probably be a union */ struct list_head i_devices; struct pipe_inode_info *i_pipe; struct block_device *i_bdev; struct cdev *i_cdev; int i_cindex; __u32 i_generation; #ifdef CONFIG_DNOTIFY unsigned long i_dnotify_mask; /* Directory notify events */ struct dnotify_struct *i_dnotify; /* for directory notifications */ #endif unsigned long i_state; unsigned long dirtied_when; /* jiffies of first dirtying */ unsigned int i_flags; atomic_t i_writecount; void *i_security; union { void *generic_ip; } u; #ifdef __NEED_I_SIZE_ORDERED seqcount_t i_size_seqcount; #endif };
2 dentry
dentry 表示目录项,这里注意目录项和目录的区分。目录中包含有文件和子目录。而目录项是文件系统逻辑概念,简单讲是一个全路径当中的字段,但这个字段必然代表某一文件系统下的目录或者文件。在文件路径名到具体文件的解析中dentry有重要应用。这里注意一个inode可能对应多个不同的dentry对象,但一个dentry能切只能指向一个inode对象。即多个文件路径指向同一个文件物理。
dentry结构体定义:
/include/linux/dcache.h 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 */ };
dentry结构有6个list_head(list_head既可以作为队列的头部,也可以将其数据结构挂入到某个队列中):
d_vfsmount:仅在该dentry结构是一个安装点时才可以使用
d_hash:一个dentry结构一旦建立就通过就通过d_hash挂入杂凑表dentry_hashtable中的某个队列中。
d_lru:当共享计数为0时,通过d_lru挂入LRU队列的dentry_unused中。
d_child:一个dentry通过d_child挂入其父节点的d_subdirs中。同时通过d_parent指向其父目录的dentry结构。
d_subdirs:该dentry自己的所有子目录挂在该队列下。
d_alias:在inode结构中有个队列i_dentry,凡是代表这个文件的所有目录项头通过d_alias挂入相应inode结构中的i_dentry队列。
一个有效的dentry必然关联一个inode,然而反过来一个inode却可能对应着不止一个dentry结构。也就是说一个文件可能有不止一个路径名(因为一个已建立的文件可以被link到其他的文件名)
3 File
4 Super_block
5 他们之间连接的数据结构