Index: uspace/lib/libfs/libfs.c
===================================================================
--- uspace/lib/libfs/libfs.c	(revision 3298ddcf6c5ee0679ee36cb28609b0960b982189)
+++ uspace/lib/libfs/libfs.c	(revision 07deef576e996d5e93d3d0c16be2bb8f453a0623)
@@ -142,4 +142,5 @@
 	int dev_handle = IPC_GET_ARG3(*request);
 	int lflag = IPC_GET_ARG4(*request);
+	int index = IPC_GET_ARG5(*request); /* when L_LINK specified */
 
 	if (last < next)
@@ -181,19 +182,32 @@
 		/* handle miss: match amongst siblings */
 		if (!tmp) {
-			if ((next > last) && (lflag & L_CREATE)) {
-				/* no components left and L_CREATE specified */
+			if (next <= last) {
+				/* there are unprocessed components */
+				ipc_answer_0(rid, ENOENT);
+				return;
+			}
+			/* 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);
 					return;
-				} 
-				void *nodep = ops->create(lflag);
+				}
+				void *nodep;
+				if (lflag & L_CREATE)
+					nodep = ops->create(lflag);
+				else
+					nodep = ops->node_get(fs_handle,
+					    dev_handle, index);
 				if (nodep) {
 					if (!ops->link(cur, nodep, component)) {
-						ops->destroy(nodep);
+						if (lflag & L_CREATE)
+							ops->destroy(nodep);
 						ipc_answer_0(rid, ENOSPC);
 					} else {
 						ipc_answer_5(rid, EOK,
 						    fs_handle, dev_handle,
-						    ops->index_get(nodep), 0,
+						    ops->index_get(nodep),
+						    ops->size_get(nodep),
 						    ops->lnkcnt_get(nodep));
 					}
@@ -202,5 +216,10 @@
 				}
 				return;
-			}
+			} else if (lflag & L_PARENT) {
+				/* return parent */
+				ipc_answer_5(rid, EOK, fs_handle, dev_handle,
+				    ops->index_get(cur), ops->size_get(cur),
+				    ops->lnkcnt_get(cur));
+			} 
 			ipc_answer_0(rid, ENOENT);
 			return;
@@ -215,5 +234,5 @@
 	/* handle miss: excessive components */
 	if (!tmp && next <= last) {
-		if (lflag & L_CREATE) {
+		if (lflag & (L_CREATE | L_LINK)) {
 			if (!ops->is_directory(cur)) {
 				ipc_answer_0(rid, ENOTDIR);
@@ -240,13 +259,20 @@
 			len = 0;
 				
-			void *nodep = ops->create(lflag);
+			void *nodep;
+			if (lflag & L_CREATE)
+				nodep = ops->create(lflag);
+			else
+				nodep = ops->node_get(fs_handle, dev_handle,
+				    index);
 			if (nodep) {
 				if (!ops->link(cur, nodep, component)) {
-					ops->destroy(nodep);
+					if (lflag & L_CREATE)
+						ops->destroy(nodep);
 					ipc_answer_0(rid, ENOSPC);
 				} else {
 					ipc_answer_5(rid, EOK,
 					    fs_handle, dev_handle,
-					    ops->index_get(nodep), 0,
+					    ops->index_get(nodep),
+					    ops->size_get(nodep),
 					    ops->lnkcnt_get(nodep));
 				}
@@ -261,5 +287,12 @@
 
 	/* handle hit */
-	if (lflag & L_DESTROY) {
+	if (lflag & L_PARENT) {
+		cur = par;
+		if (!cur) {
+			ipc_answer_0(rid, ENOENT);
+			return;
+		}
+	}
+	if (lflag & L_UNLINK) {
 		unsigned old_lnkcnt = ops->lnkcnt_get(cur);
 		int res = ops->unlink(par, cur);
@@ -268,5 +301,6 @@
 		return;
 	}
-	if ((lflag & (L_CREATE | L_EXCLUSIVE)) == (L_CREATE | L_EXCLUSIVE)) {
+	if (((lflag & (L_CREATE | L_EXCLUSIVE)) == (L_CREATE | L_EXCLUSIVE)) ||
+	    (lflag & L_LINK)) {
 		ipc_answer_0(rid, EEXIST);
 		return;
Index: uspace/lib/libfs/libfs.h
===================================================================
--- uspace/lib/libfs/libfs.h	(revision 3298ddcf6c5ee0679ee36cb28609b0960b982189)
+++ uspace/lib/libfs/libfs.h	(revision 07deef576e996d5e93d3d0c16be2bb8f453a0623)
@@ -44,4 +44,5 @@
 typedef struct {
 	bool (* match)(void *, void *, const char *);
+	void * (* node_get)(int, int, unsigned long);
 	void * (* create)(int);
 	void (* destroy)(void *);
