linux inode

分类

inode分为内存中的inode和文件系统中的inode,为了避免混淆,我们称前者为VFS inode, 而后者以EXT2为代表,我们称为Ext2 inode。

VFS inode

VFS inode包含文件访问权限、属主、组、大小、生成时间、访问时间、最后修改时间等信息。它是linux管理文件系统的最基本单位,也是文件系统连接任何子目录、文件的桥梁。inode结构中的静态信息取自物理设备上的文件系统,由文件系统指定的函数填写,它只存在于内存中,可以通过inode缓存访问。虽然每个文件都有相应的inode结点,但是只有在需要的时候系统才会在内存中为其建立相应的inode数据结构,建立的inode结构将形成一个链表,我们可以通过遍历这个链表去得到我们需要的文件结点,VFS也为已分配的inode构造缓存和哈希表,以提 高系统性能。inode结构中的struct inode_operations *i_op为我们提供了一个inode操作列表,通过这个列表提供的函数我们可以对VFS inode结点进行各种操作。每个inode结构都有一个i结点号i_ino,在同一个文件系统中每个i结点号是唯一的。

struct inode {
        struct hlist_node       i_hash;              /* 哈希表 */
        struct list_head        i_list;              /* 索引节点链表 */
        struct list_head        i_dentry;            /* 目录项链表 */
        unsigned long           i_ino;               /* 节点号,经由super block结构和其序号,我们可以很轻易的找到这个inode */
        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;
};

EXT2 inode

EXT2 inode用来定义文件系统的结构以及描述系统中每个文件的管理信息,每个文件都有且只有一个inode,即使文件中没有数据,其索引结点也是存在的。每个文件用一个单独的Ext2 inode结构来描述,而且每一个inode都有唯一的标志号。Ext2 inode为内存中的inode结构提供了文件的基本信息,随着内存中inode结构的变化,系统也将更新Ext2 inode中相应的内容。

ext2/3大小是128字节,ext4大小是256字节

  • inode要记录的数据非常多,但只有128bytes,而inode记录一个block号码要花掉4bytes,假设一个文件有400MB且每个block为4KB,那么至少要10万条block号码的记录,inode哪有这么多可记录的信息?为此我们系统将inode记录block号码的区域定义为12个直接,一个间接,一个双间接与一个三间接记录区。

inode
图中最左边为inode本身(128bytes),里面有12个直接指向block号码的对照,这12个记录可以直接取到block号码,也就是直接寻址。至于所谓的间接就是再拿一个block来当作记录block号码的记录区,如果文件过大时,就会使用间接的block来记录编号,也就是间接寻址。同理,如果文件持续长大,就会利用双间接。

这样inode能够指定多少个block呢?以较小的1KB的block来说明。可以指定的情形如下:

  • 12个直接指向:12*1K=12K,由于是直接指向,所以总共可以记录12条记录
  • 间接:256*1K = 256K
    • 每条block号码的记录会花去4bytes,因此1K的大小能记录256条记录
  • 双间接:2562561K=256^2K = 64M
  • 三间接:256256256*1K=256^3K,大约16G

总额:将直接、间接、双间接、三间接加总,得到 12 + 256 + 25 6 2 + 25 6 3 = 16 G B 12+256+256^2+ 256^3=16GB 12+256+2562+2563=16GB,此时我们知道当文件系统将block格式化为为1K大小时,能够容纳的最大文件为16GB,比较一下文件系统线指标的结果可发现是一致的。但这个方法不能用在2K及4K的block大小的计算中。因为大于2K的block将会收到文件系统本身的限制

struct ext2_inode {
	__u16 i_mode;/* File mode */
	__u16 i_uid;/* Low 16 bits of Owner Uid */
	__u32 i_size;/* Size in bytes */
	__u32 i_atime;/* Access time */
	__u32 i_ctime;/* Creation time */
	__u32 i_mtime;/* Modification time */
	__u32 i_dtime;/* Deletion Time */
	__u16 i_gid;/* Low 16 bits of Group Id */
	__u16 i_links_count;/* Links count */
	__u32 i_blocks;/* Blocks count */
	__u32 i_flags;/* File flags */
	union {
		struct {
			__u32 l_i_reserved1;
		} linux1;
		struct {
			__u32 h_i_translator;
		} hurd1;
		struct {
			__u32 m_i_reserved1;
		} masix1;
	} osd1;/* OS dependent 1 */
	__u32 i_block[EXT2_N_BLOCKS];/* Pointers to blocks */
	__u32 i_generation;/* File version (for NFS) */
	__u32 i_file_acl;/* File ACL */
	__u32 i_dir_acl;/* Directory ACL */
	__u32 i_faddr;/* Fragment address */
	union {
		struct {
			__u8l_ i_frag;/* Fragment number */
			__u8l_ i_fsize;/* Fragment size */
			__u16 i_pad1;
			__u16l_ i_uid_high;/* these 2 fields */
			__u16l_ i_gid_high;/* were reserved2[0] */
			__u32l_ i_reserved2;
		} linux2;
		struct {
			__u8h_ i_frag;/* Fragment number */
			__u8h_ i_fsize;/* Fragment size */
			__u16h_ i_mode_high;
			__u16h_ i_uid_high;
			__u16h_ i_gid_high;
			__u32h_ i_author;
		} hurd2;
		struct {
			__u8m_ i_frag;/* Fragment number */
			__u8m_ i_fsize;/* Fragment size */
			__u16m_ pad1;
			__u32m_ i_reserved2[2];
		} masix2;
	} osd2;/* OS dependent 2 */
};

