Index: uspace/srv/vfs/vfs_ops.c
===================================================================
--- uspace/srv/vfs/vfs_ops.c	(revision 1dff985eeea7ec928487e2814a82eb105072a35a)
+++ uspace/srv/vfs/vfs_ops.c	(revision c577a9a0f9567ece9535f388111534237421f139)
@@ -500,5 +500,6 @@
 	vfs_node_t *node = vfs_node_get(&lr);
 	
-	int fd = vfs_fd_alloc(false);
+	vfs_file_t *file;
+	int fd = vfs_fd_alloc(&file, false);
 	if (fd < 0) {
 		vfs_node_put(node);
@@ -509,6 +510,4 @@
 		return;
 	}
-	
-	vfs_file_t *file = vfs_file_get(fd);
 	assert(file != NULL);
 	
@@ -598,5 +597,4 @@
 	 * the same open file at a time.
 	 */
-	fibril_mutex_lock(&file->lock);
 	async_exch_t *fs_exch = vfs_exchange_grab(file->node->fs_handle);
 	
@@ -612,6 +610,4 @@
 	sysarg_t rc;
 	async_wait_for(msg, &rc);
-	
-	fibril_mutex_unlock(&file->lock);
 	
 	vfs_file_put(file);
@@ -702,12 +698,6 @@
 		return ENOENT;
 	
-	/*
-	 * Lock the open file structure so that no other thread can manipulate
-	 * the same open file at a time.
-	 */
-	fibril_mutex_lock(&file->lock);
-	
 	if ((read && !file->open_read) || (!read && !file->open_write)) {
-		fibril_mutex_unlock(&file->lock);
+		vfs_file_put(file);
 		return EINVAL;
 	}
@@ -770,5 +760,4 @@
 	if (rc == EOK)
 		file->pos += bytes;
-	fibril_mutex_unlock(&file->lock);
 	vfs_file_put(file);	
 
@@ -812,6 +801,4 @@
 		return;
 	}
-	
-	fibril_mutex_lock(&file->lock);
 	
 	off64_t newoff;
@@ -820,5 +807,4 @@
 		if (off >= 0) {
 			file->pos = (aoff64_t) off;
-			fibril_mutex_unlock(&file->lock);
 			vfs_file_put(file);
 			async_answer_1(rid, EOK, off);
@@ -828,5 +814,4 @@
 	case SEEK_CUR:
 		if ((off >= 0) && (file->pos + off < file->pos)) {
-			fibril_mutex_unlock(&file->lock);
 			vfs_file_put(file);
 			async_answer_0(rid, EOVERFLOW);
@@ -835,5 +820,4 @@
 		
 		if ((off < 0) && (file->pos < (aoff64_t) -off)) {
-			fibril_mutex_unlock(&file->lock);
 			vfs_file_put(file);
 			async_answer_0(rid, EOVERFLOW);
@@ -844,5 +828,4 @@
 		newoff = (file->pos > OFF64_MAX) ? OFF64_MAX : file->pos;
 		
-		fibril_mutex_unlock(&file->lock);
 		vfs_file_put(file);
 		async_answer_2(rid, EOK, LOWER32(newoff),
@@ -855,5 +838,4 @@
 		if ((off >= 0) && (size + off < size)) {
 			fibril_rwlock_read_unlock(&file->node->contents_rwlock);
-			fibril_mutex_unlock(&file->lock);
 			vfs_file_put(file);
 			async_answer_0(rid, EOVERFLOW);
@@ -863,5 +845,4 @@
 		if ((off < 0) && (size < (aoff64_t) -off)) {
 			fibril_rwlock_read_unlock(&file->node->contents_rwlock);
-			fibril_mutex_unlock(&file->lock);
 			vfs_file_put(file);
 			async_answer_0(rid, EOVERFLOW);
@@ -873,5 +854,4 @@
 		
 		fibril_rwlock_read_unlock(&file->node->contents_rwlock);
-		fibril_mutex_unlock(&file->lock);
 		vfs_file_put(file);
 		async_answer_2(rid, EOK, LOWER32(newoff), UPPER32(newoff));
@@ -879,5 +859,4 @@
 	}
 	
-	fibril_mutex_unlock(&file->lock);
 	vfs_file_put(file);
 	async_answer_0(rid, EINVAL);
@@ -908,5 +887,4 @@
 		return;
 	}
-	fibril_mutex_lock(&file->lock);
 
 	fibril_rwlock_write_lock(&file->node->contents_rwlock);
@@ -917,5 +895,4 @@
 	fibril_rwlock_write_unlock(&file->node->contents_rwlock);
 
-	fibril_mutex_unlock(&file->lock);
 	vfs_file_put(file);
 	async_answer_0(rid, (sysarg_t)rc);
@@ -932,4 +909,5 @@
 		return;
 	}
+	assert(file->node);
 
 	ipc_callid_t callid;
@@ -941,11 +919,11 @@
 	}
 
-	fibril_mutex_lock(&file->lock);
-
 	async_exch_t *exch = vfs_exchange_grab(file->node->fs_handle);
+	assert(exch);
 	
 	aid_t msg;
 	msg = async_send_3(exch, VFS_OUT_STAT, file->node->service_id,
 	    file->node->index, true, NULL);
+	assert(msg);
 	async_forward_fast(callid, exch, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
 	
@@ -954,5 +932,4 @@
 	async_wait_for(msg, &rc);
 	
-	fibril_mutex_unlock(&file->lock);
 	vfs_file_put(file);
 	async_answer_0(rid, rc);
@@ -989,5 +966,6 @@
 	int lflag = (wflag&WALK_DIRECTORY) ? L_DIRECTORY: 0;
 
-	if (parentfd >= 0) {
+	/* Files are retrieved in order of file descriptors, to prevent deadlock. */
+	if (parentfd >= 0 && parentfd < expectfd) {
 		parent = vfs_file_get(parentfd);
 		if (!parent) {
@@ -995,5 +973,4 @@
 			goto exit;
 		}
-		parent_node = parent->node;
 	}
 	
@@ -1004,5 +981,19 @@
 			goto exit;
 		}
-		
+	}
+	
+	if (parentfd >= 0 && parentfd >= expectfd) {
+		parent = vfs_file_get(parentfd);
+		if (!parent) {
+			rc = ENOENT;
+			goto exit;
+		}
+	}
+	
+	if (parent) {
+		parent_node = parent->node;
+	}
+	
+	if (expectfd >= 0) {
 		vfs_lookup_res_t lr;
 		rc = vfs_lookup_internal(parent_node, path, lflag, &lr);
@@ -1228,10 +1219,4 @@
 	}
 	
-	/*
-	 * Lock the open file structure so that no other thread can manipulate
-	 * the same open file at a time.
-	 */
-	fibril_mutex_lock(&oldfile->lock);
-	
 	/* Make sure newfd is closed. */
 	(void) vfs_fd_free(newfd);
@@ -1239,5 +1224,4 @@
 	/* Assign the old file to newfd. */
 	int ret = vfs_fd_assign(oldfile, newfd);
-	fibril_mutex_unlock(&oldfile->lock);
 	vfs_file_put(oldfile);
 	
