cluster: RHEL6 - gfs2_edit: Fix loop arithmetic in restore_data

Andrew Price andyp at fedoraproject.org
Fri Jun 6 15:38:35 UTC 2014


Gitweb:        http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=961deb270edfe04820e6c3bf75c949690e0d03de
Commit:        961deb270edfe04820e6c3bf75c949690e0d03de
Parent:        a0e022ff14116bc6323222a8acd3ca9a894b4974
Author:        Andrew Price <anprice at redhat.com>
AuthorDate:    Tue Jun 3 23:11:12 2014 +0100
Committer:     Andrew Price <anprice at 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 at 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),


More information about the cluster-commits mailing list