Index: uspace/srv/bd/hr/hr.c
===================================================================
--- uspace/srv/bd/hr/hr.c	(revision 586b39d8d7511fc0d699b0599563a28895d58573)
+++ uspace/srv/bd/hr/hr.c	(revision d7768d1115f533b237625835d8aed661b5451cca)
@@ -188,4 +188,5 @@
 	switch (new_volume->level) {
 	case HR_LVL_1:
+		new_volume->RLQ = 0x00; /* XXX: yet unused */
 		new_volume->hr_ops.create = hr_raid1_create;
 		new_volume->hr_ops.init = hr_raid1_init;
@@ -194,4 +195,5 @@
 		break;
 	case HR_LVL_0:
+		new_volume->RLQ = 0x00;
 		new_volume->hr_ops.create = hr_raid0_create;
 		new_volume->hr_ops.init = hr_raid0_init;
@@ -205,4 +207,5 @@
 		break;
 	case HR_LVL_5:
+		new_volume->RLQ = HR_RLQ_RAID5_NR;
 		new_volume->hr_ops.create = hr_raid5_create;
 		new_volume->hr_ops.init = hr_raid5_init;
Index: uspace/srv/bd/hr/raid5.c
===================================================================
--- uspace/srv/bd/hr/raid5.c	(revision 586b39d8d7511fc0d699b0599563a28895d58573)
+++ uspace/srv/bd/hr/raid5.c	(revision d7768d1115f533b237625835d8aed661b5451cca)
@@ -95,5 +95,5 @@
 	errno_t rc;
 
-	assert(new_volume->level == HR_LVL_5);
+	assert(new_volume->level == HR_LVL_5 || new_volume->level == HR_LVL_4);
 
 	if (new_volume->extent_no < 3) {
@@ -121,5 +121,5 @@
 	uint64_t total_blkno;
 
-	assert(vol->level == HR_LVL_5);
+	assert(vol->level == HR_LVL_5 || vol->level == HR_LVL_4);
 
 	rc = hr_check_devs(vol, &total_blkno, &bsize);
@@ -531,12 +531,43 @@
 		return rc;
 
+	uint8_t RLQ = vol->RLQ;
+	hr_level_t level = vol->level;
+
 	uint64_t strip_size = vol->strip_size / vol->bsize; /* in blocks */
 	uint64_t stripe = (ba / strip_size); /* stripe number */
-	uint64_t p_extent = (stripe / (vol->extent_no - 1)) % vol->extent_no; /* parity extent */
+
+	/* parity extent */
+	uint64_t p_extent;
+	if (level == HR_LVL_4 && RLQ == HR_RLQ_RAID4_0) {
+		p_extent = 0;
+	} else if (level == HR_LVL_4 && RLQ == HR_RLQ_RAID4_N) {
+		p_extent = vol->extent_no - 1;
+	} else if (level == HR_LVL_5 && RLQ == HR_RLQ_RAID5_0R) {
+		p_extent = (stripe / (vol->extent_no - 1)) % vol->extent_no;
+	} else if (level == HR_LVL_5 &&
+	    (RLQ == HR_RLQ_RAID5_NR || RLQ == HR_RLQ_RAID5_NC)) {
+		p_extent = (vol->extent_no - 1) -
+		    (stripe / (vol->extent_no - 1)) % vol->extent_no;
+	} else {
+		return EINVAL;
+	}
+
 	uint64_t extent;
-	if ((stripe % (vol->extent_no - 1)) < p_extent)
-		extent = (stripe % (vol->extent_no - 1));
-	else
-		extent = ((stripe % (vol->extent_no - 1)) + 1);
+	if (level == HR_LVL_4 && RLQ == HR_RLQ_RAID4_0) {
+		extent = (stripe % (vol->extent_no - 1)) + 1;
+	} else if (level == HR_LVL_4 && RLQ == HR_RLQ_RAID4_N) {
+		extent = stripe % (vol->extent_no - 1);
+	} else if (level == HR_LVL_5 &&
+	    (RLQ == HR_RLQ_RAID5_0R || RLQ == HR_RLQ_RAID5_NR)) {
+		if ((stripe % (vol->extent_no - 1)) < p_extent)
+			extent = stripe % (vol->extent_no - 1);
+		else
+			extent = (stripe % (vol->extent_no - 1)) + 1;
+	} else if (level == HR_LVL_5 && RLQ == HR_RLQ_RAID5_NC) {
+		extent = ((stripe % (vol->extent_no - 1)) + p_extent + 1) % vol->extent_no;
+	} else {
+		return EINVAL;
+	}
+
 	uint64_t ext_stripe = stripe / (vol->extent_no - 1); /* stripe level */
 	uint64_t strip_off = ba % strip_size; /* strip offset */
@@ -617,13 +648,29 @@
 		left -= cnt;
 		strip_off = 0;
-		if (extent + 1 >= vol->extent_no ||
-		    (extent + 1 == p_extent && p_extent + 1 >= vol->extent_no))
-			ext_stripe++;
 		stripe++;
-		p_extent = (stripe / (vol->extent_no - 1)) % vol->extent_no; /* parity extent */
-		if ((stripe % (vol->extent_no - 1)) < p_extent)
-			extent = (stripe % (vol->extent_no - 1));
-		else
-			extent = ((stripe % (vol->extent_no - 1)) + 1);
+
+		ext_stripe = stripe / (vol->extent_no - 1); /* stripe level */
+
+		if (level == HR_LVL_5 && RLQ == HR_RLQ_RAID5_0R) {
+			p_extent = (stripe / (vol->extent_no - 1)) % vol->extent_no;
+		} else if (level == HR_LVL_5 &&
+		    (RLQ == HR_RLQ_RAID5_NR || RLQ == HR_RLQ_RAID5_NC)) {
+			p_extent = (vol->extent_no - 1) -
+			    (stripe / (vol->extent_no - 1)) % vol->extent_no;
+		}
+
+		if (level == HR_LVL_4 && RLQ == HR_RLQ_RAID4_0) {
+			extent = (stripe % (vol->extent_no - 1)) + 1;
+		} else if (level == HR_LVL_4 && RLQ == HR_RLQ_RAID4_N) {
+			extent = stripe % (vol->extent_no - 1);
+		} else if (level == HR_LVL_5 &&
+		    (RLQ == HR_RLQ_RAID5_0R || RLQ == HR_RLQ_RAID5_NR)) {
+			if ((stripe % (vol->extent_no - 1)) < p_extent)
+				extent = stripe % (vol->extent_no - 1);
+			else
+				extent = (stripe % (vol->extent_no - 1)) + 1;
+		} else if (level == HR_LVL_5 && RLQ == HR_RLQ_RAID5_NC) {
+			extent = ((stripe % (vol->extent_no - 1)) + p_extent + 1) % vol->extent_no;
+		}
 	}
 
Index: uspace/srv/bd/hr/superblock.c
===================================================================
--- uspace/srv/bd/hr/superblock.c	(revision 586b39d8d7511fc0d699b0599563a28895d58573)
+++ uspace/srv/bd/hr/superblock.c	(revision d7768d1115f533b237625835d8aed661b5451cca)
@@ -153,11 +153,15 @@
 
 	metadata->magic = host2uint64_t_le(HR_MAGIC);
+	metadata->version = host2uint32_t_le(~(0U)); /* unused */
 	metadata->extent_no = host2uint32_t_le(vol->extent_no);
+	/* index filled separately for each extent */
 	metadata->level = host2uint32_t_le(vol->level);
+	metadata->layout = host2uint32_t_le(vol->RLQ);
+	metadata->strip_size = host2uint32_t_le(vol->strip_size);
 	metadata->nblocks = host2uint64_t_le(vol->nblocks);
 	metadata->data_blkno = host2uint64_t_le(vol->data_blkno);
-	metadata->data_offset = host2uint32_t_le(vol->data_offset);
-	metadata->strip_size = host2uint32_t_le(vol->strip_size);
-
+	metadata->data_offset = host2uint64_t_le(vol->data_offset);
+	metadata->counter = host2uint64_t_le(~(0UL)); /* unused */
+	/* UUID generated separately for each extent */
 	str_cpy(metadata->devname, HR_DEVNAME_LEN, vol->devname);
 
@@ -231,9 +235,12 @@
 	}
 
