Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add f3write --keep and f3read --delete parameters #140

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 20 additions & 3 deletions f3probe.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#define _POSIX_C_SOURCE 200809L
#define _GNU_SOURCE

#include <stdio.h>
#include <stdlib.h>
Expand Down Expand Up @@ -51,6 +52,8 @@ static struct argp_option options[] = {
"Reset method to use during the probe", 0},
{"time-ops", 't', NULL, 0,
"Time reads, writes, and resets", 0},
{"fix", 'i', NULL, 0,
AltraMayor marked this conversation as resolved.
Show resolved Hide resolved
"Run f3fix if counterfeit flash memory detected", 0},
{ 0 }
};

Expand All @@ -76,6 +79,8 @@ struct args {
int block_order;
int cache_order;
int strict_cache;

bool fix;
AltraMayor marked this conversation as resolved.
Show resolved Hide resolved
};

static error_t parse_opt(int key, char *arg, struct argp_state *state)
Expand Down Expand Up @@ -167,7 +172,11 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state)
case 't':
args->time_ops = true;
break;


case 'i':
args->fix = true;
break;

case ARGP_KEY_INIT:
args->filename = NULL;
break;
Expand Down Expand Up @@ -373,8 +382,8 @@ static int test_device(struct args *args)
uint64_t read_count, read_time_us;
uint64_t write_count, write_time_us;
uint64_t reset_count, reset_time_us;
uint64_t last_good_sector;
Copy link
Owner

@AltraMayor AltraMayor Jul 28, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of moving the declaration of last_good_sector here, declare char *fix_cmd = NULL;

More details in other comments.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You've missed this item.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To clarify, the declaration of last_good_sector should be moved back to the body of the switch..case.

const char *final_dev_filename;

AltraMayor marked this conversation as resolved.
Show resolved Hide resolved
dev = args->debug
? create_file_device(args->filename, args->real_size_byte,
args->fake_size_byte, args->wrap, args->block_order,
Expand Down Expand Up @@ -474,7 +483,7 @@ static int test_device(struct args *args)
case FKTY_LIMBO:
case FKTY_WRAPAROUND:
case FKTY_CHAIN: {
uint64_t last_good_sector = (real_size_byte >> 9) - 1;
last_good_sector = (real_size_byte >> 9) - 1;
assert(block_order >= 9);
printf("Bad news: The device `%s' is a counterfeit of type %s\n\n"
AltraMayor marked this conversation as resolved.
Show resolved Hide resolved
"You can \"fix\" this device using the following command:\n"
Expand Down Expand Up @@ -507,6 +516,13 @@ static int test_device(struct args *args)
report_ops("Reset", reset_count, reset_time_us);
}

if (fake_type == FKTY_CHAIN || fake_type == FKTY_LIMBO || fake_type == FKTY_CHAIN)
if (args->fix) {
AltraMayor marked this conversation as resolved.
Show resolved Hide resolved
char *cmd = NULL;
asprintf(&cmd, "f3fix --last-sec=%" PRIu64 " %s", last_good_sector, final_dev_filename);
system(cmd);
free(cmd);
AltraMayor marked this conversation as resolved.
Show resolved Hide resolved
}
free((void *)final_dev_filename);
return fake_type == FKTY_GOOD ? 0 : 100 + fake_type;
}
Expand Down Expand Up @@ -545,6 +561,7 @@ int main(int argc, char **argv)
.block_order = 0,
.cache_order = -1,
.strict_cache = false,
.fix = false,
};

/* Read parameters. */
Expand Down
24 changes: 19 additions & 5 deletions f3write.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ static struct argp_option options[] = {
"Maximum write rate", 0},
{"show-progress", 'p', "NUM", 0,
"Show progress if NUM is not zero", 0},
{"keep", 'k', 0, 0,
AltraMayor marked this conversation as resolved.
Show resolved Hide resolved
"Keep existing NUM.h2w file, otherwise all NUM.h2w files will be removed in each run", 0},
AltraMayor marked this conversation as resolved.
Show resolved Hide resolved
{ 0 }
};

Expand All @@ -47,6 +49,7 @@ struct args {
long end_at;
long max_write_rate;
int show_progress;
int keep;
AltraMayor marked this conversation as resolved.
Show resolved Hide resolved
const char *dev_path;
};

Expand Down Expand Up @@ -84,6 +87,10 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state)
args->show_progress = !!arg_to_long(state, arg);
break;

case 'k':
args->keep = 1;
AltraMayor marked this conversation as resolved.
Show resolved Hide resolved
break;

case ARGP_KEY_INIT:
args->dev_path = NULL;
break;
Expand Down Expand Up @@ -170,7 +177,7 @@ static int write_chunk(int fd, size_t chunk_size, uint64_t *poffset)

/* Return true when disk is full. */
static int create_and_fill_file(const char *path, long number, size_t size,
int *phas_suggested_max_write_rate, struct flow *fw)
int *phas_suggested_max_write_rate, struct flow *fw, int keep)
{
char *full_fn;
const char *filename;
Expand All @@ -184,6 +191,11 @@ static int create_and_fill_file(const char *path, long number, size_t size,
/* Create the file. */
full_fn = full_fn_from_number(&filename, path, number);
assert(full_fn);
if(access(full_fn, F_OK) != -1 && keep)
{
printf("Skipping file %s\n", filename);
return false;
}
AltraMayor marked this conversation as resolved.
Show resolved Hide resolved
printf("Creating file %s ... ", filename);
fflush(stdout);
fd = open(full_fn, O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR);
Expand Down Expand Up @@ -273,7 +285,7 @@ static int flush_chunk(const struct flow *fw, int fd)
}

static int fill_fs(const char *path, long start_at, long end_at,
long max_write_rate, int progress)
long max_write_rate, int progress, int keep)
{
uint64_t free_space;
struct flow fw;
Expand Down Expand Up @@ -310,7 +322,7 @@ static int fill_fs(const char *path, long start_at, long end_at,
assert(!gettimeofday(&t1, NULL));
for (i = start_at; i <= end_at; i++)
if (create_and_fill_file(path, i, GIGABYTES,
&has_suggested_max_write_rate, &fw))
&has_suggested_max_write_rate, &fw, keep))
break;
assert(!gettimeofday(&t2, NULL));

Expand Down Expand Up @@ -360,6 +372,7 @@ int main(int argc, char **argv)
.start_at = 0,
.end_at = LONG_MAX - 1,
.max_write_rate = 0,
.keep = 0,
AltraMayor marked this conversation as resolved.
Show resolved Hide resolved
/* If stdout isn't a terminal, supress progress. */
.show_progress = isatty(STDOUT_FILENO),
};
Expand All @@ -368,8 +381,9 @@ int main(int argc, char **argv)
argp_parse(&argp, argc, argv, 0, NULL, &args);
print_header(stdout, "write");

unlink_old_files(args.dev_path, args.start_at, args.end_at);
if(!args.keep)
unlink_old_files(args.dev_path, args.start_at, args.end_at);

return fill_fs(args.dev_path, args.start_at, args.end_at,
args.max_write_rate, args.show_progress);
args.max_write_rate, args.show_progress, args.keep);
}