diff --git a/kernel/libk/src/vfs/block/cache.rs b/kernel/libk/src/vfs/block/cache.rs
index 9392f60d..e7a54c65 100644
--- a/kernel/libk/src/vfs/block/cache.rs
+++ b/kernel/libk/src/vfs/block/cache.rs
@@ -4,7 +4,7 @@ use alloc::sync::Arc;
 use libk_mm::PageBox;
 use libk_util::{
     lru_hash_table::LruCache,
-    sync::spin_rwlock::{IrqSafeRwLock, IrqSafeRwLockReadGuard},
+    sync::spin_rwlock::{IrqSafeRwLock, IrqSafeRwLockReadGuard, IrqSafeRwLockWriteGuard},
 };
 use yggdrasil_abi::error::Error;
 
@@ -22,6 +22,11 @@ pub struct CachedBlockRef {
     lock: IrqSafeRwLockReadGuard<'static, CachedBlock>,
 }
 
+pub struct CachedBlockMut {
+    _entry: Arc<IrqSafeRwLock<CachedBlock>>,
+    lock: IrqSafeRwLockWriteGuard<'static, CachedBlock>,
+}
+
 pub struct BlockCache {
     device: &'static dyn BlockDevice,
     block_size: usize,
@@ -70,11 +75,20 @@ impl BlockCache {
         })))
     }
 
-    pub async fn get<'a>(&'a self, address: u64) -> Result<CachedBlockRef, Error> {
+    async fn entry<'a>(
+        &'a self,
+        address: u64,
+    ) -> Result<
+        MappedAsyncMutexGuard<
+            'a,
+            Arc<IrqSafeRwLock<CachedBlock>>,
+            LruCache<u64, Arc<IrqSafeRwLock<CachedBlock>>>,
+        >,
+        Error,
+    > {
         debug_assert_eq!(address % self.block_size as u64, 0);
 
-        let entry: MappedAsyncMutexGuard<_, LruCache<u64, Arc<IrqSafeRwLock<CachedBlock>>>> = self
-            .cache
+        self.cache
             .lock()
             .await
             .try_map_guard_async::<_, Error, _>(|cache: &'a mut LruCache<_, _>| async move {
@@ -88,9 +102,19 @@ impl BlockCache {
 
                 Ok(value)
             })
-            .await?;
+            .await
+    }
 
-        Ok(CachedBlockRef::new(entry.deref()))
+    pub async fn get<'a>(&'a self, address: u64) -> Result<CachedBlockRef, Error> {
+        self.entry(address)
+            .await
+            .map(|e| CachedBlockRef::new(e.deref()))
+    }
+
+    pub async fn get_mut<'a>(&'a self, address: u64) -> Result<CachedBlockMut, Error> {
+        self.entry(address)
+            .await
+            .map(|mut e| CachedBlockMut::new(e.deref_mut()))
     }
 
     pub async fn flush(&self) {
@@ -118,6 +142,18 @@ impl CachedBlockRef {
     }
 }
 
+impl CachedBlockMut {
+    pub fn new(entry: &Arc<IrqSafeRwLock<CachedBlock>>) -> Self {
+        let entry = entry.clone();
+        // Safety: ok, Arc instance is still held
+        let lock = unsafe { core::mem::transmute(entry.write()) };
+        Self {
+            lock,
+            _entry: entry,
+        }
+    }
+}
+
 impl Deref for CachedBlockRef {
     type Target = PageBox<[u8]>;
 
@@ -126,6 +162,20 @@ impl Deref for CachedBlockRef {
     }
 }
 
+impl Deref for CachedBlockMut {
+    type Target = PageBox<[u8]>;
+
+    fn deref(&self) -> &Self::Target {
+        self.lock.deref()
+    }
+}
+
+impl DerefMut for CachedBlockMut {
+    fn deref_mut(&mut self) -> &mut Self::Target {
+        self.lock.deref_mut()
+    }
+}
+
 impl Deref for CachedBlock {
     type Target = PageBox<[u8]>;