Index: uspace/lib/c/include/ipc/vfs.h
===================================================================
--- uspace/lib/c/include/ipc/vfs.h	(revision bea023b9b8202ba19f790a340e59e36be213fadf)
+++ uspace/lib/c/include/ipc/vfs.h	(revision b38dfd8028d6cec3849c0eccfe3dff997f218265)
@@ -36,6 +36,7 @@
 #define LIBC_IPC_VFS_H_
 
+#include <ipc/ipc.h>
 #include <sys/types.h>
-#include <ipc/ipc.h>
+#include <bool.h>
 
 #define FS_NAME_MAXLEN  20
@@ -55,4 +56,6 @@
 	/** Unique identifier of the fs. */
 	char name[FS_NAME_MAXLEN + 1];
+	bool concurrent_read_write;
+	bool write_retains_size;
 } vfs_info_t;
 
Index: uspace/srv/fs/devfs/devfs.c
===================================================================
--- uspace/srv/fs/devfs/devfs.c	(revision bea023b9b8202ba19f790a340e59e36be213fadf)
+++ uspace/srv/fs/devfs/devfs.c	(revision b38dfd8028d6cec3849c0eccfe3dff997f218265)
@@ -53,4 +53,6 @@
 static vfs_info_t devfs_vfs_info = {
 	.name = NAME,
+	.concurrent_read_write = false,
+	.write_retains_size = false,
 };
 
Index: uspace/srv/fs/fat/fat.c
===================================================================
--- uspace/srv/fs/fat/fat.c	(revision bea023b9b8202ba19f790a340e59e36be213fadf)
+++ uspace/srv/fs/fat/fat.c	(revision b38dfd8028d6cec3849c0eccfe3dff997f218265)
@@ -52,4 +52,6 @@
 vfs_info_t fat_vfs_info = {
 	.name = NAME,
+	.concurrent_read_write = false,
+	.write_retains_size = false,	
 };
 
Index: uspace/srv/fs/tmpfs/tmpfs.c
===================================================================
--- uspace/srv/fs/tmpfs/tmpfs.c	(revision bea023b9b8202ba19f790a340e59e36be213fadf)
+++ uspace/srv/fs/tmpfs/tmpfs.c	(revision b38dfd8028d6cec3849c0eccfe3dff997f218265)
@@ -57,4 +57,6 @@
 vfs_info_t tmpfs_vfs_info = {
 	.name = NAME,
+	.concurrent_read_write = false,
+	.write_retains_size = false,
 };
 
Index: uspace/srv/vfs/vfs.h
===================================================================
--- uspace/srv/vfs/vfs.h	(revision bea023b9b8202ba19f790a340e59e36be213fadf)
+++ uspace/srv/vfs/vfs.h	(revision b38dfd8028d6cec3849c0eccfe3dff997f218265)
@@ -172,4 +172,5 @@
 
 extern fs_handle_t fs_name_to_handle(char *, bool);
+extern vfs_info_t *fs_handle_to_info(fs_handle_t);
 
 extern int vfs_lookup_internal(char *, int, vfs_lookup_res_t *,
Index: uspace/srv/vfs/vfs_ops.c
===================================================================
--- uspace/srv/vfs/vfs_ops.c	(revision bea023b9b8202ba19f790a340e59e36be213fadf)
+++ uspace/srv/vfs/vfs_ops.c	(revision b38dfd8028d6cec3849c0eccfe3dff997f218265)
@@ -781,4 +781,5 @@
 static void vfs_rdwr(ipc_callid_t rid, ipc_call_t *request, bool read)
 {
+	vfs_info_t *vi;
 
 	/*
@@ -807,9 +808,13 @@
 	fibril_mutex_lock(&file->lock);
 
+	vi = fs_handle_to_info(file->node->fs_handle);
+	assert(vi);
+
 	/*
 	 * Lock the file's node so that no other client can read/write to it at
-	 * the same time.
-	 */
-	if (read)
+	 * the same time unless the FS supports concurrent reads/writes and its
+	 * write implementation does not modify the file size.
+	 */
+	if (read || (vi->concurrent_read_write && vi->write_retains_size))
 		fibril_rwlock_read_lock(&file->node->contents_rwlock);
 	else
@@ -857,5 +862,5 @@
 	
 	/* Unlock the VFS node. */
-	if (read)
+	if (read || (vi->concurrent_read_write && vi->write_retains_size))
 		fibril_rwlock_read_unlock(&file->node->contents_rwlock);
 	else {
Index: uspace/srv/vfs/vfs_register.c
===================================================================
--- uspace/srv/vfs/vfs_register.c	(revision bea023b9b8202ba19f790a340e59e36be213fadf)
+++ uspace/srv/vfs/vfs_register.c	(revision b38dfd8028d6cec3849c0eccfe3dff997f218265)
@@ -333,4 +333,27 @@
 }
 
+/** Find the VFS info structure.
+ *
+ * @param handle	FS handle for which the VFS info structure is sought.
+ * @return		VFS info structure on success or NULL otherwise.
+ */
+vfs_info_t *fs_handle_to_info(fs_handle_t handle)
+{
+	vfs_info_t *info = NULL;
+	link_t *cur;
+
+	fibril_mutex_lock(&fs_head_lock);
+	for (cur = fs_head.next; cur != &fs_head; cur = cur->next) {
+		fs_info_t *fs = list_get_instance(cur, fs_info_t, fs_link);
+		if (fs->fs_handle == handle) { 
+			info = &fs->vfs_info;
+			break;
+		}
+	}
+	fibril_mutex_unlock(&fs_head_lock);
+
+	return info;
+}
+
 /**
  * @}
