Index: uspace/lib/c/generic/vfs/vfs.c
===================================================================
--- uspace/lib/c/generic/vfs/vfs.c	(revision 8e80d3fa43465f93dad400fdfaebab4ec45f92a5)
+++ uspace/lib/c/generic/vfs/vfs.c	(revision 78eb2dc6fe2cd6bd7eede507d4d4acf98ab8e5ba)
@@ -33,6 +33,7 @@
  */
 
+#include <vfs/canonify.h>
 #include <vfs/vfs.h>
-#include <vfs/canonify.h>
+#include <vfs/vfs_sess.h>
 #include <macros.h>
 #include <stdlib.h>
@@ -44,5 +45,5 @@
 #include <sys/types.h>
 #include <ipc/services.h>
-#include <ipc/ns.h>
+#include <ns.h>
 #include <async.h>
 #include <fibril_synch.h>
@@ -54,8 +55,6 @@
 #include <ipc/devmap.h>
 
-static async_sess_t vfs_session;
-
-static FIBRIL_MUTEX_INITIALIZE(vfs_phone_mutex);
-static int vfs_phone = -1;
+static FIBRIL_MUTEX_INITIALIZE(vfs_mutex);
+static async_sess_t *vfs_sess = NULL;
 
 static FIBRIL_MUTEX_INITIALIZE(cwd_mutex);
@@ -65,9 +64,36 @@
 static size_t cwd_size = 0;
 
+/** Start an async exchange on the VFS session.
+ *
+ * @return New exchange.
+ *
+ */
+static async_exch_t *vfs_exchange_begin(void)
+{
+	fibril_mutex_lock(&vfs_mutex);
+	
+	while (vfs_sess == NULL)
+		vfs_sess = service_connect_blocking(EXCHANGE_PARALLEL, SERVICE_VFS,
+		    0, 0);
+	
+	fibril_mutex_unlock(&vfs_mutex);
+	
+	return async_exchange_begin(vfs_sess);
+}
+
+/** Finish an async exchange on the VFS session.
+ *
+ * @param exch Exchange to be finished.
+ *
+ */
+static void vfs_exchange_end(async_exch_t *exch)
+{
+	async_exchange_end(exch);
+}
+
 char *absolutize(const char *path, size_t *retlen)
 {
 	char *ncwd_path;
 	char *ncwd_path_nc;
-	size_t total_size; 
 
 	fibril_mutex_lock(&cwd_mutex);
@@ -78,16 +104,14 @@
 			return NULL;
 		}
-		total_size = cwd_size + 1 + size + 1;
-		ncwd_path_nc = malloc(total_size);
+		ncwd_path_nc = malloc(cwd_size + 1 + size + 1);
 		if (!ncwd_path_nc) {
 			fibril_mutex_unlock(&cwd_mutex);
 			return NULL;
 		}
-		str_cpy(ncwd_path_nc, total_size, cwd_path);
+		str_cpy(ncwd_path_nc, cwd_size + 1 + size + 1, cwd_path);
 		ncwd_path_nc[cwd_size] = '/';
 		ncwd_path_nc[cwd_size + 1] = '\0';
 	} else {
-		total_size = size + 1;
-		ncwd_path_nc = malloc(total_size);
+		ncwd_path_nc = malloc(size + 1);
 		if (!ncwd_path_nc) {
 			fibril_mutex_unlock(&cwd_mutex);
@@ -96,5 +120,5 @@
 		ncwd_path_nc[0] = '\0';
 	}
-	str_append(ncwd_path_nc, total_size, path);
+	str_append(ncwd_path_nc, cwd_size + 1 + size + 1, path);
 	ncwd_path = canonify(ncwd_path_nc, retlen);
 	if (!ncwd_path) {
@@ -118,36 +142,4 @@
 }
 
-/** Connect to VFS service and create session. */
-static void vfs_connect(void)
-{
-	while (vfs_phone < 0)
-		vfs_phone = service_connect_blocking(SERVICE_VFS, 0, 0);
-	
-	async_session_create(&vfs_session, vfs_phone, 0);
-}
-
-/** Start an async exchange on the VFS session.
- *
- * @return		New phone to be used during the exchange.
- */
-static int vfs_exchange_begin(void)
-{
-	fibril_mutex_lock(&vfs_phone_mutex);
-	if (vfs_phone < 0)
-		vfs_connect();
-	fibril_mutex_unlock(&vfs_phone_mutex);
-
-	return async_exchange_begin(&vfs_session);
-}
-
-/** End an async exchange on the VFS session.
- *
- * @param phone		Phone used during the exchange.
- */
-static void vfs_exchange_end(int phone)
-{
-	async_exchange_end(&vfs_session, phone);
-}
-
 int mount(const char *fs_name, const char *mp, const char *fqdn,
     const char *opts, unsigned int flags)
@@ -186,11 +178,11 @@
 	}
 	