/*
 * Structure of an inode on the disk
 */
struct ext4_inode {
        __le16  i_mode;         /* File mode */
        __le16  i_uid;          /* Low 16 bits of Owner Uid */
        __le32  i_size_lo;      /* Size in bytes */
        __le32  i_atime;        /* Access time */
        __le32  i_ctime;        /* Inode Change time */
        __le32  i_mtime;        /* Modification time */
        __le32  i_dtime;        /* Deletion Time */
        __le16  i_gid;          /* Low 16 bits of Group Id */
        __le16  i_links_count;  /* Links count */
        __le32  i_blocks_lo;    /* Blocks count */
        __le32  i_flags;        /* File flags */
        union {
                struct {
                        __le32  l_i_version;
                } linux1;
                struct {
                        __u32  h_i_translator;
                } hurd1;
                struct {
                        __u32  m_i_reserved1;
                } masix1;
        } osd1;                         /* OS dependent 1 */
        __le32  i_block[EXT4_N_BLOCKS];/* Pointers to blocks */
        __le32  i_generation;   /* File version (for NFS) */
        __le32  i_file_acl_lo;  /* File ACL */
        __le32  i_size_high;
        __le32  i_obso_faddr;   /* Obsoleted fragment address */
        union {
                struct {
                        __le16  l_i_blocks_high; /* were l_i_reserved1 */
                        __le16  l_i_file_acl_high;
                        __le16  l_i_uid_high;   /* these 2 fields */
                        __le16  l_i_gid_high;   /* were reserved2[0] */
                        __le16  l_i_checksum_lo;/* crc32c(uuid+inum+inode) LE */
                        __le16  l_i_reserved;
                } linux2;
                struct {
                        __le16  h_i_reserved1;  /* Obsoleted fragment number/size which are removed in ext4 */
                        __u16   h_i_mode_high;
                        __u16   h_i_uid_high;
                        __u16   h_i_gid_high;
                        __u32   h_i_author;
                } hurd2;
                struct {
                        __le16  h_i_reserved1;  /* Obsoleted fragment number/size which are removed in ext4 */
                        __le16  m_i_file_acl_high;
                        __u32   m_i_reserved2[2];
                } masix2;
        } osd2;                         /* OS dependent 2 */
        __le16  i_extra_isize;
        __le16  i_checksum_hi;  /* crc32c(uuid+inum+inode) BE */
        __le32  i_ctime_extra;  /* extra Change time      (nsec << 2 | epoch) */
        __le32  i_mtime_extra;  /* extra Modification time(nsec << 2 | epoch) */
        __le32  i_atime_extra;  /* extra Access time      (nsec << 2 | epoch) */
        __le32  i_crtime;       /* File Creation time */
        __le32  i_crtime_extra; /* extra FileCreationtime (nsec << 2 | epoch) */
        __le32  i_version_hi;   /* high 32 bits for 64-bit version */
        __le32  i_projid;       /* Project ID */
};

关系

  • VFS inode结构位于内存中,而Ext2_inode位于磁盘
  • VFS inode在需要时才会被建立,如果系统断电,此结构也随之消失。
  • Ext2_inode的存在与系统是否上电无关,而且无论文件是否包含数据,Ext2_inode都是存在的
  • VFS inode是Ext2 inode的抽象、映射与扩充,而后者是前者的静态信息部分,也是对前者的具体化、实例化和持久化。
  • 对VFS inode的操作具有通用性,对文件系统inode的操作则是文件系统相关的,依赖于特定的实现
  • 系统通过VFS inode链表来对其进行组织,并且为了提高访问效率相应地构造了inode构造缓存和hash table。
  • Ext2 inode的信息位于EXT2文件系统的划分的块组中,在每个块组中包含相应的inode位图、inode表指定具体的inode信息,每个inode对应Ext2_inode结构。
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值