EXT4文件系统之extents的ext4_get_block()

来源:互联网 发布:杭州程序员工资 编辑:程序博客网 时间:2024/06/06 00:41
static int ext4_ext_insert_index(handle_t *handle, struct inode *inode, struct ext4_ext_path *curp, int logical, ext4_fsblk_t ptr){  新的数据块插入当前的路径深度里。}static int ext4_ext_split(handle_t *handle, struct inode *inode,  unsigned int flags,  struct ext4_ext_path *path,  struct ext4_extent *newext, int at)//at是当前的深度,depth – at得出到叶子节点还差的深度,需要用新的块,建立新的索引节点和叶子节点。{1.先建立新的块为当前路径下的新叶子块,将当前路径下的旧的叶子节点信息复制到新块中;2.建立中间的索引路径节点3.路径建立好后,新块插入新的路径中}static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode, unsigned int flags, struct ext4_extent *newext){分配一个新块,将原来在INODE中的i_data数据复制到新块中,同时更新INDOE中i_data的数据,用后移的数据填充它。}static int ext4_ext_create_new_leaf(handle_t *handle, struct inode *inode,    unsigned int flags,    struct ext4_ext_path *path,    struct ext4_extent *newext){    curp = path + depth;while (i > 0 && !EXT_HAS_FREE_INDEX(curp)) {  //查找是否有空闲索引i--;curp--;}1.如果有空闲索引,分裂。err = ext4_ext_split(handle, inode, flags, path, newext, i);path = ext4_ext_find_extent(inode,   //重新建立路径,返回后有用    (ext4_lblk_t)le32_to_cpu(newext->ee_block),    path);  2.如果没有空闲索引,整棵树增加一个深度err = ext4_ext_grow_indepth(handle, inode, flags, newext);path = ext4_ext_find_extent(inode,//重新建立路径,返回后有用    (ext4_lblk_t)le32_to_cpu(newext->ee_block),    path);}int ext4_ext_insert_extent(handle_t *handle, struct inode *inode,struct ext4_ext_path *path,struct ext4_extent *newext, int flag){    depth = ext_depth(inode);ex = path[depth].p_ext;        //找到叶子节点    depth = ext_depth(inode);eh = path[depth].p_hdr;if (le16_to_cpu(eh->eh_entries) < le16_to_cpu(eh->eh_max))  //叶子节点还有空间goto has_space;                                  //跳转到有空间的处理 如果没有空间就创建新的节点  err = ext4_ext_create_new_leaf(handle, inode, flags, path, newext); has_space:     新节点插入,然后看能否合并  }int ext4_ext_map_blocks(handle_t *handle, struct inode *inode, struct ext4_map_blocks *map, int flags){1.逻辑块在节点的cache中,查找到已经分配的块,返回;2.2.1 path = ext4_ext_find_extent(inode, map->m_lblk, NULL); //查找完整的路径链depth = ext_depth(inode);           ex = path[depth].p_ext;  //叶子节点如果叶子节点存在,目标逻辑块在叶子节点范围内,则查找到块,返回;2.2如果叶子节点不存在或者上文的节点不符合要求,则分配新块;newex.ee_block = cpu_to_le32(map->m_lblk);newex.ee_len = cpu_to_le16(map->m_len);err = ext4_ext_check_overlap(sbi, inode, &newex, path); //检查是否有重叠if (err)allocated = ext4_ext_get_actual_len(&newex);elseallocated = map->m_len;        2.3 ar.inode = inode;        ar.goal = ext4_ext_find_goal(inode, path, map->m_lblk);        ar.logical = map->m_lblk;2.3newblock = ext4_mb_new_blocks(handle, &ar, &err); //分配新块        2.4  ext4_ext_store_pblock(&newex, newblock + offset);        newex.ee_len = cpu_to_le16(ar.len);err = ext4_ext_insert_extent(handle, inode, path, &newex, flags);//新块插入路径                        newblock = ext4_ext_pblock(&newex);        allocated = ext4_ext_get_actual_len(&newex);        if (allocated > map->m_len)    allocated = map->m_len;}int ext4_map_blocks(handle_t *handle, struct inode *inode,  struct ext4_map_blocks *map, int flags){    if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) {retval = ext4_ext_map_blocks(handle, inode, map, flags &     EXT4_GET_BLOCKS_KEEP_SIZE); //使用extents} else {retval = ext4_ind_map_blocks(handle, inode, map, flags &     EXT4_GET_BLOCKS_KEEP_SIZE);//使用间接块}}static int _ext4_get_block(struct inode *inode, sector_t iblock,   struct buffer_head *bh, int flags){map.m_lblk = iblock;                       //申请块的逻辑块号map.m_len = bh->b_size >> inode->i_blkbits;   //申请块的块数    if (flags && !handle) {//直接IO传输,暂时不讨论/* Direct IO write... */if (map.m_len > DIO_MAX_BLOCKS)map.m_len = DIO_MAX_BLOCKS;dio_credits = ext4_chunk_trans_blocks(inode, map.m_len);handle = ext4_journal_start(inode, dio_credits);if (IS_ERR(handle)) {ret = PTR_ERR(handle);return ret;}started = 1;}ret = ext4_map_blocks(handle, inode, &map, flags);if (ret > 0) {map_bh(bh, inode->i_sb, map.m_pblk);//申请后返回的物理块号bh->b_state = (bh->b_state & ~EXT4_MAP_FLAGS) | map.m_flags;bh->b_size = inode->i_sb->s_blocksize * map.m_len;//申请后返回的字节数ret = 0;}}int ext4_get_block(struct inode *inode, sector_t iblock,struct buffer_head *bh, int create){return _ext4_get_block(inode, iblock, bh,       create ? EXT4_GET_BLOCKS_CREATE : 0);}

原创粉丝点击