zoukankan      html  css  js  c++  java
  • Linux如何定位文件在磁盘的物理位置

    我在学习研究Linux内核结构的时候,思考过一个问题:Linux如何定位文件在磁盘的物理位置
    每个文件都有一个inode,inode在内核代码中的数据结构如下:

    1
    struct ext4_inode { 2 __le16 i_mode; /* File mode */ 3 __le16 i_uid; /* Low 16 bits of Owner Uid */ 4 __le32 i_size_lo; /* Size in bytes */ 5 __le32 i_atime; /* Access time */ 6 __le32 i_ctime; /* Inode Change time */ 7 __le32 i_mtime; /* Modification time */ 8 __le32 i_dtime; /* Deletion Time */ 9 __le16 i_gid; /* Low 16 bits of Group Id */ 10 __le16 i_links_count; /* Links count */ 11 __le32 i_blocks_lo; /* Blocks count */ 12 __le32 i_flags; /* File flags */ 13 ...... 14 __le32 i_block[EXT4_N_BLOCKS];/* Pointers to blocks */ 15 __le32 i_generation; /* File version (for NFS) */ 16 __le32 i_file_acl_lo; /* File ACL */ 17 __le32 i_size_high; 18 ...... 19 };

    我们说的“某个文件分成几块、每一块在哪里”,这些在 inode 里面,应该保存在 i_block( i_block[EXT4_N_BLOCKS];/* Pointers to blocks */)里面

    为了解决ext2和ext3文件系统大文件读写性能低下的问题,ext4 做了一定的改变。它引入了一个新的概念,叫作 Extents。我们来解释一下 Extents。比方说,一个文件大小为 128M,如果使用 4k 大小的块进行存储,需要 32k 个块。如果按照 ext2 或者 ext3 那样散着放,数量太大了。但是 Extents 可以用于存放连续的块,也就是说,我们可以把 128M 放在一个 Extents 里面。这样的话,对大文件的读写性能提高了,文件碎片也减少了。
    Exents 如何来存储呢?它其实会保存成一棵树。


    树有一个个的节点,有叶子节点,也有分支节点。每个节点都有一个头,ext4_extent_header 可以用来描述某个节点

    struct ext4_extent_header {
      __le16  eh_magic;  /* probably will support different formats */
      __le16  eh_entries;  /* number of valid entries */
      __le16  eh_max;    /* capacity of store in entries */
      __le16  eh_depth;  /* has tree real underlying blocks? */
      __le32  eh_generation;  /* generation of the tree */
    };

    我们仔细来看里面的内容。eh_entries 表示这个节点里面有多少项。这里的项分两种,如果是叶子节点,这一项会直接指向硬盘上的连续块的地址,我们称为数据节点 ext4_extent;如果是分支节点,这一项会指向下一层的分支节点或者叶子节点,我们称为索引节点 ext4_extent_idx。这两种类型的项的大小都是 12 个 byte。

    /*
     * This is the extent on-disk structure.
     * It's used at the bottom of the tree.
     */
    struct ext4_extent {
      __le32  ee_block;  /* first logical block extent covers */
      __le16  ee_len;    /* number of blocks covered by extent */
      __le16  ee_start_hi;  /* high 16 bits of physical block */
      __le32  ee_start_lo;  /* low 32 bits of physical block */
    };
    /*
     * This is index on-disk structure.
     * It's used at all the levels except the bottom.
     */
    struct ext4_extent_idx {
      __le32  ei_block;  /* index covers logical blocks from 'block' */
      __le32  ei_leaf_lo;  /* pointer to the physical block of the next *
             * level. leaf or next index could be there */
      __le16  ei_leaf_hi;  /* high 16 bits of physical block */
      __u16  ei_unused;
    };

    从上述数据结构中的ee_start_hi/ee_start_lo/ei_leaf_lo可以体现出物理块的指针。

    参考文献:《趣谈Linux操作系统》 by 刘超

    参考链接:https://blog.csdn.net/stringnewname/article/details/73740155

  • 相关阅读:
    javascript数据结构与算法---二叉树(查找最小值、最大值、给定值)
    javascript数据结构与算法---检索算法(二分查找法、计算重复次数)
    javascript数据结构与算法---检索算法(顺序查找、最大最小值、自组织查询)
    javascript数据结构与算法--高级排序算法(快速排序法,希尔排序法)
    ThinkPHP5中Session的使用
    能让你少写1000行代码的20个正则表达式
    composer 安装
    thinkphp5.0 实现图片验证效果且能点击图片刷新图片
    thinkphp5.0 实现单文件上传功能
    thinkphp5.0 输入变量
  • 原文地址:https://www.cnblogs.com/dba-john/p/12097698.html
Copyright © 2011-2022 走看看