任何文件系统中的数据分为数据和元数据。数据是指普通文件中的实际数据,而元数据(metadata)指用来描述一个文件的特征的系统数据,诸如设备标识符、访问权限、文件大小、文件拥有者、文件模式,扩展属性、文件读取或修改的时间戳、链接数量,指向存储该内容的磁盘区块的指针及文件分类等等。这个所谓的元数据就包含在inode中,因此一个文件除了自身的数据之外,还有一个附属信息,即文件的元数据,由操作系统维护的。
inode(发音:eye-node)译成中文就是索引节点,保存的其实是实际的数据的一些信息,这些信息称为“元数据”(也就是对文件属性的描述)。存储设备就如一本书,块是具体的书内容,而索引结点是这本书的目录。
下图展示了程序通过文件名获取文件内容的过程
在集群文件系统中,分布信息包括文件在磁盘上的位置以及磁盘在集群中的位置。用户需要操作一个文件必须首先得到它的元数据,才能定位到文件的位置并且得到文件的内容。
Linux文件系统中,每一个文件都有一个伴随的inode(identification
node),它的结构体如
structinode {
struct hlist_node i_hash; //哈希表*/
struct list_head i_list; //索引节点链表*/
struct list_head i_dentry; //目录项链表*/
unsigned long i_ino; //节点号*/
atomic_t i_count; //引用记数*/
umode_t i_mode; //访问权限控制*/
unsigned int i_nlink; //硬链接数*/
uid_t i_uid; //使用者id*/
gid_t i_gid; //使用者id组*/
kdev_t i_rdev; //实设备标识符*/
loff_t i_size; //以字节为单位的文件大小*/
struct timespec i_atime; //最后访问时间*/
struct timespec i_mtime; //最后修改(modify)时间*/
struct timespec i_ctime; //最后改变(change)时间*/
unsigned int i_blkbits; //以位为单位的块大小*/
unsigned long i_blksize; //以字节为单位的块大小*/
unsigned long i_version; //版本号*/
unsigned long i_blocks; /*文件的块数*/
unsigned short i_bytes; //使用的字节数*/
spinlock_t i_lock; //自旋锁*/
struct rw_semaphore i_alloc_sem; //索引节点信号量*/
struct inode_operations *i_op; //索引节点操作表*/
struct file_operations *i_fop; //默认的索引节点操作*/
struct super_block *i_sb; //相关的超级块*/
struct file_lock *i_flock; //文件锁链表*/
struct address_space *i_mapping; //相关的地址映射*/
struct address_space i_data; //设备地址映射*/
struct dquot *i_dquot[MAXQUOTAS]; //节点的磁盘限额*/
struct list_head i_devices; //块设备链表*/
struct pipe_inode_info *i_pipe; //管道信息*/
struct block_device *i_bdev; //块设备驱动*/
unsigned long i_dnotify_mask; //目录通知掩码*/
struct dnotify_struct *i_dnotify; //目录通知*/
unsigned long i_state; //状态标志*/
unsigned long dirtied_when; //首次修改时间*/
unsigned int i_flags; //文件系统标志*/
unsigned char i_sock; //可能是个套接字吧*/
atomic_t i_writecount; //写者记数*/
void *i_security; //安全模块*/
__u32 i_generation; //索引节点版本号*/
union {
void *generic_ip; //文件特殊信息*/
} u;
};
一个inode只对应一个文件,而一个文件根据其大小,会占用多块blocks。使用ls –i命令可以查看目录或文件的inode编号值,如
[NSOS1.1 ~]# cd itm
[NSOS1.1 itm]# ll
total133532
drwxr-xr-x3 root root 4096 Nov 3 14:22 tc_v5.0.1_1571
-rw-r--r--1 root root 136592436 Nov 3 14:19tc_v5.0.1_1571.tgz
[NSOS1.1 ~]# ls -i itm
819650tc_v5.0.1_1571 720907 tc_v5.0.1_1571.tgz #目录下所有文件的inode值
[NSOS1.1 itm]# ls -i tc_v5.0.1_1571.tgz #显示文件inode值
720907tc_v5.0.1_1571.tgz
[NSOS1.1 itm]#
inode记录一个block号码要占用4byte,想想看,假设block为4KB的文件系统,保存400M文件要占用400*1024/4=10W个block,inode直接记录哪能装下去?所以就出现了间接块
间接块并不保存实际数据,保存的是其他磁盘块的信息。
通过索引结点可以找到对应的文件,这个索引结点值(编号)是唯一的,两个不同的文件的inode编号是不同的,索引结点值相同的文件是硬链接关系。
在Linux中,inode是用来存储特定文件的元数据的一种数据结构,在创建一个文件系统时,inode的预先定义数量将被分配。
每个inode节点的大小,一般是128字节或256字节。inode节点的总数,在格式化时就给定,一般是每1KB或每2KB就设置一个inode。假定在一块1GB的硬盘中,每个inode节点的大小为128字节,每1KB就设置一个inode,那么inode table的大小就会达到128MB(128乘以10^6),占整块硬盘的12.8%。
查看每个inode节点的大小,
[NSOS1.1 ~]# sudo dumpe2fs -h /dev/sda1 | grep 'Inode'
dumpe2fs1.39 (29-May-2006)
Inodecount: 1048576
Inodesper group: 32768
Inodeblocks per group: 1024
Inodesize: 128
当你监视磁盘使用情况时,你必须注意的不仅仅是磁盘空间,还要有“inode”的使用情况。这意味着,一个文件系统可能耗尽空间不只是因为大文件用完了所有可用空间,也可能是因为很多小文件用完了所有可能的inode。
inode也会消耗硬盘空间,所以硬盘格式化的时候,操作系统自动将硬盘分成两个区域。一个是数据区,存放文件数据;另一个是inode区(inode table),存放inode所包含的信息。
用“df -i”命令展示每个分区的inode使用情况。
[NSOS1.1 ~]# df -i
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/sda1 1048576 35971 1012605 4% /
none 2559319 23 2559296 1% /dev/shm
/dev/sda2 1182016 169 1181847 1% /icg/conf
/dev/sda3 58818560 617512 58201048 2% /icg/data
[NSOS1.1 ~]#
由于每个文件都必须有一个inode,因此有可能发生inode已经用光,但是硬盘还未存满的情况。这时,就无法在硬盘上创建新文件。