Chinaunix首页 | 论坛 | 博客
  • 博客访问: 238611
  • 博文数量: 108
  • 博客积分: 3285
  • 博客等级: 中校
  • 技术积分: 1360
  • 用 户 组: 普通用户
  • 注册时间: 2008-04-28 15:43
文章分类

全部博文(108)

文章存档

2014年(1)

2012年(3)

2011年(28)

2010年(20)

2009年(24)

2008年(32)

我的朋友

分类: LINUX

2010-08-02 15:04:33

一.inode size 定义






inode tabledata area的索引表.
 
Inode分内存中的inode和文件系统中的inode,我们这说的是文件系统中的inode
 
1.linux FS 可以简单分成 inode tabledata area两部份。inode table上有许多的inode, 每个inode分别记录一个档案的属性与这个档案分布在哪些datablock(也就是我们说的指针)
inode两个功能:记录档案属性和指针
 
2.inode table中红色区域即inode size,是128Byte,在liunx系统上通过命令我们可以看到,系统就是这么定义的。
Inode size是指分配给一个inode来记录文档属性的磁盘块的大小。
 
dumpe2fs -h /dev/hda6 | grep node
Inode size:               128
 
3.data ares中紫色的区域block size:这就是我们一般概念上的磁盘块。这块区域是我们用来存放我们的数据的地方。
 
4.还有一个逻辑上的概念:是指FS中每分配2048 bytedata area, 就分配一个inode。但是一个inode就并不是一定就用掉2048 byte, 也不是说files allocation的最小单位是2048 byte, 它仅仅只是代表filesysteminode table/data area分配空间的比例是128/2048 也就是1/16
 
mkfs.ext3 -i 2048 这个-i参数就是我们所说的逻辑概念,它的大小决定inode count的大小,redhat5默认-i最小为可设置为1024.
 
5.网上很多介绍关于inode的文章,把inode size的定义搞错了,他们把-i参数这个值或block size解读为inode size 所以很多文章令人费解。

 
6.inode参数是可以通过mkfs.ext3命令改变的:
 
mkfs.ext3 -i 2048 -b 8192 -f 1024 /dev/sdb2
 
-i 2048更改inode2KB创建一个
-b 8192设置block size的大小为8kB
-f 1024设置fragments的大小为1KB
 
mkfs.ext3 –N 2939495  /dev/sdb2
 
–N 2939495更改inode count
 
 
二.更改一个分区inode参数的完整操作过程:
 
1.卸载硬盘分区:
[root@localhost ~]# umount /dev/hda7
 
2.调整inode参数
[root@localhost ~]# mkfs.ext3 -i 1024 -b 8192 /dev/hda7
 
mke2fs 1.39 (29-May-2006)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
2048256 inodes, 512064 blocks
25603 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=525250560
63 block groups
8240 blocks per group, 8240 fragments per group
32512 inodes per group
Superblock backups stored on blocks:
        8240, 24720, 41200, 57680, 74160, 206000, 222480, 403760
 
Writing inode tables: done                           
Creating journal (8192 blocks): done
Writing superblocks and filesystem accounting information: done
 
This filesystem will be automatically checked every 30 mounts or
180 days, whichever comes first.  Use tune2fs -c or -i to override.
 
3.修改/etc/fstab
修改前
[root@localhost ~]# vi /etc/fstab
 
LABEL=/            /                      ext3    defaults             1 1
LABEL=/boot        /boot                   ext3    defaults             1 2
devpts             /dev/pts             devpts  gid=5,mode=620         0 0
tmpfs              /dev/shm                tmpfs   defaults            0 0
LABEL=/opt         /opt                    ext3    defaults            1 2
proc               /proc                    proc    defaults            0 0
sysfs               /sys                     sysfs   defaults             0 0
LABEL=/usr         /usr                      ext3    defaults           1 2
LABEL=/var         /var                      ext3    defaults            1 2
LABEL=SWAP-hda8   swap                     swap    defaults            0 0
~                                                                            
修改后:
[root@localhost ~]# vi /etc/fstab  
 
