diff --git a/cmd_attr.c b/cmd_attr.c index aef42f4e..736554c7 100644 --- a/cmd_attr.c +++ b/cmd_attr.c @@ -108,6 +108,7 @@ int cmd_setattr(int argc, char *argv[]) for (i = 1; i < argc; i++) do_setattr(argv[i], opts); + bch2_opt_strs_free(&opts); return 0; } diff --git a/cmd_format.c b/cmd_format.c index b88ffe91..3f96f5de 100644 --- a/cmd_format.c +++ b/cmd_format.c @@ -236,6 +236,7 @@ int cmd_format(int argc, char *argv[]) fs_opts, opts, devices.item, darray_size(devices)); + bch2_opt_strs_free(&fs_opt_strs); if (!quiet) bch2_sb_print(sb, false, 1 << BCH_SB_FIELD_members, HUMAN_READABLE); diff --git a/cmd_migrate.c b/cmd_migrate.c index a0d27427..51260906 100644 --- a/cmd_migrate.c +++ b/cmd_migrate.c @@ -773,10 +773,12 @@ int cmd_migrate(int argc, char *argv[]) if (format_opts.encrypted && !no_passphrase) format_opts.passphrase = read_passphrase_twice("Enter passphrase: "); - return migrate_fs(fs_path, - fs_opt_strs, - fs_opts, - format_opts, force); + int ret = migrate_fs(fs_path, + fs_opt_strs, + fs_opts, + format_opts, force); + bch2_opt_strs_free(&fs_opt_strs); + return ret; } static void migrate_superblock_usage(void) diff --git a/libbcachefs.c b/libbcachefs.c index e5dcfd8f..fbcb237f 100644 --- a/libbcachefs.c +++ b/libbcachefs.c @@ -1006,6 +1006,16 @@ int bchu_data(struct bchfs_handle fs, struct bch_ioctl_data cmd) /* option parsing */ +void bch2_opt_strs_free(struct bch_opt_strs *opts) +{ + unsigned i; + + for (i = 0; i < bch2_opts_nr; i++) { + free(opts->by_id[i]); + opts->by_id[i] = NULL; + } +} + struct bch_opt_strs bch2_cmdline_opts_get(int *argc, char *argv[], unsigned opt_types) { @@ -1038,9 +1048,8 @@ struct bch_opt_strs bch2_cmdline_opts_get(int *argc, char *argv[], optid = bch2_opt_lookup(optstr); if (optid < 0 || !(bch2_opt_table[optid].mode & opt_types)) { - free(optstr); i++; - continue; + goto next; } if (!valstr && @@ -1052,13 +1061,15 @@ struct bch_opt_strs bch2_cmdline_opts_get(int *argc, char *argv[], if (!valstr) valstr = "1"; - opts.by_id[optid] = valstr; + opts.by_id[optid] = strdup(valstr); *argc -= nr_args; memmove(&argv[i], &argv[i + nr_args], sizeof(char *) * (*argc - i)); argv[*argc] = NULL; +next: + free(optstr); } return opts; diff --git a/libbcachefs.h b/libbcachefs.h index 45d2f874..7cdbf696 100644 --- a/libbcachefs.h +++ b/libbcachefs.h @@ -25,6 +25,7 @@ struct { }; }; +void bch2_opt_strs_free(struct bch_opt_strs *); struct bch_opt_strs bch2_cmdline_opts_get(int *, char *[], unsigned); struct bch_opts bch2_parse_opts(struct bch_opt_strs); void bch2_opts_usage(unsigned); diff --git a/libbcachefs/fsck.c b/libbcachefs/fsck.c index bcd95df0..6280b357 100644 --- a/libbcachefs/fsck.c +++ b/libbcachefs/fsck.c @@ -1138,6 +1138,8 @@ static int check_directory_structure(struct bch_fs *c, BUG_ON(ret == -EINTR); + kfree(path.entries); + return bch2_trans_exit(&trans) ?: ret; }