Index: uspace/srv/fs/fat/fat.c
===================================================================
--- uspace/srv/fs/fat/fat.c	(revision b5553a2369389ebef7f28ae29434069aa9df0fcc)
+++ uspace/srv/fs/fat/fat.c	(revision f17667abd385620bb289c9d45277c69868aa2113)
@@ -52,14 +52,7 @@
 	.ops = {
 		[IPC_METHOD_TO_VFS_OP(VFS_LOOKUP)] = VFS_OP_DEFINED,
-		[IPC_METHOD_TO_VFS_OP(VFS_OPEN)] = VFS_OP_DEFINED,
-		[IPC_METHOD_TO_VFS_OP(VFS_CLOSE)] = VFS_OP_DEFINED,
 		[IPC_METHOD_TO_VFS_OP(VFS_READ)] = VFS_OP_DEFINED,
 		[IPC_METHOD_TO_VFS_OP(VFS_WRITE)] = VFS_OP_NULL,
 		[IPC_METHOD_TO_VFS_OP(VFS_TRUNCATE)] = VFS_OP_NULL,
-		[IPC_METHOD_TO_VFS_OP(VFS_RENAME)] = VFS_OP_NULL,
-		[IPC_METHOD_TO_VFS_OP(VFS_OPENDIR)] = VFS_OP_NULL,
-		[IPC_METHOD_TO_VFS_OP(VFS_READDIR)] = VFS_OP_NULL,
-		[IPC_METHOD_TO_VFS_OP(VFS_CLOSEDIR)] = VFS_OP_NULL,
-		[IPC_METHOD_TO_VFS_OP(VFS_UNLINK)] = VFS_OP_NULL,
 		[IPC_METHOD_TO_VFS_OP(VFS_MOUNT)] = VFS_OP_NULL,
 		[IPC_METHOD_TO_VFS_OP(VFS_UNMOUNT)] = VFS_OP_NULL,
Index: uspace/srv/fs/tmpfs/tmpfs.c
===================================================================
--- uspace/srv/fs/tmpfs/tmpfs.c	(revision b5553a2369389ebef7f28ae29434069aa9df0fcc)
+++ uspace/srv/fs/tmpfs/tmpfs.c	(revision f17667abd385620bb289c9d45277c69868aa2113)
@@ -56,16 +56,10 @@
 	.ops = {
 		[IPC_METHOD_TO_VFS_OP(VFS_LOOKUP)] = VFS_OP_DEFINED,
-		[IPC_METHOD_TO_VFS_OP(VFS_OPEN)] = VFS_OP_DEFINED,
-		[IPC_METHOD_TO_VFS_OP(VFS_CLOSE)] = VFS_OP_DEFINED,
 		[IPC_METHOD_TO_VFS_OP(VFS_READ)] = VFS_OP_DEFINED,
 		[IPC_METHOD_TO_VFS_OP(VFS_WRITE)] = VFS_OP_DEFINED,
-		[IPC_METHOD_TO_VFS_OP(VFS_TRUNCATE)] = VFS_OP_NULL,
-		[IPC_METHOD_TO_VFS_OP(VFS_RENAME)] = VFS_OP_NULL,
-		[IPC_METHOD_TO_VFS_OP(VFS_OPENDIR)] = VFS_OP_NULL,
-		[IPC_METHOD_TO_VFS_OP(VFS_READDIR)] = VFS_OP_NULL,
-		[IPC_METHOD_TO_VFS_OP(VFS_CLOSEDIR)] = VFS_OP_NULL,
-		[IPC_METHOD_TO_VFS_OP(VFS_UNLINK)] = VFS_OP_NULL,
+		[IPC_METHOD_TO_VFS_OP(VFS_TRUNCATE)] = VFS_OP_DEFINED,
 		[IPC_METHOD_TO_VFS_OP(VFS_MOUNT)] = VFS_OP_NULL,
 		[IPC_METHOD_TO_VFS_OP(VFS_UNMOUNT)] = VFS_OP_NULL,
+		[IPC_METHOD_TO_VFS_OP(VFS_FREE)] = VFS_OP_DEFINED,
 	}
 };
