Currently there are many uses of ext2fs_close() which might be wrong.
First of all ext2fs_close() does not set the ext2_filsys pointer to NULL
so the caller is responsible for clearing it, however there are some
cases there we do not do it.
Second of all very small number of users of ext2fs_close() actually
check the return value. If there is a problem in ext2fs_close() it will
not even free the ext2_filsys structure, but majority of users expect it
to do so.
To fix both problems this commit introduces a new helper
ext2fs_close_free() which will not only check for the return value and
free the ext2_filsys structure if the call to ext2fs_close2() failed,
but it will also set the ext2_filsys pointer to NULL.
Replace every use of ext2fs_close() in e2fsprogs tools with
ext2fs_close_free() - there is no real reason to keep using
ext2fs_close().
Signed-off-by: Lukas Czerner <lczerner@redhat.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
ext2fs_clear_inode_bitmap@Base 1.37
ext2fs_close2@Base 1.42
ext2fs_close@Base 1.37
+ ext2fs_close_free@Base 1.42.11
ext2fs_close_inode_scan@Base 1.37
ext2fs_compare_block_bitmap@Base 1.37
ext2fs_compare_generic_bitmap@Base 1.41.0
return;
errout:
- retval = ext2fs_close(current_fs);
+ retval = ext2fs_close_free(¤t_fs);
if (retval)
com_err(device, retval, "while trying to close filesystem");
- current_fs = NULL;
}
void do_open_filesys(int argc, char **argv)
}
if (current_qctx)
quota_release_context(¤t_qctx);
- retval = ext2fs_close(current_fs);
+ retval = ext2fs_close_free(¤t_fs);
if (retval)
com_err("ext2fs_close", retval, 0);
- current_fs = NULL;
return;
}
}
- ext2fs_close(fs);
+ ext2fs_close_free(&fs);
print_resource_track(&global_rtrack);
}
log_out(ctx, "\n");
skip:
- ext2fs_close(fs);
- ctx->fs = NULL;
+ ext2fs_close_free(&fs);
e2fsck_free_context(ctx);
exit(FSCK_OK);
}
orig_superblock = ctx->superblock;
get_backup_sb(ctx, fs, ctx->filesystem_name, io_ptr);
if (fs)
- ext2fs_close(fs);
+ ext2fs_close_free(&fs);
orig_retval = retval;
retval = try_open_fs(ctx, flags, io_ptr, &fs);
if ((orig_retval == 0) && retval != 0) {
if (fs)
- ext2fs_close(fs);
+ ext2fs_close_free(&fs);
log_out(ctx, _("%s: %s while using the "
"backup blocks"),
ctx->program_name,
* reopen the filesystem after we get the device size.
*/
if (pctx.errcode == EBUSY) {
- ext2fs_close(fs);
+ ext2fs_close_free(&fs);
need_restart++;
pctx.errcode =
ext2fs_get_device_size2(ctx->filesystem_name,
/*
* Restart in order to reopen fs but this time start mmp.
*/
- ext2fs_close(fs);
- ctx->fs = NULL;
+ ext2fs_close_free(&fs);
flags &= ~EXT2_FLAG_SKIP_MMP;
goto restart;
}
ctx->device_name);
fatal_error(ctx, 0);
}
- ext2fs_close(ctx->fs);
- ctx->fs = 0;
+ ext2fs_close_free(&ctx->fs);
ctx->flags |= E2F_FLAG_RESTARTED;
goto restart;
}
_("while resetting context"));
fatal_error(ctx, 0);
}
- ext2fs_close(fs);
+ ext2fs_close_free(&fs);
goto restart;
}
if (run_result & E2F_FLAG_CANCEL) {
io_channel_flush(ctx->fs->io);
print_resource_track(ctx, NULL, &ctx->global_rtrack, ctx->fs->io);
- ext2fs_close(fs);
- ctx->fs = NULL;
+ ext2fs_close_free(&fs);
free(ctx->journal_name);
e2fsck_free_context(ctx);
if (fs != NULL) {
fs->super->s_state |= EXT2_ERROR_FS;
ext2fs_mark_super_dirty(fs);
- ext2fs_close(fs);
+ ext2fs_close_free(&fs);
}
exit(FSCK_UNCORRECTED);
}
return retval;
}
+errcode_t ext2fs_close_free(ext2_filsys *fs_ptr)
+{
+ errcode_t ret;
+ ext2_filsys fs = *fs_ptr;
+
+ ret = ext2fs_close2(fs, 0);
+ if (ret)
+ ext2fs_free(fs);
+ *fs_ptr = NULL;
+ return ret;
+}
+
errcode_t ext2fs_close(ext2_filsys fs)
{
return ext2fs_close2(fs, 0);
/* closefs.c */
extern errcode_t ext2fs_close(ext2_filsys fs);
extern errcode_t ext2fs_close2(ext2_filsys fs, int flags);
+extern errcode_t ext2fs_close_free(ext2_filsys *fs);
extern errcode_t ext2fs_flush(ext2_filsys fs);
extern errcode_t ext2fs_flush2(ext2_filsys fs, int flags);
extern int ext2fs_bg_has_super(ext2_filsys fs, dgrp_t group_block);
if (retval) {
printf("Warning, had trouble writing out superblocks.\n");
}
- ext2fs_close(fs);
+ ext2fs_close_free(&fs);
exit(0);
}
return;
errout:
- ext2fs_close(test_fs);
- test_fs = 0;
+ ext2fs_close_free(&test_fs);
}
void setup_cmd(int argc, char **argv)
unsigned int type = EXT2FS_BMAP64_BITARRAY;
int flags = EXT2_FLAG_64BITS;
- if (test_fs) {
- ext2fs_close(test_fs);
- test_fs = 0;
- }
+ if (test_fs)
+ ext2fs_close_free(&test_fs);
reset_getopt();
while ((c = getopt(argc, argv, "b:i:lt:")) != EOF) {
if (check_fs_open(argv[0]))
return;
- ext2fs_close(test_fs);
- test_fs = 0;
+ ext2fs_close_free(&test_fs);
}
if (fs->super->s_feature_incompat &
EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) {
print_journal_information(fs);
- ext2fs_close(fs);
+ ext2fs_close_free(&fs);
exit(0);
}
if ((fs->super->s_feature_compat &
print_inline_journal_information(fs);
list_bad_blocks(fs, 0);
if (header_only) {
- ext2fs_close (fs);
+ ext2fs_close_free(&fs);
exit (0);
}
retval = ext2fs_read_bitmaps (fs);
error_message(retval));
}
}
- ext2fs_close (fs);
+ ext2fs_close_free(&fs);
remove_error_table(&et_ext2_error_table);
exit (0);
}
static void close_device(char *device_name, ext2_filsys fs)
{
- int retval = ext2fs_close(fs);
+ int retval = ext2fs_close_free(&fs);
if (retval)
com_err(device_name, retval, "while closing the filesystem.\n");
}
close(fd);
- ext2fs_close (fs);
+ ext2fs_close_free(&fs);
}
static struct ext2_qcow2_hdr *check_qcow2_image(int *fd, char *name)
else
write_image_file(fs, fd);
- ext2fs_close (fs);
+ ext2fs_close_free(&fs);
if (check)
printf(_("%d blocks already contained the data to be copied\n"),
skipped_blocks);
feature_incompat = fs->super->s_feature_incompat;
log_groups_per_flex = fs->super->s_log_groups_per_flex;
- ext2fs_close(fs);
+ ext2fs_close_free(&fs);
}
switch (arg_type) {
printf(_("Using journal device's blocksize: %d\n"), blocksize);
fs_param.s_log_block_size =
int_log2(blocksize >> EXT2_MIN_BLOCK_LOG_SIZE);
- ext2fs_close(jfs);
+ ext2fs_close_free(&jfs);
}
if (optind < argc) {
if (fs->super->s_feature_incompat &
EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) {
create_journal_dev(fs);
- exit(ext2fs_close(fs) ? 1 : 0);
+ exit(ext2fs_close_free(&fs) ? 1 : 0);
}
if (bad_blocks_filename)
}
if (!quiet)
printf("%s", _("done\n"));
- ext2fs_close(jfs);
+ ext2fs_close_free(&jfs);
free(journal_device);
} else if ((journal_size) ||
(fs_param.s_feature_compat &
"filesystem accounting information: "));
checkinterval = fs->super->s_checkinterval;
max_mnt_count = fs->super->s_max_mnt_count;
- retval = ext2fs_close(fs);
+ retval = ext2fs_close_free(&fs);
if (retval) {
fprintf(stderr, "%s",
_("\nWarning, had trouble writing out superblocks."));
fflush(stdout);
retval = ext2fs_add_journal_device(fs, jfs);
- ext2fs_close(jfs);
+ ext2fs_close_free(&jfs);
if (retval) {
com_err(program_name, retval,
_("while adding filesystem to journal on %s"),
goto closefs;
}
if (io_ptr != io_ptr_orig) {
- ext2fs_close(fs);
+ ext2fs_close_free(&fs);
goto retry_open;
}
}
exit(1);
}
- return (ext2fs_close(fs) ? 1 : 0);
+ return (ext2fs_close_free(&fs) ? 1 : 0);
}
tm = sb->s_wtime;
printf(_("\tlast modified on %s"), ctime(&tm));
}
- ext2fs_close(fs);
+ ext2fs_close_free(&fs);
}
/*
_("Please run 'e2fsck -fy %s' to fix the filesystem\n"
"after the aborted resize operation.\n"),
device_name);
- ext2fs_close(fs);
+ ext2fs_close_free(&fs);
exit(1);
}
printf(_("The filesystem on %s is now %llu blocks long.\n\n"),
rfs->new_fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
print_resource_track(rfs, &overall_track, fs->io);
- retval = ext2fs_close(rfs->new_fs);
+ retval = ext2fs_close_free(&rfs->new_fs);
if (retval)
goto errout;