Index: uspace/app/vol/vol.c
===================================================================
--- uspace/app/vol/vol.c	(revision 72c72d4a367ffdd08c3e7633b0240d085bd83925)
+++ uspace/app/vol/vol.c	(revision 1a9174e79190398c1f016ea605a18f97e673cafb)
@@ -190,7 +190,7 @@
 		}
 
-		table_printf(table, "%s\t" "%s\t" "%s\t" "%d\t" "%s\n",
-		    vinfo.label, svc_name, sfstype, vinfo.cur_mp_auto,
-		    vinfo.cur_mp);
+		table_printf(table, "%s\t" "%s\t" "%s\t" "%s\t" "%s\n",
+		    vinfo.label, svc_name, sfstype,
+		    vinfo.cur_mp_auto ? "Yes" : "", vinfo.cur_mp);
 
 		free(svc_name);
Index: uspace/srv/volsrv/part.c
===================================================================
--- uspace/srv/volsrv/part.c	(revision 72c72d4a367ffdd08c3e7633b0240d085bd83925)
+++ uspace/srv/volsrv/part.c	(revision 1a9174e79190398c1f016ea605a18f97e673cafb)
@@ -51,4 +51,7 @@
 
 static errno_t vol_part_add_locked(service_id_t);
+static void vol_part_remove_locked(vol_part_t *);
+static errno_t vol_part_find_by_id_ref_locked(service_id_t, vol_part_t **);
+
 static LIST_INITIALIZE(vol_parts); /* of vol_part_t */
 static FIBRIL_MUTEX_INITIALIZE(vol_parts_lock);
@@ -83,11 +86,14 @@
 }
 
-/** Check for new partitions */
+/** Check for new and removed partitions */
 static errno_t vol_part_check_new(void)
 {
 	bool already_known;
+	bool still_exists;
 	category_id_t part_cat;
 	service_id_t *svcs;
 	size_t count, i;
+	link_t *cur, *next;
+	vol_part_t *part;
 	errno_t rc;
 
@@ -109,7 +115,9 @@
 	}
 
+	/* Check for new partitions */
 	for (i = 0; i < count; i++) {
 		already_known = false;
 
+		// XXX Make this faster
 		list_foreach(vol_parts, lparts, vol_part_t, part) {
 			if (part->svc_id == svcs[i]) {
@@ -130,4 +138,30 @@
 	}
 
+	/* Check for removed partitions */
+	cur = list_first(&vol_parts);
+	while (cur != NULL) {
+		next = list_next(cur, &vol_parts);
+		part = list_get_instance(cur, vol_part_t, lparts);
+
+		still_exists = false;
+		// XXX Make this faster
+		for (i = 0; i < count; i++) {
+			if (part->svc_id == svcs[i]) {
+				still_exists = true;
+				break;
+			}
+		}
+
+		if (!still_exists) {
+			log_msg(LOG_DEFAULT, LVL_NOTE, "Partition '%zu' is gone",
+			    part->svc_id);
+			vol_part_remove_locked(part);
+		}
+
+		cur = next;
+	}
+
+	free(svcs);
+
 	fibril_mutex_unlock(&vol_parts_lock);
 	return EOK;
@@ -144,4 +178,5 @@
 	}
 
+	atomic_set(&part->refcnt, 1);
 	link_initialize(&part->lparts);
 	part->pcnt = vpc_empty;
@@ -152,4 +187,5 @@
 static void vol_part_delete(vol_part_t *part)
 {
+	log_msg(LOG_DEFAULT, LVL_ERROR, "Freeing partition %p", part);
 	if (part == NULL)
 		return;
@@ -263,5 +299,4 @@
 }
 
-
 static errno_t vol_part_add_locked(service_id_t sid)
 {
@@ -273,7 +308,9 @@
 
 	/* Check for duplicates */
-	rc = vol_part_find_by_id(sid, &part);
-	if (rc == EOK)
+	rc = vol_part_find_by_id_ref_locked(sid, &part);
+	if (rc == EOK) {
+		vol_part_del_ref(part);
 		return EEXIST;
+	}
 
 	log_msg(LOG_DEFAULT, LVL_NOTE, "partition %zu is new", sid);
@@ -308,4 +345,15 @@
 	vol_part_delete(part);
 	return rc;
+}
+
+static void vol_part_remove_locked(vol_part_t *part)
+{
+	assert(fibril_mutex_is_locked(&vol_parts_lock));
+	log_msg(LOG_DEFAULT, LVL_NOTE, "vol_part_remove_locked(%zu)", part->svc_id);
+
+	list_remove(&part->lparts);
+
+	log_msg(LOG_DEFAULT, LVL_NOTE, "Removed partition.");
+	vol_part_del_ref(part);
 }
 
@@ -374,10 +422,14 @@
 }
 