LABEL=/            /                      ext3    defaults             1 1
LABEL=/boot        /boot                   ext3    defaults             1 2
devpts             /dev/pts             devpts  gid=5,mode=620         0 0
tmpfs              /dev/shm                tmpfs   defaults            0 0
/dev/hda7         /opt                       ext3    defaults            1 2
proc               /proc                    proc    defaults            0 0
sysfs               /sys                     sysfs   defaults             0 0
LABEL=/usr         /usr                      ext3    defaults           1 2
LABEL=/var         /var                      ext3    defaults            1 2
LABEL=SWAP-hda8   swap                     swap    defaults            0 0
 
4.挂载分区
mount -a
 
5.完成后
 
参数-i 最小值是1024,这个值的大小决定inode count的大小,对应关系:
 
i=2048          Inode count:1025024
i=1024          Inode count:2048256       
 
inode size的值在这是没有变化的,这也可以证明我上面定义的inode size
让我们更加清晰的这几个定义之间的关系。
Inode size
Block size
Inode conut
 
[root@localhost ~]# dumpe2fs -h /dev/hda7
dumpe2fs 1.39 (29-May-2006)
Filesystem volume name:  
Last mounted on:         
Filesystem UUID:          440696ad-80e7-4810-8648-a9efda177ea9
Filesystem magic number:  0xEF53
Filesystem revision #:    1 (dynamic)
Filesystem features:      has_journal resize_inode dir_index filetype needs_recovery sparse_super
Default mount options:    (none)
Filesystem state:         clean
Errors behavior:          Continue
Filesystem OS type:       Linux
Inode count:              2048256
Block count:              1024128
Reserved block count:     51206
Free blocks:              873767
Free inodes:              2048245
First block:              0
Block size:               2048
Fragment size:            2048
Reserved GDT blocks:      512
Blocks per group:         8176
Fragments per group:      8176
Inodes per group:         16256
Inode blocks per group:   1016
Filesystem created:       Fri Jul 11 18:10:33 2008
Last mount time:          Fri Jul 11 18:11:02 2008
Last write time:          Fri Jul 11 18:11:02 2008
Mount count:              1
Maximum mount count:      34
Last checked:             Fri Jul 11 18:10:33 2008
Check interval:           15552000 (6 months)
Next check after:         Wed Jan  7 18:10:33 2009
Reserved blocks uid:      0 (user root)
Reserved blocks gid:      0 (group root)
First inode:              11
Inode size:               128
Journal inode:            8
Default directory hash:   tea
Directory Hash Seed:      ad1b7c40-6978-49e9-82f6-2331c5cac122
Journal backup:           inode blocks
Journal size:             32M
 
注释:由于时间关系:
关于mkfs.ext3 -i 2048 -b 8192 -f 1024 /dev/sdb2
中这个-i参数的定义,我是根据对应关系推断,给了它只是个逻辑概念的定义。
欢迎大虾们有更有力的论据来解释一下,或推翻我的观点。
 
三.读取一个树状目录下的文件/etc/crontab 的流程
 
1.      操作系统根据根目录( / )的相关资料可取得 /etc 这个目录所在的 inode ,并前往读取 /etc 这个目录的所有相关属性;
 
2.      根据 /etc inode 的资料,可以取得 /etc 这个目录底下所有文件的关连数据是放置在哪一个 Block 当中,并前往该 block 读取文件的关连性容;
 
 
3.      由上个步骤的 Block 当中,可以知道 crontab 这个文件的 inode 所在地,并前往该 inode
 
4.      由上个步骤的 inode 当中,可以取得 crontab 这个文件的所有属性,并且可前往由 inode 所指向的 Block 区域,顺利的取得 crontab 的文件内容
 

 
.硬链接
Hard Link 只是在某个目录下新增一个该档案的关连数据而已!
 
1.举个例子来说,我的 /home/vbird/crontab 为一个 hard link 的档案,他连结到 /etc/crontab 这个档案,也就是说,其实 /home/vbird/crontab /etc/crontab 是同一个档案,只是有两个目录( /etc /home/vbird )记录了 crontab 这个档案的关连数据罢了!也就是说,我由 /etc Block 所记录的关连数据可知道 crontab inode 放置在 A 处,而由 /home/vbird 这个目录下的关连数据,contab 同样也指到 A 处的 inode !所以, crontab 这个档案的 inode block 都没有改变,有的只是有两个目录记录了关连数据.
 
