Index: uspace/app/fdisk/fdisk.c
===================================================================
--- uspace/app/fdisk/fdisk.c	(revision d858a660afff3b05ffdfe37e6957b83b447f6b26)
+++ uspace/app/fdisk/fdisk.c	(revision 9c2c7d2247cc1ad0410cd61ab534af9a246d328b)
@@ -42,4 +42,6 @@
 #include <fdisk.h>
 
+#define NO_LABEL_CAPTION "(No name)"
+
 static bool quit = false;
 static fdisk_t *fdisk;
@@ -445,4 +447,5 @@
 	fdisk_cap_t cap;
 	fdisk_cap_t mcap;
+	vol_label_supp_t vlsupp;
 	vol_fstype_t fstype = 0;
 	tinput_t *tinput = NULL;
@@ -450,4 +453,5 @@
 	char *scap;
 	char *smcap = NULL;
+	char *label = NULL;
 
 	if (pkind == lpk_logical)
@@ -502,8 +506,31 @@
 	}
 
+	fdisk_get_vollabel_support(dev, fstype, &vlsupp);
+	if (vlsupp.supported) {
+		tinput = tinput_new();
+		if (tinput == NULL) {
+			rc = ENOMEM;
+			goto error;
+		}
+
+		rc = tinput_set_prompt(tinput, "?> ");
+		if (rc != EOK)
+			goto error;
+
+		/* Ask for volume label */
+		printf("Enter volume label for new partition.\n");
+		rc = tinput_read_i(tinput, "No name", &label);
+		if (rc != EOK)
+			goto error;
+
+	    	tinput_destroy(tinput);
+		tinput = NULL;
+	}
+
 	fdisk_pspec_init(&pspec);
 	pspec.capacity = cap;
 	pspec.pkind = pkind;
 	pspec.fstype = fstype;
+	pspec.label = label;
 
 	rc = fdisk_part_create(dev, &pspec, NULL);
@@ -513,7 +540,9 @@
 	}
 
+	free(label);
 	return EOK;
 error:
 	free(smcap);
+	free(label);
 	if (tinput != NULL)
 		tinput_destroy(tinput);
@@ -530,4 +559,5 @@
 	char *sfstype = NULL;
 	char *sdesc = NULL;
+	const char *label;
 	bool confirm;
 	void *sel;
@@ -577,5 +607,11 @@
 			}
 
