Index: .gitignore
===================================================================
--- .gitignore	(revision 5f36841fc8b62edea915fd8ce6977576d3f6520f)
+++ .gitignore	(revision db9c88924815f5224f632a9114b5427633cf77dc)
@@ -1,34 +1,24 @@
+*.a
+*.check.c
+*.d
+*.deflate
 *.disasm
-*.deflate
-*.a
-*.o
 *.la
 *.lo
 *.map
+*.o
 *.prev
+*.pyc
 *.so.*
-*.d
-*.pyc
-*.check.c
-tag
-tags
-common.h.new
-deps.mk
+/Makefile.common
 /Makefile.config
-/Makefile.common
-autotool/
-boot/distroot/
-boot/initrd.img
 /common.h
 /config.h
 /cscope.out
-doxygen/doxygen.cfg
-doxygen/doxygen.cfg.gen
-doxygen/html/
-doxygen/latex/
 /hdisk.img
+/image.boot
 /image.iso
 /uImage.bin
-/image.boot
+autotool/
 boot/arch/arm32/_link.ld
 boot/arch/ia64/_link.ld
@@ -40,7 +30,16 @@
 boot/components.zip
 boot/components_desc.c
+boot/distroot/
 boot/image.bin
 boot/image.boot
 boot/image.raw
+boot/initrd.img
+common.h.new
+deps.mk
+doxygen/doxygen.cfg
+doxygen/doxygen.cfg.gen
+doxygen/html/
+doxygen/latex/
+kernel/arch/abs32le/_link.ld
 kernel/arch/amd64/_link.ld
 kernel/arch/arm32/_link.ld
@@ -50,9 +49,26 @@
 kernel/arch/ppc32/_link.ld
 kernel/arch/sparc64/_link.ld
-kernel/arch/abs32le/_link.ld
 kernel/generic/src/debug/real_map.bin
 kernel/kernel.bin
 kernel/kernel.dump
 kernel/kernel.raw
+tag
+tags
+tools/amd64-unknown-elf
+tools/arm-linux-gnueabi
+tools/binutils-*.tar.bz2
+tools/downloads/
+tools/gcc-*.tar.bz2
+tools/gdb-*.tar.gz
+tools/i686-pc-linux-gnu
+tools/ia64-pc-linux-gnu
+tools/mips-linux-gnu
+tools/mips64el-linux-gnu
+tools/mipsel-linux-gnu
+tools/ppc-linux-gnu
+tools/ppc64-linux-gnu
+tools/riscv64-unknown-linux-gnu
+tools/sparc64-linux-gnu
+tools/sycek/
 uspace/app/barber/barber
 uspace/app/barber/images.c
@@ -130,4 +146,5 @@
 uspace/app/vlaunch/images_desc.c
 uspace/app/vlaunch/vlaunch
+uspace/app/vol/vol
 uspace/app/vterm/vterm
 uspace/app/vuhid/vuh
@@ -135,4 +152,5 @@
 uspace/app/websrv/websrv
 uspace/app/wifi_supplicant/wifi_supplicant
+uspace/dist/app/
 uspace/dist/app/barber
 uspace/dist/app/bdsh
@@ -206,4 +224,5 @@
 uspace/dist/demo.wav
 uspace/dist/demo.xm
+uspace/dist/drv/
 uspace/dist/drv/ahci/
 uspace/dist/drv/apic/
@@ -217,6 +236,6 @@
 uspace/dist/drv/i8042/
 uspace/dist/drv/i8259/
+uspace/dist/drv/icp-ic/
 uspace/dist/drv/icp/
-uspace/dist/drv/icp-ic/
 uspace/dist/drv/isa/
 uspace/dist/drv/kfb/
@@ -248,12 +267,10 @@
 uspace/dist/drv/vhc/
 uspace/dist/drv/virt/
+uspace/dist/drv/xhci/
 uspace/dist/drv/xtkbd/
-uspace/dist/drv/xhci/
+uspace/dist/inc/
 uspace/dist/inc/_link.ld
 uspace/dist/inc/c/
 uspace/dist/logo.tga
