Index: uspace/lib/libfs/libfs.c
===================================================================
--- uspace/lib/libfs/libfs.c	(revision 2e983c7d80327c6df25bf13685ccc741dab6e42a)
+++ uspace/lib/libfs/libfs.c	(revision b9b105e1aa4a3f29d2494d99e7e891dc8f07480a)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2009 Jakub Jermar 
+ * Copyright (c) 2009 Jakub Jermar
  * All rights reserved.
  *
@@ -27,13 +27,13 @@
  */
 
-/** @addtogroup libfs 
+/** @addtogroup libfs
  * @{
- */ 
+ */
 /**
  * @file
- * Glue code which is commonod to all FS implementations. 
- */
-
-#include "libfs.h" 
+ * Glue code which is common to all FS implementations.
+ */
+
+#include "libfs.h"
 #include "../../srv/vfs/vfs.h"
 #include <errno.h>
@@ -67,13 +67,14 @@
  * code.
  *
- * @param vfs_phone	Open phone for communication with VFS.
- * @param reg		File system registration structure. It will be
- * 			initialized by this function.
- * @param info		VFS info structure supplied by the file system
- *			implementation.
- * @param conn		Connection fibril for handling all calls originating in
- *			VFS.
- *
- * @return		EOK on success or a non-zero error code on errror.
+ * @param vfs_phone Open phone for communication with VFS.
+ * @param reg       File system registration structure. It will be
+ *                  initialized by this function.
+ * @param info      VFS info structure supplied by the file system
+ *                  implementation.
+ * @param conn      Connection fibril for handling all calls originating in
+ *                  VFS.
+ *
+ * @return EOK on success or a non-zero error code on errror.
+ *
  */
 int fs_register(int vfs_phone, fs_reg_t *reg, vfs_info_t *info,
@@ -87,5 +88,5 @@
 	ipc_call_t answer;
 	aid_t req = async_send_0(vfs_phone, VFS_IN_REGISTER, &answer);
-
+	
 	/*
 	 * Send our VFS info structure to VFS.
@@ -96,10 +97,10 @@
 		return rc;
 	}
-
+	
 	/*
 	 * Ask VFS for callback connection.
 	 */
 	ipc_connect_to_me(vfs_phone, 0, 0, 0, &reg->vfs_phonehash);
-
+	
 	/*
 	 * Allocate piece of address space for PLB.
@@ -110,5 +111,5 @@
 		return ENOMEM;
 	}
-
+	
 	/*
 	 * Request sharing the Path Lookup Buffer with VFS.
@@ -136,5 +137,5 @@
 	 */
 	async_set_client_connection(conn);
-
+	
 	return IPC_GET_RETVAL(answer);
 }
@@ -154,18 +155,20 @@
 	int res;
 	ipcarg_t rc;
-
+	
 	ipc_call_t call;
 	ipc_callid_t callid;
-
-	/* accept the phone */
+	
+	/* Accept the phone */
 	callid = async_get_call(&call);
 	int mountee_phone = (int)IPC_GET_ARG1(call);
 	if ((IPC_GET_METHOD(call) != IPC_M_CONNECTION_CLONE) ||
-	    mountee_phone < 0) {
+	    (mountee_phone < 0)) {
 		ipc_answer_0(callid, EINVAL);
 		ipc_answer_0(rid, EINVAL);
 		return;
 	}
-	ipc_answer_0(callid, EOK);	/* acknowledge the mountee_phone */
+	
+	/* Acknowledge the mountee_phone */
+	ipc_answer_0(callid, EOK);
 	
 	res = async_data_write_receive(&callid, NULL);
@@ -176,8 +179,8 @@
 		return;
 	}
-
+	
 	fs_node_t *fn;
 	res = ops->node_get(&fn, mp_dev_handle, mp_fs_index);