-			rc = asprintf(&sdesc, "%s, %s, %s", scap, spkind, sfstype);
+			if (str_size(pinfo.label) > 0)
+				label = pinfo.label;
+			else
+				label = "(No name)";
+
+			rc = asprintf(&sdesc, "%s %s, %s, %s", label,
+			    scap, spkind, sfstype);
 			if (rc < 0) {
 				rc = ENOMEM;
@@ -773,5 +809,5 @@
 			label = pinfo.label;
 		else
-			label = "(No label)";
+			label = "(No name)";
 
 		if (linfo.ltype == lt_none)
Index: uspace/app/init/init.c
===================================================================
--- uspace/app/init/init.c	(revision d858a660afff3b05ffdfe37e6957b83b447f6b26)
+++ uspace/app/init/init.c	(revision 9c2c7d2247cc1ad0410cd61ab534af9a246d328b)
@@ -328,5 +328,5 @@
 	srv_start("/srv/klog");
 	srv_start("/srv/locfs");
-	srv_start("/srv/taskmon");
+//	srv_start("/srv/taskmon");
 	
 	if (!mount_locfs()) {
Index: uspace/app/mkfat/fat_dentry.h
===================================================================
--- uspace/app/mkfat/fat_dentry.h	(revision 9c2c7d2247cc1ad0410cd61ab534af9a246d328b)
+++ uspace/app/mkfat/fat_dentry.h	(revision 9c2c7d2247cc1ad0410cd61ab534af9a246d328b)
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2008 Jakub Jermar
+ * Copyright (c) 2011 Oleg Romanenko
+ * 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 fs
+ * @{
+ */ 
+
+#ifndef FAT_FAT_DENTRY_H_
+#define FAT_FAT_DENTRY_H_
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <unaligned.h>
+
+#define IS_D_CHAR(ch) (isalnum(ch) || ch == '_')
+#define FAT_STOP_CHARS "*?/\\\n\t|'"
+
+#define FAT_NAME_LEN		8
+#define FAT_EXT_LEN		3
+#define FAT_VOLLABEL_LEN	11
+
+#define FAT_NAME_DOT		".       "
+#define FAT_NAME_DOT_DOT	"..      "
+#define FAT_EXT_PAD		"   "
+
+#define FAT_ATTR_RDONLY   0x01
+#define FAT_ATTR_HIDDEN   0x02
+#define FAT_ATTR_SYSTEM   0x04
+#define FAT_ATTR_VOLLABEL 0x08
+#define FAT_ATTR_SUBDIR   0x10
+#define FAT_ATTR_ARCHIVE  0x20
+#define FAT_ATTR_LFN \
+    (FAT_ATTR_RDONLY | FAT_ATTR_HIDDEN | FAT_ATTR_SYSTEM | FAT_ATTR_VOLLABEL)
+    
+#define FAT_LCASE_LOWER_NAME	0x08
+#define FAT_LCASE_LOWER_EXT	0x10
+
+#define FAT_PAD			' '
+#define FAT_LFN_PAD	0xffff
+#define FAT_SFN_CHAR '_'
+
+#define FAT_DENTRY_UNUSED	0x00
+#define FAT_DENTRY_E5_ESC	0x05
+#define FAT_DENTRY_DOT		0x2e
+#define FAT_DENTRY_ERASED	0xe5
+#define FAT_LFN_LAST		0x40
+#define FAT_LFN_ERASED		0x80
+
+#define FAT_LFN_ORDER(d) ((d)->lfn.order)
+#define FAT_IS_LFN(d) \
+    ((FAT_LFN_ORDER((d)) & FAT_LFN_LAST) == FAT_LFN_LAST)
+#define FAT_LFN_COUNT(d) \
+    (FAT_LFN_ORDER((d)) ^ FAT_LFN_LAST)
+#define FAT_LFN_PART1(d) ((d)->lfn.part1)
+#define FAT_LFN_PART2(d) ((d)->lfn.part2)
+#define FAT_LFN_PART3(d) ((d)->lfn.part3)
+#define FAT_LFN_ATTR(d) ((d)->lfn.attr)
+#define FAT_LFN_CHKSUM(d) ((d)->lfn.check_sum)
+
+#define FAT_LFN_NAME_LEN    260                           /* characters */
+#define FAT_LFN_NAME_SIZE   STR_BOUNDS(FAT_LFN_NAME_LEN)  /* bytes */
+#define FAT_LFN_MAX_COUNT   20
+#define FAT_LFN_PART1_SIZE  5
+#define FAT_LFN_PART2_SIZE  6
+#define FAT_LFN_PART3_SIZE  2
+#define FAT_LFN_ENTRY_SIZE \
+    (FAT_LFN_PART1_SIZE + FAT_LFN_PART2_SIZE + FAT_LFN_PART3_SIZE)
+
+typedef enum {
+	FAT_DENTRY_SKIP,
+	FAT_DENTRY_LAST,
+	FAT_DENTRY_FREE,
+	FAT_DENTRY_VALID,
+	FAT_DENTRY_LFN,
+	FAT_DENTRY_VOLLABEL
+} fat_dentry_clsf_t;
+
+typedef union {
+	struct {
+		uint8_t		name[8];
+		uint8_t		ext[3];
+		uint8_t		attr;
+		uint8_t		lcase;
+		uint8_t		ctime_fine;
+		uint16_t	ctime;
+		uint16_t	cdate;
+		uint16_t	adate;
+		union {
+			uint16_t	eaidx;		/* FAT12/FAT16 */
+			uint16_t	firstc_hi;	/* FAT32 */
+		} __attribute__ ((packed));
+		uint16_t	mtime;
+		uint16_t	mdate;
+		union {
+			uint16_t	firstc;		/* FAT12/FAT16 */
+			uint16_t	firstc_lo;	/* FAT32 */
+		} __attribute__ ((packed));
+		uint32_t	size;
+	} __attribute__ ((packed));
+	struct {
+		uint8_t		order;
+		uint16_t	part1[FAT_LFN_PART1_SIZE];
+		uint8_t		attr;
+		uint8_t		type;
+		uint8_t		check_sum;
+		uint16_t	part2[FAT_LFN_PART2_SIZE];
+		uint16_t	firstc_lo; /* MUST be 0 */
+		uint16_t	part3[FAT_LFN_PART3_SIZE];
+	} __attribute__ ((packed)) lfn;
+} __attribute__ ((packed)) fat_dentry_t;
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/lib/c/generic/vol.c
===================================================================
--- uspace/lib/c/generic/vol.c	(revision d858a660afff3b05ffdfe37e6957b83b447f6b26)
+++ uspace/lib/c/generic/vol.c	(revision 9c2c7d2247cc1ad0410cd61ab534af9a246d328b)
@@ -39,4 +39,5 @@
 #include <loc.h>
 #include <stdlib.h>
+#include <str.h>
 #include <vol.h>
 
@@ -251,13 +252,48 @@
 }
 
+/** Get volume label support. */
+int vol_part_get_lsupp(vol_t *vol, vol_fstype_t fstype,
+    vol_label_supp_t *vlsupp)
+{
+	async_exch_t *exch;
+	sysarg_t retval;
+	ipc_call_t answer;
+
+	exch = async_exchange_begin(vol->sess);
+	aid_t req = async_send_1(exch, VOL_PART_LSUPP, fstype, &answer);
+	int rc = async_data_read_start(exch, vlsupp, sizeof(vol_label_supp_t));
+	async_exchange_end(exch);
+
+	if (rc != EOK) {
+		async_forget(req);
+		return EIO;
+	}
+
+	async_wait_for(req, &retval);
+	if (retval != EOK)
+		return EIO;
+
+	return EOK;
+}
+
 /** Create file system. */
-int vol_part_mkfs(vol_t *vol, service_id_t sid, vol_fstype_t fstype)
-{
-	async_exch_t *exch;
-	int retval;
-
-	exch = async_exchange_begin(vol->sess);
-	retval = async_req_2_0(exch, VOL_PART_MKFS, sid, fstype);
-	async_exchange_end(exch);
+int vol_part_mkfs(vol_t *vol, service_id_t sid, vol_fstype_t fstype,
+    const char *label)
+{
+	async_exch_t *exch;
+	ipc_call_t answer;
+	sysarg_t retval;
+
+	exch = async_exchange_begin(vol->sess);
+	aid_t req = async_send_2(exch, VOL_PART_MKFS, sid, fstype, &answer);
+	retval = async_data_write_start(exch, label, str_size(label));
+	async_exchange_end(exch);
+
+	if (retval != EOK) {
+		async_forget(req);
+		return retval;
+	}
+
+	async_wait_for(req, &retval);
 
 	if (retval != EOK)
Index: uspace/lib/c/include/ipc/vol.h
===================================================================
--- uspace/lib/c/include/ipc/vol.h	(revision d858a660afff3b05ffdfe37e6957b83b447f6b26)
+++ uspace/lib/c/include/ipc/vol.h	(revision 9c2c7d2247cc1ad0410cd61ab534af9a246d328b)
@@ -43,5 +43,6 @@
 	VOL_PART_INFO,
 	VOL_PART_EMPTY,
-	VOL_PART_MKFS
+	VOL_PART_LSUPP,
+	VOL_PART_MKFS,
 } vol_request_t;
 
Index: uspace/lib/c/include/types/vol.h
===================================================================
--- uspace/lib/c/include/types/vol.h	(revision d858a660afff3b05ffdfe37e6957b83b447f6b26)
+++ uspace/lib/c/include/types/vol.h	(revision 9c2c7d2247cc1ad0410cd61ab534af9a246d328b)
@@ -38,4 +38,5 @@
 #include <async.h>
 #include <ipc/vol.h>
+#include <stdbool.h>
 
 typedef enum {
@@ -76,4 +77,10 @@
 } vol_part_info_t;
 
+/** Volume label support */
+typedef struct {
+	/** Volume labels are supported */
+	bool supported;
+} vol_label_supp_t;
+
 #endif
 
Index: uspace/lib/c/include/vol.h
===================================================================
--- uspace/lib/c/include/vol.h	(revision d858a660afff3b05ffdfe37e6957b83b447f6b26)
+++ uspace/lib/c/include/vol.h	(revision 9c2c7d2247cc1ad0410cd61ab534af9a246d328b)
@@ -48,5 +48,6 @@
 extern int vol_part_info(vol_t *, service_id_t, vol_part_info_t *);
 extern int vol_part_empty(vol_t *, service_id_t);
-extern int vol_part_mkfs(vol_t *, service_id_t, vol_fstype_t);
+extern int vol_part_get_lsupp(vol_t *, vol_fstype_t, vol_label_supp_t *);
+extern int vol_part_mkfs(vol_t *, service_id_t, vol_fstype_t, const char *);
 
 #endif
Index: uspace/lib/fdisk/include/fdisk.h
===================================================================
--- uspace/lib/fdisk/include/fdisk.h	(revision d858a660afff3b05ffdfe37e6957b83b447f6b26)
+++ uspace/lib/fdisk/include/fdisk.h	(revision 9c2c7d2247cc1ad0410cd61ab534af9a246d328b)
@@ -39,4 +39,5 @@
 #include <loc.h>
 #include <types/fdisk.h>
+#include <types/vol.h>
 
 extern int fdisk_create(fdisk_t **);
@@ -81,4 +82,7 @@
 extern int fdisk_pkind_format(label_pkind_t, char **);
 
+extern int fdisk_get_vollabel_support(fdisk_dev_t *, vol_fstype_t,
+    vol_label_supp_t *);
+
 #endif
 
Index: uspace/lib/fdisk/include/types/fdisk.h
===================================================================
--- uspace/lib/fdisk/include/types/fdisk.h	(revision d858a660afff3b05ffdfe37e6957b83b447f6b26)
+++ uspace/lib/fdisk/include/types/fdisk.h	(revision 9c2c7d2247cc1ad0410cd61ab534af9a246d328b)
@@ -43,5 +43,4 @@
 #include <types/vol.h>
 #include <vbd.h>
-#include <vol.h>
 
 /** Capacity unit */
@@ -199,4 +198,6 @@
 	/** File system type */
 	vol_fstype_t fstype;
+	/** Volume label */
+	char *label;
 } fdisk_part_spec_t;
 
Index: uspace/lib/fdisk/src/fdisk.c
===================================================================
--- uspace/lib/fdisk/src/fdisk.c	(revision d858a660afff3b05ffdfe37e6957b83b447f6b26)
+++ uspace/lib/fdisk/src/fdisk.c	(revision 9c2c7d2247cc1ad0410cd61ab534af9a246d328b)
@@ -731,34 +731,56 @@
     fdisk_part_t **rpart)
 {
-	fdisk_part_t *part;
+	fdisk_part_t *part = NULL;
 	vbd_part_spec_t vpspec;
-	vbd_part_id_t partid;
-	int rc;
+	vbd_part_id_t partid = 0;
+	vol_part_info_t vpinfo;
+	char *label;
+	int rc;
+
+	label = str_dup(pspec->label);
+	if (label == NULL)
+		return ENOMEM;
 
 	rc = fdisk_part_spec_prepare(dev, pspec, &vpspec);
-	if (rc != EOK)
-		return EIO;
+	if (rc != EOK) {
+		rc = EIO;
+		goto error;
+	}
 
 	rc = vbd_part_create(dev->fdisk->vbd, dev->sid, &vpspec, &partid);
-	if (rc != EOK)
-		return EIO;
+	if (rc != EOK) {
+		rc = EIO;
+		goto error;
+	}
 
 	rc = fdisk_part_add(dev, partid, &part);
 	if (rc != EOK) {
-		/* Try rolling back */
-		(void) vbd_part_delete(dev->fdisk->vbd, partid);
-		return EIO;
+		rc = EIO;
+		goto error;
 	}
 
 	if (part->svc_id != 0) {
-		rc = vol_part_mkfs(dev->fdisk->vol, part->svc_id, pspec->fstype);
+		rc = vol_part_mkfs(dev->fdisk->vol, part->svc_id, pspec->fstype,
+		    pspec->label);
 		if (rc != EOK && rc != ENOTSUP) {
-			fdisk_part_remove(part);
-			(void) vbd_part_delete(dev->fdisk->vbd, partid);
-			return EIO;
-		}
-
-		part->pcnt = vpc_fs;
-		part->fstype = pspec->fstype;
+			rc = EIO;
+			goto error;
+		}
+
+		/* Get the real label value */
+		rc = vol_part_info(dev->fdisk->vol, part->svc_id, &vpinfo);
+		if (rc != EOK) {
+			rc = EIO;
+			goto error;
+		}
+
+		part->pcnt = vpinfo.pcnt;
+		part->fstype = vpinfo.fstype;
+		part->label = str_dup(vpinfo.label);
+
+		if (part->label == NULL) {
+			rc = EIO;
+			goto error;
+		}
 	}
 
@@ -766,4 +788,11 @@
 		*rpart = part;
 	return EOK;
+error:
+	/* Try rolling back */
+	if (part != NULL)
+		fdisk_part_remove(part);
+	if (partid != 0)
+		(void) vbd_part_delete(dev->fdisk->vbd, partid);
+	return rc;
 }
 