-uspace/dist/app/
-uspace/dist/drv/
-uspace/dist/inc/
 uspace/dist/srv/
 uspace/dist/test/
@@ -275,6 +292,6 @@
 uspace/drv/bus/usb/usbmid/usbmid
 uspace/drv/bus/usb/vhc/vhc
+uspace/drv/bus/usb/xhci/test-xhci
 uspace/drv/bus/usb/xhci/xhci
-uspace/drv/bus/usb/xhci/test-xhci
 uspace/drv/char/i8042/i8042
 uspace/drv/char/msim-con/msim-con
@@ -289,7 +306,7 @@
 uspace/drv/hid/adb-mouse/adb-mouse
 uspace/drv/hid/atkbd/atkbd
-uspace/drv/hid/xtkbd/xtkbd
 uspace/drv/hid/ps2mouse/ps2mouse
 uspace/drv/hid/usbhid/usbhid
+uspace/drv/hid/xtkbd/xtkbd
 uspace/drv/intctl/apic/apic
 uspace/drv/intctl/i8259/i8259
@@ -301,4 +318,5 @@
 uspace/drv/nic/rtl8139/rtl8139
 uspace/drv/nic/rtl8169/rtl8169
+uspace/drv/nic/virtio-net/virtio-net
 uspace/drv/platform/amdm37x/amdm37x
 uspace/drv/platform/icp/icp
@@ -316,4 +334,8 @@
 uspace/drv/test/test3/test3
 uspace/drv/time/cmos-rtc/cmos-rtc
+uspace/lib/c/arch/abs32le/_link-dlexe.ld
+uspace/lib/c/arch/abs32le/_link-loader.ld
+uspace/lib/c/arch/abs32le/_link-shlib.ld
+uspace/lib/c/arch/abs32le/_link.ld
 uspace/lib/c/arch/amd64/_link-dlexe.ld
 uspace/lib/c/arch/amd64/_link-loader.ld
@@ -348,8 +370,4 @@
 uspace/lib/c/arch/sparc64/_link-shlib.ld
 uspace/lib/c/arch/sparc64/_link.ld
-uspace/lib/c/arch/abs32le/_link-dlexe.ld
-uspace/lib/c/arch/abs32le/_link-loader.ld
-uspace/lib/c/arch/abs32le/_link-shlib.ld
-uspace/lib/c/arch/abs32le/_link.ld
 uspace/lib/c/test-libc
 uspace/lib/label/test-liblabel
@@ -408,18 +426,2 @@
 uspace/srv/vfs/vfs
 uspace/srv/volsrv/volsrv
-tools/amd64-unknown-elf
-tools/arm-linux-gnueabi
-tools/i686-pc-linux-gnu
-tools/ia64-pc-linux-gnu
-tools/mips-linux-gnu
-tools/mips64el-linux-gnu
-tools/mipsel-linux-gnu
-tools/ppc-linux-gnu
-tools/ppc64-linux-gnu
-tools/riscv64-unknown-linux-gnu
-tools/sparc64-linux-gnu
-tools/binutils-*.tar.bz2
-tools/gcc-*.tar.bz2
-tools/gdb-*.tar.gz
-tools/sycek/
-tools/downloads/
Index: boot/Makefile.common
===================================================================
--- boot/Makefile.common	(revision 5f36841fc8b62edea915fd8ce6977576d3f6520f)
+++ boot/Makefile.common	(revision db9c88924815f5224f632a9114b5427633cf77dc)
@@ -217,4 +217,5 @@
 	$(USPACE_PATH)/app/untar/untar \
 	$(USPACE_PATH)/app/usbinfo/usbinfo \
+	$(USPACE_PATH)/app/vol/vol \
 	$(USPACE_PATH)/app/vuhid/vuh \
 	$(USPACE_PATH)/app/mkbd/mkbd \
