Index: uspace/app/mkexfat/mkexfat.c
===================================================================
--- uspace/app/mkexfat/mkexfat.c	(revision e04bfbf04d706358fe00ca1e10a0461ae5764394)
+++ uspace/app/mkexfat/mkexfat.c	(revision ef144ef93f15d6f1a215abc01f114fbd273d75e0)
@@ -48,4 +48,5 @@
 #include <bool.h>
 #include <str.h>
+#include <getopt.h>
 #include "exfat.h"
 #include "upcase.h"
@@ -122,7 +123,15 @@
 upcase_table_checksum(void const *data, size_t nbytes);
 
+static struct option const long_options[] = {
+	{"help", no_argument, 0, 'h'},
+	{"cluster-size", required_argument, 0, 'c'},
+	{"fs-size", required_argument, 0, 's'},
+};
+
 static void usage(void)
 {
-	printf("Usage: mkexfat <device>\n");
+	printf("Usage: mkexfat [options] <device>\n"
+	    "-c, --cluster-size ## Specify the cluster size\n"
+	    "-s, --fs-size ##      Specify the filesystem size\n");
 }
 
@@ -137,6 +146,13 @@
 	aoff64_t const volume_bytes = (cfg->volume_count - FAT_SECTOR_START) *
 	    cfg->sector_size;
-
-	aoff64_t n_req_clusters = volume_bytes / DEFAULT_CLUSTER_SIZE;
+	aoff64_t n_req_clusters;
+
+	if (cfg->cluster_size != 0) {
+		/* The user already choose the cluster size he wants */
+		n_req_clusters = volume_bytes / cfg->cluster_size;
+		goto skip_cluster_size_set;
+	}
+
+	n_req_clusters = volume_bytes / DEFAULT_CLUSTER_SIZE;
 	cfg->cluster_size = DEFAULT_CLUSTER_SIZE;
 
@@ -149,6 +165,8 @@
 
 		cfg->cluster_size <<= 1;
-		n_req_clusters = volume_bytes / cfg->cluster_size;
-	}
+		n_req_clusters = div_round_up(volume_bytes, cfg->cluster_size);
+	}
+
+skip_cluster_size_set:
 
 	/* The first two clusters are reserved */
@@ -164,5 +182,5 @@
 
 	/* Compute the bitmap size */
-	cfg->bitmap_size = n_req_clusters / 8;
+	cfg->bitmap_size = div_round_up(n_req_clusters, 8);
 
 	/* Compute the number of clusters reserved to the bitmap */
@@ -678,4 +696,13 @@
 }
 
+static bool
+is_power_of_two(unsigned long n)
+{
+	if (n == 0)
+		return false;
+
+	return (n & (n - 1)) == 0;
+}
+
 int main (int argc, char **argv)
 {
@@ -684,5 +711,6 @@
 	char *dev_path;
 	service_id_t service_id;
-	int rc;
+	int rc, c, opt_ind;
+	aoff64_t user_fs_size = 0;
 
 	if (argc < 2) {
@@ -692,7 +720,44 @@
 	}
 
-	/* TODO: Add parameters */
-
-	++argv;
+	cfg.cluster_size = 0;
+
+	for (c = 0, optind = 0, opt_ind = 0; c != -1;) {
+		c = getopt_long(argc, argv, "hs:c:",
+		    long_options, &opt_ind);
+		switch (c) {
+		case 'h':
+			usage();
+			return 0;
+		case 's':
+			user_fs_size = (aoff64_t) strtol(optarg, NULL, 10);
+			if (user_fs_size < 1024 * 1024) {
+				printf(NAME ": Error, fs size can't be less"
+				    " than 1 Mb.\n");
+				return 1;
+			}
+			break;
+
+		case 'c':
+			cfg.cluster_size = strtol(optarg, NULL, 10);
+			if (cfg.cluster_size < 4096) {
+				printf(NAME ": Error, cluster size can't"
+				    " be less than 4096 byte.\n");
+				return 1;
+			} else if (cfg.cluster_size > 32 * 1024 * 1024) {
+				printf(NAME ": Error, cluster size can't"
+				    " be greater than 32 Mb");
+				return 1;
+			}
+
+			if (!is_power_of_two(cfg.cluster_size)) {
+				printf(NAME ": Error, the size of the cluster"
+				    " must be a power of two.\n");
+				return 1;
+			}
+			break;
+		}
+	}
+
+	argv += optind;
 	dev_path = *argv;
 
@@ -727,5 +792,4 @@
 		printf(NAME ": Warning, failed to obtain" \
 		    " device block size.\n");
-		/* FIXME: the user should be able to specify the filesystem size */
 		return 1;
 	} else {
@@ -734,4 +798,15 @@
 	}
 
+	if (user_fs_size != 0) {
+		if (user_fs_size > cfg.volume_count * cfg.sector_size) {
+			printf(NAME ": Error, the device is not big enough"
+			    " to create the filesystem a filesystem of"
+			    " the specified size.\n");
+			return 1;
+		}
+
+		cfg.volume_count = user_fs_size / cfg.sector_size;
+	}
+
 	cfg_params_initialize(&cfg);
 	cfg_print_info(&cfg);
