Index: uspace/lib/libfs/libfs.c
===================================================================
--- uspace/lib/libfs/libfs.c	(revision 3c11713f9fe58a2b3a19f2e9e4bfc0f709a63c2e)
+++ uspace/lib/libfs/libfs.c	(revision 231438126d2f4a823b7106c694ea8eecf2d00e54)
@@ -228,5 +228,45 @@
 void libfs_unmount(libfs_ops_t *ops, ipc_callid_t rid, ipc_call_t *request)
 {
-	ipc_answer_0(rid, ENOTSUP);
+	dev_handle_t mp_dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
+	fs_index_t mp_fs_index = (fs_index_t) IPC_GET_ARG2(*request);
+	fs_node_t *fn;
+	int res;
+
+	res = ops->node_get(&fn, mp_dev_handle, mp_fs_index);
+	if ((res != EOK) || (!fn)) {
+		ipc_answer_0(rid, combine_rc(res, ENOENT));
+		return;
+	}
+
+	/*
+	 * We are clearly expecting to find the mount point active.
+	 */
+	if (!fn->mp_data.mp_active) {
+		(void) ops->node_put(fn);
+		ipc_answer_0(rid, EINVAL);
+		return;
+	}
+
+	/*
+	 * Tell the mounted file system to unmount.
+	 */
+	res = async_req_1_0(fn->mp_data.phone, VFS_OUT_UNMOUNTED,
+	    fn->mp_data.dev_handle);
+
+	/*
+	 * If everything went well, perform the clean-up on our side.
+	 */
+	if (res == EOK) {
+		ipc_hangup(fn->mp_data.phone);
+		fn->mp_data.mp_active = false;
+		fn->mp_data.fs_handle = 0;
+		fn->mp_data.dev_handle = 0;
+		fn->mp_data.phone = 0;
+		/* Drop the reference created in libfs_mount(). */
+		(void) ops->node_put(fn);
+	}
+
+	(void) ops->node_put(fn);
+	ipc_answer_0(rid, res);
 }
 
