Index: uspace/app/fdisk/fdisk.c
===================================================================
--- uspace/app/fdisk/fdisk.c	(revision 6a0db5246ebe1f985f9eae45d0da15441c18fd2f)
+++ uspace/app/fdisk/fdisk.c	(revision 4b6635a753fc6cfed370d74f7f99b2d9848440e0)
@@ -262,5 +262,5 @@
 }
 
-static int fdsk_select_fstype(fdisk_fstype_t *fstype)
+static int fdsk_select_fstype(vol_fstype_t *fstype)
 {
 	nchoice_t *choice = NULL;
@@ -284,5 +284,5 @@
 	}
 
-	for (i = FDFS_CREATE_LO; i < FDFS_CREATE_HI; i++) {
+	for (i = 0; i < VOL_FSTYPE_LIMIT; i++) {
 		rc = fdisk_fstype_format(i, &sfstype);
 		if (rc != EOK)
@@ -307,5 +307,5 @@
 
 	nchoice_destroy(choice);
-	*fstype = (fdisk_fstype_t)sel;
+	*fstype = (vol_fstype_t)sel;
 	return EOK;
 error:
@@ -321,5 +321,5 @@
 	fdisk_part_spec_t pspec;
 	fdisk_cap_t cap;
-	fdisk_fstype_t fstype = fdfs_none;
+	vol_fstype_t fstype = 0;
 	tinput_t *tinput = NULL;
 	char *scap;
@@ -577,6 +577,18 @@
 		}
 
-		if (pinfo.pkind != lpk_extended)
-			printf(", %s", sfstype);
+		if (pinfo.pkind != lpk_extended) {
+			switch (pinfo.pcnt) {
+			case vpc_empty:
+				printf(", Empty");
+				break;
+			case vpc_fs:
+				printf(", %s", sfstype);
+				break;
+			case vpc_unknown:
+				printf(", Unknown");
+				break;
+			}
+		}
+
 		printf("\n");
 
Index: uspace/lib/c/include/types/vol.h
===================================================================
--- uspace/lib/c/include/types/vol.h	(revision 4b6635a753fc6cfed370d74f7f99b2d9848440e0)
+++ uspace/lib/c/include/types/vol.h	(revision 4b6635a753fc6cfed370d74f7f99b2d9848440e0)
@@ -0,0 +1,60 @@
+/*
+ * 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
+ */
+
+#ifndef LIBC_TYPES_VOL_H_
+#define LIBC_TYPES_VOL_H_
+
+typedef enum {
+	/** Partition is empty */
+	vpc_empty,
+	/** Partition contains a recognized filesystem */
+	vpc_fs,
+	/** Partition contains unrecognized data */
+	vpc_unknown
+} vol_part_cnt_t;
+
+/** File system type */
+typedef enum {
+	fs_exfat,
+	fs_fat,
+	fs_minix,
+	fs_ext4
+} vol_fstype_t;
+
+#define VOL_FSTYPE_LIMIT (fs_ext4 + 1)
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/vbd.h
===================================================================
--- uspace/lib/c/include/vbd.h	(revision 6a0db5246ebe1f985f9eae45d0da15441c18fd2f)
+++ uspace/lib/c/include/vbd.h	(revision 4b6635a753fc6cfed370d74f7f99b2d9848440e0)
@@ -87,4 +87,6 @@
 	/** Number of blocks */
 	aoff64_t nblocks;
+	/** Service ID */
+	service_id_t svc_id;
 } vbd_part_info_t;
 
Index: uspace/lib/c/include/vol.h
===================================================================
--- uspace/lib/c/include/vol.h	(revision 6a0db5246ebe1f985f9eae45d0da15441c18fd2f)
+++ uspace/lib/c/include/vol.h	(revision 4b6635a753fc6cfed370d74f7f99b2d9848440e0)
@@ -40,4 +40,5 @@
 #include <stdint.h>
 #include <types/label.h>
+#include <types/vol.h>
 
 /** Volume service */
@@ -46,21 +47,4 @@
 	async_sess_t *sess;
 } vol_t;
-
-typedef enum {
-	/** Partition is empty */
-	vpc_empty,
-	/** Partition contains a recognized filesystem */
-	vpc_fs,
-	/** Partition contains unrecognized data */
-	vpc_unknown
-} vol_part_cnt_t;
-
-/** File system type */
-typedef enum {
-	fs_exfat,
-	fs_fat,
-	fs_minix,
-	fs_ext4
-} vol_fstype_t;
 
 /** Partition information */