@@ -119,4 +113,10 @@
 			tmpfs_write(callid, &call);
 			break;
+		case VFS_TRUNCATE:
+			tmpfs_truncate(callid, &call);
+			break;
+		case VFS_FREE:
+			tmpfs_free(callid, &call);
+			break;
 		default:
 			ipc_answer_0(callid, ENOTSUP);
Index: uspace/srv/fs/tmpfs/tmpfs.h
===================================================================
--- uspace/srv/fs/tmpfs/tmpfs.h	(revision b5553a2369389ebef7f28ae29434069aa9df0fcc)
+++ uspace/srv/fs/tmpfs/tmpfs.h	(revision f17667abd385620bb289c9d45277c69868aa2113)
@@ -65,4 +65,5 @@
 extern void tmpfs_write(ipc_callid_t, ipc_call_t *);
 extern void tmpfs_truncate(ipc_callid_t, ipc_call_t *);
+extern void tmpfs_free(ipc_callid_t, ipc_call_t *);
 
 #endif
Index: uspace/srv/fs/tmpfs/tmpfs_ops.c
===================================================================
--- uspace/srv/fs/tmpfs/tmpfs_ops.c	(revision b5553a2369389ebef7f28ae29434069aa9df0fcc)
+++ uspace/srv/fs/tmpfs/tmpfs_ops.c	(revision f17667abd385620bb289c9d45277c69868aa2113)
@@ -497,4 +497,30 @@
 }
 
+void tmpfs_free(ipc_callid_t rid, ipc_call_t *request)
+{
+	int dev_handle = IPC_GET_ARG1(*request);
+	unsigned long index = IPC_GET_ARG2(*request);
+
+	link_t *hlp;
+	hlp = hash_table_find(&dentries, &index);
+	if (!hlp) {
+		ipc_answer_0(rid, ENOENT);
+		return;
+	}
+	tmpfs_dentry_t *dentry = hash_table_get_instance(hlp, tmpfs_dentry_t,
+	    dh_link);
+	
+	assert(!dentry->parent);
+	assert(!dentry->child);
+	assert(!dentry->sibling);
+
+	if (dentry->type == TMPFS_FILE)
+		free(dentry->data);
+	free(dentry->name);
+	free(dentry);
+
+	ipc_answer_0(rid, EOK);
+}
+
 /**
  * @}
Index: uspace/srv/vfs/vfs.h
===================================================================
--- uspace/srv/vfs/vfs.h	(revision b5553a2369389ebef7f28ae29434069aa9df0fcc)
+++ uspace/srv/vfs/vfs.h	(revision f17667abd385620bb289c9d45277c69868aa2113)
@@ -48,15 +48,7 @@
 
 typedef enum {
-	VFS_OPEN = VFS_FIRST,
-	VFS_CLOSE,
-	VFS_READ,
+	VFS_READ = VFS_FIRST,
 	VFS_WRITE,
 	VFS_TRUNCATE,
-	VFS_RENAME,
-	VFS_OPENDIR,
-	VFS_READDIR,
-	VFS_CLOSEDIR,
-	VFS_MKDIR,
-	VFS_UNLINK,
 	VFS_MOUNT,
 	VFS_UNMOUNT,
@@ -66,4 +58,5 @@
 typedef enum {
 	VFS_LOOKUP = VFS_LAST_CMN,
+	VFS_FREE,
 	VFS_LAST_CLNT,	/* keep this the last member of this enum */
 } vfs_request_clnt_t;
@@ -71,5 +64,10 @@
 typedef enum {
 	VFS_REGISTER = VFS_LAST_CMN,
+	VFS_OPEN,
+	VFS_CLOSE,
 	VFS_SEEK,
+	VFS_MKDIR,
+	VFS_UNLINK,
+	VFS_RENAME,
 	VFS_LAST_SRV,	/* keep this the last member of this enum */
 } vfs_request_srv_t;
