Index: uspace/srv/bd/hr/superblock.c
===================================================================
--- uspace/srv/bd/hr/superblock.c	(revision a57dde49ad2bf8c8b7f23fde7e298e3a83f565db)
+++ uspace/srv/bd/hr/superblock.c	(revision 7a80c63a95d433b1d28299842a2a0ae1f5190b8e)
@@ -52,5 +52,4 @@
 static errno_t read_metadata(service_id_t, hr_metadata_t *);
 static errno_t hr_fill_meta_from_vol(hr_volume_t *, hr_metadata_t *);
-static errno_t validate_meta(hr_metadata_t *);
 
 errno_t hr_write_meta_to_vol(hr_volume_t *vol)
@@ -71,11 +70,16 @@
 		goto error;
 
+	/* rndgen */
+	fibril_usleep(1000);
+	rc = uuid_generate(&uuid);
+	if (rc != EOK)
+		goto error;
+
+	/* XXX: for now we just copy byte by byte as "encoding" */
+	memcpy(metadata->uuid, &uuid, sizeof(HR_UUID_LEN));
+	/* uuid_encode(&uuid, metadata->uuid); */
+
 	for (i = 0; i < vol->extent_no; i++) {
 		metadata->index = host2uint32_t_le(i);
-
-		rc = uuid_generate(&uuid);
-		if (rc != EOK)
-			goto error;
-		uuid_encode(&uuid, metadata->uuid);
 
 		rc = block_write_direct(vol->extents[i].svc_id, HR_META_OFF,
@@ -84,6 +88,4 @@
 			goto error;
 
-		/* rndgen */
-		fibril_usleep(1000);
 	}
 error:
@@ -100,4 +102,5 @@
 	uuid_t uuid;
 
+	/* XXX: use scratchpad */
 	metadata = calloc(1, HR_META_SIZE * vol->bsize);
 	if (metadata == NULL)
@@ -152,6 +155,12 @@
 	}
 
-	metadata->magic = host2uint64_t_le(HR_MAGIC);
-	metadata->version = host2uint32_t_le(~(0U)); /* unused */
+	/* XXX: use scratchpad */
+	str_cpy(metadata->magic, HR_MAGIC_SIZE, HR_MAGIC_STR);
+	metadata->nblocks = host2uint64_t_le(vol->nblocks);
+	metadata->data_blkno = host2uint64_t_le(vol->data_blkno);
+	metadata->truncated_blkno = host2uint64_t_le(vol->truncated_blkno);
+	metadata->data_offset = host2uint64_t_le(vol->data_offset);
+	metadata->counter = host2uint64_t_le(~(0UL)); /* XXX: unused */
+	metadata->version = host2uint32_t_le(~(0U)); /* XXX: unused */
 	metadata->extent_no = host2uint32_t_le(vol->extent_no);
 	/* index filled separately for each extent */
@@ -159,9 +168,5 @@
 	metadata->layout = host2uint32_t_le(vol->layout);
 	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 = host2uint64_t_le(vol->data_offset);
-	metadata->counter = host2uint64_t_le(~(0UL)); /* unused */
-	/* UUID generated separately for each extent */
+	metadata->bsize = host2uint32_t_le(vol->bsize);
 	str_cpy(metadata->devname, HR_DEVNAME_LEN, vol->devname);
 
@@ -169,11 +174,10 @@
 }
 
-static errno_t validate_meta(hr_metadata_t *md)
-{
-	if (uint64_t_le2host(md->magic) != HR_MAGIC) {
-		HR_ERROR("invalid magic\n");
-		return EINVAL;
-	}
-	return EOK;
+bool hr_valid_md_magic(hr_metadata_t *md)
+{
+	if (str_lcmp(md->magic, HR_MAGIC_STR, HR_MAGIC_SIZE) != 0)
+		return false;
+
+	return true;
 }
 
@@ -203,6 +207,5 @@
 		if (rc != EOK)
 			goto end;
-		rc = validate_meta(metadata);
-		if (rc != EOK)
+		if (!hr_valid_md_magic(metadata))
 			goto end;
 		md_order_indices[i] = uint32_t_le2host(metadata->index);
@@ -244,4 +247,5 @@
 	vol->data_blkno = uint64_t_le2host(metadata->data_blkno);
 	vol->data_offset = uint64_t_le2host(metadata->data_offset);
+	vol->bsize = uint32_t_le2host(metadata->bsize);
 	vol->counter = uint64_t_le2host(0x00); /* unused */
 
@@ -274,4 +278,96 @@
 }
 