@@ -1194,4 +1223,11 @@
 }
 
+/** Get volume label support. */
+int fdisk_get_vollabel_support(fdisk_dev_t *dev, vol_fstype_t fstype,
+    vol_label_supp_t *vlsupp)
+{
+	return vol_part_get_lsupp(dev->fdisk->vol, fstype, vlsupp);
+}
+
 /** @}
  */
Index: uspace/srv/volsrv/mkfs.c
===================================================================
--- uspace/srv/volsrv/mkfs.c	(revision d858a660afff3b05ffdfe37e6957b83b447f6b26)
+++ uspace/srv/volsrv/mkfs.c	(revision 9c2c7d2247cc1ad0410cd61ab534af9a246d328b)
@@ -40,4 +40,5 @@
 #include <stdarg.h>
 #include <stdlib.h>
+#include <str.h>
 #include <str_error.h>
 #include <task.h>
@@ -101,5 +102,5 @@
 
 
-int volsrv_part_mkfs(service_id_t sid, vol_fstype_t fstype)
+int volsrv_part_mkfs(service_id_t sid, vol_fstype_t fstype, const char *label)
 {
 	const char *cmd;
@@ -131,9 +132,29 @@
 		return rc;
 
-	rc = cmd_runl(cmd, cmd, svc_name, NULL);
+	if (str_size(label) > 0)
+		rc = cmd_runl(cmd, cmd, "--label", label, svc_name, NULL);
+	else
+		rc = cmd_runl(cmd, cmd, svc_name, NULL);
+
 	free(svc_name);
 	return rc;
 }
 
