From: Amir Goldstein Date: Thu, 7 Sep 2017 10:03:08 +0000 (+0300) Subject: replay-log: add support for replaying ops in target device sector range X-Git-Tag: v2022.05.01~1880 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=b65b808ee3df0b35fc013ef959e59b99ed27aae1;p=users%2Fhch%2Fxfstests-dev.git replay-log: add support for replaying ops in target device sector range Using command line options --start-sector and --end-sector, only operations acting on the specified target device range will be replayed. Single vebbose mode (-v) prints out only replayed operations. Double verbose mode (-vv) prints out also skipped operations. Signed-off-by: Amir Goldstein Reviewed-by: Eryu Guan Signed-off-by: Eryu Guan --- diff --git a/src/log-writes/log-writes.c b/src/log-writes/log-writes.c index dbfeef7ad..fab447a86 100644 --- a/src/log-writes/log-writes.c +++ b/src/log-writes/log-writes.c @@ -117,6 +117,27 @@ int log_discard(struct log *log, struct log_write_entry *entry) return 0; } +/* + * @log: the log we are replaying. + * @entry: entry to be replayed. + * + * @return: 0 if we should replay the entry, > 0 if we should skip it. + * + * Should we skip the entry in our log or replay onto the replay device. + */ +int log_should_skip(struct log *log, struct log_write_entry *entry) +{ + u64 sector = le64_to_cpu(entry->sector); + u64 nr_sectors = le64_to_cpu(entry->nr_sectors); + + if (!nr_sectors) + return 0; + if (sector + nr_sectors <= log->start_sector || + sector > log->end_sector) + return 1; + return 0; +} + /* * @entry: entry to be replayed. * @@ -157,6 +178,7 @@ int log_replay_next_entry(struct log *log, struct log_write_entry *entry, char *buf; ssize_t ret; off_t offset; + int skip = 0; if (log->cur_entry >= log->nr_entries) return 1; @@ -185,8 +207,10 @@ int log_replay_next_entry(struct log *log, struct log_write_entry *entry, log->cur_pos += read_size; } - if (log_writes_verbose) { - printf("replaying %d@%llu: sector %llu, size %llu, flags %llu\n", + skip = log_should_skip(log, entry); + if (log_writes_verbose > 1 || (log_writes_verbose && !skip)) { + printf("%s %d@%llu: sector %llu, size %llu, flags %llu\n", + skip ? "skipping" : "replaying", (int)log->cur_entry - 1, log->cur_pos / log->sectorsize, (unsigned long long)le64_to_cpu(entry->sector), (unsigned long long)size, @@ -199,6 +223,15 @@ int log_replay_next_entry(struct log *log, struct log_write_entry *entry, if (flags & LOG_DISCARD_FLAG) return log_discard(log, entry); + if (skip) { + log->cur_pos = lseek(log->logfd, size, SEEK_CUR); + if (log->cur_pos == (off_t)-1) { + fprintf(stderr, "Error seeking in log: %d\n", errno); + return -1; + } + return 0; + } + buf = malloc(size); if (!buf) { fprintf(stderr, "Error allocating buffer %llu entry %llu\n", (unsigned long long)size, (unsigned long long)log->cur_entry - 1); diff --git a/src/log-writes/log-writes.h b/src/log-writes/log-writes.h index cdb008b3f..35ca35838 100644 --- a/src/log-writes/log-writes.h +++ b/src/log-writes/log-writes.h @@ -67,6 +67,8 @@ struct log { int replayfd; unsigned long flags; u64 sectorsize; + u64 start_sector; + u64 end_sector; u64 nr_entries; u64 cur_entry; u64 max_zero_size; diff --git a/src/log-writes/replay-log.c b/src/log-writes/replay-log.c index cf6793157..845793757 100644 --- a/src/log-writes/replay-log.c +++ b/src/log-writes/replay-log.c @@ -20,6 +20,8 @@ enum option_indexes { FSCK, CHECK, START_MARK, + START_SECTOR, + END_SECTOR, }; static struct option long_options[] = { @@ -37,6 +39,8 @@ static struct option long_options[] = { {"fsck", required_argument, NULL, 0}, {"check", required_argument, NULL, 0}, {"start-mark", required_argument, NULL, 0}, + {"start-sector", required_argument, NULL, 0}, + {"end-sector", required_argument, NULL, 0}, { NULL, 0, NULL, 0 }, }; @@ -61,6 +65,12 @@ static void usage(void) "--check\n"); fprintf(stderr, "\t--check [|flush|fua] when to check the " "file system, mush specify --fsck\n"); + fprintf(stderr, "\t--start-sector - replay ops on region " + "from onto \n"); + fprintf(stderr, "\t--end-sector - replay ops on region " + "to onto \n"); + fprintf(stderr, "\t-v or --verbose - print replayed ops\n"); + fprintf(stderr, "\t-vv - print also skipped ops\n"); exit(1); } @@ -129,6 +139,8 @@ int main(int argc, char **argv) struct log_write_entry *entry; u64 stop_flags = 0; u64 start_entry = 0; + u64 start_sector = 0; + u64 end_sector = -1ULL; u64 run_limit = 0; u64 num_entries = 0; u64 check_number = 0; @@ -249,6 +261,22 @@ int main(int argc, char **argv) tmp = NULL; } break; + case START_SECTOR: + start_sector = strtoull(optarg, &tmp, 0); + if (tmp && *tmp != '\0') { + fprintf(stderr, "Invalid sector number\n"); + exit(1); + } + tmp = NULL; + break; + case END_SECTOR: + end_sector = strtoull(optarg, &tmp, 0); + if (tmp && *tmp != '\0') { + fprintf(stderr, "Invalid sector number\n"); + exit(1); + } + tmp = NULL; + break; default: usage(); } @@ -266,6 +294,9 @@ int main(int argc, char **argv) if (!discard) log->flags |= LOG_IGNORE_DISCARD; + log->start_sector = start_sector; + log->end_sector = end_sector; + entry = malloc(log->sectorsize); if (!entry) { fprintf(stderr, "Couldn't allocate buffer\n");