• linux 2.6.32文件系统的inode


    接上文:

    crash> struct -xo dentry.d_inode ffff8818118002c0
    struct dentry {
      [ffff8818118002d0] struct inode *d_inode;
    }
    crash> struct  dentry.d_inode ffff8818118002c0
      d_inode = 0xffff880c11402cf8
    crash> struct inode 0xffff880c11402cf8
    struct inode {
      i_hash = {
        next = 0x0,
        pprev = 0xffffc900093d9118
      },
      i_list = {
        next = 0xffff880c11401ae8,
        prev = 0xffff880c11b9bda8
      },
      i_sb_list = {
        next = 0xffff880c1188ccd0,------------inode的i_sb_list串起来,形成一个双向循环链表,其链表头可以认为是该inode对应的super_block的s_inodes成员的地址
        prev = 0xffff880c11402a98
      },
      i_dentry = {
        next = 0xffff881811800330,
        prev = 0xffff881811800330
      },
      i_ino = 1,
      i_count = {
        counter = 1
      },
      i_nlink = 2,
      i_uid = 0,
      i_gid = 0,
      i_rdev = 0,
      i_version = 0,
      i_size = 0,
      i_atime = {
        tv_sec = 1533672031,
        tv_nsec = 74999849
      },
      i_mtime = {
        tv_sec = 1533672031,
        tv_nsec = 74999849
      },
      i_ctime = {
        tv_sec = 1533672031,
        tv_nsec = 74999849
      },
      i_blocks = 0,
      i_blkbits = 10,
      i_bytes = 0,
      i_mode = 16749,
      i_lock = {
        raw_lock = {
          slock = 877474893
        }
      },
      i_mutex = {
        count = {
          counter = 1
        },
        wait_lock = {
          raw_lock = {
            slock = 2655755851
          }
        },
        wait_list = {
          next = 0xffff880c11402db8,
          prev = 0xffff880c11402db8
        },
        owner = 0x0
      },
      i_alloc_sem = {
        count = 0,
        wait_lock = {
          raw_lock = {
            slock = 0
          }
        },
        wait_list = {
          next = 0xffff880c11402de0,
          prev = 0xffff880c11402de0
        }
      },
      i_op = 0xffffffff8161fb40 <proc_reg_file_ops+192>,
      i_fop = 0xffffffff8161fc00 <proc_root_inode_operations+160>,
      i_sb = 0xffff880c1188cc00,
      i_flock = 0x0,
      i_mapping = 0xffff880c11402e18,
      i_data = {
        host = 0xffff880c11402cf8,-----------------------address_space的host是指向inode,而inode的i_data是指向对应的address_space,两者就串起来了。
        page_tree = {--------------------radix树,主要管理page的
          height = 0,
          gfp_mask = 32,
          rnode = 0x0
        },
        tree_lock = {-----------------树锁
          raw_lock = {
            slock = 0
          }
        },
        i_mmap_writable = 0,
        i_mmap = {
          prio_tree_node = 0x0,
          index_bits = 1,
          raw = 1
        },
        i_mmap_nonlinear = {
          next = 0xffff880c11402e48,
          prev = 0xffff880c11402e48
        },
        i_mmap_lock = {
          raw_lock = {
            slock = 0
          }
        },
        truncate_count = 0,
        nrpages = 0,
        writeback_index = 0,
        a_ops = 0xffffffff81fcfde0 <empty_aops.36032>,
        flags = 131290,
        backing_dev_info = 0xffffffff81abfb80 <default_backing_dev_info>,
        private_lock = {
          raw_lock = {
            slock = 0
          }
        },
        private_list = {
          next = 0xffff880c11402e90,
          prev = 0xffff880c11402e90
        },
        assoc_mapping = 0x0
      },
      i_dquot = {0x0, 0x0},
      i_devices = {
        next = 0xffff880c11402eb8,
        prev = 0xffff880c11402eb8
      },
      {---------------------------这个是inode的类型描述,一个inode要么是字符设备,要么是块设备,要么是pipe设备,要么都不是
        i_pipe = 0x0,
        i_bdev = 0x0,
        i_cdev = 0x0
      },
      i_generation = 0,
      i_fsnotify_mask = 0,
      i_fsnotify_mark_entries = {
        first = 0x0
      },
      inotify_watches = {
        next = 0xffff880c11402ee0,
        prev = 0xffff880c11402ee0
      },
      inotify_mutex = {
        count = {
          counter = 1
        },
        wait_lock = {
          raw_lock = {
            slock = 0
          }
        },
        wait_list = {
          next = 0xffff880c11402ef8,
          prev = 0xffff880c11402ef8
        },
        owner = 0x0
      },
      i_state = 0,
      dirtied_when = 0,
      i_flags = 0,
      i_writecount = {
        counter = 0
      },
      i_security = 0x0,
      i_acl = 0xffffffffffffffff,
      i_default_acl = 0xffffffffffffffff,
      i_private = 0x0
    }

    每个inode对于所属的文件系统来说,是唯一的。比如有两个硬盘,都是xfs分别挂载到两个挂载点,那么对应的这个文件系统里,inode的内存地址也是唯一的,但是可以和其他文件系统中的i_ino成员可能会相同。

     inode和对应的super_block 怎么对应起来呢,inode的i_sb_list串起来,形成一个双向循环链表,其链表头可以认为是该inode对应的super_block的s_inodes成员的地址,我们验证一下:

    crash> struct inode 0xffff880c11402cf8
    struct inode {
      i_hash = {
        next = 0x0,
        pprev = 0xffffc900093d9118
      },
      i_list = {
        next = 0xffff880c11401ae8,
        prev = 0xffff880c11b9bda8
      },
      i_sb_list = {
        next = 0xffff880c1188ccd0,--------对应的地址是ccd0
        prev = 0xffff880c11402a98
      },

    可以看到,该inode对应的i_sb_list是ccd0,而该inode归属的super_block是0xffff880c1188cc00,

    crash> struct -xo super_block.s_inodes
    struct super_block {
       [0xd0] struct list_head s_inodes;
    }
    crash> px 0xffff880c1188cc00+0xd0
    $2 = 0xffff880c1188ccd0

    两者对得上,是不是很面熟,前面我们看dentry的时候,所有子dentry的d_child成员就形成双向循环链表,嵌入到父dentry的d_subdirs中,内核中类似手法很多。

    前面文章描述过dentry,但是看inode中,有一个dentry链表,这个是为啥?难道两者不是一一对应关系么?

    事实上,两者真不是一一对应,一个inode可能有多个dentry:

    crash> struct inode 0xffff880c11402cf8
    struct inode {
      i_hash = {
        next = 0x0,
        pprev = 0xffffc900093d9118
      },
      i_list = {
        next = 0xffff880c11401ae8,
        prev = 0xffff880c11b9bda8
      },
      i_sb_list = {
        next = 0xffff880c1188ccd0,
        prev = 0xffff880c11402a98
      },
      i_dentry = {
        next = 0xffff881811800330,
        prev = 0xffff881811800330
      },
    
    crash> struct -xo dentry.d_alias
    struct dentry {
      [0x70] struct list_head d_alias;
    }
    crash> px 0xffff881811800330-0x70
    $3 = 0xffff8818118002c0
    
    crash> struct dentry 0xffff8818118002c0
    struct dentry {
      d_count = {
        counter = 725
      },
      d_flags = 16,
      d_lock = {
        raw_lock = {
          slock = 797912975
        }
      },
      d_mounted = 0,
      d_inode = 0xffff880c11402cf8,
      d_hash = {
        next = 0x0,
        pprev = 0x0
      },
      d_parent = 0xffff8818118002c0,
      d_name = {
        hash = 0,
        len = 1,
        name = 0xffff881811800360 "/"
      },

    对于本例中的根目录来说,一个inode只有一个dentry,但是对于硬链接来说,则肯定有多个dentry,所以inode和dentry是1对多的关系。

    又同时可以看到,dentry中的d_alias串起来一个双向循环链表,而这个双向循环链表遍历的时候,可以认为这些dentry对应的inode的 i_dentry 是这个双向循环链表的头。

    其实inode还有个很关键常用的成员,就是i_list,根据不同的inode状态,会放入不同的list,但是由于这个成员在3.10内核中已经被i_lru和i_wb_list 来代替了,这个两个成员都会嵌入到

    该inode所属的superblock的s_inode_lru 以及i_wb_list中。所以就不放在本文中分析了。

    最后,通过files -d dentry的地址 ,可以显示对应的inode和superblock,-p的话,还可以展示在pagecache中的page:

    crash> files -d ffff8857a2440b40
         DENTRY           INODE           SUPERBLK     TYPE PATH
    ffff8857a2440b40 ffff88535be752b0 ffff88013d3a8800 REG  /mnt/ZMSS/ZMSSThreadMonitor.log
    crash> files -p ffff88535be752b0
         INODE        NRPAGES
    ffff88535be752b0        1
    
          PAGE         PHYSICAL      MAPPING       INDEX CNT FLAGS
    ffffea0121bbd840 486ef61000 ffff88535be75400        0  1 6fffff000c0038 uptodate,dirty,lru,reclaim,swapbacked
    水平有限,如果有错误,请帮忙提醒我。如果您觉得本文对您有帮助,可以点击下面的 推荐 支持一下我。版权所有,需要转发请带上本文源地址,博客一直在更新,欢迎 关注 。
  • 相关阅读:
    Django
    MySql、Mongodb和Redis的区别
    数据库读写分离之配置Django实现数据库读写分离
    MySQL数据库优化
    01--web框架本质 wsgiref模块介绍
    CI上传图片 The filetype you are attempting to upload is not allowed.
    微信小程序 swiper和video的autoplay设置冲突问题
    关于手机端页面使用border-radius:50%不能使用div变为圆形问题
    微信小程序支付获取params的时候使用JsApiPay失败
    小程序使用笔记
  • 原文地址:https://www.cnblogs.com/10087622blog/p/9527970.html
Copyright © 2020-2023  润新知