Index: uspace/app/mkfat/mkfat.c
===================================================================
--- uspace/app/mkfat/mkfat.c	(revision ee50130e3b1d50789ddf63162191a85cf20298f8)
+++ uspace/app/mkfat/mkfat.c	(revision f4ae95a65f4963c3b4f326e1810ef51c3b5d2144)
@@ -38,4 +38,5 @@
  */
 
+#include <ctype.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -48,6 +49,9 @@
 #include <errno.h>
 #include "fat.h"
+#include "fat_dentry.h"
 
 #define NAME	"mkfat"
+
+#define LABEL_NONAME "NO NAME"
 
 /** Divide and round up. */
@@ -77,4 +81,5 @@
 	uint32_t total_clusters;
 	uint8_t fat_count;
+	const char *label;
 } fat_cfg_t;
 
@@ -102,4 +107,5 @@
 	cfg.root_ent_max = 128;
 	cfg.fat_type = FATAUTO;
+	cfg.label = NULL;
 
 	if (argc < 2) {
@@ -142,4 +148,17 @@
 			return 1;
 		}
+
+		--argc; ++argv;
+	}
+
+	if (str_cmp(*argv, "--label") == 0) {
+		--argc; ++argv;
+		if (*argv == NULL) {
+			printf(NAME ": Error, argument missing.\n");
+			syntax_print();
+			return 1;
+		}
+
+		cfg.label = *argv;
 
 		--argc; ++argv;
@@ -216,5 +235,33 @@
 static void syntax_print(void)
 {
-	printf("syntax: mkfat [--size <sectors>] [--type 12|16|32] <device_name>\n");
+	printf("syntax: mkfat [--size <sectors>] [--type 12|16|32] "
+	    "[--label <label>] <device_name>\n");
+}
+
+static int fat_label_encode(void *dest, const char *src)
+{
+	int i;
+	const char *sp;
+	uint8_t *dp;
+
+	i = 0;
+	sp = src;
+	dp = (uint8_t *)dest;
+
+	while (*sp != '\0' && i < FAT_VOLLABEL_LEN) {
+		if (!ascii_check(*sp))
+			return EINVAL;
+		if (dp != NULL)
+			dp[i] = toupper(*sp);
+		++i; ++sp;
+	}
+
+	while (i < FAT_VOLLABEL_LEN) {
+		if (dp != NULL)
+			dp[i] = FAT_PAD;
+		++i;
+	}
+
+	return EOK;
 }
 
@@ -241,5 +288,5 @@
 			cfg->sector_size);
 	} else
-		cfg->rootdir_sectors = 0;
+		cfg->rootdir_sectors = cfg->sectors_per_cluster;
 	non_data_sectors_lb = cfg->reserved_sectors + cfg->rootdir_sectors;
 
@@ -268,4 +315,7 @@
 	cfg->fat_sectors = div_round_up(fat_bytes, cfg->sector_size);
 
+	if (cfg->label != NULL && fat_label_encode(NULL, cfg->label) != EOK)
+		return EINVAL;
+
 	return EOK;
 }
@@ -280,4 +330,5 @@
 	int rc;
 	struct fat_bs bs;
+	fat_dentry_t *de;
 
 	fat_bootsec_create(cfg, &bs);
@@ -339,21 +390,24 @@
 	printf("Writing root directory.\n");
 	memset(buffer, 0, cfg->sector_size);