Index: uspace/lib/fdisk/include/fdisk.h
===================================================================
--- uspace/lib/fdisk/include/fdisk.h	(revision 6a0db5246ebe1f985f9eae45d0da15441c18fd2f)
+++ uspace/lib/fdisk/include/fdisk.h	(revision 4b6635a753fc6cfed370d74f7f99b2d9848440e0)
@@ -71,5 +71,5 @@
 extern int fdisk_cap_parse(const char *, fdisk_cap_t *);
 extern int fdisk_ltype_format(label_type_t, char **);
-extern int fdisk_fstype_format(fdisk_fstype_t, char **);
+extern int fdisk_fstype_format(vol_fstype_t, char **);
 extern int fdisk_pkind_format(label_pkind_t, char **);
 
Index: uspace/lib/fdisk/include/types/fdisk.h
===================================================================
--- uspace/lib/fdisk/include/types/fdisk.h	(revision 6a0db5246ebe1f985f9eae45d0da15441c18fd2f)
+++ uspace/lib/fdisk/include/types/fdisk.h	(revision 4b6635a753fc6cfed370d74f7f99b2d9848440e0)
@@ -41,4 +41,5 @@
 #include <stdint.h>
 #include <types/label.h>
+#include <types/vol.h>
 #include <vbd.h>
 #include <vol.h>
@@ -57,21 +58,4 @@
 
 #define CU_LIMIT (cu_ybyte + 1)
-
-/** File system type */
-typedef enum {
-	fdfs_none = 0,
-	fdfs_unknown,
-	fdfs_exfat,
-	fdfs_fat,
-	fdfs_minix,
-	fdfs_ext4
-} fdisk_fstype_t;
-
-/** Highest fstype value + 1 */
-#define FDFS_LIMIT (fdfs_ext4 + 1)
-/** Lowest fstype allowed for creation */
-#define FDFS_CREATE_LO fdfs_exfat
-/** Highest fstype allowed for creation + 1 */
-#define FDFS_CREATE_HI (fdfs_ext4 + 1)
 
 /** Partition capacity */
@@ -143,6 +127,8 @@
 	/** Partition kind */
 	label_pkind_t pkind;
+	/** Partition contents */
+	vol_part_cnt_t pcnt;
 	/** File system type */
-	fdisk_fstype_t fstype;
+	vol_fstype_t fstype;
 	/** Partition ID */
 	vbd_part_id_t part_id;
@@ -153,4 +139,6 @@
 	/** Number of blocks */
 	aoff64_t nblocks;
+	/** Service ID */
+	service_id_t svc_id;
 } fdisk_part_t;
 
@@ -162,5 +150,5 @@
 	label_pkind_t pkind;
 	/** File system type */
-	fdisk_fstype_t fstype;
+	vol_fstype_t fstype;
 } fdisk_part_spec_t;
 
@@ -171,6 +159,8 @@
 	/** Partition kind */
 	label_pkind_t pkind;
+	/** Partition contents */
+	vol_part_cnt_t pcnt;
 	/** File system type */
-	fdisk_fstype_t fstype;
+	vol_fstype_t fstype;
 } fdisk_part_info_t;
 
Index: uspace/lib/fdisk/src/fdisk.c
===================================================================
--- uspace/lib/fdisk/src/fdisk.c	(revision 6a0db5246ebe1f985f9eae45d0da15441c18fd2f)
+++ uspace/lib/fdisk/src/fdisk.c	(revision 4b6635a753fc6cfed370d74f7f99b2d9848440e0)
@@ -261,4 +261,5 @@
 	fdisk_part_t *part;
 	vbd_part_info_t pinfo;
+	vol_part_info_t vpinfo;
 	int rc;
 
@@ -268,4 +269,10 @@
 
 	rc = vbd_part_get_info(dev->fdisk->vbd, partid, &pinfo);
