static errcode_t create_icache(ext2_filsys fs) { errcode_t retval; if (fs->icache) return 0; retval = ext2fs_get_mem(sizeof(struct ext2_inode_cache), &fs->icache); if (retval) return retval; memset(fs->icache, 0, sizeof(struct ext2_inode_cache)); retval = ext2fs_get_mem(fs->blocksize, &fs->icache->buffer); if (retval) { ext2fs_free_mem(&fs->icache); return retval; } fs->icache->buffer_blk = 0; fs->icache->cache_last = -1; fs->icache->cache_size = 4; fs->icache->refcount = 1; retval = ext2fs_get_array(fs->icache->cache_size, sizeof(struct ext2_inode_cache_ent), &fs->icache->cache); if (retval) { ext2fs_free_mem(&fs->icache->buffer); ext2fs_free_mem(&fs->icache); return retval; } ext2fs_flush_icache(fs); return 0; }
errcode_t ext2fs_image_inode_read(ext2_filsys fs, int fd, int flags EXT2FS_ATTR((unused))) { unsigned int group, c, left; char *buf; blk_t blk; ssize_t actual; errcode_t retval; buf = malloc(fs->blocksize * BUF_BLOCKS); if (!buf) return ENOMEM; for (group = 0; group < fs->group_desc_count; group++) { blk = fs->group_desc[(unsigned)group].bg_inode_table; if (!blk) { retval = EXT2_ET_MISSING_INODE_TABLE; goto errout; } left = fs->inode_blocks_per_group; while (left) { c = BUF_BLOCKS; if (c > left) c = left; actual = read(fd, buf, fs->blocksize * c); if (actual == -1) { retval = errno; goto errout; } if (actual != (ssize_t) (fs->blocksize * c)) { retval = EXT2_ET_SHORT_READ; goto errout; } retval = io_channel_write_blk(fs->io, blk, c, buf); if (retval) goto errout; blk += c; left -= c; } } retval = ext2fs_flush_icache(fs); errout: free(buf); return retval; }
errcode_t ext2fs_create_inode_cache(ext2_filsys fs, unsigned int cache_size) { unsigned i; errcode_t retval; if (fs->icache) return 0; retval = ext2fs_get_mem(sizeof(struct ext2_inode_cache), &fs->icache); if (retval) return retval; memset(fs->icache, 0, sizeof(struct ext2_inode_cache)); retval = ext2fs_get_mem(fs->blocksize, &fs->icache->buffer); if (retval) goto errout; fs->icache->buffer_blk = 0; fs->icache->cache_last = -1; fs->icache->cache_size = cache_size; fs->icache->refcount = 1; retval = ext2fs_get_array(fs->icache->cache_size, sizeof(struct ext2_inode_cache_ent), &fs->icache->cache); if (retval) goto errout; for (i = 0; i < fs->icache->cache_size; i++) { retval = ext2fs_get_mem(EXT2_INODE_SIZE(fs->super), &fs->icache->cache[i].inode); if (retval) goto errout; } ext2fs_flush_icache(fs); return 0; errout: ext2fs_free_inode_cache(fs->icache); fs->icache = 0; return retval; }
static void swap_inodes(e2fsck_t ctx) { ext2_filsys fs = ctx->fs; dgrp_t group; unsigned int i; ext2_ino_t ino = 1; char *buf = NULL, *block_buf = NULL; errcode_t retval; struct ext2_inode * inode; e2fsck_use_inode_shortcuts(ctx, 1); retval = ext2fs_get_array(fs->blocksize, fs->inode_blocks_per_group, &buf); if (retval) { com_err("swap_inodes", retval, _("while allocating inode buffer")); ctx->flags |= E2F_FLAG_ABORT; goto errout; } block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 4, "block interate buffer"); for (group = 0; group < fs->group_desc_count; group++) { retval = io_channel_read_blk(fs->io, fs->group_desc[group].bg_inode_table, fs->inode_blocks_per_group, buf); if (retval) { com_err("swap_inodes", retval, _("while reading inode table (group %d)"), group); ctx->flags |= E2F_FLAG_ABORT; goto errout; } inode = (struct ext2_inode *) buf; for (i=0; i < fs->super->s_inodes_per_group; i++, ino++, inode++) { ctx->stashed_ino = ino; ctx->stashed_inode = inode; if (fs->flags & EXT2_FLAG_SWAP_BYTES_READ) ext2fs_swap_inode(fs, inode, inode, 0); /* * Skip deleted files. */ if (inode->i_links_count == 0) continue; if (LINUX_S_ISDIR(inode->i_mode) || ((inode->i_block[EXT2_IND_BLOCK] || inode->i_block[EXT2_DIND_BLOCK] || inode->i_block[EXT2_TIND_BLOCK]) && ext2fs_inode_has_valid_blocks(inode))) swap_inode_blocks(ctx, ino, block_buf, inode); if (ctx->flags & E2F_FLAG_SIGNAL_MASK) goto errout; if (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE) ext2fs_swap_inode(fs, inode, inode, 1); } retval = io_channel_write_blk(fs->io, fs->group_desc[group].bg_inode_table, fs->inode_blocks_per_group, buf); if (retval) { com_err("swap_inodes", retval, _("while writing inode table (group %d)"), group); ctx->flags |= E2F_FLAG_ABORT; goto errout; } } errout: if (buf) ext2fs_free_mem(&buf); if (block_buf) ext2fs_free_mem(&block_buf); e2fsck_use_inode_shortcuts(ctx, 0); ext2fs_flush_icache(fs); }