目录,inode学习笔记

目录,inode学习笔记

1. 关于目录,文件,数据块 
对于使用计算机的人而言,经常有一种 错误的认知目录(或者说,文件夹)里面存放着文件。实际上,目录里面并不存放文件,以及文件数据。

实际上,目录是一个特殊的文件,针对这个特殊的文件也存在一些特殊的规则,比如利用命令cp /dev/null <your directory>并不能够销毁这个特殊的文件,因为目录的一些特殊的比特位保证了这一安全性,降低了人工操作带来的风险。在一些老版本的Unix系统里面,用户可以利用cat命令打开目录,查看里面的信息,在一些衍生于Debian系统的发行版linux里面,也可以利用vi工具打开目录,查看一些信息。

在Linux里面,一个文件的信息被存放于两个位置:

  1. 数据块(data block)当中

  2. inode当中

硬盘的最小存储单位叫做“扇区”(Sector)。每个扇区储存512字节(相当于0.5KB)。操作系统读取磁盘的时候,不会一个个扇区“挨个读取”,而是一次读取多个扇区,即一次读取一个“块”(block),这种由多个扇区组成的”块”,是文件存取的最小单位。”块”的大小,最常见的是4KB,即连续八个 sector组成一个 block。data block当中存放了文件的真实内容,而文件的元数据信息,被存放到了inode当中。data blockinode文件系统有效地组织到了一起。

文件系统被创建之后,inode的数量以及data block的数量也被固定下来。我们不能够修改inode的数量,也不能够修改data block的数量。

当我们创建一个文件的时候,inode编号将作为该文件的唯一id,即,一个文件在同一时刻仅拥有一个inode编号。当我们向一个文件写入内容的时候,数据被存放到了data block当中。而该文件的文件名,被存放到了该文件所在的目录文件当中。

对于目录这种“特殊的文件”,可以简单地理解为是一张表,这张表里面存放了隶属于该目录的文件的文件名,以及所匹配的inode编号

因此,在linux里面,文件被“拆分”到了3个地方,索引存于inode,文件名存于目录,数据存于data block。


2. 关于硬链接以及复制 
基于上述内容对于目录的描述,可以比较容易解释linux里面的另外一个重要的概念: hard link(硬链接)

对于文件而言,真正的ID是inode编号,而并非文件名。回忆一下目录文件: 一张含有文件名和inode编号的表。在这张表里面,我们暂定用一个如下结构表示一个文件: [directory : (filename, inode_number)],这里以/etc/passwd文件举例,假设其inode编号为123456(确实有点儿假……),则可以写为[/etc/ : (passwd, 123456)],假设我们在终端上面键入了如下命令:

[root@centos7-front1 ~]# ln /etc/passwd /root/hard_link_passwd 

则会在/root目录下面出现一个新的文件名,叫做hard_link_passwd。如果用上述结构表示这个文件,则为[/root/ : (hard_link_passwd, 123456)],因此,这种目录或文件名不同,但是inode编号相同的文件,称为硬链接。由于硬链接inode编号相同,而且对于同一个inode结构体,便会拥有相同的地址映射以及相同的块设备链表。因此,对于用户空间而言,修改/etc/passwd,就相当于修改了/root/hard_link_passwd,反之亦然。

同样基于上述内容对于目录的描述,针对i_device相同的mv操作,仅仅是删除了原目录里面对应的[directory : (filename, inode_number)],并且在目标目录新建了另一个[directory : (filename, inode_number)],由于并没有对于data block的任何操作,因此速度很快。


3. 初步查看inode 
利用ls -i命令可以查看到当前目录下面的所有文件的inode编号,注意inode编号仅仅是inode结构体里面的一项,并不代表inode全部,下面截取/etc/目录下的前5个文件:

1
2
3
4
5
6
[root@centos7-front1 etc]# ls -i | head -n 5
   768684 abrt
 34370879 adjtime
 33554592 aliases
 35506331 aliases.db
100705463 alternatives

利用stat命令可以查看一个文件更加详细的inode信息,包括inode编号,占用的块数量,块大小,硬链接个数,atime, mtime, ctime, ……下面用stat命令查看/etc目录(如上文所说,目录也是一种特殊的文件)

1
2
3
4
5
6
7
8
9
[root@centos7-front1 /]# stat /etc
  File: ‘/etc’
  Size: 8192            Blocks: 24         IO Block: 4096   directory