-	if (res != EOK || !fn) {
+	if ((res != EOK) || (!fn)) {
 		ipc_hangup(mountee_phone);
 		ipc_answer_0(callid, combine_rc(res, ENOENT));
@@ -185,5 +188,5 @@
 		return;
 	}
-
+	
 	if (fn->mp_data.mp_active) {
 		ipc_hangup(mountee_phone);
@@ -193,5 +196,5 @@
 		return;
 	}
-
+	
 	rc = async_req_0_0(mountee_phone, IPC_M_CONNECT_ME);
 	if (rc != EOK) {
@@ -215,4 +218,5 @@
 		fn->mp_data.phone = mountee_phone;
 	}
+	
 	/*
 	 * Do not release the FS node so that it stays in memory.
@@ -238,24 +242,24 @@
     ipc_call_t *request)
 {
-	unsigned first = IPC_GET_ARG1(*request);
-	unsigned last = IPC_GET_ARG2(*request);
-	unsigned next = first;
+	unsigned int first = IPC_GET_ARG1(*request);
+	unsigned int last = IPC_GET_ARG2(*request);
+	unsigned int next = first;
 	dev_handle_t dev_handle = IPC_GET_ARG3(*request);
 	int lflag = IPC_GET_ARG4(*request);
-	fs_index_t index = IPC_GET_ARG5(*request); /* when L_LINK specified */
+	fs_index_t index = IPC_GET_ARG5(*request);
 	char component[NAME_MAX + 1];
 	int len;
 	int rc;
-
+	
 	if (last < next)
 		last += PLB_SIZE;
-
+	
 	fs_node_t *par = NULL;
 	fs_node_t *cur = NULL;
 	fs_node_t *tmp = NULL;
-
+	
 	rc = ops->root_get(&cur, dev_handle);
 	on_error(rc, goto out_with_answer);
-
+	
 	if (cur->mp_data.mp_active) {
 		ipc_forward_slow(rid, cur->mp_data.phone, VFS_OUT_LOOKUP,
@@ -265,42 +269,45 @@
 		return;
 	}
-
+	
+	/* Eat slash */
 	if (ops->plb_get_char(next) == '/')
-		next++;		/* eat slash */
+		next++;
 	
 	while (next <= last) {
 		bool has_children;
-
+		
 		rc = ops->has_children(&has_children, cur);
 		on_error(rc, goto out_with_answer);
 		if (!has_children)
 			break;
-
-		/* collect the component */
+		
+		/* Collect the component */
 		len = 0;
-		while ((next <= last) &&  (ops->plb_get_char(next) != '/')) {
+		while ((next <= last) && (ops->plb_get_char(next) != '/')) {
 			if (len + 1 == NAME_MAX) {
-				/* component length overflow */
+				/* Component length overflow */
 				ipc_answer_0(rid, ENAMETOOLONG);
 				goto out;
 			}
 			component[len++] = ops->plb_get_char(next);
-			next++;	/* process next character */
+			/* Process next character */
+			next++;
 		}
-
+		
 		assert(len);
 		component[len] = '\0';
-		next++;		/* eat slash */
-
-		/* match the component */
+		/* Eat slash */
+		next++;
+		
+		/* Match the component */
 		rc = ops->match(&tmp, cur, component);
 		on_error(rc, goto out_with_answer);
-
-		if (tmp && tmp->mp_data.mp_active) {
+		
+		if ((tmp) && (tmp->mp_data.mp_active)) {
 			if (next > last)
 				next = last = first;
 			else
 				next--;
-				
+			
 			ipc_forward_slow(rid, tmp->mp_data.phone,
 			    VFS_OUT_LOOKUP, next, last, tmp->mp_data.dev_handle,
@@ -312,19 +319,21 @@
 			return;
 		}
-
-		/* handle miss: match amongst siblings */
+		
+		/* Handle miss: match amongst siblings */
 		if (!tmp) {
 			if (next <= last) {
-				/* there are unprocessed components */
+				/* There are unprocessed components */
 				ipc_answer_0(rid, ENOENT);
 				goto out;
 			}
-			/* miss in the last component */
-			if (lflag & (L_CREATE | L_LINK)) { 
-				/* request to create a new link */
+			
+			/* Miss in the last component */
+			if (lflag & (L_CREATE | L_LINK)) {
+				/* Request to create a new link */
 				if (!ops->is_directory(cur)) {
 					ipc_answer_0(rid, ENOTDIR);
 					goto out;
 				}
+				
 				fs_node_t *fn;
 				if (lflag & L_CREATE)
@@ -335,4 +344,5 @@
 					    index);
 				on_error(rc, goto out_with_answer);
+				
 				if (fn) {
 					rc = ops->link(cur, fn, component);
@@ -349,33 +359,34 @@
 						(void) ops->node_put(fn);
 					}
-				} else {
+				} else
 					ipc_answer_0(rid, ENOSPC);
-				}
+				
 				goto out;
-			} 
+			}
+			
 			ipc_answer_0(rid, ENOENT);
 			goto out;
 		}
-
+		
 		if (par) {
 			rc = ops->node_put(par);
 			on_error(rc, goto out_with_answer);
 		}
-
-		/* descend one level */
+		
+		/* Descend one level */
 		par = cur;
 		cur = tmp;
 		tmp = NULL;
 	}
-
-	/* handle miss: excessive components */
+	
+	/* Handle miss: excessive components */
 	if (next <= last) {
 		bool has_children;
-
 		rc = ops->has_children(&has_children, cur);
 		on_error(rc, goto out_with_answer);
+		
 		if (has_children)
 			goto skip_miss;
-
+		
 		if (lflag & (L_CREATE | L_LINK)) {
 			if (!ops->is_directory(cur)) {
@@ -383,24 +394,28 @@
 				goto out;
 			}
-
-			/* collect next component */
+			
+			/* Collect next component */
 			len = 0;
 			while (next <= last) {
 				if (ops->plb_get_char(next) == '/') {
-					/* more than one component */
+					/* More than one component */
 					ipc_answer_0(rid, ENOENT);
 					goto out;
 				}
+				
 				if (len + 1 == NAME_MAX) {
-					/* component length overflow */
+					/* Component length overflow */
 					ipc_answer_0(rid, ENAMETOOLONG);
 					goto out;
 				}
+				
 				component[len++] = ops->plb_get_char(next);
-				next++;	/* process next character */
+				/* Process next character */
+				next++;
 			}
+			
 			assert(len);
 			component[len] = '\0';
-				
+			
 			fs_node_t *fn;
 			if (lflag & L_CREATE)
@@ -409,4 +424,5 @@
 				rc = ops->node_get(&fn, dev_handle, index);
 			on_error(rc, goto out_with_answer);
+			
 			if (fn) {
 				rc = ops->link(cur, fn, component);
@@ -423,22 +439,25 @@
 					(void) ops->node_put(fn);
 				}
-			} else {
+			} else
 				ipc_answer_0(rid, ENOSPC);
-			}
+			
 			goto out;
 		}
+		
 		ipc_answer_0(rid, ENOENT);
 		goto out;
 	}