-	if (cfg->fat_type != FAT32) {
-		size_t idx;
-		for (idx = 0; idx < cfg->rootdir_sectors; ++idx) {
-			rc = block_write_direct(service_id, addr, 1, buffer);
-			if (rc != EOK)
-				return EIO;
-
-			++addr;
-		}
-	} else {
-		for (i = 0; i < cfg->sectors_per_cluster; i++) {
-			rc = block_write_direct(service_id, addr, 1, buffer);
-			if (rc != EOK)
-				return EIO;
-
-			++addr;
-		}	
+	de = (fat_dentry_t *)buffer;
+	size_t idx;
+	for (idx = 0; idx < cfg->rootdir_sectors; ++idx) {
+
+		if (idx == 0 && cfg->label != NULL) {
+			/* Set up volume label entry */
+			(void) fat_label_encode(&de->name, cfg->label);
+			de->attr = FAT_ATTR_VOLLABEL;
+			de->mtime = 0x1234;
+			de->mdate = 0x1234;
+		} else if (idx == 1) {
+			/* Clear volume label entry */
+			memset(buffer, 0, cfg->sector_size);
+		}
+
+		rc = block_write_direct(service_id, addr, 1, buffer);
+		if (rc != EOK)
+			return EIO;
+
+		++addr;
 	}
 
@@ -366,4 +420,14 @@
 static void fat_bootsec_create(struct fat_cfg const *cfg, struct fat_bs *bs)
 {
+	const char *bs_label;
+
+	/*
+	 * The boot sector must always contain a valid label. If there
+	 * is no label, there should be 'NO NAME'
+	 */
+	if (cfg->label != NULL)
+		bs_label = cfg->label;
+	else
+		bs_label = LABEL_NONAME;
 	memset(bs, 0, sizeof(*bs));
 
@@ -404,5 +468,5 @@
 		bs->fat32.root_cluster = 2;
 
-		memcpy(bs->fat32.label, "HELENOS_NEW", 11);
+		(void) fat_label_encode(&bs->fat32.label, bs_label);
 		memcpy(bs->fat32.type, "FAT32   ", 8);
 	} else {
@@ -412,5 +476,5 @@
 		bs->id = host2uint32_t_be(0x12345678);
 
-		memcpy(bs->label, "HELENOS_NEW", 11);
+		(void) fat_label_encode(&bs->label, bs_label);
 		memcpy(bs->type, "FAT   ", 8);
 	}
Index: uspace/srv/fs/fat/fat_dentry.h
===================================================================
--- uspace/srv/fs/fat/fat_dentry.h	(revision ee50130e3b1d50789ddf63162191a85cf20298f8)
+++ uspace/srv/fs/fat/fat_dentry.h	(revision f4ae95a65f4963c3b4f326e1810ef51c3b5d2144)
@@ -35,4 +35,5 @@
 #define FAT_FAT_DENTRY_H_
 
+#include <ctype.h>
 #include <stdint.h>
 #include <stdbool.h>
Index: uspace/srv/fs/fat/fat_ops.c
===================================================================
--- uspace/srv/fs/fat/fat_ops.c	(revision ee50130e3b1d50789ddf63162191a85cf20298f8)
+++ uspace/srv/fs/fat/fat_ops.c	(revision f4ae95a65f4963c3b4f326e1810ef51c3b5d2144)
@@ -1039,5 +1039,4 @@
 static int fat_fsprobe(service_id_t service_id, vfs_fs_probe_info_t *info)
 {
-	fat_bs_t *bs;
 	fat_idx_t *ridxp;
 	fs_node_t *rfn;
@@ -1045,5 +1044,4 @@
 	fat_directory_t di;
 	char label[FAT_VOLLABEL_LEN + 1];
-	int i;
 	int rc;
 
@@ -1060,13 +1058,8 @@
 	rc = fat_directory_vollabel_get(&di, label);
 	if (rc != EOK) {
-		/* No label in root directory. Read label from the BS */
-		bs = block_bb_get(service_id);
-		i = FAT_VOLLABEL_LEN;
-		while (i > 0 && bs->label[i - 1] == FAT_PAD)
-			--i;
-
-		/* XXX Deal with non-ASCII characters */
-		memcpy(label, bs->label, i);
-		label[i] = '\0';
+		if (rc != ENOENT)
+			return rc;
+
+		label[0] = '\0';
 	}
 
