Index: uspace/srv/bd/hr/raid4.c
===================================================================
--- uspace/srv/bd/hr/raid4.c	(revision 11111e4dfde463f8ab7ecab4ccb269cc49d1babc)
+++ uspace/srv/bd/hr/raid4.c	(revision 90eec9c053f43826a68930ff649f79c2b1d608c8)
@@ -87,5 +87,6 @@
 
 /*
- * Return first bad extent
+ * Returns (-1) if all extents are online,
+ * else returns index of first bad one.
  */
 static ssize_t hr_raid4_get_bad_ext(hr_volume_t *vol)
@@ -150,13 +151,14 @@
 {
 	errno_t rc;
-	size_t i, j;
+	size_t i;
 	void *xorbuf;
 	void *buf;
-
-	xorbuf = malloc(vol->bsize);
+	uint64_t len = vol->bsize * cnt;
+
+	xorbuf = malloc(len);
 	if (xorbuf == NULL)
 		return ENOMEM;
 
-	buf = malloc(vol->bsize);
+	buf = malloc(len);
 	if (buf == NULL) {
 		free(xorbuf);
@@ -164,22 +166,19 @@
 	}
 
-	/* read all other extents in stripe */
-	for (j = 0; j < cnt; j++) {
-		memset(xorbuf, 0, vol->bsize);
-		for (i = 0; i < vol->dev_no; i++) {
-			if (i == bad) {
-				continue;
-			} else {
-				rc = block_read_direct(vol->extents[i].svc_id,
-				    block, 1, buf);
-				if (rc != EOK)
-					goto end;
-				xor(xorbuf, buf, vol->bsize);
-			}
-		}
-		memcpy(data, xorbuf, vol->bsize);
-		data = (void *) ((uintptr_t) data + vol->bsize);
-		block++;
-	}
+	/* read all other extents in the stripe */
+	memset(xorbuf, 0, len);
+	for (i = 0; i < vol->dev_no; i++) {
+		if (i == bad) {
+			continue;
+		} else {
+			rc = block_read_direct(vol->extents[i].svc_id, block,
+			    cnt, buf);
+			if (rc != EOK)
+				goto end;
+			xor(xorbuf, buf, len);
+		}
+	}
+
+	memcpy(data, xorbuf, len);
 end:
 	free(xorbuf);
@@ -192,7 +191,8 @@
 {
 	errno_t rc;
-	size_t i, j;
+	size_t i;
 	void *xorbuf;
 	void *buf;
+	uint64_t len = vol->bsize * cnt;
 
 	ssize_t bad = hr_raid4_get_bad_ext(vol);
@@ -212,9 +212,9 @@
 	}
 
-	xorbuf = malloc(vol->bsize);
+	xorbuf = malloc(len);
 	if (xorbuf == NULL)
 		return ENOMEM;
 
-	buf = malloc(vol->bsize);
+	buf = malloc(len);
 	if (buf == NULL) {
 		free(xorbuf);
@@ -228,25 +228,21 @@
 		 * write new parity
 		 */
-		for (j = 0; j < cnt; j++) {
-			memset(xorbuf, 0, vol->bsize);
-			for (i = 1; i < vol->dev_no; i++) {
-				if (i == (size_t) bad) {
-					continue;
-				} else {
-					rc = block_read_direct(vol->extents[i].svc_id,
-					    ba, 1, buf);
-					if (rc != EOK)
-						goto end;
-					xor(xorbuf, buf, vol->bsize);
-				}
+		memset(xorbuf, 0, len);
+		for (i = 1; i < vol->dev_no; i++) {
+			if (i == (size_t) bad) {
+				continue;
+			} else {
+				rc = block_read_direct(vol->extents[i].svc_id,
+				    ba, cnt, buf);
+				if (rc != EOK)
+					goto end;
+				xor(xorbuf, buf, len);
 			}
-			xor(xorbuf, data, vol->bsize);
-			rc = block_write_direct(vol->extents[0].svc_id, ba, 1,
-			    xorbuf);
-			if (rc != EOK)
-				goto end;
-			data = (void *) ((uintptr_t) data + vol->bsize);
-			ba++;
-		}
+		}
+		xor(xorbuf, data, len);
+		rc = block_write_direct(vol->extents[0].svc_id, ba, cnt,
+		    xorbuf);
+		if (rc != EOK)
+			goto end;
 	} else {
 		/*
@@ -255,28 +251,24 @@
 		 * write parity, new data
 		 */
-		for (j = 0; j < cnt; j++) {
-			rc = block_read_direct(vol->extents[extent].svc_id, ba,
-			    1, xorbuf);
-			if (rc != EOK)
-				goto end;
-			rc = block_read_direct(vol->extents[0].svc_id, ba, 1,
-			    buf);
-			if (rc != EOK)
-				goto end;
-			xor(xorbuf, buf, vol->bsize);
-
-			xor(xorbuf, data, vol->bsize);
-
-			rc = block_write_direct(vol->extents[0].svc_id, ba, 1,
-			    xorbuf);
-			if (rc != EOK)
-				goto end;
-			rc = block_write_direct(vol->extents[extent].svc_id,
-			    ba, 1, data);
-			if (rc != EOK)
-				goto end;
-			data = (void *) ((uintptr_t) data + vol->bsize);
-			ba++;
-		}
+		rc = block_read_direct(vol->extents[extent].svc_id, ba, cnt,
+		    xorbuf);
+		if (rc != EOK)
+			goto end;
+		rc = block_read_direct(vol->extents[0].svc_id, ba, cnt, buf);
+		if (rc != EOK)
+			goto end;
+
+		xor(xorbuf, buf, len);
+
+		xor(xorbuf, data, len);
+
+		rc = block_write_direct(vol->extents[0].svc_id, ba, cnt,
+		    xorbuf);
+		if (rc != EOK)
+			goto end;
+		rc = block_write_direct(vol->extents[extent].svc_id, ba, cnt,
+		    data);
+		if (rc != EOK)
+			goto end;
 	}
 end:
@@ -290,13 +282,14 @@
 {
 	errno_t rc;
-	size_t i, j;
+	size_t i;
 	void *xorbuf;
 	void *buf;
-
-	xorbuf = malloc(vol->bsize);
+	uint64_t len = vol->bsize * cnt;
+
+	xorbuf = malloc(len);
 	if (xorbuf == NULL)
 		return ENOMEM;
 
-	buf = malloc(vol->bsize);
+	buf = malloc(len);
 	if (buf == NULL) {
 		free(xorbuf);
@@ -304,24 +297,23 @@
 	}
 
-	for (j = 0; j < cnt; j++) {
-		memset(xorbuf, 0, vol->bsize);
-		for (i = 1; i < vol->dev_no; i++) {
-			if (i == extent) {
-				xor(xorbuf, data, vol->bsize);
-			} else {
-				rc = block_read_direct(vol->extents[i].svc_id,
-				    block, 1, buf);
-				if (rc != EOK)
-					goto end;
-				xor(xorbuf, buf, vol->bsize);
-			}
-		}
-		rc = block_write_direct(vol->extents[0].svc_id, block, 1,
-		    xorbuf);
-		if (rc != EOK)
-			goto end;
-		data = (void *) ((uintptr_t) data + vol->bsize);
-		block++;
-	}
+	/*
+	 * parity = read and xor all other data extents, xor in new data
+	 *
+	 * XXX: subtract method
+	 */
+	memset(xorbuf, 0, len);
+	for (i = 1; i < vol->dev_no; i++) {
+		if (i == extent) {
+			xor(xorbuf, data, vol->bsize);
+		} else {
+			rc = block_read_direct(vol->extents[i].svc_id, block,
+			    cnt, buf);
+			if (rc != EOK)
+				goto end;
+			xor(xorbuf, buf, len);
+		}
+	}
+
+	rc = block_write_direct(vol->extents[0].svc_id, block, cnt, xorbuf);
 end:
 	free(xorbuf);
