Index: uspace/lib/libblock/libblock.c
===================================================================
--- uspace/lib/libblock/libblock.c	(revision c1b455ef81f0a7d909a50b79a5328d46c6140609)
+++ uspace/lib/libblock/libblock.c	(revision 1d8cdb185ad73e3854920a8c26df884d780b3315)
@@ -297,8 +297,11 @@
  * @param dev_handle		Device handle of the block device.
  * @param boff			Block offset.
+ * @param flags			If BLOCK_FLAGS_NOREAD is specified, block_get()
+ * 				will not read the contents of the block from the
+ *				device.
  *
  * @return			Block structure.
  */
-block_t *block_get(dev_handle_t dev_handle, bn_t boff)
+block_t *block_get(dev_handle_t dev_handle, bn_t boff, int flags)
 {
 	devcon_t *devcon;
@@ -386,11 +389,13 @@
 			abort();	/* TODO: block_write() */
 		}
-		/*
-		 * The block contains old or no data. We need to read the new
-		 * contents from the device.
-		 */
-		rc = block_read(dev_handle, &bufpos, &buflen, &pos, b->data,
-		    cache->block_size, cache->block_size);
-		assert(rc == EOK);
+		if (!(flags & BLOCK_FLAGS_NOREAD)) {
+			/*
+			 * The block contains old or no data. We need to read
+			 * the new contents from the device.
+			 */
+			rc = block_read(dev_handle, &bufpos, &buflen, &pos,
+			    b->data, cache->block_size, cache->block_size);
+			assert(rc == EOK);
+		}
 
 		futex_up(&b->lock);
Index: uspace/lib/libblock/libblock.h
===================================================================
--- uspace/lib/libblock/libblock.h	(revision c1b455ef81f0a7d909a50b79a5328d46c6140609)
+++ uspace/lib/libblock/libblock.h	(revision 1d8cdb185ad73e3854920a8c26df884d780b3315)
@@ -45,4 +45,20 @@
 #include <libadt/list.h>
 
+/*
+ * Flags that can be used with block_get().
+ */
+
+/** 
+ * This macro is a symbolic value for situations where no special flags are
+ * needed.
+ */
+#define BLOCK_FLAGS_NONE	0
+
+/**
+ * When the client of block_get() intends to overwrite the current contents of
+ * the block, this flag is used to avoid the unnecessary read.
+ */
+#define BLOCK_FLAGS_NOREAD	1
+
 typedef unsigned bn_t;	/**< Block number type. */
 
@@ -78,5 +94,5 @@
 extern int block_cache_init(dev_handle_t, size_t, unsigned);
 
-extern block_t *block_get(dev_handle_t, bn_t);
+extern block_t *block_get(dev_handle_t, bn_t, int flags);
 extern void block_put(block_t *);
 
Index: uspace/srv/fs/fat/fat_fat.c
===================================================================
--- uspace/srv/fs/fat/fat_fat.c	(revision c1b455ef81f0a7d909a50b79a5328d46c6140609)
+++ uspace/srv/fs/fat/fat_fat.c	(revision 1d8cdb185ad73e3854920a8c26df884d780b3315)
@@ -95,5 +95,5 @@
 		fidx = clst % (bps / sizeof(fat_cluster_t));
 		/* read FAT1 */
-		b = block_get(dev_handle, rscnt + fsec);
+		b = block_get(dev_handle, rscnt + fsec, BLOCK_FLAGS_NONE);
 		clst = uint16_t_le2host(((fat_cluster_t *)b->data)[fidx]);
 		assert(clst != FAT_CLST_BAD);
@@ -115,4 +115,5 @@
  *			is empty.
  * @param bn		Block number.
+ * @param flags		Flags passed to libblock.
  *
  * @return		Block structure holding the requested block.