+	/* TODO: handle version */
 	vol->level = uint32_t_le2host(metadata->level);
+	vol->RLQ = (uint8_t)uint32_t_le2host(metadata->layout);
+	vol->strip_size = uint32_t_le2host(metadata->strip_size);
 	vol->nblocks = uint64_t_le2host(metadata->nblocks);
 	vol->data_blkno = uint64_t_le2host(metadata->data_blkno);
-	vol->data_offset = uint32_t_le2host(metadata->data_offset);
-	vol->strip_size = uint32_t_le2host(metadata->strip_size);
+	vol->data_offset = uint64_t_le2host(metadata->data_offset);
+	vol->counter = uint64_t_le2host(0x00); /* unused */
 
 	if (str_cmp(metadata->devname, vol->devname) != 0) {
Index: uspace/srv/bd/hr/superblock.h
===================================================================
--- uspace/srv/bd/hr/superblock.h	(revision 586b39d8d7511fc0d699b0599563a28895d58573)
+++ uspace/srv/bd/hr/superblock.h	(revision d7768d1115f533b237625835d8aed661b5451cca)
@@ -48,13 +48,21 @@
 typedef struct hr_metadata {
 	uint64_t magic;
+	uint32_t version;	/* unused XXX */
 	uint32_t extent_no;
+
+	uint32_t index;		/* index of disk in array */
 	uint32_t level;
+	uint32_t layout;
+	uint32_t strip_size;
+
 	uint64_t nblocks;	/* all blocks */
 	uint64_t data_blkno;	/* usable blocks */
-	uint32_t data_offset;	/* block where data starts */
-	uint32_t index;		/* index of disk in array */
-	uint32_t strip_size;
-	uint32_t status;	/* yet unused */
+
+	uint64_t data_offset;	/* block where data starts */
+
+	uint64_t counter; /* unused */
+
 	uint8_t uuid[HR_UUID_LEN];
+
 	char devname[HR_DEVNAME_LEN];
 } hr_metadata_t;
Index: uspace/srv/bd/hr/var.h
===================================================================
--- uspace/srv/bd/hr/var.h	(revision 586b39d8d7511fc0d699b0599563a28895d58573)
+++ uspace/srv/bd/hr/var.h	(revision d7768d1115f533b237625835d8aed661b5451cca)
@@ -70,12 +70,26 @@
 	uint64_t nblocks;
 	uint64_t data_blkno;
-	uint32_t data_offset; /* in blocks */
+	uint64_t data_offset; /* in blocks */
 	uint32_t strip_size;
 
 	uint64_t rebuild_blk;
 
+	uint64_t counter; /* metadata syncing */
+
 	service_id_t svc_id;
 	hr_vol_status_t status;
 	hr_level_t level;
+	/*
+	 * SNIA
+	 * Common RAID Disk Data Format
+	 * Specification
+	 * Version 2.0 Revision 19
+	 */
+#define HR_RLQ_RAID4_0	0x00 /* RAID-4 Non-Rotating Parity 0 */
+#define HR_RLQ_RAID4_N	0x01 /* RAID-4 Non-Rotating Parity N */
+#define HR_RLQ_RAID5_0R	0x00 /* RAID-5 Rotating Parity 0 with Data Restart */
+#define HR_RLQ_RAID5_NR	0x02 /* RAID-5 Rotating Parity N with Data Restart */
+#define HR_RLQ_RAID5_NC	0x03 /* RAID-5 Rotating Parity N with Data Continuation */
+	uint8_t RLQ; /* RAID Level Qualifier */
 	char devname[HR_DEVNAME_LEN];
 } hr_volume_t;
