diff --git a/src/scheme/live.rs b/src/scheme/live.rs
index acf14a03fef808698dd7abdfb6e9a9e6f8ca934c..375b7ca218fa97b1df4997c352d7b1bb76780225 100644
--- a/src/scheme/live.rs
+++ b/src/scheme/live.rs
@@ -8,18 +8,21 @@ use spin::RwLock;
 use rmm::Flusher;
 
 use syscall::data::Stat;
-use syscall::error::*;
+use syscall::{error::*, CallerCtx};
 use syscall::flag::{MODE_DIR, MODE_FILE};
 use syscall::scheme::{calc_seek_offset_usize, Scheme};
 
 use crate::memory::Frame;
 use crate::paging::{KernelMapper, Page, PageFlags, PhysicalAddress, VirtualAddress};
 use crate::paging::mapper::PageFlushAll;
+use crate::syscall::usercopy::{UserSliceWo, UserSliceRo};
+
+use super::OpenResult;
 
 static mut LIST: [u8; 2] = [b'0', b'\n'];
 
 struct Handle {
-    path: &'static [u8],
+    path: &'static str,
     data: Arc<RwLock<&'static mut [u8]>>,
     mode: u16,
     seek: usize
@@ -85,123 +88,109 @@ impl DiskScheme {
 }
 
 impl Scheme for DiskScheme {
-    fn open(&self, path: &str, _flags: usize, _uid: u32, _gid: u32) -> Result<usize> {
+    fn seek(&self, id: usize, pos: isize, whence: usize) -> Result<isize> {
+        let mut handles = self.handles.write();
+        let handle = handles.get_mut(&id).ok_or(Error::new(EBADF))?;
+        let data = handle.data.read();
+        let new_offset = calc_seek_offset_usize(handle.seek, pos, whence, data.len())?;
+        handle.seek = new_offset as usize;
+        Ok(new_offset)
+    }
+
+    fn fcntl(&self, id: usize, _cmd: usize, _arg: usize) -> Result<usize> {
+        let handles = self.handles.read();
+        let _handle = handles.get(&id).ok_or(Error::new(EBADF))?;
+
+        Ok(0)
+    }
+
+    fn fsync(&self, id: usize) -> Result<usize> {
+        let handles = self.handles.read();
+        let _handle = handles.get(&id).ok_or(Error::new(EBADF))?;
+
+        Ok(0)
+    }
+
+    fn close(&self, id: usize) -> Result<usize> {
+        self.handles.write().remove(&id).ok_or(Error::new(EBADF)).and(Ok(0))
+    }
+}
+impl crate::scheme::KernelScheme for DiskScheme {
+    fn kopen(&self, path: &str, _flags: usize, _caller: CallerCtx) -> Result<OpenResult> {
         let path_trimmed = path.trim_matches('/');
         match path_trimmed {
             "" => {
                 let id = self.next_id.fetch_add(1, Ordering::SeqCst);
                 self.handles.write().insert(id, Handle {
-                    path: b"",
+                    path: "",
                     data: self.list.clone(),
                     mode: MODE_DIR | 0o755,
                     seek: 0
                 });
-                Ok(id)
+                Ok(OpenResult::SchemeLocal(id))
             },
             "0" => {
                 let id = self.next_id.fetch_add(1, Ordering::SeqCst);
                 self.handles.write().insert(id, Handle {
-                    path: b"0",
+                    path: "0",
                     data: self.data.clone(),
                     mode: MODE_FILE | 0o644,
                     seek: 0
                 });
-                Ok(id)
+                Ok(OpenResult::SchemeLocal(id))
             }
             _ => Err(Error::new(ENOENT))
         }
     }
-
-    fn read(&self, id: usize, buffer: &mut [u8]) -> Result<usize> {
+    fn kread(&self, id: usize, buffer: UserSliceWo) -> Result<usize> {
         let mut handles = self.handles.write();
         let handle = handles.get_mut(&id).ok_or(Error::new(EBADF))?;
         let data = handle.data.read();
 
-        let mut i = 0;
-        while i < buffer.len() && handle.seek < data.len() {
-            buffer[i] = data[handle.seek];
-            i += 1;
-            handle.seek += 1;
-        }
+        let src = data.get(handle.seek..).unwrap_or(&[]);
+        let bytes_read = buffer.copy_common_bytes_from_slice(src)?;
+        handle.seek += bytes_read;
 
-        Ok(i)
+        Ok(bytes_read)
     }
 
-    fn write(&self, id: usize, buffer: &[u8]) -> Result<usize> {
+    fn kwrite(&self, id: usize, buffer: UserSliceRo) -> Result<usize> {
         let mut handles = self.handles.write();
         let handle = handles.get_mut(&id).ok_or(Error::new(EBADF))?;
         let mut data = handle.data.write();
 
-        let mut i = 0;
-        while i < buffer.len() && handle.seek < data.len() {
-            data[handle.seek] = buffer[i];
-            i += 1;
-            handle.seek += 1;
-        }
+        let dst = data.get_mut(handle.seek..).unwrap_or(&mut []);
+        let bytes_written = buffer.copy_common_bytes_to_slice(dst)?;
+        handle.seek += bytes_written;
 
-        Ok(i)
+        Ok(bytes_written)
     }
-
-    fn seek(&self, id: usize, pos: isize, whence: usize) -> Result<isize> {
-        let mut handles = self.handles.write();
-        let handle = handles.get_mut(&id).ok_or(Error::new(EBADF))?;
-        let data = handle.data.read();
-        let new_offset = calc_seek_offset_usize(handle.seek, pos, whence, data.len())?;
-        handle.seek = new_offset as usize;
-        Ok(new_offset)
-    }
-
-    fn fcntl(&self, id: usize, _cmd: usize, _arg: usize) -> Result<usize> {
-        let handles = self.handles.read();
-        let _handle = handles.get(&id).ok_or(Error::new(EBADF))?;
-
-        Ok(0)
-    }
-
-    fn fpath(&self, id: usize, buf: &mut [u8]) -> Result<usize> {
+    fn kfpath(&self, id: usize, buf: UserSliceWo) -> 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"disk/live:";
-        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;
-        }
+        let src = format!("disk/live:{}", handle.path);
+        let byte_count = buf.copy_common_bytes_from_slice(src.as_bytes())?;
 
-        Ok(i)
+        Ok(byte_count)
     }
-
-    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))?;
-        let data = handle.data.read();
-
-        stat.st_mode = handle.mode;
-        stat.st_uid = 0;
-        stat.st_gid = 0;
-        stat.st_size = data.len() as u64;
-
-        Ok(0)
-    }
-
-    fn fsync(&self, id: usize) -> Result<usize> {
-        let handles = self.handles.read();
-        let _handle = handles.get(&id).ok_or(Error::new(EBADF))?;
+    fn kfstat(&self, id: usize, stat_buf: UserSliceWo) -> Result<usize> {
+        let stat = {
+            let handles = self.handles.read();
+            let handle = handles.get(&id).ok_or(Error::new(EBADF))?;
+            let data = handle.data.read();
+
+            Stat {
+                st_mode: handle.mode,
+                st_uid: 0,
+                st_gid: 0,
+                st_size: data.len() as u64,
+                ..Stat::default()
+            }
+        };
+        stat_buf.copy_exactly(&stat)?;
 
         Ok(0)
     }
 
-    fn close(&self, id: usize) -> Result<usize> {
-        self.handles.write().remove(&id).ok_or(Error::new(EBADF)).and(Ok(0))
-    }
 }
-impl crate::scheme::KernelScheme for DiskScheme {}