2.使用 hard link 设定连结文件时,磁盘的空间与 inode 的数目都不会改变!由上面的说明来看,我们可以知道, hard link 只是在某个目录下的 block 多写入一个关连数据,所以当然不会用掉 inode 与磁盘空间。
 
3.当我们修改其中一个文件的内容时,互为硬链接的文件的内容也会跟着变化。如果我们删除互为硬链接关系的某个文件时,其它的文件并不受影响.
 
4.由于 hard link 是在同一个 partition 上面进行数据关连的建立,所以 hard link 是有限制的:
a. 不能跨 Filesystem.
b. 不能 link 目录。
 
五.软链接
 
1.软链接也叫符号链接,他和硬链接有所不同,软链接文件只是其源文件的一个标记。当我们删除了源文件后,链接文件不能独立存在,虽然仍保留文件名,
但我们却不能查看软链接文件的内容了.
 
2.Symbolic Link Windows 的快捷方式可以给他划上等号,由 Symbolic link 所建立的档案为一个独立的新的档案,所以会占用掉 inode block
 
3.所以可用使用软链接解决某个分区inode conut不足的问题(软链接到另一个inode count足够多的分区)
 
 

inode size 倒底要多大才比较好?有人说如果小档案多,则以 1024 byte 较好。

这样的思考原则好像不是很谨慎。多少才叫『多』呢?我想我们需要一点定量的分析才对。

首先我们来『观察』一下 inode size 大小对我们 filesystem (以下 filesystem 均简称 fs) 及系统的相对性影响:
inode size 越小,inode table 越肥,可用空间越小。
inode size 越小,link 就越长,越会拖慢速度。
inode size 越小,空间利用率就越高。

此外,因为 x86 的 pagesize=4K 的特性,在做 mmap() 及 swap 这类的 virtual memory 动作时,如果 inode size 为 4K 的倍数,将较有效率。

所以,看来 inode size <4K 除了空间利用率较高以外,其馀全都是缺点。
而就一般实际经验来讲,空间利用率的提高,并不足以弥补因 inode table 的肥大而浪费掉的空间......所以一般而言 4K 是一个不错的经验值。

上面最後一点,我们提到了『空间利用率的提高,并不足以弥补因 inode table 的肥大而浪费掉的空间』一个事实;它的确是一个事实,除非您的 fs 是专供 BBS 这种系统而使用。以下是一些参考数据:

表一: inode size 和 inode table 大小关系 inode size(byte) inode table 在该 fs 上所占掉的百分比
1024 12.57% (约 1/8)
2048 6.31% (约 1/4)
4096 3.19%
8192 1.63%
16384 0.84%
32768 0.45%


所以以一个 1GB 的 partition 来造 fs 为例,不同的 inode size 将会立刻 先使用掉的容量 (拿去存 inode table 了) 是:

表二: inode size 与 inode table 大小 (在 1GB fs 中) inode size(byte) inode table 大小
1024 128.7MB
2048 64.6MB
4096 32.6MB
馀类推


试想,一个 1GB 的 fs 就只为了 inode size=1024 而就先用掉了 128MB 的空间, 除非将来我们的小档案真的很多很多,不然是补不回来的。

再来我们举例比较一下 inode size=1024 与 inode size=2048 的 fs:

以一个大小不到 1k 的档存在 inode size=1024 的 fs 中,是比在 inode size=2048 的 fs 中省下了 1k 的空间;但在 1GB 的 fs □, 要有 (128.7-64.6) * 1024 = 65614 个这样多的小档案,才算是『赚到了』; 呵呵.....你的 fs □凑得出这麽多小於 1k 的档吗?

类推 512MB 的 fs □,就要有 32820 个小於 1k 的档才算『赚到了』。

小於 1k 的档,除非你是开 bbs 的,不然在同一个 file system 上 想凑出 10000 个都很难;

我想,不再举个更实际的例子,恐怕还是有人不信。 以下是我以前对某个 1GB fs 中的 file size 统计:

表三: 本人某个旧 1GB fs 中的 file size 统计: 档案大小的□围 该大小□围内的档案个数
不到1K的 6538
1-2K 2053
2-4K 1565
4-8K 1064
8-16K 1011
16-32K 595
32K以上 1112