+	
 skip_miss:
-
-	/* handle hit */
+	
+	/* Handle hit */
 	if (lflag & L_UNLINK) {
-		unsigned old_lnkcnt = ops->lnkcnt_get(cur);
+		unsigned int old_lnkcnt = ops->lnkcnt_get(cur);
 		rc = ops->unlink(par, cur, component);
-		ipc_answer_5(rid, (ipcarg_t)rc, fs_handle, dev_handle,
+		ipc_answer_5(rid, (ipcarg_t) rc, fs_handle, dev_handle,
 		    ops->index_get(cur), ops->size_get(cur), old_lnkcnt);
 		goto out;
 	}
+	
 	if (((lflag & (L_CREATE | L_EXCLUSIVE)) == (L_CREATE | L_EXCLUSIVE)) ||
 	    (lflag & L_LINK)) {
@@ -446,27 +465,35 @@
 		goto out;
 	}
+	
 	if ((lflag & L_FILE) && (ops->is_directory(cur))) {
 		ipc_answer_0(rid, EISDIR);
 		goto out;
 	}
+	
 	if ((lflag & L_DIRECTORY) && (ops->is_file(cur))) {
 		ipc_answer_0(rid, ENOTDIR);
 		goto out;
 	}
-
+	
 out_with_answer:
+	
 	if (rc == EOK) {
-		ipc_answer_5(rid, EOK, fs_handle, dev_handle,
+		if (lflag & L_OPEN)
+			rc = ops->node_open(cur);
+		
+		ipc_answer_5(rid, rc, fs_handle, dev_handle,
 		    ops->index_get(cur), ops->size_get(cur),
 		    ops->lnkcnt_get(cur));
-	} else {
+	} else
 		ipc_answer_0(rid, rc);
-	}
-
+	
 out:
+	
 	if (par)
 		(void) ops->node_put(par);
+	
 	if (cur)
 		(void) ops->node_put(cur);
+	
 	if (tmp)
 		(void) ops->node_put(tmp);
@@ -478,19 +505,19 @@
 	dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
 	fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
+	
 	fs_node_t *fn;
-	int rc;
-
-	rc = ops->node_get(&fn, dev_handle, index);
+	int rc = ops->node_get(&fn, dev_handle, index);
 	on_error(rc, answer_and_return(rid, rc));
-
+	
 	ipc_callid_t callid;
 	size_t size;
-	if (!async_data_read_receive(&callid, &size) ||
-	    size != sizeof(struct stat)) {
+	if ((!async_data_read_receive(&callid, &size)) ||
+	    (size != sizeof(struct stat))) {
+		ops->node_put(fn);
 		ipc_answer_0(callid, EINVAL);
 		ipc_answer_0(rid, EINVAL);
 		return;
 	}
-
+	
 	struct stat stat;
 	memset(&stat, 0, sizeof(struct stat));
@@ -499,8 +526,12 @@
 	stat.dev_handle = dev_handle;
 	stat.index = index;
-	stat.lnkcnt = ops->lnkcnt_get(fn); 
+	stat.lnkcnt = ops->lnkcnt_get(fn);
 	stat.is_file = ops->is_file(fn);
+	stat.is_directory = ops->is_directory(fn);
 	stat.size = ops->size_get(fn);
-
+	stat.device = ops->device_get(fn);
+	
+	ops->node_put(fn);
+	
 	async_data_read_finalize(callid, &stat, sizeof(struct stat));
 	ipc_answer_0(rid, EOK);
@@ -509,8 +540,8 @@
 /** Open VFS triplet.
  *
- * @param ops       libfs operations structure with function pointers to
- *                  file system implementation
- * @param rid       Request ID of the VFS_OUT_OPEN_NODE request.
- * @param request   VFS_OUT_OPEN_NODE request data itself.
+ * @param ops     libfs operations structure with function pointers to
+ *                file system implementation
+ * @param rid     Request ID of the VFS_OUT_OPEN_NODE request.
+ * @param request VFS_OUT_OPEN_NODE request data itself.
  *
  */
@@ -531,5 +562,6 @@
 	}
 	
-	ipc_answer_3(rid, EOK, ops->size_get(fn), ops->lnkcnt_get(fn),
+	rc = ops->node_open(fn);
+	ipc_answer_3(rid, rc, ops->size_get(fn), ops->lnkcnt_get(fn),
 	    (ops->is_file(fn) ? L_FILE : 0) | (ops->is_directory(fn) ? L_DIRECTORY : 0));
 	
Index: uspace/lib/libfs/libfs.h
===================================================================
--- uspace/lib/libfs/libfs.h	(revision 2e983c7d80327c6df25bf13685ccc741dab6e42a)
+++ uspace/lib/libfs/libfs.h	(revision b9b105e1aa4a3f29d2494d99e7e891dc8f07480a)
@@ -64,4 +64,5 @@
 	int (* match)(fs_node_t **, fs_node_t *, const char *);
 	int (* node_get)(fs_node_t **, dev_handle_t, fs_index_t);
+	int (* node_open)(fs_node_t *);
 	int (* node_put)(fs_node_t *);
 	int (* create)(fs_node_t **, dev_handle_t, int);
@@ -76,8 +77,9 @@
 	fs_index_t (* index_get)(fs_node_t *);
 	size_t (* size_get)(fs_node_t *);
-	unsigned (* lnkcnt_get)(fs_node_t *);
+	unsigned int (* lnkcnt_get)(fs_node_t *);
 	char (* plb_get_char)(unsigned pos);
 	bool (* is_directory)(fs_node_t *);
 	bool (* is_file)(fs_node_t *);
+	dev_handle_t (* device_get)(fs_node_t *);
 } libfs_ops_t;
 
