Gitweb: http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=961deb270edfe0... Commit: 961deb270edfe04820e6c3bf75c949690e0d03de Parent: a0e022ff14116bc6323222a8acd3ca9a894b4974 Author: Andrew Price anprice@redhat.com AuthorDate: Tue Jun 3 23:11:12 2014 +0100 Committer: Andrew Price anprice@redhat.com CommitterDate: Wed Jun 4 16:17:09 2014 +0100
gfs2_edit: Fix loop arithmetic in restore_data
Compiling the previous commit with -O2 optimized away a memcmp and highlighted a bug related to how the loop which checked for a superblock in the first 256 bytes calculated the offsets to check within the buffer. This fixes the arithmetic and tidies up the code to clarify what this loop is doing, eradicating the memcmp for good measure.
Resolves: rhbz#1081523
Signed-off-by: Andrew Price anprice@redhat.com --- gfs2/edit/savemeta.c | 18 ++++++++++-------- 1 files changed, 10 insertions(+), 8 deletions(-)
diff --git a/gfs2/edit/savemeta.c b/gfs2/edit/savemeta.c index 27480cb..b06d164 100644 --- a/gfs2/edit/savemeta.c +++ b/gfs2/edit/savemeta.c @@ -857,8 +857,9 @@ static int restore_data(int fd, gzFile gzin_fd, int printblocksonly, uint16_t buf16; int first = 1, pos, gzerr; char rdbuf[256]; - char gfs_superblock_id[8] = {0x01, 0x16, 0x19, 0x70, - 0x00, 0x00, 0x00, 0x01}; + uint32_t magic = cpu_to_be32(GFS2_MAGIC); + const size_t hdsz = sizeof(uint64_t) + sizeof(uint16_t); + const size_t rdend = sizeof(rdbuf) - hdsz - sizeof(uint32_t);
if (!printblocksonly) lseek(fd, 0, SEEK_SET); @@ -868,15 +869,16 @@ static int restore_data(int fd, gzFile gzin_fd, int printblocksonly, fprintf(stderr, "Error: File is too small.\n"); return -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))) { + + for (pos = startpos; pos < rdend; pos++) { + char *buf = &rdbuf[pos + hdsz]; + uint32_t maybemagic = *(uint32_t *)buf; + if (maybemagic == magic) break; - } } - if (pos == startpos + sizeof(rdbuf) - sizeof(uint64_t) - sizeof(uint16_t)) + if (pos == rdend) 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),