+void volsrv_part_get_lsupp(vol_fstype_t fstype, vol_label_supp_t *vlsupp)
+{
+	vlsupp->supported = false;
+
+	switch (fstype) {
+	case fs_fat:
+		vlsupp->supported = true;
+		break;
+	case fs_exfat:
+	case fs_minix:
+	case fs_ext4:
+	case fs_cdfs:
+		break;
+	}
+}
+
 /** @}
  */
Index: uspace/srv/volsrv/mkfs.h
===================================================================
--- uspace/srv/volsrv/mkfs.h	(revision d858a660afff3b05ffdfe37e6957b83b447f6b26)
+++ uspace/srv/volsrv/mkfs.h	(revision 9c2c7d2247cc1ad0410cd61ab534af9a246d328b)
@@ -41,5 +41,6 @@
 #include <types/vol.h>
 
-extern int volsrv_part_mkfs(service_id_t, vol_fstype_t);
+extern int volsrv_part_mkfs(service_id_t, vol_fstype_t, const char *);
+extern void volsrv_part_get_lsupp(vol_fstype_t, vol_label_supp_t *);
 
 #endif
Index: uspace/srv/volsrv/part.c
===================================================================
--- uspace/srv/volsrv/part.c	(revision d858a660afff3b05ffdfe37e6957b83b447f6b26)
+++ uspace/srv/volsrv/part.c	(revision 9c2c7d2247cc1ad0410cd61ab534af9a246d328b)
@@ -143,10 +143,67 @@
 }
 