Device: 803h/2051d      Inode: 33554561    Links: 85
Access: (0755/drwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2017-03-28 17:13:00.510221799 -0400
Modify: 2017-03-28 12:37:32.150999451 -0400
Change: 2017-03-28 12:37:32.150999451 -0400
 Birth: –

从上述结果中,我们可以看出,针对/etc目录而言,其大小为8192kb,为该目录下的文件所分配的块数量为24个,类型为directory,设备名称为803h/2051d,其Inode编号为33554561,其硬链接个数为85个,权限为0755,Uid和Gid均为0,还有atime, mtime, ctime这些信息。

当然,利用stat命令查到的某个文件的inode信息并不是全部的inode结构体里面的信息。内核使用的inode结构体如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
struct inode {
        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;
};


4. inode使用情况以及大小 
inode也会消耗硬盘空间,所以硬盘格式化的时候,操作系统自动将硬盘分成两个区域。一个是数据区,存放文件数据;另一个是inode区(inode table),存放inode所包含的信息。

每个inode节点的大小,一般是128字节或256字节。inode节点的总数,在格式化时就给定,一般是每1KB或每2KB就设置一个inode。假定在一块1GB的硬盘中,每个inode节点的大小为128字节,每1KB就设置一个inode,那么inode table的大小就会达到128MB,占整块硬盘的12.8%。

查看每个硬盘分区的inode总数和已经使用的数量,可以使用df命令。

1
2
3
4
5
6
7
8
9
[root@centos7-front1 ~]# df -i
Filesystem       Inodes IUsed    IFree IUse% Mounted on
/dev/sda3      23860224 59694 23800530    1% /
devtmpfs         122809   367   122442    1% /dev
tmpfs            125170     1   125169    1% /dev/shm
tmpfs            125170   433   124737    1% /run
tmpfs            125170    13   125157    1% /sys/fs/cgroup
/dev/sda1        256000   329   255671    1% /boot
tmpfs            125170     1   125169    1% /run/user/0

查看某个分区的文件系统所分配的单个inode节点的大小,在ext文件系统下,可以使用dumpe2fs命令,例如CentOS6系统上,针对/dev/sda3分区:

1
2
3
[root@maCentos6 ~]# dumpe2fs -h /dev/sda3 | grep -i “inode size”
dumpe2fs 1.41.12 (17-May-2010)
Inode size:               256

在xfs文件系统下,可以使用xfs_info命令,例如CentOS7系统上,针对/dev/sda3分区:

1
2
3
4
5
6
7
8
9
10
[root@centos7-front1 ~]# xfs_info /dev/sda1
meta-data=/dev/sda1              isize=256    agcount=4, agsize=16000 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=0        finobt=0
data     =                       bsize=4096   blocks=64000, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=0
log      =internal               bsize=4096   blocks=853, version=2
         =                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0


4. 参考链接

  1. 阮一峰的网络日志:理解inode

  2. Linux struct inode结构

  3. Inodes – an Introduction

原创文章,作者:jiangche00,如若转载,请注明出处:http://www.178linux.com/72294

(0)
jiangche00jiangche00
上一篇 2017-04-01
下一篇 2017-04-01

相关推荐

  • rpm包管理

    前言    RPM(简称RPM,全称为The RPM Package Manager)是在Linux下广泛使用的软件包管理器。RPM此名词可能是指.rpm的文件格式的软件包,也可能是指其本身的软件包管理器(RPM Package Manager)。最早由Red Hat研制,现在也由开源社区开发。RPM通常随附于Linux发行版,…

    Linux干货 2015-05-13
  • sed命令用法详解

    1.sed运行原理         sed(stream editor)是一个行处理器。处理时,把当前处理的行放到“模式空间中”,处理完毕后,把该行输出到屏幕,接着处理下一行;这样不断重复,直到末行;此时文件本身内容并没有改变 2.sed用途    …

    Linux干货 2016-08-15
  • 搭建缓存功能的WEB服务集群

    搭建缓存功能的WEB服务集群 实验简介 本文主要介绍双主模型的nginx proxy高可用集群的搭建方式。实验环境: 使用nfs服务器提供页面数据共享 使用单独的mariadb服务器提供关系型数据库 使用两台httpd服务器处理动态的php和静态页面资源 使用两台nginx服务器处理图片资源 使用两台varnish服务器作缓存处理 使用两台nginx作代理 …

    Linux干货 2017-07-15
  • 高级文件系统管理之磁盘配额及RAID的运用

    本章内容 设定文件系统配额 设定和管理软RAID设备 一,概述 配置配额系统: 综述 在内核中执行 以文件系统为单位启用 磁盘配额最小单位是以文件系统为单位启用,就是一个挂载点,而不能以目录为单位 对不同组或者用户的策略不同 根据块或者节点进行限制 执行软限制(soft limit) 硬限制(hard limit) 初始化 分区挂载选项:usrquota、g…

    Linux干货 2016-09-07
  • Linux用户和组管理常用命令

    Linux用户和组管理常用命令 1、useradd:创建用户   useradd [options] LOGIN     -u UID: [UID_MIN, UID_MAX]指定uid,(默认500|1000开头)定义在/etc/login.defs     -o 配合-u 选项, 不检查…

    Linux干货 2017-04-04
  • LVM逻辑卷扩展与缩小

    逻辑卷扩容:扩展逻辑卷前一定要卸载设备和挂载点的关联 第一步:把逻辑卷lv扩展至300M 第二步:检查硬盘,并重置硬盘容量 第三步:重新挂载,查看挂载状态   缩小逻辑卷:对逻辑卷缩容时,丢失数据的风险更大。在执行操作前一定要提前备份好数据。在进行缩减前先把文件系统卸载掉。 第一步:检查文件 第二步:把逻辑卷lv减小到100M 第三步:重新挂载并查…

    2017-12-17

评论列表(1条)

  • renjin
    renjin 2017-04-05 14:43

    内容总结的非常详细尤其在查看内核的inode结构体这块,排版也很不错,继续努力