-	int vfs_phone = vfs_exchange_begin();
+	async_exch_t *exch = vfs_exchange_begin();
 
 	sysarg_t rc_orig;
-	aid_t req = async_send_2(vfs_phone, VFS_IN_MOUNT, devmap_handle, flags, NULL);
-	sysarg_t rc = async_data_write_start(vfs_phone, (void *) mpa, mpa_size);
-	if (rc != EOK) {
-		vfs_exchange_end(vfs_phone);
+	aid_t req = async_send_2(exch, VFS_IN_MOUNT, devmap_handle, flags, NULL);
+	sysarg_t rc = async_data_write_start(exch, (void *) mpa, mpa_size);
+	if (rc != EOK) {
+		vfs_exchange_end(exch);
 		free(mpa);
 		async_wait_for(req, &rc_orig);
@@ -205,7 +197,7 @@
 	}
 	
-	rc = async_data_write_start(vfs_phone, (void *) opts, str_size(opts));
-	if (rc != EOK) {
-		vfs_exchange_end(vfs_phone);
+	rc = async_data_write_start(exch, (void *) opts, str_size(opts));
+	if (rc != EOK) {
+		vfs_exchange_end(exch);
 		free(mpa);
 		async_wait_for(req, &rc_orig);
@@ -220,7 +212,7 @@
 	}
 	
-	rc = async_data_write_start(vfs_phone, (void *) fs_name, str_size(fs_name));
-	if (rc != EOK) {
-		vfs_exchange_end(vfs_phone);
+	rc = async_data_write_start(exch, (void *) fs_name, str_size(fs_name));
+	if (rc != EOK) {
+		vfs_exchange_end(exch);
 		free(mpa);
 		async_wait_for(req, &rc_orig);
@@ -236,7 +228,7 @@
 	
 	/* Ask VFS whether it likes fs_name. */
-	rc = async_req_0_0(vfs_phone, IPC_M_PING);
-	if (rc != EOK) {
-		vfs_exchange_end(vfs_phone);
+	rc = async_req_0_0(exch, VFS_IN_PING);
+	if (rc != EOK) {
+		vfs_exchange_end(exch);
 		free(mpa);
 		async_wait_for(req, &rc_orig);
@@ -251,5 +243,5 @@
 	}
 	
-	vfs_exchange_end(vfs_phone);
+	vfs_exchange_end(exch);
 	free(mpa);
 	async_wait_for(req, &rc);
@@ -273,10 +265,10 @@
 		return ENOMEM;
 	
-	int vfs_phone = vfs_exchange_begin();
-	
-	req = async_send_0(vfs_phone, VFS_IN_UNMOUNT, NULL);
-	rc = async_data_write_start(vfs_phone, (void *) mpa, mpa_size);
-	if (rc != EOK) {
-		vfs_exchange_end(vfs_phone);
+	async_exch_t *exch = vfs_exchange_begin();
+	
+	req = async_send_0(exch, VFS_IN_UNMOUNT, NULL);
+	rc = async_data_write_start(exch, (void *) mpa, mpa_size);
+	if (rc != EOK) {
+		vfs_exchange_end(exch);
 		free(mpa);
 		async_wait_for(req, &rc_orig);
@@ -288,5 +280,5 @@
 	
 
-	vfs_exchange_end(vfs_phone);
+	vfs_exchange_end(exch);
 	free(mpa);
 	async_wait_for(req, &rc);
@@ -297,12 +289,12 @@
 static int open_internal(const char *abs, size_t abs_size, int lflag, int oflag)
 {
-	int vfs_phone = vfs_exchange_begin();
+	async_exch_t *exch = vfs_exchange_begin();
 	
 	ipc_call_t answer;
-	aid_t req = async_send_3(vfs_phone, VFS_IN_OPEN, lflag, oflag, 0, &answer);
-	sysarg_t rc = async_data_write_start(vfs_phone, abs, abs_size);
-	
-	if (rc != EOK) {
-		vfs_exchange_end(vfs_phone);
+	aid_t req = async_send_3(exch, VFS_IN_OPEN, lflag, oflag, 0, &answer);
+	sysarg_t rc = async_data_write_start(exch, abs, abs_size);
+	
+	if (rc != EOK) {
+		vfs_exchange_end(exch);
 
 		sysarg_t rc_orig;
@@ -315,5 +307,5 @@
 	}
 	
-	vfs_exchange_end(vfs_phone);
+	vfs_exchange_end(exch);
 	async_wait_for(req, &rc);
 	
@@ -339,11 +331,11 @@
 int open_node(fdi_node_t *node, int oflag)
 {
-	int vfs_phone = vfs_exchange_begin();
+	async_exch_t *exch = vfs_exchange_begin();
 	
 	ipc_call_t answer;
-	aid_t req = async_send_4(vfs_phone, VFS_IN_OPEN_NODE, node->fs_handle,
+	aid_t req = async_send_4(exch, VFS_IN_OPEN_NODE, node->fs_handle,
 	    node->devmap_handle, node->index, oflag, &answer);
 	
-	vfs_exchange_end(vfs_phone);
+	vfs_exchange_end(exch);
 
 	sysarg_t rc;
@@ -360,11 +352,9 @@
 	sysarg_t rc;
 	
-	int vfs_phone = vfs_exchange_begin();
-	
-	rc = async_req_1_0(vfs_phone, VFS_IN_CLOSE, fildes);
-	
-	vfs_exchange_end(vfs_phone);
-	
-	return (int)rc;
+	async_exch_t *exch = vfs_exchange_begin();
+	rc = async_req_1_0(exch, VFS_IN_CLOSE, fildes);
+	vfs_exchange_end(exch);
+	
+	return (int) rc;
 }
 
@@ -374,12 +364,11 @@
 	ipc_call_t answer;
 	aid_t req;
-
-	int vfs_phone = vfs_exchange_begin();
-	
-	req = async_send_1(vfs_phone, VFS_IN_READ, fildes, &answer);
-	rc = async_data_read_start_generic(vfs_phone, (void *) buf, nbyte,
-	    IPC_XF_RESTRICT);
-	if (rc != EOK) {
-		vfs_exchange_end(vfs_phone);
+	
+	async_exch_t *exch = vfs_exchange_begin();
+	
+	req = async_send_1(exch, VFS_IN_READ, fildes, &answer);
+	rc = async_data_read_start(exch, (void *)buf, nbyte);
+	if (rc != EOK) {
+		vfs_exchange_end(exch);
 
 		sysarg_t rc_orig;
@@ -391,5 +380,5 @@
 			return (ssize_t) rc_orig;
 	}
-	vfs_exchange_end(vfs_phone);
+	vfs_exchange_end(exch);
 	async_wait_for(req, &rc);
 	if (rc == EOK)
@@ -404,12 +393,11 @@
 	ipc_call_t answer;
 	aid_t req;
-
-	int vfs_phone = vfs_exchange_begin();
-	
-	req = async_send_1(vfs_phone, VFS_IN_WRITE, fildes, &answer);
-	rc = async_data_write_start_generic(vfs_phone, (void *) buf, nbyte,
-	    IPC_XF_RESTRICT);
-	if (rc != EOK) {
-		vfs_exchange_end(vfs_phone);
+	
+	async_exch_t *exch = vfs_exchange_begin();
+	
+	req = async_send_1(exch, VFS_IN_WRITE, fildes, &answer);
+	rc = async_data_write_start(exch, (void *)buf, nbyte);
+	if (rc != EOK) {
+		vfs_exchange_end(exch);
 
 		sysarg_t rc_orig;
@@ -421,5 +409,5 @@
 			return (ssize_t) rc_orig;
 	}
-	vfs_exchange_end(vfs_phone);
+	vfs_exchange_end(exch);
 	async_wait_for(req, &rc);
 	if (rc == EOK)
@@ -431,9 +419,7 @@
 int fsync(int fildes)
 {
-	int vfs_phone = vfs_exchange_begin();
-	
-	sysarg_t rc = async_req_1_0(vfs_phone, VFS_IN_SYNC, fildes);
-	
-	vfs_exchange_end(vfs_phone);
+	async_exch_t *exch = vfs_exchange_begin();
+	sysarg_t rc = async_req_1_0(exch, VFS_IN_SYNC, fildes);
+	vfs_exchange_end(exch);
 	
 	return (int) rc;
@@ -442,13 +428,13 @@
 off64_t lseek(int fildes, off64_t offset, int whence)
 {
-	int vfs_phone = vfs_exchange_begin();
+	async_exch_t *exch = vfs_exchange_begin();
 	
 	sysarg_t newoff_lo;
 	sysarg_t newoff_hi;
-	sysarg_t rc = async_req_4_2(vfs_phone, VFS_IN_SEEK, fildes,
+	sysarg_t rc = async_req_4_2(exch, VFS_IN_SEEK, fildes,
 	    LOWER32(offset), UPPER32(offset), whence,
 	    &newoff_lo, &newoff_hi);
 	
-	vfs_exchange_end(vfs_phone);
+	vfs_exchange_end(exch);
 	
 	if (rc != EOK)
@@ -462,9 +448,8 @@
 	sysarg_t rc;
 	
-	int vfs_phone = vfs_exchange_begin();
-	
-	rc = async_req_3_0(vfs_phone, VFS_IN_TRUNCATE, fildes,
+	async_exch_t *exch = vfs_exchange_begin();
+	rc = async_req_3_0(exch, VFS_IN_TRUNCATE, fildes,
 	    LOWER32(length), UPPER32(length));
-	vfs_exchange_end(vfs_phone);
+	vfs_exchange_end(exch);
 	
 	return (int) rc;
@@ -475,11 +460,11 @@
 	sysarg_t rc;
 	aid_t req;
-
-	int vfs_phone = vfs_exchange_begin();
-	
-	req = async_send_1(vfs_phone, VFS_IN_FSTAT, fildes, NULL);
-	rc = async_data_read_start(vfs_phone, (void *) stat, sizeof(struct stat));
-	if (rc != EOK) {
-		vfs_exchange_end(vfs_phone);
+	
+	async_exch_t *exch = vfs_exchange_begin();
+	
+	req = async_send_1(exch, VFS_IN_FSTAT, fildes, NULL);
+	rc = async_data_read_start(exch, (void *) stat, sizeof(struct stat));
+	if (rc != EOK) {
+		vfs_exchange_end(exch);
 
 		sysarg_t rc_orig;
@@ -491,5 +476,5 @@
 			return (ssize_t) rc_orig;
 	}
-	vfs_exchange_end(vfs_phone);
+	vfs_exchange_end(exch);
 	async_wait_for(req, &rc);
 
@@ -508,10 +493,10 @@
 		return ENOMEM;
 	
-	int vfs_phone = vfs_exchange_begin();
-	
-	req = async_send_0(vfs_phone, VFS_IN_STAT, NULL);
-	rc = async_data_write_start(vfs_phone, pa, pa_size);
-	if (rc != EOK) {
-		vfs_exchange_end(vfs_phone);
+	async_exch_t *exch = vfs_exchange_begin();
+	
+	req = async_send_0(exch, VFS_IN_STAT, NULL);
+	rc = async_data_write_start(exch, pa, pa_size);
+	if (rc != EOK) {
+		vfs_exchange_end(exch);
 		free(pa);
 		async_wait_for(req, &rc_orig);
@@ -521,7 +506,7 @@
 			return (int) rc_orig;
 	}
-	rc = async_data_read_start(vfs_phone, stat, sizeof(struct stat));
-	if (rc != EOK) {
-		vfs_exchange_end(vfs_phone);
+	rc = async_data_read_start(exch, stat, sizeof(struct stat));
+	if (rc != EOK) {
+		vfs_exchange_end(exch);
 		free(pa);
 		async_wait_for(req, &rc_orig);
@@ -531,5 +516,5 @@
 			return (int) rc_orig;
 	}
-	vfs_exchange_end(vfs_phone);
+	vfs_exchange_end(exch);
 	free(pa);
 	async_wait_for(req, &rc);
@@ -592,10 +577,10 @@
 		return ENOMEM;
 	
-	int vfs_phone = vfs_exchange_begin();
-	
-	req = async_send_1(vfs_phone, VFS_IN_MKDIR, mode, NULL);
-	rc = async_data_write_start(vfs_phone, pa, pa_size);
-	if (rc != EOK) {
-		vfs_exchange_end(vfs_phone);
+	async_exch_t *exch = vfs_exchange_begin();
+	
+	req = async_send_1(exch, VFS_IN_MKDIR, mode, NULL);
+	rc = async_data_write_start(exch, pa, pa_size);
+	if (rc != EOK) {
+		vfs_exchange_end(exch);
 		free(pa);
 
@@ -608,5 +593,5 @@
 			return (int) rc_orig;
 	}
-	vfs_exchange_end(vfs_phone);
+	vfs_exchange_end(exch);
 	free(pa);
 	async_wait_for(req, &rc);
@@ -623,11 +608,11 @@
 	if (!pa)
 		return ENOMEM;
-
-	int vfs_phone = vfs_exchange_begin();
-	
-	req = async_send_0(vfs_phone, VFS_IN_UNLINK, NULL);
-	rc = async_data_write_start(vfs_phone, pa, pa_size);
-	if (rc != EOK) {
-		vfs_exchange_end(vfs_phone);
+	
+	async_exch_t *exch = vfs_exchange_begin();
+	
+	req = async_send_0(exch, VFS_IN_UNLINK, NULL);
+	rc = async_data_write_start(exch, pa, pa_size);
+	if (rc != EOK) {
+		vfs_exchange_end(exch);
 		free(pa);
 
@@ -640,5 +625,5 @@
 			return (int) rc_orig;
 	}
-	vfs_exchange_end(vfs_phone);
+	vfs_exchange_end(exch);
 	free(pa);
 	async_wait_for(req, &rc);
@@ -673,11 +658,11 @@
 		return ENOMEM;
 	}
-
-	int vfs_phone = vfs_exchange_begin();
-	
-	req = async_send_0(vfs_phone, VFS_IN_RENAME, NULL);
-	rc = async_data_write_start(vfs_phone, olda, olda_size);
-	if (rc != EOK) {
-		vfs_exchange_end(vfs_phone);
+	
+	async_exch_t *exch = vfs_exchange_begin();
+	
+	req = async_send_0(exch, VFS_IN_RENAME, NULL);
+	rc = async_data_write_start(exch, olda, olda_size);
+	if (rc != EOK) {
+		vfs_exchange_end(exch);
 		free(olda);
 		free(newa);
@@ -688,7 +673,7 @@
 			return (int) rc_orig;
 	}
-	rc = async_data_write_start(vfs_phone, newa, newa_size);
-	if (rc != EOK) {
-		vfs_exchange_end(vfs_phone);
+	rc = async_data_write_start(exch, newa, newa_size);
+	if (rc != EOK) {
+		vfs_exchange_end(exch);
 		free(olda);
 		free(newa);
@@ -699,5 +684,5 @@
 			return (int) rc_orig;
 	}
-	vfs_exchange_end(vfs_phone);
+	vfs_exchange_end(exch);
 	free(olda);
 	free(newa);
@@ -755,16 +740,19 @@
 }
 
-int fd_phone(int fildes)
+async_sess_t *fd_session(exch_mgmt_t mgmt, int fildes)
 {
 	struct stat stat;
-	
 	int rc = fstat(fildes, &stat);
-	if (rc != 0)
-		return rc;
-	
-	if (!stat.device)
-		return -1;
-	
-	return devmap_device_connect(stat.device, 0);
+	if (rc != 0) {
+		errno = rc;
+		return NULL;
+	}
+	
+	if (!stat.device) {
+		errno = ENOENT;
+		return NULL;
+	}
+	
+	return devmap_device_connect(mgmt, stat.device, 0);
 }
 
@@ -772,7 +760,5 @@
 {
 	struct stat stat;
-	int rc;
-
-	rc = fstat(fildes, &stat);
+	int rc = fstat(fildes, &stat);
 	
 	if (rc == EOK) {
@@ -787,10 +773,10 @@
 int dup2(int oldfd, int newfd)
 {
-	int vfs_phone = vfs_exchange_begin();
+	async_exch_t *exch = vfs_exchange_begin();
 	
 	sysarg_t ret;
-	sysarg_t rc = async_req_2_1(vfs_phone, VFS_IN_DUP, oldfd, newfd, &ret);
-	
-	vfs_exchange_end(vfs_phone);
+	sysarg_t rc = async_req_2_1(exch, VFS_IN_DUP, oldfd, newfd, &ret);
+	
+	vfs_exchange_end(exch);
 	
 	if (rc == EOK)