Index: uspace/srv/vfs/vfs_file.c
===================================================================
--- uspace/srv/vfs/vfs_file.c	(revision b5553a2369389ebef7f28ae29434069aa9df0fcc)
+++ uspace/srv/vfs/vfs_file.c	(revision f17667abd385620bb289c9d45277c69868aa2113)
@@ -131,5 +131,5 @@
 	if (file->refcnt-- == 1) {
 		/*
-		 * Lost last reference to a file, need to drop our reference
+		 * Lost the last reference to a file, need to drop our reference
 		 * to the underlying VFS node.
 		 */
Index: uspace/srv/vfs/vfs_node.c
===================================================================
--- uspace/srv/vfs/vfs_node.c	(revision b5553a2369389ebef7f28ae29434069aa9df0fcc)
+++ uspace/srv/vfs/vfs_node.c	(revision f17667abd385620bb289c9d45277c69868aa2113)
@@ -44,4 +44,6 @@
 #include <libadt/hash_table.h>
 #include <assert.h>
+#include <async.h>
+#include <errno.h>
 
 /** Futex protecting the VFS node hash table. */
@@ -102,6 +104,13 @@
 void vfs_node_delref(vfs_node_t *node)
 {
+	bool free_vfs_node = false;
+	bool free_fs_node = false;
+
 	futex_down(&nodes_futex);
 	if (node->refcnt-- == 1) {
+		/*
+		 * We are dropping the last reference to this node.
+		 * Remove it from the VFS node hash table.
+		 */
 		unsigned long key[] = {
 			[KEY_FS_HANDLE] = node->fs_handle,
@@ -110,6 +119,24 @@
 		};
 		hash_table_remove(&nodes, key, 3);
+		free_vfs_node = true;
+		if (!node->lnkcnt)
+			free_fs_node = true;
 	}
 	futex_up(&nodes_futex);
+
+	if (free_fs_node) {
+		/* 
+		 * The node is not visible in the file system namespace.
+		 * Free up its resources.
+		 */
+		int phone = vfs_grab_phone(node->fs_handle);
+		ipcarg_t rc;
+		rc = async_req_2_0(phone, VFS_FREE, (ipcarg_t)node->dev_handle,
+		    (ipcarg_t)node->index);
+		assert(rc == EOK);
+		vfs_release_phone(phone);
+	}
+	if (free_vfs_node)
+		free(node);
 }
 
@@ -197,6 +224,4 @@
 void nodes_remove_callback(link_t *item)
 {
-	vfs_node_t *node = hash_table_get_instance(item, vfs_node_t, nh_link);
-	free(node);
 }
 
Index: uspace/srv/vfs/vfs_register.c
===================================================================
--- uspace/srv/vfs/vfs_register.c	(revision b5553a2369389ebef7f28ae29434069aa9df0fcc)
+++ uspace/srv/vfs/vfs_register.c	(revision f17667abd385620bb289c9d45277c69868aa2113)
@@ -105,12 +105,4 @@
 	if (info->ops[IPC_METHOD_TO_VFS_OP(VFS_LOOKUP)] != VFS_OP_DEFINED) {
 		dprintf("Operation VFS_LOOKUP not defined by the client.\n");
-		return false;
-	}
-	if (info->ops[IPC_METHOD_TO_VFS_OP(VFS_OPEN)] != VFS_OP_DEFINED) {
-		dprintf("Operation VFS_OPEN not defined by the client.\n");
-		return false;
-	}
-	if (info->ops[IPC_METHOD_TO_VFS_OP(VFS_CLOSE)] != VFS_OP_DEFINED) {
-		dprintf("Operation VFS_CLOSE not defined by the client.\n");
 		return false;
 	}
