[Cluster-devel] [PATCH 2/2] gfs2_edit: savemeta and restoremeta improvements
Andrew Price
anprice at redhat.com
Mon May 19 11:55:00 UTC 2014
This adds various improvements to savemeta and restoremeta including:
- Made the saved_metablock buffer a flexible array to make better use of
sizeof() etc.
- Read/write saved_metablock structures with one read/write call instead
of one per field (gives a small perf improvement).
- Factor out the block restore code and split the "find highest block"
code out of restore_data.
- Print more, clearer information relating to the metadata file,
progress made and errors.
- Made global variables static, removed unused ones.
- Improved code clarity, separation of concerns.
Signed-off-by: Andrew Price <anprice at redhat.com>
---
gfs2/edit/savemeta.c | 474 +++++++++++++++++++++++++++------------------------
tests/edit.at | 2 +-
2 files changed, 255 insertions(+), 221 deletions(-)
diff --git a/gfs2/edit/savemeta.c b/gfs2/edit/savemeta.c
index a10da19..e336100 100644
--- a/gfs2/edit/savemeta.c
+++ b/gfs2/edit/savemeta.c
@@ -27,7 +27,6 @@
#include "hexedit.h"
#include "libgfs2.h"
-#define BUFSIZE (4096)
#define DFT_SAVE_FILE "/tmp/gfsmeta.XXXXXX"
#define MAX_JOURNALS_SAVED 256
@@ -45,8 +44,11 @@ struct savemeta_header {
struct saved_metablock {
uint64_t blk;
uint16_t siglen; /* significant data length */
- char buf[BUFSIZE];
-};
+ char buf[];
+/* This needs to be packed because old versions of gfs2_edit read and write the
+ individual fields separately, so the hole after siglen must be eradicated
+ before the struct reflects what's on disk. */
+} __attribute__((__packed__));
struct metafd {
int fd;
@@ -55,15 +57,12 @@ struct metafd {
int gziplevel;
};
-struct saved_metablock *savedata;
-uint64_t last_reported_block, blks_saved, total_out, pct;
-uint64_t journal_blocks[MAX_JOURNALS_SAVED];
-uint64_t gfs1_journal_size = 0; /* in blocks */
-int journals_found = 0;
+static uint64_t blks_saved;
+static uint64_t journal_blocks[MAX_JOURNALS_SAVED];
+static uint64_t gfs1_journal_size = 0; /* in blocks */
+static int journals_found = 0;
int print_level = MSG_NOTICE;
-extern void read_superblock(void);
-
static int block_is_a_journal(void)
{
int j;
@@ -121,7 +120,7 @@ static const char *anthropomorphize(unsigned long long inhuman_value)
remainder = val % 1024;
val /= 1024;
}
- sprintf(out_val, "%llu.%llu%c", val, remainder, symbols[i]);
+ sprintf(out_val, "%llu.%llu%cB", val, remainder, symbols[i]);
return out_val;
}
@@ -223,8 +222,7 @@ static void warm_fuzzy_stuff(uint64_t wfsblock, int force)
{
static struct timeval tv;
static uint32_t seconds = 0;
-
- last_reported_block = wfsblock;
+
gettimeofday(&tv, NULL);
if (!seconds)
seconds = tv.tv_sec;
@@ -235,8 +233,7 @@ static void warm_fuzzy_stuff(uint64_t wfsblock, int force)
if (sbd.fssize) {
printf("\r");
percent = (wfsblock * 100) / sbd.fssize;
- printf("%llu inodes processed, %llu blocks saved "
- "(%llu%%) processed, ",
+ printf("%llu blocks processed, %llu saved (%llu%%)",
(unsigned long long)wfsblock,
(unsigned long long)blks_saved,
(unsigned long long)percent);
@@ -339,10 +336,10 @@ static int savemetaclose(struct metafd *mfd)
static int save_block(int fd, struct metafd *mfd, uint64_t blk)
{
- int blktype, blklen, outsz;
- uint16_t trailing0;
- char *p;
+ int blktype, blklen;
+ size_t outsz;
struct gfs2_buffer_head *savebh;
+ struct saved_metablock *savedata;
if (gfs2_check_range(&sbd, blk) && blk != sbd.sb_addr) {
fprintf(stderr, "\nWarning: bad block pointer '0x%llx' "
@@ -351,9 +348,7 @@ static int save_block(int fd, struct metafd *mfd, uint64_t blk)
(unsigned long long)block, (unsigned long long)block);
return 0;
}
- memset(savedata, 0, sizeof(struct saved_metablock));
savebh = bread(&sbd, blk);
- memcpy(&savedata->buf, savebh->b_data, sbd.bsize);
/* If this isn't metadata and isn't a system file, we don't want it.
Note that we're checking "block" here rather than blk. That's
@@ -365,43 +360,34 @@ static int save_block(int fd, struct metafd *mfd, uint64_t blk)
brelse(savebh);
return 0; /* Not metadata, and not system file, so skip it */
}
- trailing0 = 0;
- p = &savedata->buf[blklen - 1];
- while (*p=='\0' && trailing0 < sbd.bsize) {
- trailing0++;
- p--;
+
+ /* No need to save trailing zeroes */
+ for (; blklen > 0 && savebh->b_data[blklen - 1] == '\0'; blklen--);
+
+ if (blklen == 0) /* No significant data; skip. */
+ return 0;
+
+ outsz = sizeof(*savedata) + blklen;
+ savedata = calloc(1, outsz);
+ if (savedata == NULL) {
+ perror("Failed to save block");
+ exit(1);
}
savedata->blk = cpu_to_be64(blk);
- if (savemetawrite(mfd, &savedata->blk, sizeof(savedata->blk)) !=
- sizeof(savedata->blk)) {
- fprintf(stderr, "write error: %s from %s:%d: "
- "block %lld (0x%llx)\n", strerror(errno),
- __FUNCTION__, __LINE__,
- (unsigned long long)savedata->blk,
- (unsigned long long)savedata->blk);
- exit(-1);
- }
- outsz = blklen - trailing0;
- savedata->siglen = cpu_to_be16(outsz);
- if (savemetawrite(mfd, &savedata->siglen, sizeof(savedata->siglen)) !=
- sizeof(savedata->siglen)) {
- fprintf(stderr, "write error: %s from %s:%d: "
- "block %lld (0x%llx)\n", strerror(errno),
- __FUNCTION__, __LINE__,
- (unsigned long long)savedata->blk,
- (unsigned long long)savedata->blk);
- exit(-1);
- }
- if (savemetawrite(mfd, savedata->buf, outsz) != outsz) {
- fprintf(stderr, "write error: %s from %s:%d: "
- "block %lld (0x%llx)\n", strerror(errno),
- __FUNCTION__, __LINE__,
+ savedata->siglen = cpu_to_be16(blklen);
+ memcpy(savedata->buf, savebh->b_data, blklen);
+
+ if (savemetawrite(mfd, savedata, outsz) != outsz) {
+ fprintf(stderr, "write error: %s from %s:%d: block %lld (0x%llx)\n",
+ strerror(errno), __FUNCTION__, __LINE__,
(unsigned long long)savedata->blk,
(unsigned long long)savedata->blk);
+ free(savedata);
exit(-1);
}
- total_out += sizeof(savedata->blk) + sizeof(savedata->siglen) + outsz;
+
blks_saved++;
+ free(savedata);
brelse(savebh);
return blktype;
}
@@ -701,6 +687,7 @@ static int read_header(gzFile gzin_fd, struct savemeta_header *smh)
size_t rs;
struct savemeta_header smh_be = {0};
+ gzseek(gzin_fd, 0, SEEK_SET);
rs = gzread(gzin_fd, &smh_be, sizeof(smh_be));
if (rs == -1) {
perror("Failed to read savemeta file header");
@@ -721,8 +708,7 @@ static int check_header(struct savemeta_header *smh)
{
if (smh->sh_magic != SAVEMETA_MAGIC || smh->sh_format > SAVEMETA_FORMAT)
return -1;
- printf("Savemeta file format %"PRIu32"\n", smh->sh_format);
- printf("Created %s\n", ctime((time_t *)&smh->sh_time));
+ printf("Metadata saved at %s", ctime((time_t *)&smh->sh_time)); /* ctime() adds \n */
printf("File system size %s\n", anthropomorphize(smh->sh_fs_bytes));
return 0;
}
@@ -741,14 +727,10 @@ void savemeta(char *out_fn, int saveoption, int gziplevel)
mfd = savemetaopen(out_fn, gziplevel);
- savedata = malloc(sizeof(struct saved_metablock));
- if (!savedata)
- die("Can't allocate memory for the operation.\n");
-
lseek(sbd.device_fd, 0, SEEK_SET);
- blks_saved = total_out = last_reported_block = 0;
+ blks_saved = 0;
if (!sbd.gfs1)
- sbd.bsize = BUFSIZE;
+ sbd.bsize = GFS2_DEFAULT_BSIZE;
if (lgfs2_get_dev_info(sbd.device_fd, &sbd.dinfo)) {
perror(sbd.device_name);
exit(-1);
@@ -864,7 +846,6 @@ void savemeta(char *out_fn, int saveoption, int gziplevel)
} else {
printf("(uncompressed).\n");
}
- free(savedata);
savemetaclose(&mfd);
close(sbd.device_fd);
free(indirect);
@@ -872,174 +853,227 @@ void savemeta(char *out_fn, int saveoption, int gziplevel)
exit(0);
}
-static int restore_data(int fd, gzFile gzin_fd, int printblocksonly,
- int find_highblk, const int startpos)
+static off_t restore_init(gzFile gzfd, struct savemeta_header *smh)
{
+ int err;
+ unsigned i;
size_t rs;
- uint64_t buf64, writes = 0, highest_valid_block = 0;
- uint16_t buf16;
- int first = 1, pos, gzerr;
- char rdbuf[256];
- char gfs_superblock_id[8] = {0x01, 0x16, 0x19, 0x70,
- 0x00, 0x00, 0x00, 0x01};
-
- if (!printblocksonly)
- lseek(fd, 0, SEEK_SET);
- gzseek(gzin_fd, startpos, SEEK_SET);
- rs = gzread(gzin_fd, rdbuf, sizeof(rdbuf));
- if (rs != sizeof(rdbuf)) {
+ char buf[256];
+ off_t startpos = 0;
+ struct saved_metablock *svb;
+ struct gfs2_meta_header *sbmh;
+
+ err = read_header(gzfd, smh);
+ if (err < 0) {
+ exit(1);
+ } else if (check_header(smh) != 0) {
+ printf("No valid file header found. Falling back to old format...\n");
+ } else if (err == 0) {
+ startpos = sizeof(*smh);
+ }
+
+ gzseek(gzfd, startpos, SEEK_SET);
+ rs = gzread(gzfd, buf, sizeof(buf));
+ if (rs != sizeof(buf)) {
fprintf(stderr, "Error: File is too small.\n");
- return -1;
+ exit(1);
}
- for (pos = startpos; pos < startpos + sizeof(rdbuf) - sizeof(uint64_t) - sizeof(uint16_t);
- pos++) {
- if (!memcmp(&rdbuf[pos + sizeof(uint64_t) + sizeof(uint16_t)],
- gfs_superblock_id, sizeof(gfs_superblock_id))) {
+ /* Scan for the beginning of the file body. Required to support old formats(?). */
+ for (i = 0; i < (256 - sizeof(*svb) - sizeof(*sbmh)); i++) {
+ svb = (struct saved_metablock *)&buf[i];
+ sbmh = (struct gfs2_meta_header *)svb->buf;
+ if (sbmh->mh_magic == cpu_to_be32(GFS2_MAGIC) &&
+ sbmh->mh_type == cpu_to_be32(GFS2_METATYPE_SB))
break;
+ }
+ if (i == (sizeof(buf) - sizeof(*svb) - sizeof(*sbmh)))
+ i = 0;
+ return startpos + i; /* File offset of saved sb */
+}
+
+
+static int restore_block(gzFile gzfd, struct saved_metablock *svb, uint16_t maxlen)
+{
+ int gzerr;
+ int ret;
+ uint16_t checklen;
+ const char *errstr;
+
+ ret = gzread(gzfd, svb, sizeof(*svb));
+ if (ret < sizeof(*svb)) {
+ goto gzread_err;
+ }
+ svb->blk = be64_to_cpu(svb->blk);
+ svb->siglen = be16_to_cpu(svb->siglen);
+
+ if (sbd.fssize && svb->blk >= sbd.fssize) {
+ fprintf(stderr, "Error: File system is too small to restore this metadata.\n");
+ fprintf(stderr, "File system is %llu blocks. Restore block = %llu\n",
+ (unsigned long long)sbd.fssize, (unsigned long long)svb->blk);
+ return -1;
+ }
+
+ if (maxlen)
+ checklen = maxlen;
+ else
+ checklen = sbd.bsize;
+
+ if (checklen && svb->siglen > checklen) {
+ fprintf(stderr, "Bad record length: %u for block %"PRIu64" (0x%"PRIx64").\n",
+ svb->siglen, svb->blk, svb->blk);
+ return -1;
+ }
+
+ if (maxlen) {
+ ret = gzread(gzfd, svb + 1, svb->siglen);
+ if (ret < svb->siglen) {
+ goto gzread_err;
}
}
- if (pos == startpos + sizeof(rdbuf) - sizeof(uint64_t) - sizeof(uint16_t))
- pos = startpos;
- if (gzseek(gzin_fd, pos, SEEK_SET) != pos) {
- fprintf(stderr, "bad seek: %s from %s:%d: "
- "offset %lld (0x%llx)\n", strerror(errno),
- __FUNCTION__, __LINE__, (unsigned long long)pos,
- (unsigned long long)pos);
- exit(-1);
+
+ return 0;
+
+gzread_err:
+ if (gzeof(gzfd))
+ return 1;
+
+ errstr = gzerror(gzfd, &gzerr);
+ if (gzerr == Z_ERRNO)
+ errstr = strerror(errno);
+ fprintf(stderr, "Failed to restore block: %s\n", errstr);
+ return -1;
+}
+
+static int restore_super(gzFile gzfd, off_t pos)
+{
+ int ret;
+ struct saved_metablock *svb;
+ struct gfs2_buffer_head dummy_bh;
+ size_t len = sizeof(*svb) + sizeof(struct gfs2_sb);
+
+ svb = calloc(1, len);
+ if (svb == NULL) {
+ perror("Failed to restore super block");
+ exit(1);
}
- blks_saved = total_out = 0;
- while (TRUE) {
- struct gfs2_buffer_head dummy_bh;
+ gzseek(gzfd, pos, SEEK_SET);
+ ret = restore_block(gzfd, svb, sizeof(struct gfs2_sb));
+ if (ret == 1) {
+ fprintf(stderr, "Reached end of file while restoring superblock\n");
+ goto err;
+ } else if (ret != 0) {
+ goto err;
+ }
+
+ dummy_bh.b_data = (char *)svb->buf;
+ gfs2_sb_in(&sbd.sd_sb, &dummy_bh);
+ sbd1 = (struct gfs_sb *)&sbd.sd_sb;
+ ret = check_sb(&sbd.sd_sb);
+ if (ret < 0) {
+ fprintf(stderr,"Error: Invalid superblock data.\n");
+ goto err;
+ }
+ if (ret == 1)
+ sbd.gfs1 = 1;
+ sbd.bsize = sbd.sd_sb.sb_bsize;
+ free(svb);
+ printf("Block size is %uB\n", sbd.bsize);
+ return 0;
+err:
+ free(svb);
+ return -1;
+}
+
+static int find_highest_block(gzFile gzfd, off_t pos, uint64_t fssize)
+{
+ int err = 0;
+ uint64_t highest = 0;
+ struct saved_metablock svb = {0};
- memset(savedata, 0, sizeof(struct saved_metablock));
- rs = gzread(gzin_fd, &buf64, sizeof(uint64_t));
- if (!rs)
+ while (1) {
+ gzseek(gzfd, pos, SEEK_SET);
+ err = restore_block(gzfd, &svb, 0);
+ if (err == 1)
break;
- if (rs != sizeof(uint64_t)) {
- fprintf(stderr, "Error reading from file.\n");
- return -1;
- }
- total_out += sbd.bsize;
- savedata->blk = be64_to_cpu(buf64);
- if (!printblocksonly &&
- sbd.fssize && savedata->blk >= sbd.fssize) {
- fprintf(stderr, "Error: File system is too small to "
- "restore this metadata.\n");
- fprintf(stderr, "File system is %llu blocks, ",
- (unsigned long long)sbd.fssize);
- fprintf(stderr, "Restore block = %llu\n",
- (unsigned long long)savedata->blk);
+ if (err != 0)
return -1;
- }
- if (gzread(gzin_fd, &buf16, sizeof(uint16_t)) !=
- sizeof(uint16_t)) {
- fprintf(stderr, "read error: %s from %s:%d: "
- "block %lld (0x%llx)\n",
- gzerror(gzin_fd, &gzerr), __FUNCTION__, __LINE__,
- (unsigned long long)savedata->blk,
- (unsigned long long)savedata->blk);
- exit(-1);
- }
- savedata->siglen = be16_to_cpu(buf16);
- if (savedata->siglen > sizeof(savedata->buf)) {
- fprintf(stderr, "\nBad record length: %d for block #%llu"
- " (0x%llx).\n", savedata->siglen,
- (unsigned long long)savedata->blk,
- (unsigned long long)savedata->blk);
+
+ if (svb.blk > highest)
+ highest = svb.blk;
+ pos += sizeof(svb) + svb.siglen;
+ }
+
+ if (fssize > 0) {
+ printf("Saved file system size is %"PRIu64" (0x%"PRIx64") blocks, %s\n",
+ fssize, fssize, anthropomorphize(fssize * sbd.bsize));
+ sbd.fssize = fssize;
+ } else {
+ sbd.fssize = highest + 1;
+ }
+
+ printf("Highest saved block is %"PRIu64" (0x%"PRIx64")\n", highest, highest);
+ return 0;
+}
+
+static int restore_data(int fd, gzFile gzin_fd, off_t pos, int printonly)
+{
+ struct saved_metablock *savedata;
+ size_t insz = sizeof(*savedata) + sbd.bsize;
+ uint64_t writes = 0;
+
+ savedata = calloc(1, insz);
+ if (savedata == NULL) {
+ perror("Failed to restore data");
+ exit(1);
+ }
+
+ gzseek(gzin_fd, pos, SEEK_SET);
+ blks_saved = 0;
+ while (TRUE) {
+ int err;
+ err = restore_block(gzin_fd, savedata, sbd.bsize);
+ if (err == 1)
+ break;
+ if (err != 0) {
+ free(savedata);
return -1;
}
- if (savedata->siglen &&
- gzread(gzin_fd, savedata->buf, savedata->siglen) !=
- savedata->siglen) {
- fprintf(stderr, "read error: %s from %s:%d: "
- "block %lld (0x%llx)\n",
- gzerror(gzin_fd, &gzerr), __FUNCTION__, __LINE__,
- (unsigned long long)savedata->blk,
- (unsigned long long)savedata->blk);
- exit(-1);
- }
- if (first) {
- struct gfs2_sb bufsb;
- int ret;
-
- dummy_bh.b_data = (char *)&bufsb;
- memcpy(&bufsb, savedata->buf, sizeof(bufsb));
- gfs2_sb_in(&sbd.sd_sb, &dummy_bh);
- sbd1 = (struct gfs_sb *)&sbd.sd_sb;
- ret = check_sb(&sbd.sd_sb);
- if (ret < 0) {
- fprintf(stderr,"Error: Invalid superblock data.\n");
- return -1;
- }
- if (ret == 1)
- sbd.gfs1 = TRUE;
- sbd.bsize = sbd.sd_sb.sb_bsize;
- if (find_highblk)
- ;
- else if (!printblocksonly) {
- sbd.fssize =
- lseek(fd, 0, SEEK_END) / sbd.bsize;
- printf("There are %llu blocks of %u bytes in "
- "the destination device.\n\n",
- (unsigned long long)sbd.fssize, sbd.bsize);
- } else {
- printf("This is %s metadata\n", sbd.gfs1 ?
- "gfs (not gfs2)" : "gfs2");
- }
- first = 0;
- }
- bh = &dummy_bh;
- bh->b_data = savedata->buf;
- if (savedata->blk > highest_valid_block)
- highest_valid_block = savedata->blk;
- if (find_highblk)
- ;
- else if (printblocksonly) {
+
+ if (printonly) {
+ struct gfs2_buffer_head dummy_bh;
+ dummy_bh.b_data = savedata->buf;
+ bh = &dummy_bh;
block = savedata->blk;
- if (printblocksonly > 1 && printblocksonly == block) {
+ if (printonly > 1 && printonly == block) {
block_in_mem = block;
display(0, 0, 0, 0);
bh = NULL;
- return 0;
- } else if (printblocksonly == 1) {
- print_gfs2("%d (l=0x%x): ", blks_saved,
- savedata->siglen);
+ break;
+ } else if (printonly == 1) {
+ print_gfs2("%d (l=0x%x): ", blks_saved, savedata->siglen);
display_block_type(TRUE);
}
+ bh = NULL;
} else {
warm_fuzzy_stuff(savedata->blk, FALSE);
- if (savedata->blk >= sbd.fssize) {
- printf("\nOut of space on the destination "
- "device; quitting.\n");
- bh = NULL;
- break;
- }
+ memset(savedata->buf + savedata->siglen, 0, sbd.bsize - savedata->siglen);
if (pwrite(fd, savedata->buf, sbd.bsize, savedata->blk * sbd.bsize) != sbd.bsize) {
- fprintf(stderr, "write error: %s from "
- "%s:%d: block %lld (0x%llx)\n",
- strerror(errno), __FUNCTION__,
- __LINE__,
+ fprintf(stderr, "write error: %s from %s:%d: block %lld (0x%llx)\n",
+ strerror(errno), __FUNCTION__, __LINE__,
(unsigned long long)savedata->blk,
(unsigned long long)savedata->blk);
- exit(-1);
+ free(savedata);
+ return -1;
}
writes++;
if (writes % 1000 == 0)
fsync(fd);
}
blks_saved++;
- /* Don't leave a dangling reference to our local dummy_bh */
- bh = NULL;
- }
- if (!printblocksonly && !find_highblk)
- warm_fuzzy_stuff(sbd.fssize, TRUE);
- if (find_highblk && startpos == 0) {
- printf("File system size: %lld (0x%llx) blocks, aka %sB\n",
- (unsigned long long)highest_valid_block,
- (unsigned long long)highest_valid_block,
- anthropomorphize(highest_valid_block * sbd.bsize));
- sbd.fssize = highest_valid_block;
}
+ if (!printonly)
+ warm_fuzzy_stuff(sbd.fssize, 1);
+ free(savedata);
return 0;
}
@@ -1050,56 +1084,56 @@ static void complain(const char *complaint)
"<dest file system>\n");
}
-void restoremeta(const char *in_fn, const char *out_device,
- uint64_t printblocksonly)
+void restoremeta(const char *in_fn, const char *out_device, uint64_t printonly)
{
int error;
gzFile gzfd;
- int startpos = 0;
+ off_t pos = 0;
struct savemeta_header smh = {0};
termlines = 0;
if (!in_fn)
complain("No source file specified.");
- if (!printblocksonly && !out_device)
+ if (!printonly && !out_device)
complain("No destination file system specified.");
+
gzfd = gzopen(in_fn, "rb");
if (!gzfd)
die("Can't open source file %s: %s\n",
in_fn, strerror(errno));
- if (!printblocksonly) {
+ if (!printonly) {
sbd.device_fd = open(out_device, O_RDWR);
if (sbd.device_fd < 0)
die("Can't open destination file system %s: %s\n",
out_device, strerror(errno));
} else if (out_device) /* for printsavedmeta, the out_device is an
optional block no */
- printblocksonly = check_keywords(out_device);
- savedata = malloc(sizeof(struct saved_metablock));
- if (!savedata)
- die("Can't allocate memory for the restore operation.\n");
-
- gzseek(gzfd, 0, SEEK_SET);
- error = read_header(gzfd, &smh);
- if (error < 0) {
+ printonly = check_keywords(out_device);
+
+ pos = restore_init(gzfd, &smh);
+ error = restore_super(gzfd, pos);
+ if (error)
exit(1);
- } else if (check_header(&smh) != 0) {
- printf("No valid file header found. Falling back to old format...\n");
- gzseek(gzfd, 0, SEEK_SET);
- } else if (error == 0) {
- startpos = sizeof(smh);
+
+ printf("This is gfs%c metadata.\n", sbd.gfs1 ? '1': '2');
+
+ if (!printonly) {
+ uint64_t space = lseek(sbd.device_fd, 0, SEEK_END) / sbd.bsize;
+ printf("There are %"PRIu64" free blocks on the destination device.\n", space);
}
- blks_saved = 0;
- restore_data(sbd.device_fd, gzfd, printblocksonly, 1, startpos);
- error = restore_data(sbd.device_fd, gzfd, printblocksonly, 0, startpos);
+ error = find_highest_block(gzfd, pos, sbd.fssize);
+ if (error)
+ exit(1);
+
+ error = restore_data(sbd.device_fd, gzfd, pos, printonly);
printf("File %s %s %s.\n", in_fn,
- (printblocksonly ? "print" : "restore"),
+ (printonly ? "print" : "restore"),
(error ? "error" : "successful"));
- free(savedata);
+
gzclose(gzfd);
- if (!printblocksonly)
+ if (!printonly)
close(sbd.device_fd);
free(indirect);
exit(error);
diff --git a/tests/edit.at b/tests/edit.at
index 014d118..3428d64 100644
--- a/tests/edit.at
+++ b/tests/edit.at
@@ -6,7 +6,7 @@ GFS_TGT_REGEN
AT_CHECK([$GFS_MKFS -p lock_nolock $GFS_TGT $(($(gfs_max_blocks 4096)/2))], 0, [ignore], [ignore])
AT_CHECK([gfs2_edit savemeta $GFS_TGT test.meta > savemeta.log], 0, [ignore], [ignore])
AT_CHECK([head -2 savemeta.log], 0, [There are 2621440 blocks of 4096 bytes in the destination device.
-Reading resource groups...Done. File system size: 4.1023G
+Reading resource groups...Done. File system size: 4.1023GB
], [ignore])
GFS_TGT_REGEN
AT_CHECK([gfs2_edit restoremeta test.meta $GFS_TGT], 0, [ignore], [ignore])
--
1.9.0
More information about the Cluster-devel
mailing list