+	if (rc != EOK) {
+		rc = EIO;
+		goto error;
+	}
+
+	rc = vol_part_info(dev->fdisk->vol, pinfo.svc_id, &vpinfo);
 	if (rc != EOK) {
 		rc = EIO;
@@ -278,4 +285,7 @@
 	part->nblocks = pinfo.nblocks;
 	part->pkind = pinfo.pkind;
+	part->svc_id = pinfo.svc_id;
+	part->pcnt = vpinfo.pcnt;
+	part->fstype = vpinfo.fstype;
 
 	switch (part->pkind) {
@@ -551,4 +561,5 @@
 {
 	info->capacity = part->capacity;
+	info->pcnt = part->pcnt;
 	info->fstype = part->fstype;
 	info->pkind = part->pkind;
@@ -589,4 +600,5 @@
 
 	printf("fdisk_part_create() - done\n");
+	part->pcnt = vpc_fs;
 	part->fstype = pspec->fstype;
 	part->capacity = pspec->capacity;
@@ -700,5 +712,5 @@
 }
 
-int fdisk_fstype_format(fdisk_fstype_t fstype, char **rstr)
+int fdisk_fstype_format(vol_fstype_t fstype, char **rstr)
 {
 	const char *sfstype;
@@ -707,20 +719,14 @@
 	sfstype = NULL;
 	switch (fstype) {
-	case fdfs_none:
-		sfstype = "None";
-		break;
-	case fdfs_unknown:
-		sfstype = "Unknown";
-		break;
-	case fdfs_exfat:
+	case fs_exfat:
 		sfstype = "ExFAT";
 		break;
-	case fdfs_fat:
+	case fs_fat:
 		sfstype = "FAT";
 		break;
-	case fdfs_minix:
+	case fs_minix:
 		sfstype = "MINIX";
 		break;
-	case fdfs_ext4:
+	case fs_ext4:
 		sfstype = "Ext4";
 		break;
@@ -916,5 +922,4 @@
 	int rc;
 
-//	pspec->fstype
 	printf("fdisk_part_spec_prepare() - dev=%p pspec=%p vpspec=%p\n", dev, pspec,
 	    vpspec);
@@ -935,17 +940,14 @@
 
 	switch (pspec->fstype) {
-	case fdfs_none:
-	case fdfs_unknown:
-		break;
-	case fdfs_exfat:
+	case fs_exfat:
 		pcnt = lpc_exfat;
 		break;
-	case fdfs_fat:
+	case fs_fat:
 		pcnt = lpc_fat32; /* XXX Detect FAT12/16 vs FAT32 */
 		break;
-	case fdfs_minix:
+	case fs_minix:
 		pcnt = lpc_minix;
 		break;
-	case fdfs_ext4:
+	case fs_ext4:
 		pcnt = lpc_ext4;
 		break;
Index: uspace/srv/bd/vbd/disk.c
===================================================================
--- uspace/srv/bd/vbd/disk.c	(revision 6a0db5246ebe1f985f9eae45d0da15441c18fd2f)
+++ uspace/srv/bd/vbd/disk.c	(revision 4b6635a753fc6cfed370d74f7f99b2d9848440e0)
@@ -647,4 +647,5 @@
 	pinfo->block0 = lpinfo.block0;
 	pinfo->nblocks = lpinfo.nblocks;
+	pinfo->svc_id = part->svc_id;
 	return EOK;
 }
Index: uspace/srv/volsrv/Makefile
===================================================================
--- uspace/srv/volsrv/Makefile	(revision 6a0db5246ebe1f985f9eae45d0da15441c18fd2f)
+++ uspace/srv/volsrv/Makefile	(revision 4b6635a753fc6cfed370d74f7f99b2d9848440e0)
@@ -28,7 +28,12 @@
 
 USPACE_PREFIX = ../..
+
+LIBS = $(LIBBLOCK_PREFIX)/libblock.a
+EXTRA_CFLAGS = -I $(LIBBLOCK_PREFIX)
+
 BINARY = volsrv
 
 SOURCES = \
+	empty.c \
 	part.c \
 	volsrv.c
Index: uspace/srv/volsrv/empty.c
===================================================================
--- uspace/srv/volsrv/empty.c	(revision 4b6635a753fc6cfed370d74f7f99b2d9848440e0)
+++ uspace/srv/volsrv/empty.c	(revision 4b6635a753fc6cfed370d74f7f99b2d9848440e0)
@@ -0,0 +1,160 @@
+/*
+ * 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 volsrv
+ * @{
+ */
+/**
+ * @file Empty partition handling
+ * @brief
+ */
+
+#include <block.h>
+#include <errno.h>
+#include <io/log.h>
+#include <loc.h>
+#include <stdlib.h>
+
+#include "empty.h"
+
+static bool mem_is_zero(void *buf, size_t size)
+{
+	uint8_t *bp;
+	size_t i;
+
+	bp = (uint8_t *)buf;
+	for (i = 0; i < size; i++) {
+		if (bp[i] != 0)
+			return false;
+	}
+
+	return true;
+}
+
+int vol_part_is_empty(service_id_t sid, bool *rempty)
+{
+	int rc;
+	bool block_inited = false;
+	void *buf = NULL;
+	aoff64_t nblocks;
+	aoff64_t n;
+	aoff64_t i;
+	size_t block_size;
+	bool empty;
+
+	rc = block_init(EXCHANGE_SERIALIZE, sid, 2048);
+	if (rc != EOK) {
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Error opening "
+		    "block device service %zu", sid);
+		rc = EIO;
+		goto error;
+	}
+
+	block_inited = true;
+
+	rc = block_get_bsize(sid, &block_size);
+	if (rc != EOK) {
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Error getting "
+		    "block size.");
+		rc = EIO;
+		goto error;
+	}
+
+	rc = block_get_nblocks(sid, &nblocks);
+	if (rc != EOK) {
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Error getting "
+		    "number of blocks.");
+		rc = EIO;
+		goto error;
+	}
+
+	/* Check first 16 kiB / 16 blocks, whichever is more */
+	n = (16384 + block_size - 1) / block_size;
+	if (n < 16)
+		n = 16;
+	/*
+	 * Limit to half of the device so we do not process the same blocks
+	 * twice
+	 */
+	if (n > (nblocks + 1) / 2)
+		n = (nblocks + 1) / 2;
+
+	buf = calloc(block_size, 1);
+	if (buf == NULL) {
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Error allocating buffer.");
+		rc = ENOMEM;
+		goto error;
+	}
+
+	empty = true;
+
+	for (i = 0; i < n; i++) {
+		rc = block_read_direct(sid, i, 1, buf);
+		if (rc != EOK) {
+			log_msg(LOG_DEFAULT, LVL_ERROR, "Error "
+			    "reading blocks.");
+			rc = EIO;
+			goto error;
+		}
+
+		if (!mem_is_zero(buf, block_size)) {
+			empty = false;
+			goto done;
+		}
+	}
+
+	for (i = 0; i < n; i++) {
+		rc = block_read_direct(sid, nblocks - n + i, 1, buf);
+		if (rc != EOK) {
+			log_msg(LOG_DEFAULT, LVL_ERROR, "Error "
+			    "reading blocks.");
+			rc = EIO;
+			goto error;
+		}
+
+		if (!mem_is_zero(buf, block_size)) {
+			empty = false;
+			goto done;
+		}
+	}
+
+done:
+	block_fini(sid);
+	free(buf);
+	*rempty = empty;
+	return EOK;
+error:
+	if (block_inited)
+		block_fini(sid);
+	if (buf != NULL)
+		free(buf);
+	return rc;
+}
+
+/** @}
+ */
Index: uspace/srv/volsrv/empty.h
===================================================================
--- uspace/srv/volsrv/empty.h	(revision 4b6635a753fc6cfed370d74f7f99b2d9848440e0)
+++ uspace/srv/volsrv/empty.h	(revision 4b6635a753fc6cfed370d74f7f99b2d9848440e0)
@@ -0,0 +1,47 @@
+/*
+ * 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 volsrv
+ * @{
+ */
+/**
+ * @file
+ * @brief
+ */
+
+#ifndef EMPTY_H_
+#define EMPTY_H_
+
+#include <loc.h>
+
+extern int vol_part_is_empty(service_id_t, bool *);
+
+#endif
+
+/** @}
+ */
Index: uspace/srv/volsrv/part.c
===================================================================
--- uspace/srv/volsrv/part.c	(revision 6a0db5246ebe1f985f9eae45d0da15441c18fd2f)
+++ uspace/srv/volsrv/part.c	(revision 4b6635a753fc6cfed370d74f7f99b2d9848440e0)
@@ -43,4 +43,5 @@
 #include <str.h>
 
+#include "empty.h"
 #include "part.h"
 #include "types/part.h"
@@ -130,4 +131,5 @@
 {
 	vol_part_t *part;
+	bool empty;
 	int rc;
 
@@ -148,6 +150,12 @@
 
 	log_msg(LOG_DEFAULT, LVL_NOTE, "Probe partition %s", part->svc_name);
-
-	part->pcnt = vpc_unknown;
+	rc = vol_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;
 	list_append(&part->lparts, &vol_parts);
 
Index: uspace/srv/volsrv/part.h
===================================================================
--- uspace/srv/volsrv/part.h	(revision 6a0db5246ebe1f985f9eae45d0da15441c18fd2f)
+++ uspace/srv/volsrv/part.h	(revision 4b6635a753fc6cfed370d74f7f99b2d9848440e0)
@@ -36,6 +36,7 @@
 
 #ifndef PART_H_
-#define pART_H_
+#define PART_H_
 
+#include <loc.h>
 #include <sys/types.h>
 #include <vol.h>
