Index: uspace/srv/vfs/vfs_register.c
===================================================================
--- uspace/srv/vfs/vfs_register.c	(revision ffa2c8ef45390c01f3f4be4827bcd41c32f7951c)
+++ uspace/srv/vfs/vfs_register.c	(revision b72efe87f3e33beaa3b0d0cf7c8b598a58f6a6de)
@@ -52,7 +52,7 @@
 #include "vfs.h"
 
-FIBRIL_CONDVAR_INITIALIZE(fs_head_cv);
-FIBRIL_MUTEX_INITIALIZE(fs_head_lock);
-LIST_INITIALIZE(fs_head);
+FIBRIL_CONDVAR_INITIALIZE(fs_list_cv);
+FIBRIL_MUTEX_INITIALIZE(fs_list_lock);
+LIST_INITIALIZE(fs_list);
 
 atomic_t fs_handle_next = {
@@ -62,12 +62,13 @@
 /** Verify the VFS info structure.
  *
- * @param info		Info structure to be verified.
- *
- * @return		Non-zero if the info structure is sane, zero otherwise.
+ * @param info Info structure to be verified.
+ *
+ * @return Non-zero if the info structure is sane, zero otherwise.
+ *
  */
 static bool vfs_info_sane(vfs_info_t *info)
 {
 	int i;
-
+	
 	/*
 	 * Check if the name is non-empty and is composed solely of ASCII
@@ -78,4 +79,5 @@
 		return false;
 	}
+	
 	for (i = 1; i < FS_NAME_MAXLEN; i++) {
 		if (!(islower(info->name[i]) || isdigit(info->name[i])) &&
@@ -90,4 +92,5 @@
 		}
 	}
+	
 	/*
 	 * This check is not redundant. It ensures that the name is
@@ -104,11 +107,10 @@
 /** VFS_REGISTER protocol function.
  *
- * @param rid		Hash of the call with the request.
- * @param request	Call structure with the request.
+ * @param rid     Hash of the call with the request.
+ * @param request Call structure with the request.
+ *
  */
 void vfs_register(ipc_callid_t rid, ipc_call_t *request)
 {
-	int phone;
-	
 	dprintf("Processing VFS_REGISTER request received from %p.\n",
 	    request->in_phone_hash);
@@ -147,5 +149,5 @@
 	}
 	
-	fibril_mutex_lock(&fs_head_lock);
+	fibril_mutex_lock(&fs_list_lock);
 	
 	/*
@@ -157,5 +159,5 @@
 		 */
 		dprintf("FS is already registered.\n");
-		fibril_mutex_unlock(&fs_head_lock);
+		fibril_mutex_unlock(&fs_list_lock);
 		free(fs_info);
 		async_answer_0(rid, EEXISTS);
@@ -167,5 +169,5 @@
 	 */
 	dprintf("Inserting FS into the list of registered file systems.\n");
-	list_append(&fs_info->fs_link, &fs_head);
+	list_append(&fs_info->fs_link, &fs_list);
 	
 	/*
@@ -174,20 +176,14 @@
 	 * which to forward VFS requests to it.
 	 */
-	ipc_call_t call;
-	ipc_callid_t callid = async_get_call(&call);
-	if (IPC_GET_IMETHOD(call) != IPC_M_CONNECT_TO_ME) {
-		dprintf("Unexpected call, method = %d\n", IPC_GET_IMETHOD(call));
+	fs_info->sess = async_callback_receive(EXCHANGE_PARALLEL);
+	if (!fs_info->sess) {
+		dprintf("Callback connection expected\n");
 		list_remove(&fs_info->fs_link);
-		fibril_mutex_unlock(&fs_head_lock);
-		free(fs_info);
-		async_answer_0(callid, EINVAL);
+		fibril_mutex_unlock(&fs_list_lock);
+		free(fs_info);
 		async_answer_0(rid, EINVAL);
 		return;
 	}
 	
-	phone = IPC_GET_ARG5(call);
-	async_session_create(&fs_info->session, phone, 0);
-	async_answer_0(callid, EOK);
-	
 	dprintf("Callback connection to FS created.\n");
 	
@@ -197,10 +193,10 @@
 	
 	size_t size;
+	ipc_callid_t callid;
 	if (!async_share_in_receive(&callid, &size)) {
 		dprintf("Unexpected call, method = %d\n", IPC_GET_IMETHOD(call));
 		list_remove(&fs_info->fs_link);
-		fibril_mutex_unlock(&fs_head_lock);
-		async_session_destroy(&fs_info->session);
-		async_hangup(phone);
+		fibril_mutex_unlock(&fs_list_lock);
+		async_hangup(fs_info->sess);
 		free(fs_info);
 		async_answer_0(callid, EINVAL);
@@ -215,7 +211,6 @@
 		dprintf("Client suggests wrong size of PFB, size = %d\n", size);
 		list_remove(&fs_info->fs_link);
-		fibril_mutex_unlock(&fs_head_lock);
-		async_session_destroy(&fs_info->session);
-		async_hangup(phone);
+		fibril_mutex_unlock(&fs_list_lock);
+		async_hangup(fs_info->sess);
 		free(fs_info);
 		async_answer_0(callid, EINVAL);
@@ -240,6 +235,6 @@
 	async_answer_1(rid, EOK, (sysarg_t) fs_info->fs_handle);
 	
-	fibril_condvar_broadcast(&fs_head_cv);
-	fibril_mutex_unlock(&fs_head_lock);
+	fibril_condvar_broadcast(&fs_list_cv);
+	fibril_mutex_unlock(&fs_list_lock);
 	
 	dprintf("\"%.*s\" filesystem successfully registered, handle=%d.\n",
@@ -247,69 +242,58 @@
 }
 
-/** For a given file system handle, implement policy for allocating a phone.
- *
- * @param handle	File system handle.
- *
- * @return		Phone over which a multi-call request can be safely
- *			sent. Return 0 if no phone was found.
- */
-int vfs_grab_phone(fs_handle_t handle)
-{
-	link_t *cur;
-	fs_info_t *fs;
-	int phone;
-
-	/*
-	 * For now, we don't try to be very clever and very fast.  We simply
-	 * lookup the phone in the fs_head list and duplicate it.  The duplicate
-	 * phone will be returned to the client and the client will use it for
-	 * communication.  In the future, we should cache the connections so
-	 * that they do not have to be reestablished over and over again.
-	 */
-	fibril_mutex_lock(&fs_head_lock);
-	for (cur = fs_head.next; cur != &fs_head; cur = cur->next) {
-		fs = list_get_instance(cur, fs_info_t, fs_link);
+/** Begin an exchange for a given file system handle
+ *
+ * @param handle File system handle.
+ *
+ * @return Exchange for a multi-call request.
+ * @return NULL if no such file exists.
+ *
+ */
+async_exch_t *vfs_exchange_grab(fs_handle_t handle)
+{
+	/*
+	 * For now, we don't try to be very clever and very fast.
+	 * We simply lookup the session in fs_list and
+	 * begin an exchange.
+	 */
+	fibril_mutex_lock(&fs_list_lock);
+	
+	list_foreach(fs_list, cur) {
+		fs_info_t *fs = list_get_instance(cur, fs_info_t, fs_link);
+		
 		if (fs->fs_handle == handle) {
-			fibril_mutex_unlock(&fs_head_lock);
-			phone = async_exchange_begin(&fs->session);
-
-			assert(phone > 0);
-			return phone;
+			fibril_mutex_unlock(&fs_list_lock);
+			
+			assert(fs->sess);
+			async_exch_t *exch = async_exchange_begin(fs->sess);
+			
+			assert(exch);
+			return exch;
 		}
 	}
-	fibril_mutex_unlock(&fs_head_lock);
-	return 0;
-}
-
-/** Tell VFS that the phone is not needed anymore.
- *
- * @param phone		Phone to FS task.
- */
-void vfs_release_phone(fs_handle_t handle, int phone)
-{
-	link_t *cur;
-	fs_info_t *fs;
-
-	fibril_mutex_lock(&fs_head_lock);
-	for (cur = fs_head.next; cur != &fs_head; cur = cur->next) {
-		fs = list_get_instance(cur, fs_info_t, fs_link);
-		if (fs->fs_handle == handle) {
-			fibril_mutex_unlock(&fs_head_lock);
-			async_exchange_end(&fs->session, phone);
-			return;
-		}
-	}
-	/* should not really get here */
-	abort();
-	fibril_mutex_unlock(&fs_head_lock);
+	
+	fibril_mutex_unlock(&fs_list_lock);
+	
+	return NULL;
+}
+
+/** End VFS server exchange.
+ *
+ * @param exch   VFS server exchange.
+ *
+ */
+void vfs_exchange_release(async_exch_t *exch)
+{
+	async_exchange_end(exch);
 }
 
 /** Convert file system name to its handle.
  *
- * @param name		File system name.
- * @param lock		If true, the function will lock and unlock the
- * 			fs_head_lock.
- *
- * @return		File system handle or zero if file system not found.
+ * @param name File system name.
+ * @param lock If true, the function will lock and unlock the
+ *             fs_list_lock.
+ *
+ * @return File system handle or zero if file system not found.
+ *
  */
 fs_handle_t fs_name_to_handle(char *name, bool lock)
@@ -318,7 +302,7 @@
 	
 	if (lock)
-		fibril_mutex_lock(&fs_head_lock);
-	link_t *cur;
-	for (cur = fs_head.next; cur != &fs_head; cur = cur->next) {
+		fibril_mutex_lock(&fs_list_lock);
+	
+	list_foreach(fs_list, cur) {
 		fs_info_t *fs = list_get_instance(cur, fs_info_t, fs_link);
 		if (str_cmp(fs->vfs_info.name, name) == 0) { 
@@ -327,6 +311,8 @@
 		}
 	}
+	
 	if (lock)
-		fibril_mutex_unlock(&fs_head_lock);
+		fibril_mutex_unlock(&fs_list_lock);
+	
 	return handle;
 }
@@ -334,14 +320,15 @@
 /** 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.
+ * @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) {
+	
+	fibril_mutex_lock(&fs_list_lock);
+	list_foreach(fs_list, cur) {
 		fs_info_t *fs = list_get_instance(cur, fs_info_t, fs_link);
 		if (fs->fs_handle == handle) { 
@@ -350,6 +337,6 @@
 		}
 	}
-	fibril_mutex_unlock(&fs_head_lock);
-
+	fibril_mutex_unlock(&fs_list_lock);
+	
 	return info;
 }
@@ -357,3 +344,3 @@
 /**
  * @}
- */ 
+ */
