diff --git a/era_copy.c b/era_copy.c index 26a6e06..5ca625a 100644 --- a/era_copy.c +++ b/era_copy.c @@ -45,7 +45,7 @@ void read_era_invalidate_and_copy(FILE *fp, int src, int era_block_size) // read input XML char buf[XML_BUFSIZE] = { 0 }; char c = 0; - long long start = 0, length = 0; + long long start = 0, length = 0, total = 0; if (fgets(buf, XML_BUFSIZE, fp) == NULL) { fprintf(stderr, "Input block list is empty\n"); @@ -70,47 +70,67 @@ void read_era_invalidate_and_copy(FILE *fp, int src, int era_block_size) { break; } - start = start*era_block_size; - length = length*era_block_size; - // write a very simple binary format: SIGNATURE, start, length, data, ... - write(1, SIGNATURE, 8); - write(1, &start, 8); - write(1, &length, 8); - copy_blocks(src, 1, start, length); + start = start*era_block_size*512; + length = length*era_block_size*512; + if (src >= 0) + { + // write a very simple binary format: SIGNATURE, start, length, data, ... + write(1, SIGNATURE, 8); + write(1, &start, 8); + write(1, &length, 8); + copy_blocks(src, 1, start, length); + } + else + { + // calculate diff size + total += length; + } } if (sscanf(buf, " %c", &c) == 0 || c != 0) { fprintf(stderr, " expected, but \"%s\" found\n", buf); exit(1); } + if (src < 0) + { + printf("%lld bytes\n", total); + } } void era_copy(char *src_path, int era_block_size) { - int src; - src = open(src_path, O_RDONLY|O_LARGEFILE); - if (src < 0) + int src = -1; + if (src_path != NULL) { - fprintf(stderr, "Failed to open %s for reading: %s\n", src_path, strerror(errno)); - exit(1); + src = open(src_path, O_RDONLY|O_LARGEFILE); + if (src < 0) + { + fprintf(stderr, "Failed to open %s for reading: %s\n", src_path, strerror(errno)); + exit(1); + } } read_era_invalidate_and_copy(stdin, src, era_block_size); - close(src); + if (src_path != NULL) + { + close(src); + } } int main(int narg, char *args[]) { - if (narg < 3) + if (narg < 2) { fprintf(stderr, "era_copy - parses era_invalidate output and saves changed blocks to a stream\n" "(c) Vitaliy Filippov, 2019+, distributed under the terms of GNU GPLv3.0 or later license\n" "\n" "USAGE:\nera_invalidate --metadata-snapshot --written-since |\\\n" - " era_copy > era_copy.bin\n" + " era_copy [] > era_copy.bin\n" "\n" - "ERA_BLOCK_SIZE is the block size you used when creating dm-era device\n" - "You can take it from `dmsetup table `: it's the last number in the table\n" + "When invoked without , era_copy only calculates the future diff size and prints it\n" + "\n" + "ERA_BLOCK_SIZE is dm-era's granularity in 512-byte sectors you used when creating dm-era device\n" + "You can take it from `dmsetup table `: it's the last number in DM table\n" "For example, in `0 3625546496 era 259:3 259:2 65536` it's 65536\n" ); exit(1); @@ -121,6 +141,6 @@ int main(int narg, char *args[]) fprintf(stderr, "Incorrect era_block_size = %d\n", bs); exit(1); } - era_copy(args[2], bs); + era_copy(narg == 2 ? NULL : args[2], bs); return 0; }