Index: uspace/Makefile
===================================================================
--- uspace/Makefile	(revision 5f36841fc8b62edea915fd8ce6977576d3f6520f)
+++ uspace/Makefile	(revision db9c88924815f5224f632a9114b5427633cf77dc)
@@ -79,4 +79,5 @@
 	app/untar \
 	app/usbinfo \
+	app/vol \
 	app/vuhid \
 	app/nic \
Index: uspace/app/fdisk/fdisk.c
===================================================================
--- uspace/app/fdisk/fdisk.c	(revision 5f36841fc8b62edea915fd8ce6977576d3f6520f)
+++ uspace/app/fdisk/fdisk.c	(revision db9c88924815f5224f632a9114b5427633cf77dc)
@@ -37,10 +37,12 @@
 #include <cap.h>
 #include <errno.h>
+#include <fdisk.h>
+#include <io/label.h>
 #include <nchoice.h>
 #include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <fdisk.h>
 #include <str.h>
+#include <vol.h>
 
 #define NO_LABEL_CAPTION "(No name)"
@@ -69,32 +71,4 @@
 } devac_t;
 
-static errno_t fdsk_pcnt_fs_format(vol_part_cnt_t pcnt, vol_fstype_t fstype,
-    char **rstr)
-{
-	errno_t rc;
-	char *s;
-
-	switch (pcnt) {
-	case vpc_empty:
-		s = str_dup("Empty");
-		if (s == NULL)
-			return ENOMEM;
-		break;
-	case vpc_fs:
-		rc = fdisk_fstype_format(fstype, &s);
-		if (rc != EOK)
-			return ENOMEM;
-		break;
-	case vpc_unknown:
-		s = str_dup("Unknown");
-		if (s == NULL)
-			return ENOMEM;
-		break;
-	}
-
-	*rstr = s;
-	return EOK;
-}
-
 /** Confirm user selection. */
 static errno_t fdsk_confirm(const char *msg, bool *rconfirm)
