Index: uspace/srv/bd/vbd/disk.c
===================================================================
--- uspace/srv/bd/vbd/disk.c	(revision ddfe233f65f4a86f6e6b48ef5065323f0f82c1d2)
+++ uspace/srv/bd/vbd/disk.c	(revision 94ea2e3771e36d7eaa5eef3ba668b8f14e4c2291)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2024 Jiri Svoboda
+ * Copyright (c) 2025 Jiri Svoboda
  * All rights reserved.
  *
@@ -35,4 +35,5 @@
 
 #include <adt/list.h>
+#include <bd.h>
 #include <bd_srv.h>
 #include <block.h>
@@ -71,4 +72,5 @@
 static errno_t vbds_bd_get_block_size(bd_srv_t *, size_t *);
 static errno_t vbds_bd_get_num_blocks(bd_srv_t *, aoff64_t *);
+static errno_t vbds_bd_eject(bd_srv_t *);
 
 static errno_t vbds_bsa_translate(vbds_part_t *, aoff64_t, size_t, aoff64_t *);
@@ -93,5 +95,6 @@
 	.write_blocks = vbds_bd_write_blocks,
 	.get_block_size = vbds_bd_get_block_size,
-	.get_num_blocks = vbds_bd_get_num_blocks
+	.get_num_blocks = vbds_bd_get_num_blocks,
+	.eject = vbds_bd_eject
 };
 
@@ -1070,4 +1073,41 @@
 
 	return EOK;
+}
+
+static errno_t vbds_bd_eject(bd_srv_t *bd)
+{
+	vbds_part_t *part = bd_srv_part(bd);
+	async_sess_t *sess;
+	bd_t *bdc;
+	errno_t rc;
+
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "vbds_bd_eject()");
+
+	fibril_rwlock_read_lock(&part->lock);
+
+	sess = loc_service_connect(part->disk->svc_id, INTERFACE_BLOCK, 0);
+	if (sess == NULL) {
+		log_msg(LOG_DEFAULT, LVL_WARN,
+		    "vbds_bd_eject() - failed connect");
+		fibril_rwlock_read_unlock(&part->lock);
+		return EIO;
+	}
+
+	rc = bd_open(sess, &bdc);
+	if (rc != EOK) {
+		log_msg(LOG_DEFAULT, LVL_WARN,
+		    "vbds_bd_eject() - failed open");
+		async_hangup(sess);
+		fibril_rwlock_read_unlock(&part->lock);
+		return EIO;
+	}
+
+	rc = bd_eject(bdc);
+
+	bd_close(bdc);
+	async_hangup(sess);
+
+	fibril_rwlock_read_unlock(&part->lock);
+	return rc;
 }
 
