Index: uspace/srv/bd/vbd/disk.c
===================================================================
--- uspace/srv/bd/vbd/disk.c	(revision 7354b5e275cfd7f15773c38db318e1fa938eab6e)
+++ uspace/srv/bd/vbd/disk.c	(revision b76ce3fafabca2ee4bc41e417ad02ab3546c67f2)
@@ -75,4 +75,10 @@
 static vbd_part_id_t vbds_part_id = 1;
 
+static int vbds_label_get_bsize(void *, size_t *);
+static int vbds_label_get_nblocks(void *, aoff64_t *);
+static int vbds_label_read(void *, aoff64_t, size_t, void *);
+static int vbds_label_write(void *, aoff64_t, size_t, const void *);
+
+/** Block device operations provided by VBD */
 static bd_ops_t vbds_bd_ops = {
 	.open = vbds_bd_open,
@@ -83,4 +89,12 @@
 	.get_block_size = vbds_bd_get_block_size,
 	.get_num_blocks = vbds_bd_get_num_blocks
+};
+
+/** Provide disk access to liblabel */
+static label_bd_ops_t vbds_label_bd_ops = {
+	.get_bsize = vbds_label_get_bsize,
+	.get_nblocks = vbds_label_get_nblocks,
+	.read = vbds_label_read,
+	.write = vbds_label_write
 };
 
@@ -450,4 +464,5 @@
 {
 	label_t *label = NULL;
+	label_bd_t lbd;
 	vbds_disk_t *disk = NULL;
 	bool block_inited = false;
@@ -467,4 +482,7 @@
 		return ENOMEM;
 
+	/* Must be set before calling label_open */
+	disk->svc_id = sid;
+
 	rc = loc_service_get_name(sid, &disk->svc_name);
 	if (rc != EOK) {
@@ -501,5 +519,8 @@
 	block_inited = true;
 
-	rc = label_open(sid, &label);
+	lbd.ops = &vbds_label_bd_ops;
+	lbd.arg = (void *) disk;
+
+	rc = label_open(&lbd, &label);
 	if (rc != EOK) {
 		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed to open label in disk %s.",
@@ -509,5 +530,4 @@
 	}
 
-	disk->svc_id = sid;
 	disk->label = label;
 	disk->block_size = block_size;
@@ -648,4 +668,5 @@
 {
 	label_t *label;
+	label_bd_t lbd;
 	label_info_t linfo;
 	vbds_disk_t *disk;
@@ -683,5 +704,8 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "vbds_label_create(%zu) - label_create", sid);
 
-	rc = label_create(sid, ltype, &label);
+	lbd.ops = &vbds_label_bd_ops;
+	lbd.arg = (void *) disk;
+
+	rc = label_create(&lbd, ltype, &label);
 	if (rc != EOK)
 		goto error;
@@ -695,5 +719,8 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "vbds_label_create(%zu) - failure", sid);
 	if (disk->label == NULL) {
-		rc2 = label_open(sid, &label);
+		lbd.ops = &vbds_label_bd_ops;
+		lbd.arg = (void *) disk;
+
+		rc2 = label_open(&lbd, &label);
 		if (rc2 != EOK) {
 			log_msg(LOG_DEFAULT, LVL_ERROR, "Failed to open label in disk %s.",
@@ -713,4 +740,5 @@
 	vbds_disk_t *disk;
 	label_t *label;
+	label_bd_t lbd;
 	int rc;
 
@@ -735,5 +763,8 @@
 	disk->label = NULL;
 
-	rc = label_open(disk->svc_id, &label);
+	lbd.ops = &vbds_label_bd_ops;
+	lbd.arg = (void *) disk;
+
+	rc = label_open(&lbd, &label);
 	if (rc != EOK) {
 		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed to open label in disk %s.",
@@ -1179,4 +1210,32 @@
 }
 
+/** Get block size wrapper for liblabel */
+static int vbds_label_get_bsize(void *arg, size_t *bsize)
+{
+	vbds_disk_t *disk = (vbds_disk_t *)arg;
+	return block_get_bsize(disk->svc_id, bsize);
+}
+
+/** Get number of blocks wrapper for liblabel */
+static int vbds_label_get_nblocks(void *arg, aoff64_t *nblocks)
+{
+	vbds_disk_t *disk = (vbds_disk_t *)arg;
+	return block_get_nblocks(disk->svc_id, nblocks);
+}
+
+/** Read blocks wrapper for liblabel */
+static int vbds_label_read(void *arg, aoff64_t ba, size_t cnt, void *buf)
+{
+	vbds_disk_t *disk = (vbds_disk_t *)arg;
+	return block_read_direct(disk->svc_id, ba, cnt, buf);
+}
+
+/** Write blocks wrapper for liblabel */
+static int vbds_label_write(void *arg, aoff64_t ba, size_t cnt, const void *data)
+{
+	vbds_disk_t *disk = (vbds_disk_t *)arg;
+	return block_write_direct(disk->svc_id, ba, cnt, data);
+}
+
 /** @}
  */