@@ -305,5 +279,5 @@
 
 	for (i = LT_FIRST; i < LT_LIMIT; i++) {
-		rc = fdisk_ltype_format(i, &sltype);
+		rc = label_type_format(i, &sltype);
 		if (rc != EOK)
 			goto error;
@@ -413,5 +387,5 @@
 
 	for (i = 0; i < VOL_FSTYPE_LIMIT; i++) {
-		rc = fdisk_fstype_format(i, &sfstype);
+		rc = vol_fstype_format(i, &sfstype);
 		if (rc != EOK)
 			goto error;
@@ -598,5 +572,5 @@
 		}
 
-		rc = fdisk_pkind_format(pinfo.pkind, &spkind);
+		rc = label_pkind_format(pinfo.pkind, &spkind);
 		if (rc != EOK) {
 			printf("\nOut of memory.\n");
@@ -605,5 +579,5 @@
 
 		if (pinfo.pkind != lpk_extended) {
-			rc = fdsk_pcnt_fs_format(pinfo.pcnt, pinfo.fstype, &sfstype);
+			rc = vol_pcnt_fs_format(pinfo.pcnt, pinfo.fstype, &sfstype);
 			if (rc != EOK) {
 				printf("Out of memory.\n");
@@ -773,5 +747,5 @@
 		break;
 	default:
-		rc = fdisk_ltype_format(linfo.ltype, &sltype);
+		rc = label_type_format(linfo.ltype, &sltype);
 		if (rc != EOK) {
 			assert(rc == ENOMEM);
@@ -804,5 +778,5 @@
 		}
 
-		rc = fdsk_pcnt_fs_format(pinfo.pcnt, pinfo.fstype, &sfstype);
+		rc = vol_pcnt_fs_format(pinfo.pcnt, pinfo.fstype, &sfstype);
 		if (rc != EOK) {
 			printf("Out of memory.\n");
@@ -821,5 +795,5 @@
 
 		if ((linfo.flags & lf_ext_supp) != 0) {
-			rc = fdisk_pkind_format(pinfo.pkind, &spkind);
+			rc = label_pkind_format(pinfo.pkind, &spkind);
 			if (rc != EOK) {
 				printf("\nOut of memory.\n");
Index: uspace/app/vol/Makefile
===================================================================
--- uspace/app/vol/Makefile	(revision db9c88924815f5224f632a9114b5427633cf77dc)
+++ uspace/app/vol/Makefile	(revision db9c88924815f5224f632a9114b5427633cf77dc)
@@ -0,0 +1,35 @@
+#
+# Copyright (c) 2017 Jiri Svoboda
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+USPACE_PREFIX = ../..
+BINARY = vol
+
+SOURCES = \
+	vol.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/app/vol/vol.c
===================================================================
--- uspace/app/vol/vol.c	(revision db9c88924815f5224f632a9114b5427633cf77dc)
+++ uspace/app/vol/vol.c	(revision db9c88924815f5224f632a9114b5427633cf77dc)
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2017 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup vol
+ * @{
+ */
+/** @file Volume administration (interface to volsrv).
+ */
+
+#include <errno.h>
+#include <io/table.h>
+#include <loc.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <str.h>
+#include <vfs/vfs.h>
+#include <vol.h>
+
+#define NAME "vol"
+
+static char *volspec;
+
+typedef enum {
+	vcmd_eject,
+	vcmd_help,
+	vcmd_list,
+} vol_cmd_t;
+
+static int vol_cmd_list(void)
+{
+	vol_t *vol = NULL;
+	vol_part_info_t vinfo;
+	service_id_t *part_ids = NULL;
+	char *svc_name;
+	char *sfstype;
+	size_t nparts;
+	size_t i;
+	table_t *table = NULL;
+	int rc;
+
+	rc = vol_create(&vol);
+	if (rc != EOK) {
+		printf("Error contacting volume service.\n");
+		goto out;
+	}
+
+	rc = vol_get_parts(vol, &part_ids, &nparts);
+	if (rc != EOK) {
+		printf("Error getting list of volumes.\n");
+		goto out;
+	}
+
+	rc = table_create(&table);
+	if (rc != EOK) {
+		printf("Out of memory.\n");
+		goto out;
+	}
+
+	table_header_row(table);
+	table_printf(table, "Volume Name\t" "Resource\t" "Content\t" "Auto\t"
+	    "Mounted at\n");
+
+	for (i = 0; i < nparts; i++) {
+		rc = vol_part_info(vol, part_ids[i], &vinfo);
+		if (rc != EOK) {
+			printf("Error getting volume information.\n");
+			return EIO;
+		}
+
+		rc = loc_service_get_name(part_ids[i], &svc_name);
+		if (rc != EOK) {
+			printf("Error getting service name.\n");
+			return EIO;
+		}
+
+		rc = vol_pcnt_fs_format(vinfo.pcnt, vinfo.fstype, &sfstype);
+		if (rc != EOK) {
+			printf("Out of memory.\n");
+			free(svc_name);
+			return ENOMEM;
+		}
+
+		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);
+
+		free(svc_name);
+		free(sfstype);
+		svc_name = NULL;
+	}
+
+	rc = table_print_out(table, stdout);
+	if (rc != EOK)
+		printf("Error printing table.\n");
+out:
+	table_destroy(table);
+	vol_destroy(vol);
+	free(part_ids);
+
+	return rc;
+}
+
+static void print_syntax(void)
+{
+	printf("Syntax:\n");
+	printf("  %s                List volumes\n", NAME);
+	printf("  %s -h             Print help\n", NAME);
+	printf("  %s eject <volume> Eject volume\n", NAME);
+}
+
+int main(int argc, char *argv[])
+{
+	char *cmd;
+	vol_cmd_t vcmd;
+	int i;
+	int rc;
+
+	if (argc < 2) {
+		vcmd = vcmd_list;
+		i = 1;
+	} else {
+		cmd = argv[1];
+		i = 2;
+		if (str_cmp(cmd, "-h") == 0) {
+			vcmd = vcmd_help;
+		} else if (str_cmp(cmd, "eject") == 0) {
+			vcmd = vcmd_eject;
+			if (argc <= i) {
+				printf("Parameter missing.\n");
+				goto syntax_error;
+			}
+			volspec = argv[i++];
+		} else {
+			printf("Invalid sub-command '%s'.\n", cmd);
+			goto syntax_error;
+		}
+	}
+
+	if (argc > i) {
+		printf("Unexpected argument '%s'.\n", argv[i]);
+		goto syntax_error;
+	}
+
+	switch (vcmd) {
+	case vcmd_eject:
+		rc = EOK;
+		break;
+	case vcmd_help:
+		print_syntax();
+		rc = EOK;
+		break;
+	case vcmd_list:
+		rc = vol_cmd_list();
+		break;
+	}
+
+	if (rc != EOK)
+		return 1;
+
+	return 0;
+
+syntax_error:
+	printf("Use %s -h to get help.\n", NAME);
+	return 1;
+}
+
+/** @}
+ */
Index: uspace/lib/c/Makefile
===================================================================
--- uspace/lib/c/Makefile	(revision 5f36841fc8b62edea915fd8ce6977576d3f6520f)
+++ uspace/lib/c/Makefile	(revision db9c88924815f5224f632a9114b5427633cf77dc)
@@ -112,4 +112,5 @@
 	generic/io/log.c \
 	generic/io/logctl.c \
+	generic/io/label.c \
 	generic/io/kio.c \
 	generic/io/klog.c \
Index: uspace/lib/c/generic/io/label.c
===================================================================
--- uspace/lib/c/generic/io/label.c	(revision db9c88924815f5224f632a9114b5427633cf77dc)
+++ uspace/lib/c/generic/io/label.c	(revision db9c88924815f5224f632a9114b5427633cf77dc)
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2015 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file Volume service API
+ */
+
+#include <errno.h>
+#include <io/label.h>
+#include <stdlib.h>
+#include <str.h>
+
+/** Format label type as string.
+ *
+ * @param ltype Label type
+ * @param rstr Place to return pointer to newly allocated string
+ * @return EOK on success, ENOMEM if out of memory
+ */
+int label_type_format(label_type_t ltype, char **rstr)
+{
+	const char *sltype;
+	char *s;
+
+	sltype = NULL;
+	switch (ltype) {
+	case lt_none:
+		sltype = "None";
+		break;
+	case lt_mbr:
+		sltype = "MBR";
+		break;
+	case lt_gpt:
+		sltype = "GPT";
+		break;
+	}
+
+	s = str_dup(sltype);
+	if (s == NULL)
+		return ENOMEM;
+
+	*rstr = s;
+	return EOK;
+}
+
+/** Format partition kind as string.
+ *
+ * @param pkind Partition kind
+ * @param rstr Place to return pointer to newly allocated string
+ * @return EOK on success, ENOMEM if out of memory
+ */
+int label_pkind_format(label_pkind_t pkind, char **rstr)
+{
+	const char *spkind;
+	char *s;
+
+	spkind = NULL;
+	switch (pkind) {
+	case lpk_primary:
+		spkind = "Primary";
+		break;
+	case lpk_extended:
+		spkind = "Extended";
+		break;
+	case lpk_logical:
+		spkind = "Logical";
+		break;
+	}
+
+	s = str_dup(spkind);
+	if (s == NULL)
+		return ENOMEM;
+
+	*rstr = s;
+	return EOK;
+}
+
+/** @}
+ */
Index: uspace/lib/c/generic/vol.c
===================================================================
--- uspace/lib/c/generic/vol.c	(revision 5f36841fc8b62edea915fd8ce6977576d3f6520f)
+++ uspace/lib/c/generic/vol.c	(revision db9c88924815f5224f632a9114b5427633cf77dc)
@@ -304,4 +304,78 @@
 }
 
+/** Format file system type as string.
+ *
+ * @param fstype File system type
+ * @param rstr Place to store pointer to newly allocated string
+ * @return EOK on success, ENOMEM if out of memory
+ */
+errno_t vol_fstype_format(vol_fstype_t fstype, char **rstr)
+{
+	const char *sfstype;
+	char *s;
+
+	sfstype = NULL;
+	switch (fstype) {
+	case fs_exfat:
+		sfstype = "ExFAT";
+		break;
+	case fs_fat:
+		sfstype = "FAT";
+		break;
+	case fs_minix:
+		sfstype = "MINIX";
+		break;
+	case fs_ext4:
+		sfstype = "Ext4";
+		break;
+	case fs_cdfs:
+		sfstype = "ISO 9660";
+		break;
+	}
+
+	s = str_dup(sfstype);
+	if (s == NULL)
+		return ENOMEM;
+
+	*rstr = s;
+	return EOK;
+}
+
+/** Format partition content / file system type as string.
+ *
+ * @param pcnt Partition content
+ * @param fstype File system type
+ * @param rstr Place to store pointer to newly allocated string
+ * @return EOK on success, ENOMEM if out of memory
+ */
+errno_t vol_pcnt_fs_format(vol_part_cnt_t pcnt, vol_fstype_t fstype,
+    char **rstr)
+{
+	int rc;
+	char *s = NULL;
+
+	switch (pcnt) {
+	case vpc_empty:
+		s = str_dup("Empty");
+		if (s == NULL)
+			return ENOMEM;
+		break;
+	case vpc_fs:
+		rc = vol_fstype_format(fstype, &s);
+		if (rc != EOK)
+			return ENOMEM;
+		break;
+	case vpc_unknown:
+		s = str_dup("Unknown");
+		if (s == NULL)
+			return ENOMEM;
+		break;
+	}
+
+	assert(s != NULL);
+	*rstr = s;
+	return EOK;
+}
+
 /** @}
  */
Index: uspace/lib/c/include/io/label.h
===================================================================
--- uspace/lib/c/include/io/label.h	(revision db9c88924815f5224f632a9114b5427633cf77dc)
+++ uspace/lib/c/include/io/label.h	(revision db9c88924815f5224f632a9114b5427633cf77dc)
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2017 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_IO_LABEL_H_
+#define LIBC_IO_LABEL_H_
+
+#include <types/label.h>
+
+extern int label_type_format(label_type_t, char **);
+extern int label_pkind_format(label_pkind_t, char **);
+
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/types/vol.h
===================================================================
--- uspace/lib/c/include/types/vol.h	(revision 5f36841fc8b62edea915fd8ce6977576d3f6520f)
+++ uspace/lib/c/include/types/vol.h	(revision db9c88924815f5224f632a9114b5427633cf77dc)
@@ -37,4 +37,5 @@
 
 #include <async.h>
+#include <ipc/vfs.h>
 #include <ipc/vol.h>
 #include <stdbool.h>
@@ -75,4 +76,8 @@
 	/** Volume label */
 	char label[VOL_LABEL_MAXLEN + 1];
+	/** Current mount point */
+	char cur_mp[MAX_PATH_LEN + 1]; /* XXX too big */
+	/** Current mount point is automatic */
+	bool cur_mp_auto;
 } vol_part_info_t;
 
Index: uspace/lib/c/include/vol.h
===================================================================
--- uspace/lib/c/include/vol.h	(revision 5f36841fc8b62edea915fd8ce6977576d3f6520f)
+++ uspace/lib/c/include/vol.h	(revision db9c88924815f5224f632a9114b5427633cf77dc)
@@ -37,4 +37,5 @@
 
 #include <async.h>
+#include <errno.h>
 #include <loc.h>
 #include <stdint.h>
@@ -47,7 +48,11 @@
 extern errno_t vol_part_add(vol_t *, service_id_t);
 extern errno_t vol_part_info(vol_t *, service_id_t, vol_part_info_t *);
+extern errno_t vol_part_eject(vol_t *, service_id_t);
 extern errno_t vol_part_empty(vol_t *, service_id_t);
 extern errno_t vol_part_get_lsupp(vol_t *, vol_fstype_t, vol_label_supp_t *);
 extern errno_t vol_part_mkfs(vol_t *, service_id_t, vol_fstype_t, const char *);
+
+extern errno_t vol_fstype_format(vol_fstype_t, char **);
+extern errno_t vol_pcnt_fs_format(vol_part_cnt_t, vol_fstype_t, char **);
 
 #endif
Index: uspace/lib/fdisk/include/fdisk.h
===================================================================
--- uspace/lib/fdisk/include/fdisk.h	(revision 5f36841fc8b62edea915fd8ce6977576d3f6520f)
+++ uspace/lib/fdisk/include/fdisk.h	(revision db9c88924815f5224f632a9114b5427633cf77dc)
@@ -37,4 +37,5 @@
 #define LIBFDISK_FDISK_H_
 
+#include <errno.h>
 #include <loc.h>
 #include <types/fdisk.h>
@@ -72,8 +73,4 @@
 extern void fdisk_pspec_init(fdisk_part_spec_t *);
 
-extern errno_t fdisk_ltype_format(label_type_t, char **);
-extern errno_t fdisk_fstype_format(vol_fstype_t, char **);
-extern errno_t fdisk_pkind_format(label_pkind_t, char **);
-
 extern errno_t fdisk_get_vollabel_support(fdisk_dev_t *, vol_fstype_t,
     vol_label_supp_t *);
Index: uspace/lib/fdisk/src/fdisk.c
===================================================================
--- uspace/lib/fdisk/src/fdisk.c	(revision 5f36841fc8b62edea915fd8ce6977576d3f6520f)
+++ uspace/lib/fdisk/src/fdisk.c	(revision db9c88924815f5224f632a9114b5427633cf77dc)
@@ -813,88 +813,4 @@
 }
 
-errno_t fdisk_ltype_format(label_type_t ltype, char **rstr)
-{
-	const char *sltype;
-	char *s;
-
-	sltype = NULL;
-	switch (ltype) {
-	case lt_none:
-		sltype = "None";
-		break;
-	case lt_mbr:
-		sltype = "MBR";
-		break;
-	case lt_gpt:
-		sltype = "GPT";
-		break;
-	}
-
-	s = str_dup(sltype);
-	if (s == NULL)
-		return ENOMEM;
-
-	*rstr = s;
-	return EOK;
-}
-
-errno_t fdisk_fstype_format(vol_fstype_t fstype, char **rstr)
-{
-	const char *sfstype;
-	char *s;
-
-	sfstype = NULL;
-	switch (fstype) {
-	case fs_exfat:
-		sfstype = "ExFAT";
-		break;
-	case fs_fat:
-		sfstype = "FAT";
-		break;
-	case fs_minix:
-		sfstype = "MINIX";
-		break;
-	case fs_ext4:
-		sfstype = "Ext4";
-		break;
-	case fs_cdfs:
-		sfstype = "ISO 9660";
-		break;
-	}
-
-	s = str_dup(sfstype);
-	if (s == NULL)
-		return ENOMEM;
-
-	*rstr = s;
-	return EOK;
-}
-
-errno_t fdisk_pkind_format(label_pkind_t pkind, char **rstr)
-{
-	const char *spkind;
-	char *s;
-
-	spkind = NULL;
-	switch (pkind) {
-	case lpk_primary:
-		spkind = "Primary";
-		break;
-	case lpk_extended:
-		spkind = "Extended";
-		break;
-	case lpk_logical:
-		spkind = "Logical";
-		break;
-	}
-
-	s = str_dup(spkind);
-	if (s == NULL)
-		return ENOMEM;
-
-	*rstr = s;
-	return EOK;
-}
-
 /** Get free partition index. */
 static errno_t fdisk_part_get_free_idx(fdisk_dev_t *dev, int *rindex)
Index: uspace/srv/volsrv/part.c
===================================================================
--- uspace/srv/volsrv/part.c	(revision 5f36841fc8b62edea915fd8ce6977576d3f6520f)
+++ uspace/srv/volsrv/part.c	(revision db9c88924815f5224f632a9114b5427633cf77dc)
@@ -155,4 +155,5 @@
 		return;
 
+	free(part->cur_mp);
 	free(part->svc_name);
 	free(part);
@@ -219,8 +220,9 @@
 }
 
-static int vol_part_mount(vol_part_t *part)
+static errno_t vol_part_mount(vol_part_t *part)
 {
 	char *mp;
-	int rc;
+	int err;
+	errno_t rc;
 
 	if (str_size(part->label) < 1) {
@@ -231,7 +233,7 @@
 
 	log_msg(LOG_DEFAULT, LVL_NOTE, "Determine MP label='%s'", part->label);
-	rc = asprintf(&mp, "/vol/%s", part->label);
-	if (rc < 0) {
-		log_msg(LOG_DEFAULT, LVL_NOTE, "rc -> %d", rc);
+	err = asprintf(&mp, "/vol/%s", part->label);
+	if (err < 0) {
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Out of memory");
 		return ENOMEM;
 	}
@@ -255,5 +257,7 @@
 	log_msg(LOG_DEFAULT, LVL_NOTE, "Mount to %s -> %d\n", mp, rc);
 
-	free(mp);
+	part->cur_mp = mp;
+	part->cur_mp_auto = true;
+
 	return rc;
 }
@@ -381,4 +385,38 @@
 
 	return ENOENT;
+}
+
+errno_t vol_part_eject_part(vol_part_t *part)
+{
+	int rc;
+
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "vol_part_eject_part()");
+
+	if (part->cur_mp == NULL) {
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "Attempt to mount unmounted "
+		    "partition.");
+		return EINVAL;
+	}
+
+	rc = vfs_unmount_path(part->cur_mp);
+	if (rc != EOK) {
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed unmounting partition "
+		    "from %s", part->cur_mp);
+		return rc;
+	}
+
+	if (part->cur_mp_auto) {
+		rc = vfs_unlink_path(part->cur_mp);
+		if (rc != EOK) {
+			log_msg(LOG_DEFAULT, LVL_ERROR, "Failed deleting "
+			    "mount directory %s.", part->cur_mp);
+		}
+	}
+
+	free(part->cur_mp);
+	part->cur_mp = NULL;
+	part->cur_mp_auto = false;
+
+	return EOK;
 }
 
@@ -443,4 +481,6 @@
 	pinfo->fstype = part->fstype;
 	str_cpy(pinfo->label, sizeof(pinfo->label), part->label);
+	str_cpy(pinfo->cur_mp, sizeof(pinfo->cur_mp), part->cur_mp);
+	pinfo->cur_mp_auto = part->cur_mp_auto;
 	return EOK;
 }
Index: uspace/srv/volsrv/part.h
===================================================================
--- uspace/srv/volsrv/part.h	(revision 5f36841fc8b62edea915fd8ce6977576d3f6520f)
+++ uspace/srv/volsrv/part.h	(revision db9c88924815f5224f632a9114b5427633cf77dc)
@@ -48,4 +48,5 @@
 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_eject_part(vol_part_t *);
 extern errno_t vol_part_empty_part(vol_part_t *);
 extern errno_t vol_part_mkfs_part(vol_part_t *, vol_fstype_t, const char *);
Index: uspace/srv/volsrv/types/part.h
===================================================================
--- uspace/srv/volsrv/types/part.h	(revision 5f36841fc8b62edea915fd8ce6977576d3f6520f)
+++ uspace/srv/volsrv/types/part.h	(revision db9c88924815f5224f632a9114b5427633cf77dc)
@@ -39,4 +39,5 @@
 
 #include <adt/list.h>
+#include <stdbool.h>
 #include <types/label.h>
 
@@ -55,4 +56,8 @@
 	/** Volume label */
 	char *label;
+	/** Where volume is currently mounted */
+	char *cur_mp;
+	/** Mounted at automatic mount point */
+	bool cur_mp_auto;
 } vol_part_t;
 
