Ext2文件系统 inode

ext2文件系统读取 索引节点信息代码:

void ext2_read_inode (struct inode * inode)
{
         struct buffer_head * bh;
         struct ext2_inode * raw_inode;
         unsigned long block_group;
         unsigned long group_desc;
         unsigned long desc;
         unsigned long block;
         unsigned long offset;
        struct ext2_group_desc * gdp;
 
         if ((inode->i_ino != EXT2_ROOT_INO 
         && inode->i_ino != EXT2_ACL_IDX_INO 
         && inode->i_ino != EXT2_ACL_DATA_INO && inode->i_ino < EXT2_FIRST_INO(inode->i_sb))
         || inode->i_ino > le32_to_cpu(inode->i_sb->u.ext2_sb.s_es->s_inodes_count))   
        {
                ext2_error (inode->i_sb, "ext2_read_inode",
                             "bad inode number: %lu", inode->i_ino);
                 goto bad_inode;
        }
         //块组号        
         block_group = (inode->i_ino - 1) / EXT2_INODES_PER_GROUP(inode->i_sb);
         if (block_group >= inode->i_sb->u.ext2_sb.s_groups_count) {
                ext2_error (inode->i_sb, "ext2_read_inode",
                             "group >= groups count");
                 goto bad_inode;
        }
          //对于该块组描述符所在的逻辑块号
         group_desc = block_group >> EXT2_DESC_PER_BLOCK_BITS(inode->i_sb);
         //该inode对应的块组描述符在该逻辑块中的偏移
         desc = block_group & (EXT2_DESC_PER_BLOCK(inode->i_sb) - 1);
         bh = inode->i_sb->u.ext2_sb.s_group_desc[group_desc];
         if (!bh) {
                 ext2_error (inode->i_sb, "ext2_read_inode",
                             "Descriptor not loaded");
                goto bad_inode;
         }
 
         gdp = (struct ext2_group_desc *) bh->b_data;
         /*
          * Figure out the offset within the block group inode table
         */
        //该inode在该块组中,相对于inode节点起始地址的偏移
        offset = ((inode->i_ino - 1) % EXT2_INODES_PER_GROUP(inode->i_sb)) *
                 EXT2_INODE_SIZE(inode->i_sb);
        /*块组描述符.bg_inode_table: Block number of first inode table block,即inode节点表的起始逻辑块号,所以off需要除以块大小,1K
         */
         block = le32_to_cpu(gdp[desc].bg_inode_table) +
                (offset >> EXT2_BLOCK_SIZE_BITS(inode->i_sb));
        if (!(bh = sb_bread(inode->i_sb, block))) {
                ext2_error (inode->i_sb, "ext2_read_inode",
                             "unable to read inode block - "
                             "inode=%lu, block=%lu", inode->i_ino, block);
                 goto bad_inode;
         }
       /*由于sb_bread已经把inode所在的逻辑块block读入到bh中,所以offset应是相对于该块起始地址的偏移,即offset如下
        */
        offset &= (EXT2_BLOCK_SIZE(inode->i_sb) - 1);
         raw_inode = (struct ext2_inode *) (bh->b_data + offset);
 
        inode->i_mode = le16_to_cpu(raw_inode->i_mode);
        inode->i_uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low);
        inode->i_gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low);
        if(!(test_opt (inode->i_sb, NO_UID32))) {
               inode->i_uid |= le16_to_cpu(raw_inode->i_uid_high) << 16;
               inode->i_gid |= le16_to_cpu(raw_inode->i_gid_high) << 16;
        }
        inode->i_nlink = le16_to_cpu(raw_inode->i_links_count);
        inode->i_size = le32_to_cpu(raw_inode->i_size);
        inode->i_atime = le32_to_cpu(raw_inode->i_atime);
        inode->i_ctime = le32_to_cpu(raw_inode->i_ctime);
        inode->i_mtime = le32_to_cpu(raw_inode->i_mtime);
        inode->u.ext2_i.i_dtime = le32_to_cpu(raw_inode->i_dtime);
        /* We now have enough fields to check if the inode was active or not.
         * This is needed because nfsd might try to access dead inodes
         * the test is that same one that e2fsck uses
         * NeilBrown 1999oct15
         */
         if (inode->i_nlink == 0 && (inode->i_mode == 0 || inode->u.ext2_i.i_dtime)) {
                /* this inode is deleted */
                 brelse (bh);
                 goto bad_inode;
         }
         inode->i_blksize = PAGE_SIZE;   /* This is the optimal IO size (for stat), not the fs block size */
         inode->i_blocks = le32_to_cpu(raw_inode->i_blocks);
         inode->i_version = ++event;
         inode->u.ext2_i.i_flags = le32_to_cpu(raw_inode->i_flags);
         inode->u.ext2_i.i_faddr = le32_to_cpu(raw_inode->i_faddr);
         inode->u.ext2_i.i_frag_no = raw_inode->i_frag;
         inode->u.ext2_i.i_frag_size = raw_inode->i_fsize;
         inode->u.ext2_i.i_file_acl = le32_to_cpu(raw_inode->i_file_acl);
         if (S_ISREG(inode->i_mode))
          inode->i_size |= ((__u64)le32_to_cpu(raw_inode->i_size_high)) << 32;
         else
               inode->u.ext2_i.i_dir_acl = le32_to_cpu(raw_inode->i_dir_acl);
         inode->i_generation = le32_to_cpu(raw_inode->i_generation);
         inode->u.ext2_i.i_prealloc_count = 0;
         inode->u.ext2_i.i_block_group = block_group;
 
         /*
          * NOTE! The in-memory inode i_data array is in little-endian order
          * even on big-endian machines: we do NOT byteswap the block numbers!
          */
        for (block = 0; block < EXT2_N_BLOCKS; block++)
                inode->u.ext2_i.i_data[block] = raw_inode->i_block[block];
 
         if (inode->i_ino == EXT2_ACL_IDX_INO ||
            inode->i_ino == EXT2_ACL_DATA_INO)
                 /* Nothing to do */ ;
         else if (S_ISREG(inode->i_mode)) {
                inode->i_op = &ext2_file_inode_operations;
                 inode->i_fop = &ext2_file_operations;
                 inode->i_mapping->a_ops = &ext2_aops;
         } else if (S_ISDIR(inode->i_mode)) {
                 inode->i_op = &ext2_dir_inode_operations;
                 inode->i_fop = &ext2_dir_operations;
                 inode->i_mapping->a_ops = &ext2_aops;
        } else if (S_ISLNK(inode->i_mode)) {
                 if (!inode->i_blocks)
                         inode->i_op = &ext2_fast_symlink_inode_operations;
                else {
                        inode->i_op = &page_symlink_inode_operations;
                         inode->i_mapping->a_ops = &ext2_aops;
                }
        } else
                 init_special_inode(inode, inode->i_mode,
                                    le32_to_cpu(raw_inode->i_block[0]));
         brelse (bh);
         inode->i_attr_flags = 0;
         if (inode->u.ext2_i.i_flags & EXT2_SYNC_FL) {
                 inode->i_attr_flags |= ATTR_FLAG_SYNCRONOUS;
                 inode->i_flags |= S_SYNC;
         }
         if (inode->u.ext2_i.i_flags & EXT2_APPEND_FL) {
                 inode->i_attr_flags |= ATTR_FLAG_APPEND;
                inode->i_flags |= S_APPEND;
         }
         if (inode->u.ext2_i.i_flags & EXT2_IMMUTABLE_FL) {
                 inode->i_attr_flags |= ATTR_FLAG_IMMUTABLE;
                inode->i_flags |= S_IMMUTABLE;
         }
         if (inode->u.ext2_i.i_flags & EXT2_NOATIME_FL) {
                inode->i_attr_flags |= ATTR_FLAG_NOATIME;
                inode->i_flags |= S_NOATIME;
         }
         return;
        
bad_inode:
         make_bad_inode(inode);
         return;
}

 

inode到硬盘的过程:

06094419_4NEt.gif

转载于:https://my.oschina.net/manmao/blog/598147

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值