@@ -120,5 +121,5 @@
 block_t *
 _fat_block_get(fat_bs_t *bs, dev_handle_t dev_handle, fat_cluster_t firstc,
-    bn_t bn)
+    bn_t bn, int flags)
 {
 	block_t *b;
@@ -144,5 +145,5 @@
 		/* root directory special case */
 		assert(bn < rds);
-		b = block_get(dev_handle, rscnt + bs->fatcnt * sf + bn);
+		b = block_get(dev_handle, rscnt + bs->fatcnt * sf + bn, flags);
 		return b;
 	}
@@ -154,5 +155,5 @@
 
 	b = block_get(dev_handle, ssa + (lastc - FAT_CLST_FIRST) * bs->spc +
-	    bn % bs->spc);
+	    bn % bs->spc, flags);
 
 	return b;
@@ -184,5 +185,7 @@
 	for (o = nodep->size - 1; o < pos && o < boundary;
 	    o = ALIGN_DOWN(o + bps, bps)) {
-		b = fat_block_get(bs, nodep, o / bps);
+	    	int flags = (o % bps == 0) ?
+		    BLOCK_FLAGS_NOREAD : BLOCK_FLAGS_NONE;
+		b = fat_block_get(bs, nodep, o / bps, flags);
 		memset(b->data + o % bps, 0, bps - o % bps);
 		b->dirty = true;		/* need to sync node */
@@ -196,5 +199,5 @@
 	for (o = boundary; o < pos; o += bps) {
 		b = _fat_block_get(bs, nodep->idx->dev_handle, mcl,
-		    (o - boundary) / bps);
+		    (o - boundary) / bps, BLOCK_FLAGS_NOREAD);
 		memset(b->data, 0, min(bps, pos - o));
 		b->dirty = true;		/* need to sync node */
@@ -222,5 +225,6 @@
 	rscnt = uint16_t_le2host(bs->rscnt);
 
-	b = block_get(dev_handle, rscnt + (clst * sizeof(fat_cluster_t)) / bps);
+	b = block_get(dev_handle, rscnt + (clst * sizeof(fat_cluster_t)) / bps,
+	    BLOCK_FLAGS_NONE);
 	cp = (fat_cluster_t *)b->data + clst % (bps / sizeof(fat_cluster_t));
 	value = uint16_t_le2host(*cp);
@@ -254,5 +258,5 @@
 	assert(fatno < bs->fatcnt);
 	b = block_get(dev_handle, rscnt + sf * fatno +
-	    (clst * sizeof(fat_cluster_t)) / bps);
+	    (clst * sizeof(fat_cluster_t)) / bps, BLOCK_FLAGS_NONE);
 	cp = (fat_cluster_t *)b->data + clst % (bps / sizeof(fat_cluster_t));
 	*cp = host2uint16_t_le(value);
@@ -324,5 +328,5 @@
 	futex_down(&fat_alloc_lock);
 	for (b = 0, cl = 0; b < sf; blk++) {
-		blk = block_get(dev_handle, rscnt + b);
+		blk = block_get(dev_handle, rscnt + b, BLOCK_FLAGS_NOREAD);
 		for (c = 0; c < bps / sizeof(fat_cluster_t); c++, cl++) {
 			fat_cluster_t *clst = (fat_cluster_t *)blk->data + c;
Index: uspace/srv/fs/fat/fat_fat.h
===================================================================
--- uspace/srv/fs/fat/fat_fat.h	(revision c1b455ef81f0a7d909a50b79a5328d46c6140609)
+++ uspace/srv/fs/fat/fat_fat.h	(revision 1d8cdb185ad73e3854920a8c26df884d780b3315)
@@ -64,9 +64,9 @@
     fat_cluster_t *, uint16_t);
 
-#define fat_block_get(bs, np, bn) \
-    _fat_block_get((bs), (np)->idx->dev_handle, (np)->firstc, (bn))
+#define fat_block_get(bs, np, bn, flags) \
+    _fat_block_get((bs), (np)->idx->dev_handle, (np)->firstc, (bn), (flags))
 
 extern struct block *_fat_block_get(struct fat_bs *, dev_handle_t,
-    fat_cluster_t, bn_t);
+    fat_cluster_t, bn_t, int);
   
 extern void fat_append_clusters(struct fat_bs *, struct fat_node *,
Index: uspace/srv/fs/fat/fat_ops.c
===================================================================
--- uspace/srv/fs/fat/fat_ops.c	(revision c1b455ef81f0a7d909a50b79a5328d46c6140609)
+++ uspace/srv/fs/fat/fat_ops.c	(revision 1d8cdb185ad73e3854920a8c26df884d780b3315)
@@ -90,5 +90,5 @@
 	/* Read the block that contains the dentry of interest. */
 	b = _fat_block_get(bs, node->idx->dev_handle, node->idx->pfc,
-	    (node->idx->pdi * sizeof(fat_dentry_t)) / bps);
+	    (node->idx->pdi * sizeof(fat_dentry_t)) / bps, BLOCK_FLAGS_NONE);
 
 	d = ((fat_dentry_t *)b->data) + (node->idx->pdi % dps);
