Index: uspace/srv/vfs/vfs.h
===================================================================
--- uspace/srv/vfs/vfs.h	(revision df3c6f025cfa7241c63072736ea365c3118485f9)
+++ uspace/srv/vfs/vfs.h	(revision 25bef0fffb8b3af53596c5e316bdff004cb3f31a)
@@ -176,5 +176,4 @@
     vfs_pair_t *, ...);
 extern int vfs_open_node_internal(vfs_lookup_res_t *);
-extern int vfs_close_internal(vfs_file_t *);
 
 extern bool vfs_nodes_init(void);
Index: uspace/srv/vfs/vfs_file.c
===================================================================
--- uspace/srv/vfs/vfs_file.c	(revision df3c6f025cfa7241c63072736ea365c3118485f9)
+++ uspace/srv/vfs/vfs_file.c	(revision 25bef0fffb8b3af53596c5e316bdff004cb3f31a)
@@ -79,5 +79,4 @@
 	for (i = 0; i < MAX_OPEN_FILES; i++) {
 		if (FILES[i]) {
-			(void) vfs_close_internal(FILES[i]);
 			(void) vfs_fd_free(i);
 		}
@@ -108,4 +107,24 @@
 }
 
+/** Close the file in the endpoint FS server. */
+static int vfs_file_close_remote(vfs_file_t *file)
+{
+	ipc_call_t answer;
+	aid_t msg;
+	sysarg_t rc;
+	int phone;
+
+	assert(!file->refcnt);
+
+	phone = vfs_grab_phone(file->node->fs_handle);
+	msg = async_send_2(phone, VFS_OUT_CLOSE, file->node->devmap_handle,
+	    file->node->index, &answer);
+	async_wait_for(msg, &rc);
+	vfs_release_phone(file->node->fs_handle, phone);
+
+	return IPC_GET_ARG1(answer);
+}
+
+
 /** Increment reference count of VFS file structure.
  *
@@ -125,16 +144,21 @@
  *			decremented.
  */
-static void vfs_file_delref(vfs_file_t *file)
-{
+static int vfs_file_delref(vfs_file_t *file)
+{
+	int rc = EOK;
+
 	assert(fibril_mutex_is_locked(&VFS_DATA->lock));
 
 	if (file->refcnt-- == 1) {
 		/*
-		 * Lost the last reference to a file, need to drop our reference
-		 * to the underlying VFS node.
+		 * Lost the last reference to a file, need to close it in the
+		 * endpoint FS and drop our reference to the underlying VFS node.
 		 */
+		rc = vfs_file_close_remote(file);
 		vfs_node_delref(file->node);
 		free(file);
 	}
+
+	return rc;
 }
 
@@ -201,4 +225,6 @@
 int vfs_fd_free(int fd)
 {
+	int rc;
+
 	if (!vfs_files_init())
 		return ENOMEM;
@@ -210,9 +236,9 @@
 	}
 	
-	vfs_file_delref(FILES[fd]);
+	rc = vfs_file_delref(FILES[fd]);
 	FILES[fd] = NULL;
 	fibril_mutex_unlock(&VFS_DATA->lock);
 	
-	return EOK;
+	return rc;
 }
 
Index: uspace/srv/vfs/vfs_ops.c
===================================================================
--- uspace/srv/vfs/vfs_ops.c	(revision df3c6f025cfa7241c63072736ea365c3118485f9)
+++ uspace/srv/vfs/vfs_ops.c	(revision 25bef0fffb8b3af53596c5e316bdff004cb3f31a)
@@ -717,55 +717,9 @@
 }
 
-int vfs_close_internal(vfs_file_t *file)
-{
-	/*
-	 * 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 (file->refcnt <= 1) {
-		/* Only close the file on the destination FS server
-		   if there are no more file descriptors (except the
-		   present one) pointing to this file. */
-		
-		int fs_phone = vfs_grab_phone(file->node->fs_handle);
-		
-		/* Make a VFS_OUT_CLOSE request at the destination FS server. */
-		aid_t msg;
-		ipc_call_t answer;
-		msg = async_send_2(fs_phone, VFS_OUT_CLOSE,
-		    file->node->devmap_handle, file->node->index, &answer);
-		
-		/* Wait for reply from the FS server. */
-		sysarg_t rc;
-		async_wait_for(msg, &rc);
-		
-		vfs_release_phone(file->node->fs_handle, fs_phone);
-		fibril_mutex_unlock(&file->lock);
-		
-		return IPC_GET_ARG1(answer);
-	}
-	
-	fibril_mutex_unlock(&file->lock);
-	return EOK;
-}
-
 void vfs_close(ipc_callid_t rid, ipc_call_t *request)
 {
 	int fd = IPC_GET_ARG1(*request);
-	
-	/* Lookup the file structure corresponding to the file descriptor. */
-	vfs_file_t *file = vfs_file_get(fd);
-	if (!file) {
-		async_answer_0(rid, ENOENT);
-		return;
-	}
-	
-	int ret = vfs_close_internal(file);
-	if (ret != EOK)
-		async_answer_0(rid, ret);
-	
-	vfs_file_put(file);
+	int ret;
+	
 	ret = vfs_fd_free(fd);
 	async_answer_0(rid, ret);
@@ -1369,27 +1323,6 @@
 	fibril_mutex_lock(&oldfile->lock);
 	
-	/* Lookup an open file structure possibly corresponding to newfd. */
-	vfs_file_t *newfile = vfs_file_get(newfd);
-	if (newfile) {
-		/* Close the originally opened file. */
-		int ret = vfs_close_internal(newfile);
-		if (ret != EOK) {
-			fibril_mutex_unlock(&oldfile->lock);
-			vfs_file_put(oldfile);
-			vfs_file_put(newfile);
-			async_answer_0(rid, ret);
-			return;
-		}
-		
-		ret = vfs_fd_free(newfd);
-		if (ret != EOK) {
-			fibril_mutex_unlock(&oldfile->lock);
-			vfs_file_put(oldfile);
-			vfs_file_put(newfile);
-			async_answer_0(rid, ret);
-			return;
-		}
-		vfs_file_put(newfile);
-	}
+	/* Make sure newfd is closed. */
+	(void) vfs_fd_free(newfd);
 	
 	/* Assign the old file to newfd. */
