// read real fs inode 128++ int intern_read_inode_full(ext2_ino_t ino, struct ext2_inode * inode, int bufsize) { int retval; retval = ext2fs_read_inode_full(current_fs, ino, inode, bufsize); if (retval) { fprintf(stderr,"Error %d while reading inode %u\n",retval, ino); return 1; } return 0; }
int debugfs_read_inode_full(ext2_ino_t ino, struct ext2_inode * inode, const char *cmd, int bufsize) { int retval; retval = ext2fs_read_inode_full(current_fs, ino, inode, bufsize); if (retval) { com_err(cmd, retval, "while reading inode %u", ino); return 1; } return 0; }
void e2fsck_read_inode_full(e2fsck_t ctx, unsigned long ino, struct ext2_inode *inode, int bufsize, const char *proc) { errcode_t retval; retval = ext2fs_read_inode_full(ctx->fs, ino, inode, bufsize); if (retval) { com_err("ext2fs_read_inode_full", retval, _("while reading inode %lu in %s"), ino, proc); fatal_error(ctx, 0); } }
errcode_t ext2fs_write_inode_full(ext2_filsys fs, ext2_ino_t ino, struct ext2_inode * inode, int bufsize) { blk64_t block_nr; unsigned long group, block, offset; errcode_t retval = 0; struct ext2_inode_large *w_inode; char *ptr; unsigned i; int clen; int length = EXT2_INODE_SIZE(fs->super); EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); /* Check to see if user provided an override function */ if (fs->write_inode) { retval = (fs->write_inode)(fs, ino, inode); if (retval != EXT2_ET_CALLBACK_NOTHANDLED) return retval; } if ((ino == 0) || (ino > fs->super->s_inodes_count)) return EXT2_ET_BAD_INODE_NUM; /* Prepare our shadow buffer for read/modify/byteswap/write */ retval = ext2fs_get_mem(length, &w_inode); if (retval) return retval; if (bufsize < length) { int old_flags = fs->flags; fs->flags |= EXT2_FLAG_IGNORE_CSUM_ERRORS; retval = ext2fs_read_inode_full(fs, ino, (struct ext2_inode *)w_inode, length); fs->flags = (old_flags & EXT2_FLAG_IGNORE_CSUM_ERRORS) | (fs->flags & ~EXT2_FLAG_IGNORE_CSUM_ERRORS); if (retval) goto errout; } /* Check to see if the inode cache needs to be updated */ if (fs->icache) { for (i=0; i < fs->icache->cache_size; i++) { if (fs->icache->cache[i].ino == ino) { memcpy(fs->icache->cache[i].inode, inode, (bufsize > length) ? length : bufsize); break; } } } else { retval = ext2fs_create_inode_cache(fs, 4); if (retval) goto errout; } memcpy(w_inode, inode, (bufsize > length) ? length : bufsize); if (!(fs->flags & EXT2_FLAG_RW)) { retval = EXT2_ET_RO_FILSYS; goto errout; } #ifdef WORDS_BIGENDIAN ext2fs_swap_inode_full(fs, w_inode, w_inode, 1, length); #endif retval = ext2fs_inode_csum_set(fs, ino, w_inode); if (retval) goto errout; group = (ino - 1) / EXT2_INODES_PER_GROUP(fs->super); offset = ((ino - 1) % EXT2_INODES_PER_GROUP(fs->super)) * EXT2_INODE_SIZE(fs->super); block = offset >> EXT2_BLOCK_SIZE_BITS(fs->super); if (!ext2fs_inode_table_loc(fs, (unsigned) group)) { retval = EXT2_ET_MISSING_INODE_TABLE; goto errout; } block_nr = ext2fs_inode_table_loc(fs, (unsigned) group) + block; offset &= (EXT2_BLOCK_SIZE(fs->super) - 1); ptr = (char *) w_inode; while (length) { clen = length; if ((offset + length) > fs->blocksize) clen = fs->blocksize - offset; if (fs->icache->buffer_blk != block_nr) { retval = io_channel_read_blk64(fs->io, block_nr, 1, fs->icache->buffer); if (retval) goto errout; fs->icache->buffer_blk = block_nr; } memcpy((char *) fs->icache->buffer + (unsigned) offset, ptr, clen); retval = io_channel_write_blk64(fs->io, block_nr, 1, fs->icache->buffer); if (retval) goto errout; offset = 0; ptr += clen; length -= clen; block_nr++; } fs->flags |= EXT2_FLAG_CHANGED; errout: ext2fs_free_mem(&w_inode); return retval; }
errcode_t ext2fs_read_inode(ext2_filsys fs, ext2_ino_t ino, struct ext2_inode * inode) { return ext2fs_read_inode_full(fs, ino, inode, sizeof(struct ext2_inode)); }
extern errcode_t ext2fs_extent_open(ext2_filsys fs, ext2_ino_t ino, ext2_extent_handle_t *ret_handle) { struct ext2_extent_handle *handle; errcode_t retval; int isize = EXT2_INODE_SIZE(fs->super); int i; struct ext3_extent_header *eh; EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); if ((ino == 0) || (ino > fs->super->s_inodes_count)) return EXT2_ET_BAD_INODE_NUM; retval = ext2fs_get_mem(sizeof(struct ext2_extent_handle), &handle); if (retval) return retval; memset(handle, 0, sizeof(struct ext2_extent_handle)); retval = ext2fs_get_mem(isize, &handle->inode); if (retval) goto errout; handle->ino = ino; handle->fs = fs; retval = ext2fs_read_inode_full(fs, ino, handle->inode, isize); if (retval) goto errout; eh = (struct ext3_extent_header *) &handle->inode->i_block[0]; for (i=0; i < EXT2_N_BLOCKS; i++) if (handle->inode->i_block[i]) break; if (i >= EXT2_N_BLOCKS) { eh->eh_magic = ext2fs_cpu_to_le16(EXT3_EXT_MAGIC); eh->eh_depth = 0; eh->eh_entries = 0; i = (sizeof(handle->inode->i_block) - sizeof(*eh)) / sizeof(struct ext3_extent); eh->eh_max = ext2fs_cpu_to_le16(i); handle->inode->i_flags |= EXT4_EXTENTS_FL; } if (!(handle->inode->i_flags & EXT4_EXTENTS_FL)) { retval = EXT2_ET_INODE_NOT_EXTENT; goto errout; } retval = ext2fs_extent_header_verify(eh, sizeof(handle->inode->i_block)); if (retval) goto errout; handle->max_depth = ext2fs_le16_to_cpu(eh->eh_depth); handle->type = ext2fs_le16_to_cpu(eh->eh_magic); retval = ext2fs_get_mem(((handle->max_depth+1) * sizeof(struct extent_path)), &handle->path); memset(handle->path, 0, (handle->max_depth+1) * sizeof(struct extent_path)); handle->path[0].buf = (char *) handle->inode->i_block; handle->path[0].left = handle->path[0].entries = ext2fs_le16_to_cpu(eh->eh_entries); handle->path[0].max_entries = ext2fs_le16_to_cpu(eh->eh_max); handle->path[0].curr = 0; handle->path[0].end_blk = ((((__u64) handle->inode->i_size_high << 32) + handle->inode->i_size + (fs->blocksize - 1)) >> EXT2_BLOCK_SIZE_BITS(fs->super)); handle->path[0].visit_num = 1; handle->level = 0; handle->magic = EXT2_ET_MAGIC_EXTENT_HANDLE; *ret_handle = handle; return 0; errout: ext2fs_extent_free(handle); return retval; }
int main(int argc, char *argv[]) { ext2_ino_t inode; struct ext2_inode *inode_buf; struct ext2_inode_large *large_inode; int retval; char *fs; if (argc != 2) { fprintf(stderr, "Usage: crtime <file>\n"); return -1; } retval = check_permissions(argv[1]); if (retval) { return retval; } retval = get_inode(argv[1], &inode); if (retval) { return retval; } retval = get_fs_name(argv[1], &fs); if (retval) { return retval; } retval = open_filesystem(fs); if (retval) { free(fs); return retval; } inode_buf = (struct ext2_inode *)malloc(EXT2_INODE_SIZE(current_fs->super)); if (!inode_buf) { free(fs); fprintf(stderr, "Failed to allocate memory\n"); return -1; } retval = ext2fs_read_inode_full(current_fs, inode, inode_buf, EXT2_INODE_SIZE(current_fs->super)); if (retval) { fprintf(stderr, "Failed to read inode\n"); free(fs); free(inode_buf); return retval; } if (EXT2_INODE_SIZE(current_fs->super) <= EXT2_GOOD_OLD_INODE_SIZE) { free(fs); free(inode_buf); fprintf(stderr, "Create time unavailable"); return -1; } large_inode = (struct ext2_inode_large *)inode_buf; if (large_inode->i_extra_isize < 24) { free(fs); free(inode_buf); fprintf(stderr, "Create time unavailable"); return -1; } printf("%d\n", large_inode->i_crtime); free(fs); free(inode_buf); ext2fs_close(current_fs); return 0; }