-static int vol_part_add_locked(service_id_t sid)
-{
-	vol_part_t *part;
+static int vol_part_probe(vol_part_t *part)
+{
 	bool empty;
 	vfs_fs_probe_info_t info;
 	struct fsname_type *fst;
+	char *label;
+	int rc;
+
+	log_msg(LOG_DEFAULT, LVL_NOTE, "Probe partition %s", part->svc_name);
+
+	assert(fibril_mutex_is_locked(&vol_parts_lock));
+
+	fst = &fstab[0];
+	while (fst->name != NULL) {
+		rc = vfs_fsprobe(fst->name, part->svc_id, &info);
+		if (rc == EOK)
+			break;
+		++fst;
+	}
+
+	if (fst->name != NULL) {
+		log_msg(LOG_DEFAULT, LVL_NOTE, "Found %s, label '%s'",
+		    fst->name, info.label);
+		label = str_dup(info.label);
+		if (label == NULL) {
+			rc = ENOMEM;
+			goto error;
+		}
+
+		part->pcnt = vpc_fs;
+		part->fstype = fst->fstype;
+		part->label = label;
+	} else {
+		log_msg(LOG_DEFAULT, LVL_NOTE, "Partition does not contain "
+		    "a recognized file system.");
+
+		rc = volsrv_part_is_empty(part->svc_id, &empty);
+		if (rc != EOK) {
+			log_msg(LOG_DEFAULT, LVL_ERROR, "Failed determining if "
+			    "partition is empty.");
+			rc = EIO;
+			goto error;
+		}
+
+		label = str_dup("");
+		if (label == NULL) {
+			rc = ENOMEM;
+			goto error;
+		}
+
+		part->pcnt = empty ? vpc_empty : vpc_unknown;
+		part->label = label;
+	}
+
+	return EOK;
+
+error:
+	return rc;
+}
+
+static int vol_part_add_locked(service_id_t sid)
+{
+	vol_part_t *part;
 	int rc;
 
@@ -171,38 +228,7 @@
 	}
 
-	log_msg(LOG_DEFAULT, LVL_NOTE, "Probe partition %s", part->svc_name);
-
-	fst = &fstab[0];
-	while (fst->name != NULL) {
-		rc = vfs_fsprobe(fst->name, sid, &info);
-		if (rc == EOK)
-			break;
-		++fst;
-	}
-
-	if (fst->name != NULL) {
-		log_msg(LOG_DEFAULT, LVL_NOTE, "Found %s, label '%s'",
-		    fst->name, info.label);
-		part->pcnt = vpc_fs;
-		part->fstype = fst->fstype;
-		part->label = str_dup(info.label);
-		if (part->label == NULL)
-			goto error;
-	} else {
-		log_msg(LOG_DEFAULT, LVL_NOTE, "Partition does not contain "
-		    "a recognized file system.");
-
-		rc = volsrv_part_is_empty(sid, &empty);
-		if (rc != EOK) {
-			log_msg(LOG_DEFAULT, LVL_ERROR, "Failed determining if "
-			    "partition is empty.");
-			goto error;
-		}
-
-		part->pcnt = empty ? vpc_empty : vpc_unknown;
-		part->label = str_dup("");
-		if (part->label == NULL)
-			goto error;
-	}
+	rc = vol_part_probe(part);
+	if (rc != EOK)
+		goto error;
 
 	list_append(&part->lparts, &vol_parts);
@@ -311,5 +337,6 @@
 }
 
