diff --git a/src/lib.rs b/src/lib.rs
index d2399984fcdae86bc40f97d3a5b9fd0d3f649d11..3c326fd5e4a1e39e9bbb49b6c7130c5e54a5fcfa 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -26,7 +26,7 @@ pub enum OpenResult {
 use core::mem::size_of;
 
 #[repr(transparent)]
-#[derive(Clone, Copy, Debug, Default)]
+#[derive(Debug, Default)]
 pub struct Request {
     sqe: Sqe,
 }
@@ -40,11 +40,13 @@ pub struct CancellationRequest {
 }
 
 #[repr(transparent)]
-#[derive(Clone, Copy, Debug)]
+#[derive(Debug)]
 pub struct CallRequest {
     inner: Request,
 }
 
+#[repr(transparent)]
+#[derive(Debug)]
 pub struct SendFdRequest {
     inner: Request,
 }
@@ -61,15 +63,15 @@ pub enum RequestKind {
 
 impl CallRequest {
     #[inline]
-    pub fn request(&self) -> Request {
-        self.inner
+    pub fn request(&self) -> &Request {
+        &self.inner
     }
 }
 
 impl SendFdRequest {
     #[inline]
-    pub fn request(&self) -> Request {
-        self.inner
+    pub fn request(&self) -> &Request {
+        &self.inner
     }
 
     pub fn id(&self) -> usize {
@@ -173,7 +175,8 @@ impl Socket {
     pub fn next_request(&self, behavior: SignalBehavior) -> Result<Option<Request>> {
         let mut buf = [Request::default()];
         Ok(if self.read_requests(&mut buf, behavior)? > 0 {
-            Some(buf[0])
+            let [req] = buf;
+            Some(req)
         } else {
             None
         })
@@ -203,7 +206,7 @@ impl Socket {
 pub struct Response(Cqe);
 
 impl Response {
-    pub fn new(req: &CallRequest, status: Result<usize>) -> Self {
+    pub fn new(req: CallRequest, status: Result<usize>) -> Self {
         Self(Cqe {
             flags: CqeOpcode::RespondRegular as u8,
             extra_raw: [0_u8; 3],
@@ -211,16 +214,16 @@ impl Response {
             tag: req.inner.sqe.tag,
         })
     }
-    pub fn open_dup_like(req: &CallRequest, res: Result<OpenResult>) -> Response {
+    pub fn open_dup_like(req: CallRequest, res: Result<OpenResult>) -> Response {
         match res {
             Ok(OpenResult::ThisScheme { number, flags }) => {
-                Response::new(&req, Ok(number)).with_extra([flags.bits(), 0, 0])
+                Response::new(req, Ok(number)).with_extra([flags.bits(), 0, 0])
             }
-            Err(e) => Response::new(&req, Err(e)),
-            Ok(OpenResult::OtherScheme { fd }) => Response::return_external_fd(&req, fd),
+            Err(e) => Response::new(req, Err(e)),
+            Ok(OpenResult::OtherScheme { fd }) => Response::return_external_fd(req, fd),
         }
     }
-    pub fn return_external_fd(req: &CallRequest, fd: usize) -> Self {
+    pub fn return_external_fd(req: CallRequest, fd: usize) -> Self {
         Self(Cqe {
             flags: CqeOpcode::RespondWithFd as u8,
             extra_raw: [0_u8; 3],
@@ -235,7 +238,7 @@ impl Response {
         })
     }
 
-    pub fn for_sendfd(req: &SendFdRequest, status: Result<usize>) -> Self {
+    pub fn for_sendfd(req: SendFdRequest, status: Result<usize>) -> Self {
         Self(Cqe {
             flags: CqeOpcode::RespondRegular as u8,
             extra_raw: [0_u8; 3],
diff --git a/src/scheme.rs b/src/scheme.rs
index b22c4513f684fea73e8abfdfc1bd70752829a166..b245f921976744a8f8152f29feec9413cb9d6525 100644
--- a/src/scheme.rs
+++ b/src/scheme.rs
@@ -112,6 +112,12 @@ pub enum Op<'a> {
 }
 
 impl<'a> Op<'a> {
+    /// Decode the raw SQE into an Op with borrowed buffers passed as slices.
+    ///
+    /// # Safety
+    ///
+    /// Any borrowed buffers will be unmapped whenever a response is sent, which unlike the
+    /// move-based CallRequest API, needs to be managed manually by the caller.
     pub unsafe fn from_sqe_unchecked(sqe: &'a Sqe) -> Option<Op<'a>> {
         let opcode = Opcode::try_from_raw(sqe.opcode)?;
         let args = sqe.args;
@@ -234,202 +240,180 @@ impl<'a> Op<'a> {
     }
 }
 impl CallRequest {
-    pub fn with<T>(self, f: impl FnOnce(Self, &CallerCtx, Op<'_>) -> T) -> Result<T, Response> {
+    pub fn caller(&self) -> CallerCtx {
         let sqe = &self.inner.sqe;
 
-        let caller = CallerCtx {
+        CallerCtx {
             pid: sqe.caller as usize,
             uid: sqe.args[5] as u32,
             gid: (sqe.args[5] >> 32) as u32,
-        };
-
-        let Some(op) = (unsafe { Op::from_sqe_unchecked(sqe) }) else {
-            return Err(Response::new(&self, Err(Error::new(ENOSYS))));
-        };
-
-        Ok(f(self, &caller, op))
+        }
+    }
+    pub fn op(&self) -> Option<Op<'_>> {
+        unsafe { Op::from_sqe_unchecked(&self.inner.sqe) }
     }
     pub async fn handle_async(self, s: &mut impl SchemeAsync) -> Result<Response> {
-        let sqe = &self.inner.sqe;
+        let caller = self.caller();
 
-        let caller = CallerCtx {
-            pid: sqe.caller as usize,
-            uid: sqe.args[5] as u32,
-            gid: (sqe.args[5] >> 32) as u32,
+        let Some(op) = self.op() else {
+            return Ok(Response::new(self, Err(Error::new(ENOSYS))));
         };
 
-        let Some(op) = (unsafe { Op::from_sqe_unchecked(sqe) }) else {
-            return Ok(Response::new(&self, Err(Error::new(ENOSYS))));
-        };
+        let res = match op {
+            Op::Open { path, flags } => {
+                let res = s.open(path, flags, &caller).await;
+                return Ok(Response::open_dup_like(self, res));
+            }
+            Op::Rmdir { path } => s.rmdir(path, &caller).await.map(|()| 0),
+            Op::Unlink { path } => s.unlink(path, &caller).await.map(|()| 0),
 
-        Ok(Response::new(
-            &self,
-            match op {
-                Op::Open { path, flags } => {
-                    return Ok(Response::open_dup_like(
-                        &self,
-                        s.open(path, flags, &caller).await,
-                    ))
-                }
-                Op::Rmdir { path } => s.rmdir(path, &caller).await.map(|()| 0),
-                Op::Unlink { path } => s.unlink(path, &caller).await.map(|()| 0),
-
-                Op::Dup { old_fd, buf } => {
-                    return Ok(Response::open_dup_like(
-                        &self,
-                        s.dup(old_fd, buf, &caller).await,
-                    ))
-                }
-                Op::Read {
-                    fd,
-                    buf,
-                    offset,
-                    flags,
-                } => s.read(fd, buf, offset, flags, &caller).await,
-                Op::Write {
-                    fd,
-                    buf,
-                    offset,
-                    flags,
-                } => s.write(fd, buf, offset, flags, &caller).await,
-
-                // TODO: Don't convert to usize
-                Op::Fsize { fd } => s.fsize(fd, &caller).await.map(|l| l as usize),
-
-                Op::Fchmod { fd, new_mode } => s.fchmod(fd, new_mode, &caller).await.map(|()| 0),
-                Op::Fchown {
-                    fd,
-                    new_uid,
-                    new_gid,
-                } => s.fchown(fd, new_uid, new_gid, &caller).await.map(|()| 0),
-                Op::Fcntl { fd, cmd, arg } => s.fcntl(fd, cmd, arg, &caller).await,
-                Op::Fevent { fd, req_flags } => {
-                    s.fevent(fd, req_flags, &caller).await.map(|f| f.bits())
-                }
-                Op::Fpath { fd, buf } => s.fpath(fd, buf, &caller).await,
-                Op::Frename { fd, new_path } => s.frename(fd, new_path, &caller).await,
-                Op::Fstat { fd, stat } => s.fstat(fd, stat, &caller).await.map(|()| 0),
-                Op::FstatVfs { fd, stat } => s.fstatvfs(fd, stat, &caller).await.map(|()| 0),
-                Op::Fsync { fd } => s.fsync(fd, &caller).await.map(|()| 0),
-                Op::Ftruncate { fd, new_sz } => s.ftruncate(fd, new_sz, &caller).await.map(|()| 0),
-                Op::Futimens { fd, times } => s.futimens(fd, times, &caller).await.map(|()| 0),
-
-                Op::MmapPrep {
-                    fd,
-                    offset,
-                    len,
-                    flags,
-                } => s.mmap_prep(fd, offset, len, flags, &caller).await,
-                Op::Munmap {
-                    fd,
-                    offset,
-                    len,
-                    flags,
-                } => s.munmap(fd, offset, len, flags, &caller).await.map(|()| 0),
-
-                Op::Call {
-                    fd,
-                    payload,
-                    metadata,
-                } => s.call(fd, payload, metadata).await,
-
-                Op::Getdents {
-                    fd,
-                    buf,
-                    opaque_offset,
-                } => {
-                    let buf = s.getdents(fd, buf, opaque_offset).await?;
-                    Ok(buf.finalize())
-                }
-            },
-        ))
+            Op::Dup { old_fd, buf } => {
+                let res = s.dup(old_fd, buf, &caller).await;
+                return Ok(Response::open_dup_like(self, res));
+            }
+            Op::Read {
+                fd,
+                buf,
+                offset,
+                flags,
+            } => s.read(fd, buf, offset, flags, &caller).await,
+            Op::Write {
+                fd,
+                buf,
+                offset,
+                flags,
+            } => s.write(fd, buf, offset, flags, &caller).await,
+
+            // TODO: Don't convert to usize
+            Op::Fsize { fd } => s.fsize(fd, &caller).await.map(|l| l as usize),
+
+            Op::Fchmod { fd, new_mode } => s.fchmod(fd, new_mode, &caller).await.map(|()| 0),
+            Op::Fchown {
+                fd,
+                new_uid,
+                new_gid,
+            } => s.fchown(fd, new_uid, new_gid, &caller).await.map(|()| 0),
+            Op::Fcntl { fd, cmd, arg } => s.fcntl(fd, cmd, arg, &caller).await,
+            Op::Fevent { fd, req_flags } => {
+                s.fevent(fd, req_flags, &caller).await.map(|f| f.bits())
+            }
+            Op::Fpath { fd, buf } => s.fpath(fd, buf, &caller).await,
+            Op::Frename { fd, new_path } => s.frename(fd, new_path, &caller).await,
+            Op::Fstat { fd, stat } => s.fstat(fd, stat, &caller).await.map(|()| 0),
+            Op::FstatVfs { fd, stat } => s.fstatvfs(fd, stat, &caller).await.map(|()| 0),
+            Op::Fsync { fd } => s.fsync(fd, &caller).await.map(|()| 0),
+            Op::Ftruncate { fd, new_sz } => s.ftruncate(fd, new_sz, &caller).await.map(|()| 0),
+            Op::Futimens { fd, times } => s.futimens(fd, times, &caller).await.map(|()| 0),
+
+            Op::MmapPrep {
+                fd,
+                offset,
+                len,
+                flags,
+            } => s.mmap_prep(fd, offset, len, flags, &caller).await,
+            Op::Munmap {
+                fd,
+                offset,
+                len,
+                flags,
+            } => s.munmap(fd, offset, len, flags, &caller).await.map(|()| 0),
+
+            Op::Call {
+                fd,
+                payload,
+                metadata,
+            } => s.call(fd, payload, metadata).await,
+
+            Op::Getdents {
+                fd,
+                buf,
+                opaque_offset,
+            } => {
+                let buf = s.getdents(fd, buf, opaque_offset).await?;
+                Ok(buf.finalize())
+            }
+        };
+        Ok(Response::new(self, res))
     }
     // TODO: Fix function coloring
     pub fn handle_sync(self, s: &mut impl SchemeSync) -> Result<Response> {
-        let sqe = &self.inner.sqe;
-
-        let caller = CallerCtx {
-            pid: sqe.caller as usize,
-            uid: sqe.args[5] as u32,
-            gid: (sqe.args[5] >> 32) as u32,
-        };
-
-        let Some(op) = (unsafe { Op::from_sqe_unchecked(sqe) }) else {
-            return Ok(Response::new(&self, Err(Error::new(ENOSYS))));
+        let caller = self.caller();
+        let Some(op) = self.op() else {
+            return Ok(Response::new(self, Err(Error::new(ENOSYS))));
         };
 
-        Ok(Response::new(
-            &self,
-            match op {
-                Op::Open { path, flags } => {
-                    return Ok(Response::open_dup_like(&self, s.open(path, flags, &caller)))
-                }
-                Op::Rmdir { path } => s.rmdir(path, &caller).map(|()| 0),
-                Op::Unlink { path } => s.unlink(path, &caller).map(|()| 0),
+        let res = match op {
+            Op::Open { path, flags } => {
+                let res = s.open(path, flags, &caller);
+                return Ok(Response::open_dup_like(self, res));
+            }
+            Op::Rmdir { path } => s.rmdir(path, &caller).map(|()| 0),
+            Op::Unlink { path } => s.unlink(path, &caller).map(|()| 0),
 
-                Op::Dup { old_fd, buf } => {
-                    return Ok(Response::open_dup_like(&self, s.dup(old_fd, buf, &caller)))
-                }
-                Op::Read {
-                    fd,
-                    buf,
-                    offset,
-                    flags,
-                } => s.read(fd, buf, offset, flags, &caller),
-                Op::Write {
-                    fd,
-                    buf,
-                    offset,
-                    flags,
-                } => s.write(fd, buf, offset, flags, &caller),
-
-                // TODO: Don't convert to usize
-                Op::Fsize { fd } => s.fsize(fd, &caller).map(|l| l as usize),
-
-                Op::Fchmod { fd, new_mode } => s.fchmod(fd, new_mode, &caller).map(|()| 0),
-                Op::Fchown {
-                    fd,
-                    new_uid,
-                    new_gid,
-                } => s.fchown(fd, new_uid, new_gid, &caller).map(|()| 0),
-                Op::Fcntl { fd, cmd, arg } => s.fcntl(fd, cmd, arg, &caller),
-                Op::Fevent { fd, req_flags } => s.fevent(fd, req_flags, &caller).map(|f| f.bits()),
-                Op::Fpath { fd, buf } => s.fpath(fd, buf, &caller),
-                Op::Frename { fd, new_path } => s.frename(fd, new_path, &caller),
-                Op::Fstat { fd, stat } => s.fstat(fd, stat, &caller).map(|()| 0),
-                Op::FstatVfs { fd, stat } => s.fstatvfs(fd, stat, &caller).map(|()| 0),
-                Op::Fsync { fd } => s.fsync(fd, &caller).map(|()| 0),
-                Op::Ftruncate { fd, new_sz } => s.ftruncate(fd, new_sz, &caller).map(|()| 0),
-                Op::Futimens { fd, times } => s.futimens(fd, times, &caller).map(|()| 0),
-
-                Op::MmapPrep {
-                    fd,
-                    offset,
-                    len,
-                    flags,
-                } => s.mmap_prep(fd, offset, len, flags, &caller),
-                Op::Munmap {
-                    fd,
-                    offset,
-                    len,
-                    flags,
-                } => s.munmap(fd, offset, len, flags, &caller).map(|()| 0),
-                Op::Call {
-                    fd,
-                    payload,
-                    metadata,
-                } => s.call(fd, payload, metadata),
-
-                Op::Getdents {
-                    fd,
-                    buf,
-                    opaque_offset,
-                } => {
-                    let buf = s.getdents(fd, buf, opaque_offset)?;
-                    Ok(buf.finalize())
-                }
-            },
-        ))
+            Op::Dup { old_fd, buf } => {
+                let res = s.dup(old_fd, buf, &caller);
+                return Ok(Response::open_dup_like(self, res));
+            }
+            Op::Read {
+                fd,
+                buf,
+                offset,
+                flags,
+            } => s.read(fd, buf, offset, flags, &caller),
+            Op::Write {
+                fd,
+                buf,
+                offset,
+                flags,
+            } => s.write(fd, buf, offset, flags, &caller),
+
+            // TODO: Don't convert to usize
+            Op::Fsize { fd } => s.fsize(fd, &caller).map(|l| l as usize),
+
+            Op::Fchmod { fd, new_mode } => s.fchmod(fd, new_mode, &caller).map(|()| 0),
+            Op::Fchown {
+                fd,
+                new_uid,
+                new_gid,
+            } => s.fchown(fd, new_uid, new_gid, &caller).map(|()| 0),
+            Op::Fcntl { fd, cmd, arg } => s.fcntl(fd, cmd, arg, &caller),
+            Op::Fevent { fd, req_flags } => s.fevent(fd, req_flags, &caller).map(|f| f.bits()),
+            Op::Fpath { fd, buf } => s.fpath(fd, buf, &caller),
+            Op::Frename { fd, new_path } => s.frename(fd, new_path, &caller),
+            Op::Fstat { fd, stat } => s.fstat(fd, stat, &caller).map(|()| 0),
+            Op::FstatVfs { fd, stat } => s.fstatvfs(fd, stat, &caller).map(|()| 0),
+            Op::Fsync { fd } => s.fsync(fd, &caller).map(|()| 0),
+            Op::Ftruncate { fd, new_sz } => s.ftruncate(fd, new_sz, &caller).map(|()| 0),
+            Op::Futimens { fd, times } => s.futimens(fd, times, &caller).map(|()| 0),
+
+            Op::MmapPrep {
+                fd,
+                offset,
+                len,
+                flags,
+            } => s.mmap_prep(fd, offset, len, flags, &caller),
+            Op::Munmap {
+                fd,
+                offset,
+                len,
+                flags,
+            } => s.munmap(fd, offset, len, flags, &caller).map(|()| 0),
+            Op::Call {
+                fd,
+                payload,
+                metadata,
+            } => s.call(fd, payload, metadata),
+
+            Op::Getdents {
+                fd,
+                buf,
+                opaque_offset,
+            } => {
+                let buf = s.getdents(fd, buf, opaque_offset)?;
+                Ok(buf.finalize())
+            }
+        };
+        Ok(Response::new(self, res))
     }
 }