OK,看起来很明显地,不满 1k 大小的档案个数,已经占了快一半了; 所以直觉上会认为 inode size=1024 比较好?错了......

以下是以 inode size 来看 (fs 为 1GB 大小) 相对浪费空间的大小:

表四: 档案空间相对浪费大小与 inode size 对应表: inode size(byte) 档案空间相对浪费大小加上 inode table 大小
1024 131766KB (即 inode table 大小)
2048 72743KB (inode table size + 1K*6538)
4096 57208KB (inode table size + 3K*6538 + 2K*2053)
8192 81410KB (inode table size + 7K*6538 + 6K*2053.....)
16384 162959KB (馀请类推)
32768 354549KB


所以反而以 inode size=4k 最佳。

上面那些『空间相对浪费大小』计算上有点复杂, 不另说明. (呵呵, 搞不好我的算法是错的......所以不敢公布算法)

以同样的分析来看我的 bbs 的情况, inode size=1024 是最佳的, 因为小於 1k 的档案竟然多达四万个以上.

/usr 分析出来是以 inode size=2048 最佳。

但请注意, 以上只是空间利用率的分析, 不是速度上的分析...
转自:http://blog.chinaunix.net/u/12909/showart_2041325.html
什么是super block
一、预备知识
    1、block
    对于ext2(ext3类似)文件系统来说,硬盘分 区首先被划分为一个个的block,同一个ext2文件系统上的每个block大小都是一样的。但是对于不同的ext2文件系统,block的大小可以有 区别。典型的block大小是1024 bytes或者4096 bytes。这个大小在创建ext2文件系统的时候被决定,它可以由系统管理员指定,也可以由文件系统的创建程序根据硬盘分区的大小,自动选择一个较合理的值。
    一个硬盘分区上的block计数是从0开始的,并且这个计数对于这个硬盘分区来说是全局性质的。

    2、block group和group descriptor
    硬盘分区中所有block被聚在一起分成几个大的block group,其中每个block group中有多少个block是固定的。
    每个block group都相对应一个group descriptor,这些group descriptor被聚在一起放在硬盘分区的开头部分,跟在super block的后面。在每个group descriptor当中有几个重要的block指针,指向block group的inode table、block bitmap和inode bitmap。

    3、inode table、block bitmap和inode bitmap
    以上三个结构记载了其所属block group的许多信息,他们依次被存放在这个block group的开头部分,由该block group所对应的group descriptor中的指针所指向。

二、super block的定义
    super block的中文名称是超级块,它是硬盘分区开头——开头的第一个byte是byte 0,从 byte 1024开始往后的一部分数据。由于 block size最小是 1024 bytes,所以super block可能是在block 1中(此时block 的大小正好是 1024 bytes),也可能是在block 0中。
    超级块中的数据其实就是文件卷的控制信息部分,也可以说它是卷资源表,有关文件卷的大部分信息都保存在这里。例如:硬盘分区中每个block的大小、硬盘 分区上一共有多少个block group、以及每个block group中有多少个inode。(下有详细说明)

