Index: uspace/srv/fs/mfs/mfs_ops.c
===================================================================
--- uspace/srv/fs/mfs/mfs_ops.c	(revision b69e4c0e57c95841447ac2ff2a399e6f98d04b10)
+++ uspace/srv/fs/mfs/mfs_ops.c	(revision 3002434fa388f59c77ee7bd7c849335a51dbc72a)
@@ -143,8 +143,8 @@
 {
 	enum cache_mode cmode;
-	struct mfs_superblock *sb;
-	struct mfs3_superblock *sb3;
-	struct mfs_sb_info *sbi;
-	struct mfs_instance *instance;
+	struct mfs_superblock *sb = NULL;
+	struct mfs3_superblock *sb3 = NULL;
+	struct mfs_sb_info *sbi = NULL;
+	struct mfs_instance *instance = NULL;
 	bool native, longnames;
 	mfs_version_t version;
@@ -166,6 +166,6 @@
 	sbi = malloc(sizeof(*sbi));
 	if (!sbi) {
-		block_fini(service_id);
-		return ENOMEM;
+		rc = ENOMEM;
+		goto out_error;
 	}
 
@@ -173,26 +173,18 @@
 	instance = malloc(sizeof(*instance));
 	if (!instance) {
-		free(sbi);
-		block_fini(service_id);
-		return ENOMEM;
+		rc = ENOMEM;
+		goto out_error;
 	}
 
 	sb = malloc(MFS_SUPERBLOCK_SIZE);
 	if (!sb) {
-		free(instance);
-		free(sbi);
-		block_fini(service_id);
-		return ENOMEM;
+		rc = ENOMEM;
+		goto out_error;
 	}
 
 	/* Read the superblock */
 	rc = block_read_direct(service_id, MFS_SUPERBLOCK << 1, 2, sb);
-	if (rc != EOK) {
-		free(instance);
-		free(sbi);
-		free(sb);
-		block_fini(service_id);
-		return rc;
-	}
+	if (rc != EOK)
+		goto out_error;
 
 	sb3 = (struct mfs3_superblock *) sb;
@@ -207,9 +199,6 @@
 		/*Not recognized*/
 		mfsdebug("magic number not recognized\n");
-		free(instance);
-		free(sbi);
-		free(sb);
-		block_fini(service_id);
-		return ENOTSUP;
+		rc = ENOTSUP;
+		goto out_error;
 	}
 
@@ -256,16 +245,24 @@
 				    MFS_MAX_NAME_LEN;
 	}
+
+	if (sbi->log2_zone_size != 0) {
+		/* In MFS, file space is allocated per zones.
+		 * Zones are a collection of consecutive blocks on disk.
+		 *
+		 * The current MFS implementation supports only filesystems
+		 * where the size of a zone is equal to the
+		 * size of a block.
+		 */
+		rc = ENOTSUP;
+		goto out_error;
+	}
+
 	sbi->itable_off = 2 + sbi->ibmap_blocks + sbi->zbmap_blocks;
-
-	free(sb);
 
 	rc = block_cache_init(service_id, sbi->block_size, 0, cmode);
 	if (rc != EOK) {
-		free(instance);
-		free(sbi);
-		block_cache_fini(service_id);
-		block_fini(service_id);
 		mfsdebug("block cache initialization failed\n");
-		return EINVAL;
+		rc = EINVAL;
+		goto out_error;
 	}
 
@@ -295,5 +292,17 @@
 	*linkcnt = 1;
 
+	free(sb);
+
 	return mfs_node_put(fn);
+
+out_error:
+	block_fini(service_id);
+	if (sb)
+		free(sb);
+	if (sbi)
+		free(sbi);
+	if(instance)
+		free(instance);
+	return rc;
 }
 
@@ -880,6 +889,5 @@
 	struct mfs_ino_info *ino_i = mnode->ino_i;
 	const size_t bs = sbi->block_size;
-	size_t bytes = min(len, bs - pos % bs);
-	size_t boundary = ROUND_UP(ino_i->i_size, bs);
+	size_t bytes = min(len, bs - (pos % bs));
 	uint32_t block;
 
@@ -887,17 +895,10 @@
 		flags = BLOCK_FLAGS_NOREAD;
 
-	if (pos < boundary) {
-		r = mfs_read_map(&block, mnode, pos);
-		if (r != EOK)
-			goto out_err;
-
-		if (block == 0) {
-			/*Writing in a sparse block*/
-			r = mfs_alloc_zone(mnode->instance, &block);
-			if (r != EOK)
-				goto out_err;
-			flags = BLOCK_FLAGS_NOREAD;
-		}
-	} else {
+	r = mfs_read_map(&block, mnode, pos);
+	if (r != EOK)
+		goto out_err;
+
+	if (block == 0) {
+		/*Writing in a sparse block*/
 		uint32_t dummy;
 
@@ -905,8 +906,10 @@
 		if (r != EOK)
 			goto out_err;
-
+		
 		r = mfs_write_map(mnode, pos, block, &dummy);
 		if (r != EOK)
 			goto out_err;
+
+		flags = BLOCK_FLAGS_NOREAD;
 	}
 
@@ -916,5 +919,8 @@
 		goto out_err;
 
-	async_data_write_finalize(callid, b->data + pos % bs, bytes);
+	if (flags == BLOCK_FLAGS_NOREAD)
+		memset(b->data, 0, sbi->block_size);
+
+	async_data_write_finalize(callid, b->data + (pos % bs), bytes);
 	b->dirty = true;
 
@@ -925,8 +931,10 @@
 	}
 
-	ino_i->i_size = pos + bytes;
-	ino_i->dirty = true;
+	if (pos + bytes > ino_i->i_size) {
+		ino_i->i_size = pos + bytes;
+		ino_i->dirty = true;
+	}
 	r = mfs_node_put(fn);
-	*nsize = pos + bytes;
+	*nsize = ino_i->i_size;
 	*wbytes = bytes;
 	return r;
Index: uspace/srv/fs/mfs/mfs_rw.c
===================================================================
--- uspace/srv/fs/mfs/mfs_rw.c	(revision b69e4c0e57c95841447ac2ff2a399e6f98d04b10)
+++ uspace/srv/fs/mfs/mfs_rw.c	(revision 3002434fa388f59c77ee7bd7c849335a51dbc72a)
@@ -31,4 +31,5 @@
  */
 
+#include <align.h>
 #include "mfs.h"
 
@@ -70,5 +71,5 @@
 	int rblock = pos / block_size;
 
-	if (mnode->ino_i->i_size < pos) {
+	if (ROUND_UP(mnode->ino_i->i_size, sbi->block_size) < pos) {
 		/*Trying to read beyond the end of file*/
 		r = EOK;