@@ -182,5 +182,5 @@
 	/* Read the block that contains the dentry of interest. */
 	b = _fat_block_get(bs, idxp->dev_handle, idxp->pfc,
-	    (idxp->pdi * sizeof(fat_dentry_t)) / bps);
+	    (idxp->pdi * sizeof(fat_dentry_t)) / bps, BLOCK_FLAGS_NONE);
 	assert(b);
 
@@ -283,5 +283,5 @@
 	blocks = parentp->size / bps;
 	for (i = 0; i < blocks; i++) {
-		b = fat_block_get(bs, parentp, i);
+		b = fat_block_get(bs, parentp, i, BLOCK_FLAGS_NONE);
 		for (j = 0; j < dps; j++) { 
 			d = ((fat_dentry_t *)b->data) + j;
@@ -373,5 +373,5 @@
 		fat_dentry_t *d;
 	
-		b = fat_block_get(bs, nodep, i);
+		b = fat_block_get(bs, nodep, i, BLOCK_FLAGS_NONE);
 		for (j = 0; j < dps; j++) {
 			d = ((fat_dentry_t *)b->data) + j;
@@ -575,5 +575,6 @@
 			bytes = min(len, bps - pos % bps);
 			bytes = min(bytes, nodep->size - pos);
-			b = fat_block_get(bs, nodep, pos / bps);
+			b = fat_block_get(bs, nodep, pos / bps,
+			    BLOCK_FLAGS_NONE);
 			(void) ipc_data_read_finalize(callid, b->data + pos % bps,
 			    bytes);
@@ -600,5 +601,5 @@
 			off_t o;
 
-			b = fat_block_get(bs, nodep, bnum);
+			b = fat_block_get(bs, nodep, bnum, BLOCK_FLAGS_NONE);
 			for (o = pos % (bps / sizeof(fat_dentry_t));
 			    o < bps / sizeof(fat_dentry_t);
@@ -648,4 +649,5 @@
 	unsigned bpc;		/* bytes per cluster */
 	off_t boundary;
+	int flags = BLOCK_FLAGS_NONE;
 	
 	if (!nodep) {
@@ -676,4 +678,6 @@
 	 */ 
 	bytes = min(len, bps - pos % bps);
+	if (bytes == bps)
+		flags |= BLOCK_FLAGS_NOREAD;
 	
 	boundary = ROUND_UP(nodep->size, bpc);
@@ -686,5 +690,5 @@
 		 */
 		fat_fill_gap(bs, nodep, FAT_CLST_RES0, pos);
-		b = fat_block_get(bs, nodep, pos / bps);
+		b = fat_block_get(bs, nodep, pos / bps, flags);
 		(void) ipc_data_write_finalize(callid, b->data + pos % bps,
 		    bytes);
@@ -719,5 +723,6 @@
 		/* zero fill any gaps */
 		fat_fill_gap(bs, nodep, mcl, pos);
-		b = _fat_block_get(bs, dev_handle, lcl, (pos / bps) % spc);
+		b = _fat_block_get(bs, dev_handle, lcl, (pos / bps) % spc,
+		    flags);
 		(void) ipc_data_write_finalize(callid, b->data + pos % bps,
 		    bytes);