三、super block的结构和涵义
struct ext3_super_block {
/*00*/ __u32 s_inodes_count;      /* inodes 计数 */
       __u32 s_blocks_count;      /* blocks 计数 */
       __u32 s_r_blocks_count;    /* 保留的 blocks 计数 */
       __u32 s_free_blocks_count; /* 空闲的 blocks 计数 */
/*10*/ __u32 s_free_inodes_count; /* 空闲的 inodes 计数 */
       __u32 s_first_data_block;  /* 第一个数据 block */
       __u32 s_log_block_size;    /* block 的大小 */
       __s32 s_log_frag_size;     /* 可以忽略 */
/*20*/ __u32 s_blocks_per_group;  /* 每 block group 的 block 数量 */
       __u32 s_frags_per_group;   /* 可以忽略 */
       __u32 s_inodes_per_group;  /* 每 block group 的 inode 数量 */
       __u32 s_mtime;             /* Mount time */
/*30*/ __u32 s_wtime;             /* Write time */
       __u16 s_mnt_count;         /* Mount count */
       __s16 s_max_mnt_count;     /* Maximal mount count */
       __u16 s_magic;             /* Magic 签名 */
       __u16 s_state;             /* File system state */
       __u16 s_errors;            /* Behaviour when detecting errors */
       __u16 s_minor_rev_level;   /* minor revision level */
/*40*/ __u32 s_lastcheck;         /* time of last check */
       __u32 s_checkinterval;     /* max. time between checks */
       __u32 s_creator_os;        /* 可以忽略 */
       __u32 s_rev_level;         /* Revision level */
/*50*/ __u16 s_def_resuid;        /* Default uid for reserved blocks */
       __u16 s_def_resgid;        /* Default gid for reserved blocks */
       __u32 s_first_ino;         /* First non-reserved inode */
       __u16 s_inode_size;        /* size of inode structure */
       __u16 s_block_group_nr;    /* block group # of this superblock */
       __u32 s_feature_compat;    /* compatible feature set */
/*60*/ __u32 s_feature_incompat;  /* incompatible feature set */
       __u32 s_feature_ro_compat; /* readonly-compatible feature set */
/*68*/ __u8  s_uuid[16];          /* 128-bit uuid for volume */
/*78*/ char  s_volume_name[16];   /* volume name */
/*88*/ char  s_last_mounted[64];  /* directory where last mounted */
/*C8*/ __u32 s_algorithm_usage_bitmap; /* 可以忽略 */
       __u8  s_prealloc_blocks;        /* 可以忽略 */
       __u8  s_prealloc_dir_blocks;    /* 可以忽略 */
       __u16 s_padding1;               /* 可以忽略 */
/*D0*/ __u8  s_journal_uuid[16]; /* uuid of journal superblock */
/*E0*/ __u32 s_journal_inum;     /* 日志文件的 inode 号数 */
       __u32 s_journal_dev;      /* 日志文件的设备号 */
       __u32 s_last_orphan;      /* start of list of inodes to delete */
/*EC*/ __u32 s_reserved[197];    /* 可以忽略 */
};

四、super block的几个重要成员

1、Magic 签名
    对于ext2和ext3文件系统来说,这个字段的值应该正好等于0xEF53。如果不等的话,那么这个硬盘分区上肯定不是一个正常的ext2或ext3文件系统。

2、s_log_block_size
    从这个字段,我们可以得出真正的block的大小。我们把真正block的大小记作B,B=1 << s_log_block_size + 10),单位是bytes。举例来说,如果这个字段是0,那么block的大小就是 1024bytes,这正好就是最小的block大小;如果这个字段是2,那么block大小就是4096 bytes。从这里我们就得到了block的大小这一非常重要的数据。

3、s_blocks_count和s_blocks_per_group
    通过这两个成员,我们可以得到硬盘分区上一共有多少个block group,或者说一共有多少个group descriptors
    s_blocks_count记录了硬盘分区上的block的总数,而s_blocks_per_group记录了每个group中有多少个block。 显然,文件系统上的block groups数量,我们把它记作G,G=(s_blocks_count-s_first_data_block-1) /s_blocks_per_group+1。为什么要减去s_first_data_block,因为s_blocks_count是硬盘分区上全部的 block的数量,而在s_first_data_block之前的block是不归block group管的,所以当然要减去。最后为什么又要加一,这是因为尾巴上可能多出来一些block,这些block我们要把它划在一个相对较小的group 里面。

4、s_inodes_per_group
    s_inodes_per_group记载了每个block group中有多少个inode。在从已知的inode号,读取这个inode数据的过程中,s_inodes_per_group起到了至关重要的作用。
    用我们得到的inode号数除以s_inodes_per_group,我们就知道了我们要的这个inode是在哪一个block group里面,这个除法的余数也告诉我们,我们要的这个inode是这个block group里面的第几个inode;然后,我们可以先找到这个block group的group descriptor,从这个descriptor,我们找到这个group的inode table,再从inode table找到我们要的第几个 inode,再以后,我们就可以开始读取inode中的用户数据了。这个公式是这样的:

block_group = (ino - 1) / s_inodes_per_group。这里ino就是我们的inode号数
offset = (ino - 1) % s_inodes_per_group,这个offset就指出了我们要的inode是这个block group里面的第几个inode。

图片转自:
http://blog.chinaunix.net/u2/61187/showart_2035823.html
阅读(661) | 评论(0) | 转发(0) |
0

上一篇:c++ this指针

下一篇:grub详解

给主人留下些什么吧!~~