+errno_t hr_get_metadata_block(service_id_t dev, void **rblock)
+{
+	HR_DEBUG("%s()", __func__);
+	errno_t rc;
+	uint64_t blkno;
+	size_t bsize;
+	void *block;
+
+	rc = block_get_bsize(dev, &bsize);
+	if (rc != EOK)
+		return rc;
+
+	if (bsize < sizeof(hr_metadata_t))
+		return EINVAL;
+
+	rc = block_get_nblocks(dev, &blkno);
+	if (rc != EOK)
+		return rc;
+
+	if (blkno < HR_META_OFF + HR_META_SIZE)
+		return EINVAL;
+
+	block = malloc(bsize);
+	if (block == NULL)
+		return ENOMEM;
+
+	rc = block_read_direct(dev, HR_META_OFF, HR_META_SIZE, block);
+	if (rc != EOK) {
+		free(block);
+		return rc;
+	}
+
+	if (rblock == NULL) {
+		free(block);
+		return EINVAL;
+	}
+
+	*rblock = block;
+	return EOK;
+}
+
+void hr_decode_metadata_from_block(void *block, hr_metadata_t *metadata)
+{
+	/*
+	 * Use scratch metadata for easier decoding without the need
+	 * for manualy specifying offsets.
+	 */
+	hr_metadata_t scratch_md;
+	memcpy(&scratch_md, block, sizeof(hr_metadata_t));
+
+	memcpy(metadata->magic, scratch_md.magic, HR_MAGIC_SIZE);
+	memcpy(metadata->uuid, scratch_md.uuid, HR_UUID_LEN);
+	metadata->nblocks = uint64_t_le2host(scratch_md.nblocks);
+	metadata->data_blkno = uint64_t_le2host(scratch_md.data_blkno);
+	metadata->truncated_blkno = uint64_t_le2host(
+	    scratch_md.truncated_blkno);
+	metadata->data_offset = uint64_t_le2host(scratch_md.data_offset);
+	metadata->counter = uint64_t_le2host(scratch_md.counter);
+	metadata->version = uint32_t_le2host(scratch_md.version);
+	metadata->extent_no = uint32_t_le2host(scratch_md.extent_no);
+	metadata->index = uint32_t_le2host(scratch_md.index);
+	metadata->level = uint32_t_le2host(scratch_md.level);
+	metadata->layout = uint32_t_le2host(scratch_md.layout);
+	metadata->strip_size = uint32_t_le2host(scratch_md.strip_size);
+	metadata->bsize = uint64_t_le2host(scratch_md.bsize);
+	memcpy(metadata->devname, scratch_md.devname, HR_DEVNAME_LEN);
+}
+
+void hr_metadata_dump(hr_metadata_t *metadata)
+{
+	printf("\tmagic: %s\n", metadata->magic);
+	printf("\tUUID: ");
+	for (size_t i = 0; i < HR_UUID_LEN; ++i) {
+		printf("%.2X", metadata->uuid[i]);
+		if (i + 1 < HR_UUID_LEN)
+			printf(" ");
+	}
+	printf("\n");
+	printf("\tnblocks: %lu\n", metadata->nblocks);
+	printf("\tdata_blkno: %lu\n", metadata->data_blkno);
+	printf("\ttruncated_blkno: %lu\n", metadata->truncated_blkno);
+	printf("\tdata_offset: %lu\n", metadata->data_offset);
+	printf("\tcounter: %lu\n", metadata->counter);
+	printf("\tversion: %u\n", metadata->version);
+	printf("\textent_no: %u\n", metadata->extent_no);
+	printf("\tindex: %u\n", metadata->index);
+	printf("\tlevel: %u\n", metadata->level);
+	printf("\tlayout: %u\n", metadata->layout);
+	printf("\tstrip_size: %u\n", metadata->strip_size);
+	printf("\tdevname: %s\n", metadata->devname);
+}
+
 /** @}
  */
