diff --git a/scheme/initfs.rs b/scheme/initfs.rs
index e3f1d4006b912576d03b07b9dd6abc8b2186dfb5..d23adc755e42ea11193912eff23e1e46bf222479 100644
--- a/scheme/initfs.rs
+++ b/scheme/initfs.rs
@@ -12,6 +12,7 @@ use syscall::scheme::Scheme;
 mod gen;
 
 struct Handle {
+    path: &'static [u8],
     data: &'static [u8],
     mode: u16,
     seek: usize
@@ -35,28 +36,37 @@ impl InitFsScheme {
 
 impl Scheme for InitFsScheme {
     fn open(&self, path: &[u8], _flags: usize) -> Result<usize> {
-        let path = str::from_utf8(path).map_err(|_err| Error::new(ENOENT))?.trim_matches('/');
-        let file = self.files.get(path.as_bytes()).ok_or(Error::new(ENOENT))?;
-
-        let id = self.next_id.fetch_add(1, Ordering::SeqCst);
-        self.handles.write().insert(id, Handle {
-            data: file.0,
-            mode: if file.1 { MODE_DIR } else { MODE_FILE },
-            seek: 0
-        });
+        let path_utf8 = str::from_utf8(path).map_err(|_err| Error::new(ENOENT))?;
+        let path_trimmed = path_utf8.trim_matches('/');
+
+        //Have to iterate to get the path without allocation
+        for entry in self.files.iter() {
+            if entry.0 == &path_trimmed.as_bytes() {
+                let id = self.next_id.fetch_add(1, Ordering::SeqCst);
+                self.handles.write().insert(id, Handle {
+                    path: entry.0,
+                    data: (entry.1).0,
+                    mode: if (entry.1).1 { MODE_DIR } else { MODE_FILE },
+                    seek: 0
+                });
+
+                return Ok(id)
+            }
+        }
 
-        Ok(id)
+        Err(Error::new(ENOENT))
     }
 
     fn dup(&self, id: usize) -> Result<usize> {
-        let (data, mode, seek) = {
+        let (path, data, mode, seek) = {
             let handles = self.handles.read();
             let handle = handles.get(&id).ok_or(Error::new(EBADF))?;
-            (handle.data, handle.mode, handle.seek)
+            (handle.path, handle.data, handle.mode, handle.seek)
         };
 
         let id = self.next_id.fetch_add(1, Ordering::SeqCst);
         self.handles.write().insert(id, Handle {
+            path: path,
             data: data,
             mode: mode,
             seek: seek
@@ -93,6 +103,28 @@ impl Scheme for InitFsScheme {
         Ok(handle.seek)
     }
 
+    fn fpath(&self, id: usize, buf: &mut [u8]) -> Result<usize> {
+        let handles = self.handles.read();
+        let handle = handles.get(&id).ok_or(Error::new(EBADF))?;
+
+        //TODO: Copy scheme part in kernel
+        let mut i = 0;
+        let scheme_path = b"initfs:";
+        while i < buf.len() && i < scheme_path.len() {
+            buf[i] = scheme_path[i];
+            i += 1;
+        }
+
+        let mut j = 0;
+        while i < buf.len() && j < handle.path.len() {
+            buf[i] = handle.path[j];
+            i += 1;
+            j += 1;
+        }
+
+        Ok(i)
+    }
+
     fn fstat(&self, id: usize, stat: &mut Stat) -> Result<usize> {
         let handles = self.handles.read();
         let handle = handles.get(&id).ok_or(Error::new(EBADF))?;
diff --git a/syscall/fs.rs b/syscall/fs.rs
index 029222b78297fbc2b8010a9b5792eac8e316fdae..646a05ca6c6a0ba86da03f6f608698b513c67534 100644
--- a/syscall/fs.rs
+++ b/syscall/fs.rs
@@ -98,6 +98,24 @@ pub fn dup(fd: usize) -> Result<usize> {
     scheme.dup(file.number)
 }
 
+/// Get the canonical path of the file
+pub fn fpath(fd: usize, buf: &mut [u8]) -> Result<usize> {
+    let file = {
+        let contexts = context::contexts();
+        let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
+        let context = context_lock.read();
+        let file = context.get_file(fd).ok_or(Error::new(EBADF))?;
+        file
+    };
+
+    let scheme = {
+        let schemes = scheme::schemes();
+        let scheme = schemes.get(file.scheme).ok_or(Error::new(EBADF))?;
+        scheme.clone()
+    };
+    scheme.fpath(file.number, buf)
+}
+
 /// Get information about the file
 pub fn fstat(fd: usize, stat: &mut Stat) -> Result<usize> {
     let file = {
diff --git a/syscall/mod.rs b/syscall/mod.rs
index 4befeb782c28c9edfd8d36048c70c9ee350be79f..2c507ea4f219218cdbff8d2a9763333200cc1eb3 100644
--- a/syscall/mod.rs
+++ b/syscall/mod.rs
@@ -44,6 +44,7 @@ pub extern fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize
             SYS_CLONE => clone(b, stack),
             SYS_YIELD => sched_yield(),
             SYS_GETCWD => getcwd(validate_slice_mut(b as *mut u8, c)?),
+            SYS_FPATH => fpath(b, validate_slice_mut(c as *mut u8, d)?),
             SYS_PHYSMAP => physmap(b, c, d),
             SYS_PHYSUNMAP => physunmap(b),
             _ => {