zoukankan      html  css  js  c++  java
  • [ext4]010 磁盘布局

    在linux系统中,任何一个文件,都有一个inode与其对应,也就是说,在一个文件系统中,一个文件都有唯一的ino来标示他,那么在ext4系统中,ino是如何确定的哪?

    当我们新创建的文件或目录时,会调用ext4_create函数,其调用路径是:ext4_create -> ext4_new_inode。就是在函数ext4_new_inode定义了inode->ino。

    分析函数ext4_new_inode相关部分 

    struct inode *__ext4_new_inode(handle_t *handle, struct inode *dir,

                       umode_t mode, const struct qstr *qstr,

                       __u32 goal, uid_t *owner, int handle_type,

                       unsigned int line_no, int nblocks)

    {

        …

        for (i = 0; i < ngroups; i++, ino = 0) {

            err = -EIO;

     

            gdp = ext4_get_group_desc(sb, group, &group_desc_bh);

            if (!gdp)

                goto out;

     

           /* 1.在加载inode bitmap之前,先检查是否有free indode */

            if (ext4_free_inodes_count(sb, gdp) == 0) {

                if (++group == ngroups)

                    group = 0;

                continue;

            }

            inode_bitmap_bh = ext4_read_inode_bitmap(sb, group);

           /* 2.在inode位图中查找ino+1开始的下一个为0的位 */

            ino = ext4_find_next_zero_bit((unsigned long *)

                              inode_bitmap_bh->b_data,

                              EXT4_INODES_PER_GROUP(sb), ino);

           /* 3.检查free inode是否有效:(1) 大于inode_per_group,(2) 小与first_ino */

            if (ino >= EXT4_INODES_PER_GROUP(sb))

                goto next_group;

            if (group == 0 && (ino+1) < EXT4_FIRST_INO(sb)) {

                ext4_error(sb, "reserved inode found cleared - "

                       "inode=%lu", ino + 1);

                continue;

            }

            …

           /* 4.更新inode bitmap,若更新inode bitmap失败,重新搜索*/

            ext4_lock_group(sb, group);

            ret2 = ext4_test_and_set_bit(ino, inode_bitmap_bh->b_data);

            ext4_unlock_group(sb, group);

            ino++;      /* the inode bitmap is zero-based */

            if (!ret2)

                goto got; /* we grabbed the inode! */

    next_inode:

            if (ino < EXT4_INODES_PER_GROUP(sb))

                goto repeat_in_this_group;

    next_group:

            if (++group == ngroups)

                group = 0;

        }

       /* 5.更新group中的free_inodes_count变量 */

        ext4_free_inodes_set(sb, gdp, ext4_free_inodes_count(sb, gdp) - 1);

        if (S_ISDIR(mode)) {

            ext4_used_dirs_set(sb, gdp, ext4_used_dirs_count(sb, gdp) + 1);

            if (sbi->s_log_groups_per_flex) {

                ext4_group_t f = ext4_flex_group(sbi, group);

     

                atomic_inc(&sbi->s_flex_groups[f].used_dirs);

            }

        }

        if (ext4_has_group_desc_csum(sb)) {

            ext4_inode_bitmap_csum_set(sb, group, gdp, inode_bitmap_bh,

                           EXT4_INODES_PER_GROUP(sb) / 8);

            ext4_group_desc_csum_set(sb, group, gdp);

        }

        ext4_unlock_group(sb, group);

        …

       /* 6.得到inode->ino */

        inode->i_ino = ino + group * EXT4_INODES_PER_GROUP(sb);

        …

    }

    步骤:

    1. 在加载inode bitmap之前,先检查是否有free indode

    2.在inode位图中查找ino+1开始的下一个为0的位

    3.检查free inode是否有效:(1) 大于inode_per_group,(2) 小与first_ino

    4.更新inode bitmap,更新失败重新搜索

    5.更新group中的free_inodes_count变量

    6. 得到inode->ino

     

    因此可以通过inode->ino计算inode所处的group和block:

    Group_id

    =(inode->ino-1)/inodes_per_group

    Inode_blkid

    =first_inode_blk_in_group

    + ((inode->ino-1) % inodes_per_group) / (inodes_per_block);

    Inode_offset

    = first_inode_blk_in_group * blk_size

    + ((inode->ino-1) % inodes_per_group) * inode_size

    其中:

    之所以inode->ino-1原因是ext4系统不存在0号文件索引

    (1) inode->ino:可以通过stat file_name获取;

    (2) inodes_per_group:指每个group中inode的数目,见debugfs;

    (3) first_inode_blk_in_group:指的是inode table的起始block id,可以debugfs获取;

    (4) blk_size:逻辑块大小,可以debugfs获取;

    (5) inode_size:一个inode在磁盘上存放所需的空间大小,可以debugfs获取;

    (6) inodes_per_block:每个block所能存放inode的个数,可以通过blk_size/inode_size获取;

    root@ubuntu:/mnt/ext4# debugfs /dev/sdc

    debugfs 1.42 (29-Nov-2011)

    debugfs:  stats

    Filesystem volume name:   <none>

    Last mounted on:          /mnt/ext4

    Filesystem UUID:          883c6632-e61d-4420-b309-0695f321cf9d

    Filesystem magic number:  0xEF53

    Inode count:              327680

    Fragments per group:      32768

    Inodes per group:        8192

    Inode blocks per group:  512

    First inode:             11

    Inode size:              256

    Required extra isize:     28

     Group  0: block bitmap at 321, inode bitmap at 337,inode table at 353

               24217 free blocks, 8180 free inodes, 2 used directories, 8180 unused inodes

               [Checksum 0x25aa]

     Group  1: block bitmap at 322, inode bitmap at 338, inode table at 865

               31423 free blocks, 8192 free inodes, 0 used directories, 8192 unused inodes

               [Inode not init, Checksum 0x94f1]

     Group  2: block bitmap at 323, inode bitmap at 339, inode table at 1377

               32768 free blocks, 8192 free inodes, 0 used directories, 8192 unused inodes

  • 相关阅读:
    php RSA 简单实现
    redis 常用操作命令
    ajax短轮询+php与服务器交互制作简易即时聊天网站
    PHP解决网站大数据大流量与高并发
    Memcache所有方法及参数详解
    apache 与 nginx 详解
    apache 与 nginx的区别
    Redis,Memcache的区别和具体应用场景
    Memcache Redis 与Mogodb优缺点
    MySQL 存储
  • 原文地址:https://www.cnblogs.com/youngerchina/p/5624485.html
Copyright © 2011-2022 走看看