From bad5ce5ca531b65116edfc9c79abc65b1c6ab9ed Mon Sep 17 00:00:00 2001 From: Wang Shilong Date: Wed, 24 Feb 2016 19:33:13 +0800 Subject: [PATCH] LU-4017 e2fsprogs: always read full inode structure Project quota need use some extra field of inode for computing quota accounting, this patch tries to use ext2fs_get_next_inode_full() everywhere to read full inode into memeory, also fixes a bug that only copy small inode in the function. Always use ext2fs_read_inode_full() internally reading and storing an inode instead of ext2fs_read_inode(). At least for the tools in e2fsprogs they will always have the full inode data, though we can't control other e2fsprogs users. This should not hurt performance, since the full inode block is always read from disk anyway, and in some cases it may improve performance because it won't do the extra reads from disk Signed-off-by: Wang Shilong Change-Id: If545e37587701ac60933e9b09162429d874254ef Reviewed-on: http://review.whamcloud.com/18569 Reviewed-by: Andreas Dilger Tested-by: Jenkins Tested-by: Maloo --- debugfs/icheck.c | 26 ++++++++++++++++++-------- debugfs/lsdel.c | 26 +++++++++++++++++--------- debugfs/ncheck.c | 20 ++++++++++++++------ e2fsck/e2fsck.h | 2 +- e2fsck/iscan.c | 21 ++++++++++++++++++--- e2fsck/journal.c | 2 +- e2fsck/pass1.c | 28 ++++++++++++++-------------- e2fsck/pass1b.c | 27 +++++++++++++++++++-------- e2fsck/scantest.c | 25 +++++++++++++++++-------- e2scan/e2scan.c | 18 ++++++++++++++---- lib/ext2fs/bmove.c | 37 +++++++++++++++++++++++++------------ lib/ext2fs/inode.c | 2 +- lib/ext2fs/tst_iscan.c | 17 ++++++++++++++--- lib/quota/mkquota.c | 27 ++++++++++++++++++--------- misc/e2image.c | 41 ++++++++++++++++++++++++++--------------- misc/tune2fs.c | 28 ++++++++++++++++++---------- resize/resize2fs.c | 7 ++++--- 17 files changed, 239 insertions(+), 115 deletions(-) diff --git a/debugfs/icheck.c b/debugfs/icheck.c index 3b9bd14..9f36d27 100644 --- a/debugfs/icheck.c +++ b/debugfs/icheck.c @@ -60,8 +60,9 @@ void do_icheck(int argc, char **argv) int i; ext2_inode_scan scan = 0; ext2_ino_t ino; - struct ext2_inode inode; errcode_t retval; + struct ext2_inode *inode; + int inode_size; char *block_buf; if (argc < 2) { @@ -71,8 +72,14 @@ void do_icheck(int argc, char **argv) if (check_fs_open(argv[0])) return; + inode_size = EXT2_INODE_SIZE(current_fs->super); + retval = ext2fs_get_mem(inode_size, &inode); + if (retval) + return; + bw.barray = malloc(sizeof(struct block_info) * argc); if (!bw.barray) { + ext2fs_free_mem(&inode); com_err("icheck", ENOMEM, "while allocating inode info array"); return; @@ -99,7 +106,8 @@ void do_icheck(int argc, char **argv) } do { - retval = ext2fs_get_next_inode(scan, &ino, &inode); + retval = ext2fs_get_next_inode_full(scan, &ino, + inode, inode_size); } while (retval == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE); if (retval) { com_err("icheck", retval, "while starting inode scan"); @@ -109,27 +117,27 @@ void do_icheck(int argc, char **argv) while (ino) { blk64_t blk; - if (!inode.i_links_count) + if (!inode->i_links_count) goto next; bw.inode = ino; - blk = ext2fs_file_acl_block(current_fs, &inode); + blk = ext2fs_file_acl_block(current_fs, inode); if (blk) { icheck_proc(current_fs, &blk, 0, 0, 0, &bw); if (bw.blocks_left == 0) break; - ext2fs_file_acl_block_set(current_fs, &inode, blk); + ext2fs_file_acl_block_set(current_fs, inode, blk); } - if (!ext2fs_inode_has_valid_blocks2(current_fs, &inode)) + if (!ext2fs_inode_has_valid_blocks2(current_fs, inode)) goto next; /* * To handle filesystems touched by 0.3c extfs; can be * removed later. */ - if (inode.i_dtime) + if (inode->i_dtime) goto next; retval = ext2fs_block_iterate3(current_fs, ino, @@ -146,7 +154,8 @@ void do_icheck(int argc, char **argv) next: do { - retval = ext2fs_get_next_inode(scan, &ino, &inode); + retval = ext2fs_get_next_inode_full(scan, &ino, + inode, inode_size); } while (retval == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE); if (retval) { com_err("icheck", retval, @@ -165,6 +174,7 @@ void do_icheck(int argc, char **argv) } error_out: + ext2fs_free_mem(&inode); free(bw.barray); free(block_buf); if (scan) diff --git a/debugfs/lsdel.c b/debugfs/lsdel.c index e5b2d20..9a38783 100644 --- a/debugfs/lsdel.c +++ b/debugfs/lsdel.c @@ -78,7 +78,8 @@ void do_lsdel(int argc, char **argv) int num_delarray, max_delarray; ext2_inode_scan scan = 0; ext2_ino_t ino; - struct ext2_inode inode; + struct ext2_inode *inode = NULL; + int inode_size; errcode_t retval; char *block_buf; int i; @@ -121,9 +122,14 @@ void do_lsdel(int argc, char **argv) "while opening inode scan"); goto error_out; } + inode_size = EXT2_INODE_SIZE(current_fs->super); + retval = ext2fs_get_mem(inode_size, &inode); + if (retval) + goto error_out; do { - retval = ext2fs_get_next_inode(scan, &ino, &inode); + retval = ext2fs_get_next_inode_full(scan, &ino, + inode, inode_size); } while (retval == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE); if (retval) { com_err("ls_deleted_inodes", retval, @@ -132,8 +138,8 @@ void do_lsdel(int argc, char **argv) } while (ino) { - if ((inode.i_dtime == 0) || - (secs && ((unsigned) abs(now - secs) > inode.i_dtime))) + if ((inode->i_dtime == 0) || + (secs && ((unsigned) abs(now - secs) > inode->i_dtime))) goto next; lsd.inode = ino; @@ -163,10 +169,10 @@ void do_lsdel(int argc, char **argv) } delarray[num_delarray].ino = ino; - delarray[num_delarray].mode = inode.i_mode; - delarray[num_delarray].uid = inode_uid(inode); - delarray[num_delarray].size = EXT2_I_SIZE(&inode); - delarray[num_delarray].dtime = inode.i_dtime; + delarray[num_delarray].mode = inode->i_mode; + delarray[num_delarray].uid = inode_uid(*inode); + delarray[num_delarray].size = EXT2_I_SIZE(inode); + delarray[num_delarray].dtime = inode->i_dtime; delarray[num_delarray].num_blocks = lsd.num_blocks; delarray[num_delarray].free_blocks = lsd.free_blocks; num_delarray++; @@ -174,7 +180,8 @@ void do_lsdel(int argc, char **argv) next: do { - retval = ext2fs_get_next_inode(scan, &ino, &inode); + retval = ext2fs_get_next_inode_full(scan, &ino, + inode, inode_size); } while (retval == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE); if (retval) { com_err("ls_deleted_inodes", retval, @@ -201,6 +208,7 @@ void do_lsdel(int argc, char **argv) close_pager(out); error_out: + ext2fs_free_mem(&inode); free(block_buf); free(delarray); if (scan) diff --git a/debugfs/ncheck.c b/debugfs/ncheck.c index 58f3a50..10a38a3 100644 --- a/debugfs/ncheck.c +++ b/debugfs/ncheck.c @@ -93,7 +93,8 @@ void do_ncheck(int argc, char **argv) int c, i; ext2_inode_scan scan = 0; ext2_ino_t ino; - struct ext2_inode inode; + struct ext2_inode *inode = NULL; + int inode_size; errcode_t retval; char *tmp; @@ -143,9 +144,14 @@ void do_ncheck(int argc, char **argv) com_err("ncheck", retval, "while opening inode scan"); goto error_out; } + inode_size = EXT2_INODE_SIZE(current_fs->super); + retval = ext2fs_get_mem(inode_size, &inode); + if (retval) + goto error_out; do { - retval = ext2fs_get_next_inode(scan, &ino, &inode); + retval = ext2fs_get_next_inode_full(scan, &ino, + inode, inode_size); } while (retval == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE); if (retval) { com_err("ncheck", retval, "while starting inode scan"); @@ -154,16 +160,16 @@ void do_ncheck(int argc, char **argv) printf("Inode\tPathname\n"); while (ino) { - if (!inode.i_links_count) + if (!inode->i_links_count) goto next; /* * To handle filesystems touched by 0.3c extfs; can be * removed later. */ - if (inode.i_dtime) + if (inode->i_dtime) goto next; /* Ignore anything that isn't a directory */ - if (!LINUX_S_ISDIR(inode.i_mode)) + if (!LINUX_S_ISDIR(inode->i_mode)) goto next; iw.position = 0; @@ -185,7 +191,8 @@ void do_ncheck(int argc, char **argv) next: do { - retval = ext2fs_get_next_inode(scan, &ino, &inode); + retval = ext2fs_get_next_inode_full(scan, &ino, + inode, inode_size); } while (retval == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE); if (retval) { @@ -196,6 +203,7 @@ void do_ncheck(int argc, char **argv) } error_out: + ext2fs_free_mem(inode); free(iw.iarray); if (scan) ext2fs_close_inode_scan(scan); diff --git a/e2fsck/e2fsck.h b/e2fsck/e2fsck.h index 5163d36..a6a9e58 100644 --- a/e2fsck/e2fsck.h +++ b/e2fsck/e2fsck.h @@ -314,7 +314,7 @@ struct e2fsck_struct { * For pass1_check_directory and pass1_get_blocks */ ext2_ino_t stashed_ino; - struct ext2_inode *stashed_inode; + struct ext2_inode_large *stashed_inode; /* * Location of the lost and found directory diff --git a/e2fsck/iscan.c b/e2fsck/iscan.c index 52cad11..5190caa 100644 --- a/e2fsck/iscan.c +++ b/e2fsck/iscan.c @@ -97,7 +97,9 @@ int main (int argc, char *argv[]) ext2_filsys fs; ext2_ino_t ino; __u32 num_inodes = 0; - struct ext2_inode inode; + struct ext2_inode *inode = NULL; + int inode_size; + int ret = 0; ext2_inode_scan scan; init_resource_track(&global_rtrack); @@ -117,21 +119,34 @@ int main (int argc, char *argv[]) retval = ext2fs_open_inode_scan(fs, inode_buffer_blocks, &scan); if (retval) { com_err(program_name, retval, _("while opening inode scan")); + ext2fs_close_free(&fs); + exit(1); + } + + inode_size = EXT2_INODE_SIZE(current_fs->super); + retval = ext2fs_get_mem(inode_size, &inode); + if (retval) { + ext2fs_close_inode_scan(&scan); + ext2fs_close_free(&fs); exit(1); } while (1) { - retval = ext2fs_get_next_inode(scan, &ino, &inode); + retval = ext2fs_get_next_inode_full(scan, &ino, + inode, inode_size); if (retval) { com_err(program_name, retval, _("while getting next inode")); + ext2fs_close_inode_scan(&scan); + ext2fs_close_free(&fs); + ext2fs_free_mem(&inode); exit(1); } if (ino == 0) break; num_inodes++; } - + ext2fs_free_mem(&inode); print_resource_track(NULL, &global_rtrack); printf(_("%u inodes scanned.\n"), num_inodes); diff --git a/e2fsck/journal.c b/e2fsck/journal.c index 3b40e00..afbd38c 100644 --- a/e2fsck/journal.c +++ b/e2fsck/journal.c @@ -296,7 +296,7 @@ static errcode_t e2fsck_get_journal(e2fsck_t ctx, journal_t **ret_journal) j_inode->i_ext2.i_mode = LINUX_S_IFREG | 0600; e2fsck_use_inode_shortcuts(ctx, 1); ctx->stashed_ino = j_inode->i_ino; - ctx->stashed_inode = &j_inode->i_ext2; + ctx->stashed_inode = (struct ext2_inode_large *)&j_inode->i_ext2; tried_backup_jnl++; } if (!j_inode->i_ext2.i_links_count || diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c index 589d4b4..c547db0 100644 --- a/e2fsck/pass1.c +++ b/e2fsck/pass1.c @@ -99,7 +99,7 @@ struct process_block_struct { struct process_inode_block { ext2_ino_t ino; - struct ext2_inode inode; + struct ext2_inode_large inode; }; struct scan_callback_struct { @@ -1010,11 +1010,9 @@ void e2fsck_pass1(e2fsck_t ctx) return; } inode_size = EXT2_INODE_SIZE(fs->super); - inode = (struct ext2_inode *) - e2fsck_allocate_memory(ctx, inode_size, "scratch inode"); + inode = e2fsck_allocate_memory(ctx, inode_size, "scratch inode"); - inodes_to_process = (struct process_inode_block *) - e2fsck_allocate_memory(ctx, + inodes_to_process = e2fsck_allocate_memory(ctx, (ctx->process_inode_size * sizeof(struct process_inode_block)), "array of inodes to process"); @@ -1063,7 +1061,7 @@ void e2fsck_pass1(e2fsck_t ctx) goto endit; } ext2fs_inode_scan_flags(scan, EXT2_SF_SKIP_MISSING_ITABLE, 0); - ctx->stashed_inode = inode; + ctx->stashed_inode = (struct ext2_inode_large *)inode; scan_struct.ctx = ctx; scan_struct.block_buf = block_buf; ext2fs_set_inode_callback(scan, scan_callback, &scan_struct); @@ -1525,7 +1523,8 @@ void e2fsck_pass1(e2fsck_t ctx) inode->i_block[EXT2_TIND_BLOCK] || ext2fs_file_acl_block(fs, inode))) { inodes_to_process[process_inode_count].ino = ino; - inodes_to_process[process_inode_count].inode = *inode; + inodes_to_process[process_inode_count].inode = + *((struct ext2_inode_large *)inode); process_inode_count++; } else check_blocks(ctx, &pctx, block_buf); @@ -1676,7 +1675,7 @@ static errcode_t scan_callback(ext2_filsys fs, static void process_inodes(e2fsck_t ctx, char *block_buf) { int i; - struct ext2_inode *old_stashed_inode; + struct ext2_inode_large *old_stashed_inode; ext2_ino_t old_stashed_ino; const char *old_operation; char buf[80]; @@ -1694,7 +1693,8 @@ static void process_inodes(e2fsck_t ctx, char *block_buf) sizeof(struct process_inode_block), process_inode_cmp); clear_problem_context(&pctx); for (i=0; i < process_inode_count; i++) { - pctx.inode = ctx->stashed_inode = &inodes_to_process[i].inode; + ctx->stashed_inode = &inodes_to_process[i].inode; + pctx.inode = (struct ext2_inode *)ctx->stashed_inode; pctx.ino = ctx->stashed_ino = inodes_to_process[i].ino; #if 0 @@ -1732,8 +1732,8 @@ static EXT2_QSORT_TYPE process_inode_cmp(const void *a, const void *b) * inodes, so it's OK to pass NULL to * ext2fs_file_acl_block() here. */ - ret = ext2fs_file_acl_block(0, &(ib_a->inode)) - - ext2fs_file_acl_block(0, &(ib_b->inode)); + ret = ext2fs_file_acl_block(0, (struct ext2_inode *)&(ib_a->inode)) - + ext2fs_file_acl_block(0, (struct ext2_inode *)&(ib_b->inode)); if (ret == 0) ret = ib_a->ino - ib_b->ino; return ret; @@ -3436,7 +3436,7 @@ static errcode_t pass1_read_inode(ext2_filsys fs, ext2_ino_t ino, if ((ino != ctx->stashed_ino) || !ctx->stashed_inode) return EXT2_ET_CALLBACK_NOTHANDLED; - *inode = *ctx->stashed_inode; + *inode = *(struct ext2_inode *)ctx->stashed_inode; return 0; } @@ -3446,8 +3446,8 @@ static errcode_t pass1_write_inode(ext2_filsys fs, ext2_ino_t ino, e2fsck_t ctx = (e2fsck_t) fs->priv_data; if ((ino == ctx->stashed_ino) && ctx->stashed_inode && - (inode != ctx->stashed_inode)) - *ctx->stashed_inode = *inode; + (inode != (struct ext2_inode *)ctx->stashed_inode)) + *(struct ext2_inode *)ctx->stashed_inode = *inode; return EXT2_ET_CALLBACK_NOTHANDLED; } diff --git a/e2fsck/pass1b.c b/e2fsck/pass1b.c index 03be872..cfa2fea 100644 --- a/e2fsck/pass1b.c +++ b/e2fsck/pass1b.c @@ -270,7 +270,8 @@ static void pass1b(e2fsck_t ctx, char *block_buf) { ext2_filsys fs = ctx->fs; ext2_ino_t ino = 0; - struct ext2_inode inode; + struct ext2_inode *inode; + int inode_size; ext2_inode_scan scan; struct process_block_struct pb; struct problem_context pctx; @@ -286,7 +287,15 @@ static void pass1b(e2fsck_t ctx, char *block_buf) ctx->flags |= E2F_FLAG_ABORT; return; } - ctx->stashed_inode = &inode; + inode_size = EXT2_INODE_SIZE(fs->super); + pctx.errcode = ext2fs_get_mem(inode_size, &inode); + if (pctx.errcode) { + ext2fs_close_inode_scan(scan); + ctx->flags |= E2F_FLAG_ABORT; + return; + } + + ctx->stashed_inode = (struct ext2_inode_large *)inode; pb.ctx = ctx; pb.pctx = &pctx; pctx.str = "pass1b"; @@ -295,7 +304,8 @@ static void pass1b(e2fsck_t ctx, char *block_buf) if (e2fsck_mmp_update(fs)) fatal_error(ctx, 0); } - pctx.errcode = ext2fs_get_next_inode(scan, &ino, &inode); + pctx.errcode = ext2fs_get_next_inode_full(scan, &ino, + inode, inode_size); if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE) continue; if (pctx.errcode) { @@ -313,22 +323,22 @@ static void pass1b(e2fsck_t ctx, char *block_buf) pb.ino = ino; pb.dup_blocks = 0; - pb.inode = &inode; + pb.inode = inode; pb.cur_cluster = ~0; pb.phys_cluster = ~0; - if (ext2fs_inode_has_valid_blocks2(fs, &inode) || + if (ext2fs_inode_has_valid_blocks2(fs, inode) || (ino == EXT2_BAD_INO)) pctx.errcode = ext2fs_block_iterate3(fs, ino, BLOCK_FLAG_READ_ONLY, block_buf, process_pass1b_block, &pb); /* If the feature is not set, attrs will be cleared later anyway */ if ((fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) && - ext2fs_file_acl_block(fs, &inode)) { - blk64_t blk = ext2fs_file_acl_block(fs, &inode); + ext2fs_file_acl_block(fs, inode)) { + blk64_t blk = ext2fs_file_acl_block(fs, inode); process_pass1b_block(fs, &blk, BLOCK_COUNT_EXTATTR, 0, 0, &pb); - ext2fs_file_acl_block_set(fs, &inode, blk); + ext2fs_file_acl_block_set(fs, inode, blk); } if (pb.dup_blocks) { end_problem_latch(ctx, PR_LATCH_DBLOCK); @@ -339,6 +349,7 @@ static void pass1b(e2fsck_t ctx, char *block_buf) if (pctx.errcode) fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx); } + ext2fs_free_mem(&inode); ext2fs_close_inode_scan(scan); e2fsck_use_inode_shortcuts(ctx, 0); } diff --git a/e2fsck/scantest.c b/e2fsck/scantest.c index 6131141..b38cff8 100644 --- a/e2fsck/scantest.c +++ b/e2fsck/scantest.c @@ -88,12 +88,12 @@ static void print_resource_track(struct resource_track *track) int main (int argc, char *argv[]) { errcode_t retval = 0; - int exit_value = 0; int i; ext2_filsys fs; ext2_inode_scan scan; ext2_ino_t ino; - struct ext2_inode inode; + struct ext2_inode *inode; + int inode_size; printf(_("size of inode=%d\n"), sizeof(inode)); @@ -114,17 +114,26 @@ int main (int argc, char *argv[]) com_err(argv[0], retval, _("while opening inode scan")); exit(1); } - retval = ext2fs_get_next_inode(scan, &ino, &inode); + + inode_size = EXT2_INODE_SIZE(fs->super); + retval = ext2fs_get_mem(inode_size, &inode); + if (retval) { + com_err(argv[0], retval, _("while allocating inode memory")); + exit(1); + } + retval = ext2fs_get_next_inode_full(scan, &ino, + inode, inode_size); if (retval) { com_err(argv[0], retval, _("while starting inode scan")); exit(1); } while (ino) { - if (!inode.i_links_count) + if (!inode->i_links_count) goto next; - printf("%lu\n", inode.i_blocks); + printf("%lu\n", inode->i_blocks); next: - retval = ext2fs_get_next_inode(scan, &ino, &inode); + retval = ext2fs_get_next_inode_full(scan, &ino, + inode, inode_size); if (retval) { com_err(argv[0], retval, _("while doing inode scan")); @@ -133,9 +142,9 @@ int main (int argc, char *argv[]) } + ext2fs_free_mem(&inode); ext2fs_close_free(&fs); print_resource_track(&global_rtrack); - - return exit_value; + return 0; } diff --git a/e2scan/e2scan.c b/e2scan/e2scan.c index 36736b1..aabcbeb 100644 --- a/e2scan/e2scan.c +++ b/e2scan/e2scan.c @@ -320,7 +320,8 @@ int main(int argc, char **argv) errcode_t retval; char *block_buf; ext2_inode_scan scan; - struct ext2_inode inode; + struct ext2_inode *inode; + int inode_size; ext2_ino_t ino; dgrp_t nr; time_t t; @@ -537,6 +538,13 @@ int main(int argc, char **argv) default: break; } + inode_size = EXT2_INODE_SIZE(fs->super); + retval = ext2fs_get_mem(inode_size, &inode); + if (retval) { + fprintf(stderr, "%s: failed to allocate inode memory\n", + argv[0]); + exit(1); + } t = time(NULL); fprintf(stderr, "scanning inode tables .. "); @@ -544,7 +552,8 @@ int main(int argc, char **argv) done_group_callback(fs, scan, -readahead_groups * 2, NULL); done_group_callback(fs, scan, -readahead_groups, NULL); - while (ext2fs_get_next_inode(scan, &ino, &inode) == 0) { + while (ext2fs_get_next_inode_full(scan, &ino, + inode, inode_size) == 0) { if (ino == 0) break; @@ -554,12 +563,12 @@ int main(int argc, char **argv) continue; switch (scan_data.mode) { case SM_DATABASE: - database_iscan_action(ino, &inode, scan_data.db.fd, + database_iscan_action(ino, inode, scan_data.db.fd, block_buf); break; case SM_FILELIST: - filelist_iscan_action(ino, &inode, block_buf); + filelist_iscan_action(ino, inode, block_buf); break; default: @@ -650,6 +659,7 @@ int main(int argc, char **argv) ext2fs_close_inode_scan(scan); ext2fs_close(fs); free(block_buf); + ext2fs_free_mem(&inode); return 0; } diff --git a/lib/ext2fs/bmove.c b/lib/ext2fs/bmove.c index e2ea405..a4ae35b 100644 --- a/lib/ext2fs/bmove.c +++ b/lib/ext2fs/bmove.c @@ -100,11 +100,17 @@ errcode_t ext2fs_move_blocks(ext2_filsys fs, int flags) { ext2_ino_t ino; - struct ext2_inode inode; + struct ext2_inode *inode; + int inode_size; errcode_t retval; struct process_block_struct pb; ext2_inode_scan scan; - char *block_buf; + char *block_buf = NULL; + + inode_size = EXT2_INODE_SIZE(fs->super); + retval = ext2fs_get_mem(inode_size, &inode); + if (retval) + return retval; retval = ext2fs_open_inode_scan(fs, 0, &scan); if (retval) @@ -132,20 +138,21 @@ errcode_t ext2fs_move_blocks(ext2_filsys fs, } retval = ext2fs_init_dblist(fs, 0); if (retval) - return retval; + goto error; } - retval = ext2fs_get_next_inode(scan, &ino, &inode); + retval = ext2fs_get_next_inode_full(scan, &ino, + inode, inode_size); if (retval) - return retval; + goto error; while (ino) { - if ((inode.i_links_count == 0) || - !ext2fs_inode_has_valid_blocks2(fs, &inode)) + if ((inode->i_links_count == 0) || + !ext2fs_inode_has_valid_blocks2(fs, inode)) goto next; pb.ino = ino; - pb.inode = &inode; + pb.inode = inode; pb.add_dir = (LINUX_S_ISDIR(inode.i_mode) && flags & EXT2_BMOVE_GET_DBLIST); @@ -153,15 +160,21 @@ errcode_t ext2fs_move_blocks(ext2_filsys fs, retval = ext2fs_block_iterate3(fs, ino, 0, block_buf, process_block, &pb); if (retval) - return retval; - if (pb.error) - return pb.error; + goto error; + if (pb.error) { + retval = pb.error; + goto error; + } next: - retval = ext2fs_get_next_inode(scan, &ino, &inode); + retval = ext2fs_get_next_inode_full(scan, &ino, + inode, inode_size); if (retval == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE) goto next; } +error: + ext2fs_free_mem(&inode); + ext2fs_free_mem(&block_buf); return 0; } diff --git a/lib/ext2fs/inode.c b/lib/ext2fs/inode.c index a2f2ecd..b7805bc 100644 --- a/lib/ext2fs/inode.c +++ b/lib/ext2fs/inode.c @@ -489,7 +489,7 @@ errcode_t ext2fs_get_next_inode_full(ext2_inode_scan scan, ext2_ino_t *ino, (struct ext2_inode_large *) scan->temp_buffer, 0, bufsize); #else - *inode = *((struct ext2_inode *) scan->temp_buffer); + memcpy(inode, scan->temp_buffer, bufsize); #endif if (scan->scan_flags & EXT2_SF_BAD_EXTRA_BYTES) retval = EXT2_ET_BAD_BLOCK_IN_INODE_TABLE; diff --git a/lib/ext2fs/tst_iscan.c b/lib/ext2fs/tst_iscan.c index 70bfbec..3d8281a 100644 --- a/lib/ext2fs/tst_iscan.c +++ b/lib/ext2fs/tst_iscan.c @@ -140,7 +140,8 @@ static void setup(void) */ static void iterate(void) { - struct ext2_inode inode; + struct ext2_inode *inode; + int inode_size; ext2_inode_scan scan; errcode_t retval; ext2_ino_t ino; @@ -150,14 +151,23 @@ static void iterate(void) com_err("iterate", retval, "While opening inode scan"); exit(1); } + + inode_size = EXT2_INODE_SIZE(test_fs->super); + retval = ext2fs_get_mem(inode_size, &inode); + if (retval) { + com_err("iterate", retval, "while allocating inode mem"); + exit(1); + } printf("Reading blocks: "); - retval = ext2fs_get_next_inode(scan, &ino, &inode); + retval = ext2fs_get_next_inode_full(scan, &ino, + inode, inode_size); if (retval) { com_err("iterate", retval, "while reading first inode"); exit(1); } while (ino) { - retval = ext2fs_get_next_inode(scan, &ino, &inode); + retval = ext2fs_get_next_inode_full(scan, &ino, + inode, inode_size); if (retval == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE) { ext2fs_mark_inode_bitmap2(bad_inode_map, ino); continue; @@ -169,6 +179,7 @@ static void iterate(void) } } printf("\n"); + ext2fs_free_mem(&inode); ext2fs_close_inode_scan(scan); } diff --git a/lib/quota/mkquota.c b/lib/quota/mkquota.c index 0ece088..0cd00a5 100644 --- a/lib/quota/mkquota.c +++ b/lib/quota/mkquota.c @@ -416,41 +416,50 @@ errcode_t quota_compute_usage(quota_ctx_t qctx) ext2_filsys fs; ext2_ino_t ino; errcode_t ret; - struct ext2_inode inode; + struct ext2_inode* inode; + int inode_size; qsize_t space; ext2_inode_scan scan; if (!qctx) return 0; + inode_size = EXT2_INODE_SIZE(qctx->fs->super); + ret = ext2fs_get_mem(inode_size, &inode); + if (ret) + return ret; + fs = qctx->fs; ret = ext2fs_open_inode_scan(fs, 0, &scan); if (ret) { + ext2fs_free_mem(&inode); log_err("while opening inode scan. ret=%ld", ret); return ret; } while (1) { - ret = ext2fs_get_next_inode(scan, &ino, &inode); + ret = ext2fs_get_next_inode_full(scan, &ino, inode, + inode_size); if (ret) { log_err("while getting next inode. ret=%ld", ret); - ext2fs_close_inode_scan(scan); - return ret; + goto err; } if (ino == 0) break; - if (inode.i_links_count && + if (inode->i_links_count && (ino == EXT2_ROOT_INO || ino >= EXT2_FIRST_INODE(fs->super))) { - space = ext2fs_inode_i_blocks(fs, &inode) << 9; - quota_data_add(qctx, &inode, ino, space); - quota_data_inodes(qctx, &inode, ino, +1); + space = ext2fs_inode_i_blocks(fs, inode) << 9; + quota_data_add(qctx, inode, ino, space); + quota_data_inodes(qctx, inode, ino, +1); } } +err: ext2fs_close_inode_scan(scan); + ext2fs_free_mem(&inode); - return 0; + return ret; } struct scan_dquots_data { diff --git a/misc/e2image.c b/misc/e2image.c index 82fe3e8..e337e31 100644 --- a/misc/e2image.c +++ b/misc/e2image.c @@ -1255,7 +1255,8 @@ static void output_qcow2_meta_data_blocks(ext2_filsys fs, int fd) static void write_raw_image_file(ext2_filsys fs, int fd, int type, int flags) { struct process_block_struct pb; - struct ext2_inode inode; + struct ext2_inode *inode; + int inode_size; ext2_inode_scan scan; ext2_ino_t ino; errcode_t retval; @@ -1298,10 +1299,19 @@ static void write_raw_image_file(ext2_filsys fs, int fd, int type, int flags) exit(1); } + inode_size = EXT2_INODE_SIZE(fs->super); + retval = ext2fs_get_mem(inode_size, &inode); + if (retval) { + com_err(program_name, retval, + _("while allocating inode memory")); + exit(1); + } + use_inode_shortcuts(fs, 1); - stashed_inode = &inode; + stashed_inode = inode; while (1) { - retval = ext2fs_get_next_inode(scan, &ino, &inode); + retval = ext2fs_get_next_inode_full(scan, &ino, + inode, inode_size); if (retval == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE) continue; if (retval) { @@ -1311,22 +1321,22 @@ static void write_raw_image_file(ext2_filsys fs, int fd, int type, int flags) } if (ino == 0) break; - if (!inode.i_links_count) + if (!inode->i_links_count) continue; - if (ext2fs_file_acl_block(fs, &inode)) { + if (ext2fs_file_acl_block(fs, inode)) { ext2fs_mark_block_bitmap2(meta_block_map, - ext2fs_file_acl_block(fs, &inode)); + ext2fs_file_acl_block(fs, inode)); meta_blocks_count++; } - if (!ext2fs_inode_has_valid_blocks2(fs, &inode)) + if (!ext2fs_inode_has_valid_blocks2(fs, inode)) continue; stashed_ino = ino; pb.ino = ino; - pb.is_dir = LINUX_S_ISDIR(inode.i_mode); - if (LINUX_S_ISDIR(inode.i_mode) || - (LINUX_S_ISLNK(inode.i_mode) && - ext2fs_inode_has_valid_blocks2(fs, &inode)) || + pb.is_dir = LINUX_S_ISDIR(inode->i_mode); + if (LINUX_S_ISDIR(inode->i_mode) || + (LINUX_S_ISLNK(inode->i_mode) && + ext2fs_inode_has_valid_blocks2(fs, inode)) || ino == fs->super->s_journal_inum) { retval = ext2fs_block_iterate3(fs, ino, BLOCK_FLAG_READ_ONLY, block_buf, @@ -1338,10 +1348,10 @@ static void write_raw_image_file(ext2_filsys fs, int fd, int type, int flags) exit(1); } } else { - if ((inode.i_flags & EXT4_EXTENTS_FL) || - inode.i_block[EXT2_IND_BLOCK] || - inode.i_block[EXT2_DIND_BLOCK] || - inode.i_block[EXT2_TIND_BLOCK] || all_data) { + if ((inode->i_flags & EXT4_EXTENTS_FL) || + inode->i_block[EXT2_IND_BLOCK] || + inode->i_block[EXT2_DIND_BLOCK] || + inode->i_block[EXT2_TIND_BLOCK] || all_data) { retval = ext2fs_block_iterate3(fs, ino, BLOCK_FLAG_READ_ONLY, block_buf, process_file_block, &pb); @@ -1360,6 +1370,7 @@ static void write_raw_image_file(ext2_filsys fs, int fd, int type, int flags) else output_meta_data_blocks(fs, fd, flags); + ext2fs_free_mem(&inode); ext2fs_free_mem(&block_buf); ext2fs_close_inode_scan(scan); ext2fs_free_block_bitmap(meta_block_map); diff --git a/misc/tune2fs.c b/misc/tune2fs.c index e48e641..6c5d253 100644 --- a/misc/tune2fs.c +++ b/misc/tune2fs.c @@ -1549,26 +1549,33 @@ static int inode_scan_and_fix(ext2_filsys fs, ext2fs_block_bitmap bmap) ext2_ino_t ino; blk64_t blk; char *block_buf = 0; - struct ext2_inode inode; + struct ext2_inode *inode; + int inode_size; ext2_inode_scan scan = NULL; - retval = ext2fs_get_mem(fs->blocksize * 3, &block_buf); + inode_size = EXT2_INODE_SIZE(fs->super); + retval = ext2fs_get_mem(inode_size, &inode); if (retval) return retval; + retval = ext2fs_get_mem(fs->blocksize * 3, &block_buf); + if (retval) + goto err_out; + retval = ext2fs_open_inode_scan(fs, 0, &scan); if (retval) goto err_out; while (1) { - retval = ext2fs_get_next_inode(scan, &ino, &inode); + retval = ext2fs_get_next_inode_full(scan, &ino, + inode, inode_size); if (retval) goto err_out; if (!ino) break; - if (inode.i_links_count == 0) + if (inode->i_links_count == 0) continue; /* inode not in use */ /* FIXME!! @@ -1578,26 +1585,26 @@ static int inode_scan_and_fix(ext2_filsys fs, ext2fs_block_bitmap bmap) * Do we need to fix this ?? */ - if (ext2fs_file_acl_block(fs, &inode) && + if (ext2fs_file_acl_block(fs, inode) && ext2fs_test_block_bitmap2(bmap, - ext2fs_file_acl_block(fs, &inode))) { + ext2fs_file_acl_block(fs, inode))) { blk = translate_block(ext2fs_file_acl_block(fs, - &inode)); + inode)); if (!blk) continue; - ext2fs_file_acl_block_set(fs, &inode, blk); + ext2fs_file_acl_block_set(fs, inode, blk); /* * Write the inode to disk so that inode table * resizing can work */ - retval = ext2fs_write_inode(fs, ino, &inode); + retval = ext2fs_write_inode(fs, ino, inode); if (retval) goto err_out; } - if (!ext2fs_inode_has_valid_blocks2(fs, &inode)) + if (!ext2fs_inode_has_valid_blocks2(fs, inode)) continue; retval = ext2fs_block_iterate3(fs, ino, 0, block_buf, @@ -1608,6 +1615,7 @@ static int inode_scan_and_fix(ext2_filsys fs, ext2fs_block_bitmap bmap) } err_out: + ext2fs_free_mem(&inode); ext2fs_free_mem(&block_buf); ext2fs_close_inode_scan(scan); diff --git a/resize/resize2fs.c b/resize/resize2fs.c index a2806b1..c1a4446 100644 --- a/resize/resize2fs.c +++ b/resize/resize2fs.c @@ -1584,8 +1584,8 @@ static errcode_t inode_scan_and_fix(ext2_resize_t rfs) pb.error = 0; new_inode = EXT2_FIRST_INODE(rfs->new_fs->super); inode_size = EXT2_INODE_SIZE(rfs->new_fs->super); - inode = malloc(inode_size); - if (!inode) { + retval = ext2fs_get_mem(inode_size, &inode); + if (retval) { retval = ENOMEM; goto errout; } @@ -1677,7 +1677,8 @@ errout: ext2fs_close_inode_scan(scan); if (block_buf) ext2fs_free_mem(&block_buf); - free(inode); + if (inode) + ext2fs_free_mem(&inode); return retval; } -- 1.8.3.1