-int vol_part_mkfs_part(vol_part_t *part, vol_fstype_t fstype)
+int vol_part_mkfs_part(vol_part_t *part, vol_fstype_t fstype,
+    const char *label)
 {
 	int rc;
@@ -317,13 +344,26 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "vol_part_mkfs_part()");
 
-	rc = volsrv_part_mkfs(part->svc_id, fstype);
+	fibril_mutex_lock(&vol_parts_lock);
+
+	rc = volsrv_part_mkfs(part->svc_id, fstype, label);
 	if (rc != EOK) {
 		log_msg(LOG_DEFAULT, LVL_DEBUG, "vol_part_mkfs_part() - failed %d",
 		    rc);
+		fibril_mutex_unlock(&vol_parts_lock);
 		return rc;
 	}
 
-	part->pcnt = vpc_fs;
-	part->fstype = fstype;
+	/*
+	 * Re-probe the partition to update information. This is needed since
+	 * the FS can make conversions of the volume label (e.g. make it
+	 * uppercase).
+	 */
+	rc = vol_part_probe(part);
+	if (rc != EOK) {
+		fibril_mutex_unlock(&vol_parts_lock);
+		return rc;
+	}
+
+	fibril_mutex_unlock(&vol_parts_lock);
 	return EOK;
 }