-errno_t vol_part_find_by_id(service_id_t sid, vol_part_t **rpart)
-{
+static errno_t vol_part_find_by_id_ref_locked(service_id_t sid,
+    vol_part_t **rpart)
+{
+	assert(fibril_mutex_is_locked(&vol_parts_lock));
+
 	list_foreach(vol_parts, lparts, vol_part_t, part) {
 		if (part->svc_id == sid) {
+			/* Add reference */
+			atomic_inc(&part->refcnt);
 			*rpart = part;
-			/* XXX Add reference */
 			return EOK;
 		}
@@ -385,4 +437,21 @@
 
 	return ENOENT;
+}
+
+errno_t vol_part_find_by_id_ref(service_id_t sid, vol_part_t **rpart)
+{
+	errno_t rc;
+
+	fibril_mutex_lock(&vol_parts_lock);
+	rc = vol_part_find_by_id_ref_locked(sid, rpart);
+	fibril_mutex_unlock(&vol_parts_lock);
+
+	return rc;
+}
+
+void vol_part_del_ref(vol_part_t *part)
+{
+	if (atomic_predec(&part->refcnt) == 0)
+		vol_part_delete(part);
 }
 
Index: uspace/srv/volsrv/part.h
===================================================================
--- uspace/srv/volsrv/part.h	(revision 72c72d4a367ffdd08c3e7633b0240d085bd83925)
+++ uspace/srv/volsrv/part.h	(revision 1a9174e79190398c1f016ea605a18f97e673cafb)
@@ -47,5 +47,6 @@
 extern errno_t vol_part_add(service_id_t);
 extern errno_t vol_part_get_ids(service_id_t *, size_t, size_t *);
-extern errno_t vol_part_find_by_id(service_id_t, vol_part_t **);
+extern errno_t vol_part_find_by_id_ref(service_id_t, vol_part_t **);
+extern void vol_part_del_ref(vol_part_t *);
 extern errno_t vol_part_eject_part(vol_part_t *);
 extern errno_t vol_part_empty_part(vol_part_t *);
Index: uspace/srv/volsrv/types/part.h
===================================================================
--- uspace/srv/volsrv/types/part.h	(revision 72c72d4a367ffdd08c3e7633b0240d085bd83925)
+++ uspace/srv/volsrv/types/part.h	(revision 1a9174e79190398c1f016ea605a18f97e673cafb)
@@ -39,4 +39,5 @@
 
 #include <adt/list.h>
+#include <atomic.h>
 #include <stdbool.h>
 #include <types/label.h>
@@ -46,4 +47,6 @@
 	/** Link to vol_parts */
 	link_t lparts;
+	/** Reference count */
+	atomic_t refcnt;
 	/** Service ID */
 	service_id_t svc_id;
Index: uspace/srv/volsrv/volsrv.c
===================================================================
--- uspace/srv/volsrv/volsrv.c	(revision 72c72d4a367ffdd08c3e7633b0240d085bd83925)
+++ uspace/srv/volsrv/volsrv.c	(revision 1a9174e79190398c1f016ea605a18f97e673cafb)
@@ -144,5 +144,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "vol_part_info_srv(%zu)",
 	    sid);
-	rc = vol_part_find_by_id(sid, &part);
+	rc = vol_part_find_by_id_ref(sid, &part);
 	if (rc != EOK) {
 		async_answer_0(icall_handle, ENOENT);
@@ -153,5 +153,5 @@
 	if (rc != EOK) {
 		async_answer_0(icall_handle, EIO);
-		return;
+		goto error;
 	}
 
@@ -161,5 +161,5 @@
 		async_answer_0(chandle, EREFUSED);
 		async_answer_0(icall_handle, EREFUSED);
-		return;
+		goto error;
 	}
 
@@ -167,5 +167,5 @@
 		async_answer_0(chandle, EINVAL);
 		async_answer_0(icall_handle, EINVAL);
-		return;
+		goto error;
 	}
 
@@ -175,8 +175,10 @@
 		async_answer_0(chandle, rc);
 		async_answer_0(icall_handle, rc);
-		return;
-	}
-
-	async_answer_0(icall_handle, EOK);
+		goto error;
+	}
+
+	async_answer_0(icall_handle, EOK);
+error:
+	vol_part_del_ref(part);
 }
 
@@ -190,8 +192,8 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "vol_part_eject_srv(%zu)", sid);
 
-	rc = vol_part_find_by_id(sid, &part);
+	rc = vol_part_find_by_id_ref(sid, &part);
 	if (rc != EOK) {
 		async_answer_0(icall_handle, ENOENT);
-		return;
+		goto error;
 	}
 
@@ -199,8 +201,10 @@
 	if (rc != EOK) {
 		async_answer_0(icall_handle, EIO);
-		return;
-	}
-
-	async_answer_0(icall_handle, EOK);
+		goto error;
+	}
+
+	async_answer_0(icall_handle, EOK);
+error:
+	vol_part_del_ref(part);
 }
 
@@ -214,5 +218,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "vol_part_empty_srv(%zu)", sid);
 
-	rc = vol_part_find_by_id(sid, &part);
+	rc = vol_part_find_by_id_ref(sid, &part);
 	if (rc != EOK) {
 		async_answer_0(icall_handle, ENOENT);
@@ -223,8 +227,10 @@
 	if (rc != EOK) {
 		async_answer_0(icall_handle, EIO);
-		return;
-	}
-
-	async_answer_0(icall_handle, EOK);
+		goto error;
+	}
+
+	async_answer_0(icall_handle, EOK);
+error:
+	vol_part_del_ref(part);
 }
 
@@ -292,5 +298,5 @@
 	}
 
-	rc = vol_part_find_by_id(sid, &part);
+	rc = vol_part_find_by_id_ref(sid, &part);
 	if (rc != EOK) {
 		free(label);
@@ -303,4 +309,5 @@
 		free(label);
 		async_answer_0(icall_handle, rc);
+		vol_part_del_ref(part);
 		return;
 	}