Index: uspace/srv/volsrv/part.h
===================================================================
--- uspace/srv/volsrv/part.h	(revision d858a660afff3b05ffdfe37e6957b83b447f6b26)
+++ uspace/srv/volsrv/part.h	(revision 9c2c7d2247cc1ad0410cd61ab534af9a246d328b)
@@ -49,5 +49,5 @@
 extern int vol_part_find_by_id(service_id_t, vol_part_t **);
 extern int vol_part_empty_part(vol_part_t *);
-extern int vol_part_mkfs_part(vol_part_t *, vol_fstype_t);
+extern int vol_part_mkfs_part(vol_part_t *, vol_fstype_t, const char *);
 extern int vol_part_get_info(vol_part_t *, vol_part_info_t *);
 
Index: uspace/srv/volsrv/volsrv.c
===================================================================
--- uspace/srv/volsrv/volsrv.c	(revision d858a660afff3b05ffdfe37e6957b83b447f6b26)
+++ uspace/srv/volsrv/volsrv.c	(revision 9c2c7d2247cc1ad0410cd61ab534af9a246d328b)
@@ -46,4 +46,5 @@
 #include <types/vol.h>
 
+#include "mkfs.h"
 #include "part.h"
 
@@ -131,5 +132,4 @@
 	async_answer_0(iid, EOK);
 }
-
 
 static void vol_part_info_srv(ipc_callid_t iid, ipc_call_t *icall)
@@ -204,4 +204,42 @@
 }
 
+static void vol_part_get_lsupp_srv(ipc_callid_t iid, ipc_call_t *icall)
+{
+	vol_fstype_t fstype;
+	vol_label_supp_t vlsupp;
+	int rc;
+
+	fstype = IPC_GET_ARG1(*icall);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "vol_part_get_lsupp_srv(%u)",
+	    fstype);
+
+	volsrv_part_get_lsupp(fstype, &vlsupp);
+
+	ipc_callid_t callid;
+	size_t size;
+	if (!async_data_read_receive(&callid, &size)) {
+		async_answer_0(callid, EREFUSED);
+		async_answer_0(iid, EREFUSED);
+		return;
+	}
+
+	if (size != sizeof(vol_label_supp_t)) {
+		async_answer_0(callid, EINVAL);
+		async_answer_0(iid, EINVAL);
+		return;
+	}
+
+	rc = async_data_read_finalize(callid, &vlsupp,
+	    min(size, sizeof(vlsupp)));
+	if (rc != EOK) {
+		async_answer_0(callid, rc);
+		async_answer_0(iid, rc);
+		return;
+	}
+
+	async_answer_0(iid, EOK);
+}
+
+
 static void vol_part_mkfs_srv(ipc_callid_t iid, ipc_call_t *icall)
 {
@@ -209,4 +247,5 @@
 	vol_part_t *part;
 	vol_fstype_t fstype;
+	char *label;
 	int rc;
 
@@ -214,19 +253,29 @@
 	fstype = IPC_GET_ARG2(*icall);
 
+	rc = async_data_write_accept((void **)&label, true, 0, VOL_LABEL_MAXLEN,
+	    0, NULL);
+	if (rc != EOK) {
+		async_answer_0(iid, rc);
+		return;
+	}
+
+	printf("vol_part_mkfs_srv: label=%p\n", label);
+	if (label!=NULL) printf("vol_part_mkfs_srv: label='%s'\n", label);
+
 	rc = vol_part_find_by_id(sid, &part);
 	if (rc != EOK) {
+		free(label);
 		async_answer_0(iid, ENOENT);
 		return;
 	}
 
-	rc = vol_part_mkfs_part(part, fstype);
-	if (rc != EOK) {
-		async_answer_0(iid, rc);
-		return;
-	}
-
-	part->pcnt = vpc_fs;
-	part->fstype = fstype;
-
+	rc = vol_part_mkfs_part(part, fstype, label);
+	if (rc != EOK) {
+		free(label);
+		async_answer_0(iid, rc);
+		return;
+	}
+
+	free(label);
 	async_answer_0(iid, EOK);
 }
@@ -263,4 +312,7 @@
 			vol_part_empty_srv(callid, &call);
 			break;
+		case VOL_PART_LSUPP:
+			vol_part_get_lsupp_srv(callid, &call);
+			break;
 		case VOL_PART_MKFS:
 			vol_part_mkfs_srv(callid, &call);
