This is an automated email from the ASF dual-hosted git repository.

xuanwo pushed a commit to branch remove-virtiofs
in repository https://gitbox.apache.org/repos/asf/opendal.git

commit f95aaabfe9502032fb9f02445d578791a5abba4d
Author: Xuanwo <[email protected]>
AuthorDate: Thu Oct 16 21:03:01 2025 +0800

    refactor: Remove deprecated project virtiofs
    
    Signed-off-by: Xuanwo <[email protected]>
---
 .github/workflows/ci_integration_virtiofs.yml   |  51 --
 .github/workflows/docs.yml                      |  30 -
 README.md                                       |   8 -
 integrations/virtiofs/.gitignore                |   1 -
 integrations/virtiofs/Cargo.toml                |  46 --
 integrations/virtiofs/DEPENDENCIES.rust.tsv     | 200 -------
 integrations/virtiofs/README.md                 |  15 -
 integrations/virtiofs/src/buffer.rs             | 117 ----
 integrations/virtiofs/src/error.rs              |  94 ----
 integrations/virtiofs/src/filesystem.rs         | 699 ------------------------
 integrations/virtiofs/src/filesystem_message.rs | 288 ----------
 integrations/virtiofs/src/lib.rs                |  25 -
 integrations/virtiofs/src/virtiofs.rs           | 329 -----------
 integrations/virtiofs/src/virtiofs_util.rs      | 492 -----------------
 website/docs/30-integrations/virtiofs.mdx       |  10 -
 15 files changed, 2405 deletions(-)

diff --git a/.github/workflows/ci_integration_virtiofs.yml 
b/.github/workflows/ci_integration_virtiofs.yml
deleted file mode 100644
index 5bd736e0e..000000000
--- a/.github/workflows/ci_integration_virtiofs.yml
+++ /dev/null
@@ -1,51 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-name: Integration Virtiofs CI
-
-on:
-  push:
-    branches:
-      - main
-  pull_request:
-    branches:
-      - main
-    paths:
-      - "integrations/virtiofs/**"
-      - "core/**"
-      - ".github/workflows/ci_integration_virtiofs.yml"
-
-concurrency:
-  group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}
-  cancel-in-progress: true
-
-jobs:
-  check_clippy:
-    runs-on: ubuntu-latest
-    steps:
-      - uses: actions/checkout@v5
-
-      - name: Setup Rust toolchain
-        uses: ./.github/actions/setup
-        with:
-          need-rocksdb: true
-          need-protoc: true
-          github-token: ${{ secrets.GITHUB_TOKEN }}
-
-      - name: Cargo clippy
-        working-directory: integrations/virtiofs
-        run: cargo clippy --all-targets --all-features -- -D warnings
diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml
index c53b013ae..6509dbaed 100644
--- a/.github/workflows/docs.yml
+++ b/.github/workflows/docs.yml
@@ -446,29 +446,6 @@ jobs:
           name: unftp-sbe-opendal-docs
           path: ./integrations/unftp-sbe/target/doc
 
-  build-virtiofs-opendal-doc:
-    runs-on: ubuntu-latest
-
-    steps:
-      - uses: actions/checkout@v5
-
-      - name: Setup Rust toolchain
-        uses: ./.github/actions/setup
-
-      - name: Setup Rust Nightly
-        run: |
-          rustup toolchain install ${{ env.RUST_DOC_TOOLCHAIN }}
-
-      - name: Build virtiofs-opendal doc
-        working-directory: "integrations/virtiofs"
-        run: cargo +${{ env.RUST_DOC_TOOLCHAIN }} doc --lib --no-deps 
--all-features
-
-      - name: Upload docs
-        uses: actions/upload-artifact@v4
-        with:
-          name: virtiofs-opendal-docs
-          path: ./integrations/virtiofs/target/doc
-
   build-parquet-opendal-doc:
     runs-on: ubuntu-latest
 
@@ -511,7 +488,6 @@ jobs:
       - build-dav-server-opendalfs-doc
       - build-fuse3-opendal-doc
       - build-unftp-sbe-opendal-doc
-      - build-virtiofs-opendal-doc
       - build-parquet-opendal-doc
 
     steps:
@@ -618,12 +594,6 @@ jobs:
           name: unftp-sbe-opendal-docs
           path: ./website/static/docs/unftp-sbe-opendal
 
-      - name: Download virtiofs-opendal docs
-        uses: actions/download-artifact@v5
-        with:
-          name: virtiofs-opendal-docs
-          path: ./website/static/docs/virtiofs-opendal
-
       - name: Install Dependencies
         working-directory: website
         run: pnpm install --frozen-lockfile
diff --git a/README.md b/README.md
index 784c84ffb..d43c5afaa 100644
--- a/README.md
+++ b/README.md
@@ -105,7 +105,6 @@ OpenDAL's development is guided by its vision of **One 
Layer, All Storage** and
 | [dav-server-opendalfs] | a [dav-server-rs] implementation using opendal.     
                          | [![dav-server image]][dav-server crate]     | 
[![Docs Release]][dav-server release docs] [![Docs Dev]][dav-server dev docs]   
  |
 | [object_store_opendal] | an [object_store] implementation using opendal.     
                          | [![object_store image]][object_store crate] | 
[![Docs Release]][object_store release docs] [![Docs Dev]][object_store dev 
docs] |
 | [fuse3_opendal]        | Access data via integrations to [fuse3]             
                          | [![fuse3 image]][fuse3 crate]               | 
[![Docs Release]][fuse3 release docs] [![Docs Dev]][fuse3 dev docs]             
  |
-| [virtiofs_opendal]     | Access data via integrations to 
[vhost-user-backend]                          | [![virtiofs image]][virtiofs 
crate]         | [![Docs Release]][virtiofs release docs] [![Docs 
Dev]][virtiofs dev docs]         |
 | [unftp-sbe-opendal]    | an [unftp] storage backend implementation using 
opendal.                      | [![unftp-sbe image]][unftp-sbe crate]       | 
[![Docs Release]][unftp-sbe release docs] [![Docs Dev]][unftp-sbe dev docs]     
  |
 | [parquet_opendal]      | Provides 
[`parquet`](https://crates.io/crates/parquet) efficient IO utilities | 
[![parquet image]][parquet crate]           | [![Docs Release]][parquet release 
docs] [![Docs Dev]][parquet dev docs]           |
 
@@ -130,13 +129,6 @@ OpenDAL's development is guided by its vision of **One 
Layer, All Storage** and
 [fuse3 release docs]: https://docs.rs/fuse3_opendal/
 [fuse3 dev docs]: https://opendal.apache.org/docs/fuse3-opendal/fuse3_opendal/
 
-[virtiofs_opendal]: integrations/virtiofs/README.md
-[vhost-user-backend]: https://docs.rs/vhost-user-backend
-[virtiofs image]: https://img.shields.io/crates/v/virtiofs_opendal.svg
-[virtiofs crate]: https://crates.io/crates/virtiofs_opendal
-[virtiofs release docs]: https://docs.rs/virtiofs_opendal/
-[virtiofs dev docs]: 
https://opendal.apache.org/docs/virtiofs-opendal/virtiofs_opendal/
-
 [unftp-sbe-opendal]: integrations/unftp-sbe/README.md
 [unftp]: https://crates.io/crates/unftp
 [unftp-sbe image]: https://img.shields.io/crates/v/unftp-sbe-opendal.svg
diff --git a/integrations/virtiofs/.gitignore b/integrations/virtiofs/.gitignore
deleted file mode 100644
index 03314f77b..000000000
--- a/integrations/virtiofs/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-Cargo.lock
diff --git a/integrations/virtiofs/Cargo.toml b/integrations/virtiofs/Cargo.toml
deleted file mode 100644
index a98c883e1..000000000
--- a/integrations/virtiofs/Cargo.toml
+++ /dev/null
@@ -1,46 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-[package]
-description = "virtiofs integration for Apache OpenDAL"
-name = "virtiofs_opendal"
-
-authors = ["Apache OpenDAL <[email protected]>"]
-edition = "2024"
-homepage = "https://opendal.apache.org/";
-license = "Apache-2.0"
-repository = "https://github.com/apache/opendal";
-rust-version = "1.85"
-version = "0.0.0"
-
-[dependencies]
-anyhow = { version = "1.0.86", features = ["std"] }
-libc = "0.2.139"
-log = "0.4.22"
-opendal = { version = "0.54.0", path = "../../core" }
-sharded-slab = "0.1.7"
-snafu = "0.8.4"
-tokio = { version = "1.39.2", features = ["rt-multi-thread"] }
-vhost = "0.10.0"
-vhost-user-backend = "0.13.1"
-virtio-bindings = { version = "0.2.1", features = ["virtio-v5_0_0"] }
-virtio-queue = "0.11.0"
-vm-memory = { version = "0.14.0", features = [
-  "backend-mmap",
-  "backend-atomic",
-] }
-vmm-sys-util = "0.12.1"
diff --git a/integrations/virtiofs/DEPENDENCIES.rust.tsv 
b/integrations/virtiofs/DEPENDENCIES.rust.tsv
deleted file mode 100644
index 14f8c26f0..000000000
--- a/integrations/virtiofs/DEPENDENCIES.rust.tsv
+++ /dev/null
@@ -1,200 +0,0 @@
-crate  0BSD    Apache-2.0      Apache-2.0 WITH LLVM-exception  BSD-3-Clause    
BSL-1.0 CDLA-Permissive-2.0     ISC     LGPL-2.1-or-later       MIT     
Unicode-3.0     Unlicense       Zlib
[email protected]               X                                               
        X                       
[email protected]   X       X                                                       
X                       
[email protected]           X                                               
        X                       
[email protected]                X                               
                        X                       
[email protected]          X                                                       
X                       
[email protected]         X                                                       
X                       
[email protected]          X                                                       
X                       
[email protected]           X                                                       
                        
[email protected]               X                                               
        X                       
[email protected]          X                                                       
X                       
[email protected]                         X                                       
                        
[email protected]         X                                                       
X                       
[email protected]         X                                                       
X                       
[email protected]            X                                               
        X                       
[email protected]         X                                                       
X                       
[email protected]                                                                   
X                       
[email protected]              X                                                       
X                       
[email protected]            X                                                       
X                       
[email protected]           X                                                       
X                       
[email protected]          X                                                       
X                       
[email protected]                X                                               
                                
[email protected]              X                                       
                X                       
[email protected]            X                                               
        X                       
[email protected]          X                                                       
X                       
[email protected]               X                                               
        X                       
[email protected]          X                                                       
X                       
[email protected]         X                                                       
X                       
[email protected]              X                                                       
X                       
[email protected]          X                                               
        X                       
[email protected]         X                                                       
X                       
[email protected]         X                                               
        X                       
[email protected]            X                                               
        X                       
[email protected]              X                                               
        X                       
[email protected]           X                                               
        X                       
[email protected]            X                                               
        X                       
[email protected]            X                                               
        X                       
[email protected]            X                                               
        X                       
[email protected]                                                           
        X                       
[email protected]               X                                               
        X                       
[email protected]                X                                               
        X                       
[email protected]           X                                                       
X                       
[email protected]             X                                                       
X                       
[email protected]              X                                               
        X                       
[email protected]             X                                                       
X                       
[email protected]             X                                                       
X                       
[email protected]                                                                
        X                       
[email protected]                                                           
        X                       
[email protected]                X                                               
        X                       
[email protected]                                                                    
X                       
[email protected]            X                                       X       
        X                       
[email protected]                                                              
        X                       
[email protected]          X                                               
        X                       
[email protected]             X                                       
                X                       
[email protected]                                                          
                X               
[email protected]                                                          
                X               
[email protected]                                                           
                X               
[email protected]                                                      
                        X               
[email protected]                                                           
                X               
[email protected]                                                      
                        X               
[email protected]                                                             
                X               
[email protected]             X                                                       
X                       
[email protected]             X                                               
        X                       
[email protected]         X                                                       
X                       
[email protected]           X                                                       
X                       
[email protected]               X                                               
        X                       
[email protected]               X                                               
        X                       
[email protected]            X                                                       
X                       
[email protected]          X                                                       
X                       
[email protected]              X                                               
        X                       
[email protected]           X                                                       
X                       
[email protected]                                                       X       
                                
[email protected]                                                                  
        X               
[email protected]             X                                                       
X                       
[email protected]            X                                                       
X                       
[email protected]                                                                   
X               X       
[email protected]          X                                               
        X                       
[email protected]              X                                               
        X                       X
[email protected]                                                                      
X                       
[email protected]                                                                      
X                       
[email protected]              X                                               
        X                       
[email protected]          X                                                       
X                       
[email protected]               X                                               
        X                       
[email protected]         X                                                       
                        
[email protected]         X                                               
        X                       
[email protected]                X                                       
                X                       
[email protected]                X                                               
        X                       
[email protected]                                                            
                X               
[email protected]            X                                               
        X                       
[email protected]             X                                               
        X                       
[email protected]                                                               
        X                       
[email protected]           X                                                       
X                       
[email protected]            X                                               X       
X                       
[email protected]           X                                                       
X                       
[email protected]           X                                               
        X                       
[email protected]             X                                               
        X                       
[email protected]                X                                               
        X                       
[email protected]           X                                       X               
                        
[email protected]          X                                               
        X                       
[email protected]               X                                               
        X                       
[email protected]         X                                       X               
X                       
[email protected]                X                                       
                X                       
[email protected]                                                  X       
                                
[email protected]             X                                               
        X                       
[email protected]             X                       X                               
                        
[email protected]          X                                                       
X                       
[email protected]           X                                               
        X                       
[email protected]             X                                               
        X                       
[email protected]         X                                               
        X                       
[email protected]                                                             
        X                       
[email protected]            X                                                       
X                       
[email protected]                                                                    
X                       
[email protected]                X                                               
        X                       
[email protected]            X                                                       
X                       
[email protected]             X                                               
        X                       
[email protected]         X                                                       
X                       
[email protected]          X                                                       
X                       
[email protected]               X                                       
                X                       
[email protected]                           X                                       
                        
[email protected]            X                                                       
X                       
[email protected]             X                                               
                                
[email protected]                                                            
        X                       
[email protected]               X                                               
        X                       
[email protected]          X                                               
        X                       
[email protected]                                                                  
        X               
[email protected]                                                                   
X                       
[email protected]            X                                               
        X                       
[email protected]                                                              
        X                       
[email protected]                                                                    
X                       
[email protected]                                                               
        X                       
[email protected]                                                              
        X                       
[email protected]                                                            
        X                       
[email protected]                                                                 
X                       
[email protected]                                                            
        X                       
[email protected]                                                                 
X                       
[email protected]         X                                                       
X                       
[email protected]           X                                               
        X       X               
[email protected]                                                        X       
                                
[email protected]              X                                                       
X                       
[email protected]                X                                               
        X                       
[email protected]            X                                                       
X                       
[email protected]            X                                               
        X                       
[email protected]           X               X                                       
                        
[email protected]              X                                       
                                        
[email protected]          X               X                               
                                
[email protected]            X               X                               
                                
[email protected]         X                                               
                                
[email protected]               X               X                               
                                
[email protected]                            X                               
                                
[email protected]                                                                     
X                       
[email protected]+wasi-snapshot-preview1             X       X                       
                        X                       
[email protected]+wasi-0.2.4         X       X                                       
        X                       
[email protected]           X                                               
        X                       
[email protected]           X                                       
                X                       
[email protected]            X                                       
                X                       
[email protected]             X                                       
                X                       
[email protected]             X                               
                        X                       
[email protected]            X                                       
                X                       
[email protected]             X                                               
        X                       
[email protected]         X                                                       
X                       
[email protected]                                             X               
                                
[email protected]           X                                                       
X                       
[email protected]               X                               
                        X                       
[email protected]             X                               
                        X                       
[email protected]            X                                               
        X                       
[email protected]               X                                       
                X                       
[email protected]               X                                       
                X                       
[email protected]             X                                               
        X                       
[email protected]           X                                               
        X                       
[email protected]          X                                               
        X                       
[email protected]             X                                               
        X                       
[email protected]             X                                               
        X                       
[email protected]         X                                               
        X                       
[email protected]         X                                               
        X                       
[email protected]         X                                       
                X                       
[email protected]         X                                       
                X                       
[email protected]            X                                       
                X                       
[email protected]            X                                       
                X                       
[email protected]                X                                       
                X                       
[email protected]                X                                       
                X                       
[email protected]            X                                       
                X                       
[email protected]            X                                       
                X                       
[email protected]               X                                       
                X                       
[email protected]               X                                       
                X                       
[email protected]              X                                       
                X                       
[email protected]              X                                       
                X                       
[email protected]          X                                       
                X                       
[email protected]          X                                       
                X                       
[email protected]             X                                       
                X                       
[email protected]             X                                       
                X                       
[email protected]          X       X                                       
        X                       
[email protected]                                                                
                X               
[email protected]                                                                     
        X               
[email protected]                                                              
                X               
[email protected]                                                                 
        X               
[email protected]                                                          
                X               
[email protected]          X                                                       
X                       
[email protected]                                                                 
        X               
[email protected]                                                                 
        X               
[email protected]                                                          
                X               
diff --git a/integrations/virtiofs/README.md b/integrations/virtiofs/README.md
deleted file mode 100644
index 23a1f844b..000000000
--- a/integrations/virtiofs/README.md
+++ /dev/null
@@ -1,15 +0,0 @@
-# Apache OpenDALâ„¢ VirtioFS Integration
-
-`virtiofs_opendal` is an integration which uses OpenDAL as a backend to access 
data in various services with VirtioFS protocol.
-
-## Branding
-
-The first and most prominent mentions must use the full form: **Apache 
OpenDALâ„¢** of the name for any individual usage (webpage, handout, slides, 
etc.) Depending on the context and writing style, you should use the full form 
of the name sufficiently often to ensure that readers clearly understand the 
association of both the OpenDAL project and the OpenDAL software product to the 
ASF as the parent organization.
-
-For more details, see the [Apache Product Name Usage 
Guide](https://www.apache.org/foundation/marks/guide).
-
-## License and Trademarks
-
-Licensed under the Apache License, Version 2.0: 
http://www.apache.org/licenses/LICENSE-2.0
-
-Apache OpenDAL, OpenDAL, and Apache are either registered trademarks or 
trademarks of the Apache Software Foundation.
diff --git a/integrations/virtiofs/src/buffer.rs 
b/integrations/virtiofs/src/buffer.rs
deleted file mode 100644
index 9b2d1aa65..000000000
--- a/integrations/virtiofs/src/buffer.rs
+++ /dev/null
@@ -1,117 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-use std::cell::RefCell;
-use std::cmp::min;
-use std::ptr;
-
-use vm_memory::VolatileSlice;
-use vm_memory::bitmap::BitmapSlice;
-
-use crate::error::*;
-
-/// ReadWriteAtVolatile is a trait that allows reading and writing from a 
slice of VolatileSlice.
-pub trait ReadWriteAtVolatile<B: BitmapSlice> {
-    fn read_vectored_at_volatile(&self, bufs: &[&VolatileSlice<B>]) -> 
Result<usize>;
-    fn write_vectored_at_volatile(&self, bufs: &[&VolatileSlice<B>]) -> 
Result<usize>;
-}
-
-impl<B: BitmapSlice, T: ReadWriteAtVolatile<B> + ?Sized> 
ReadWriteAtVolatile<B> for &T {
-    fn read_vectored_at_volatile(&self, bufs: &[&VolatileSlice<B>]) -> 
Result<usize> {
-        (**self).read_vectored_at_volatile(bufs)
-    }
-
-    fn write_vectored_at_volatile(&self, bufs: &[&VolatileSlice<B>]) -> 
Result<usize> {
-        (**self).write_vectored_at_volatile(bufs)
-    }
-}
-
-/// BufferWrapper is a wrapper around opendal::Buffer that implements 
ReadWriteAtVolatile.
-pub struct BufferWrapper {
-    buffer: RefCell<opendal::Buffer>,
-}
-
-impl BufferWrapper {
-    pub fn new(buffer: opendal::Buffer) -> BufferWrapper {
-        BufferWrapper {
-            buffer: RefCell::new(buffer),
-        }
-    }
-
-    pub fn get_buffer(&self) -> opendal::Buffer {
-        return self.buffer.borrow().clone();
-    }
-}
-
-impl<B: BitmapSlice> ReadWriteAtVolatile<B> for BufferWrapper {
-    fn read_vectored_at_volatile(&self, bufs: &[&VolatileSlice<B>]) -> 
Result<usize> {
-        let slice_guards: Vec<_> = bufs.iter().map(|s| 
s.ptr_guard_mut()).collect();
-        let iovecs: Vec<_> = slice_guards
-            .iter()
-            .map(|s| libc::iovec {
-                iov_base: s.as_ptr() as *mut libc::c_void,
-                iov_len: s.len() as libc::size_t,
-            })
-            .collect();
-        if iovecs.is_empty() {
-            return Ok(0);
-        }
-        let data = self.buffer.borrow().to_vec();
-        let mut result = 0;
-        for (index, iovec) in iovecs.iter().enumerate() {
-            let num = min(data.len() - result, iovec.iov_len);
-            if num == 0 {
-                break;
-            }
-            unsafe {
-                ptr::copy_nonoverlapping(data[result..].as_ptr(), 
iovec.iov_base as *mut u8, num)
-            }
-            bufs[index].bitmap().mark_dirty(0, num);
-            result += num;
-        }
-        Ok(result)
-    }
-
-    fn write_vectored_at_volatile(&self, bufs: &[&VolatileSlice<B>]) -> 
Result<usize> {
-        let slice_guards: Vec<_> = bufs.iter().map(|s| 
s.ptr_guard()).collect();
-        let iovecs: Vec<_> = slice_guards
-            .iter()
-            .map(|s| libc::iovec {
-                iov_base: s.as_ptr() as *mut libc::c_void,
-                iov_len: s.len() as libc::size_t,
-            })
-            .collect();
-        if iovecs.is_empty() {
-            return Ok(0);
-        }
-        let len = iovecs.iter().map(|iov| iov.iov_len).sum();
-        let mut data = vec![0; len];
-        let mut offset = 0;
-        for iov in iovecs.iter() {
-            unsafe {
-                ptr::copy_nonoverlapping(
-                    iov.iov_base as *const u8,
-                    data.as_mut_ptr().add(offset),
-                    iov.iov_len,
-                );
-            }
-            offset += iov.iov_len;
-        }
-        *self.buffer.borrow_mut() = opendal::Buffer::from(data);
-        Ok(len)
-    }
-}
diff --git a/integrations/virtiofs/src/error.rs 
b/integrations/virtiofs/src/error.rs
deleted file mode 100644
index 7fde4a2e0..000000000
--- a/integrations/virtiofs/src/error.rs
+++ /dev/null
@@ -1,94 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-use std::ffi::CStr;
-use std::io;
-
-use anyhow::Error as AnyError;
-use snafu::prelude::Snafu;
-
-/// Error is a error struct returned by all ovfs functions.
-#[derive(Debug, Snafu)]
-#[non_exhaustive]
-pub enum Error {
-    #[snafu(display("Vhost user fs error: {}, source: {:?}", message, source))]
-    VhostUserFsError {
-        message: String,
-        #[snafu(source(false))]
-        source: Option<AnyError>,
-    },
-    #[snafu(display("Unexpected error: {}, source: {:?}", message, source))]
-    Unexpected {
-        message: String,
-        #[snafu(source(false))]
-        source: Option<AnyError>,
-    },
-}
-
-impl From<libc::c_int> for Error {
-    fn from(errno: libc::c_int) -> Error {
-        let err_str = unsafe { libc::strerror(errno) };
-        let message = if err_str.is_null() {
-            format!("errno: {errno}")
-        } else {
-            let c_str = unsafe { CStr::from_ptr(err_str) };
-            c_str.to_string_lossy().into_owned()
-        };
-        Error::VhostUserFsError {
-            message,
-            source: None,
-        }
-    }
-}
-
-impl From<Error> for io::Error {
-    fn from(error: Error) -> io::Error {
-        match error {
-            Error::VhostUserFsError { message, source } => {
-                let message = format!("Vhost user fs error: {message}");
-                match source {
-                    Some(source) => io::Error::other(format!("{message}, 
source: {source:?}")),
-                    None => io::Error::other(message),
-                }
-            }
-            Error::Unexpected { message, source } => {
-                let message = format!("Unexpected error: {message}");
-                match source {
-                    Some(source) => io::Error::other(format!("{message}, 
source: {source:?}")),
-                    None => io::Error::other(message),
-                }
-            }
-        }
-    }
-}
-
-/// Result is a result wrapper in ovfs.
-pub type Result<T, E = Error> = std::result::Result<T, E>;
-
-pub fn new_vhost_user_fs_error(message: &str, source: Option<AnyError>) -> 
Error {
-    Error::VhostUserFsError {
-        message: message.to_string(),
-        source,
-    }
-}
-
-pub fn new_unexpected_error(message: &str, source: Option<AnyError>) -> Error {
-    Error::Unexpected {
-        message: message.to_string(),
-        source,
-    }
-}
diff --git a/integrations/virtiofs/src/filesystem.rs 
b/integrations/virtiofs/src/filesystem.rs
deleted file mode 100644
index f1cb4a8e6..000000000
--- a/integrations/virtiofs/src/filesystem.rs
+++ /dev/null
@@ -1,699 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-use std::collections::HashMap;
-use std::ffi::CStr;
-use std::io::Read;
-use std::io::Write;
-use std::mem::size_of;
-use std::sync::Mutex;
-use std::time::Duration;
-
-use log::debug;
-use opendal::Buffer;
-use opendal::ErrorKind;
-use opendal::Operator;
-use sharded_slab::Slab;
-use tokio::runtime::Builder;
-use tokio::runtime::Runtime;
-use vm_memory::ByteValued;
-
-use crate::buffer::BufferWrapper;
-use crate::error::*;
-use crate::filesystem_message::*;
-use crate::virtiofs_util::Reader;
-use crate::virtiofs_util::Writer;
-
-/// Version number of this interface.
-const KERNEL_VERSION: u32 = 7;
-/// Minor version number of this interface.
-const KERNEL_MINOR_VERSION: u32 = 38;
-/// Minimum Minor version number supported.
-const MIN_KERNEL_MINOR_VERSION: u32 = 27;
-/// The length of the header part of the message.
-const BUFFER_HEADER_SIZE: u32 = 4096;
-/// The maximum length of the data part of the message, used for read/write 
data.
-const MAX_BUFFER_SIZE: u32 = 1 << 20;
-/// The default time to live of the attributes.
-const DEFAULT_TTL: Duration = Duration::from_secs(1);
-/// The default mode of the opened file.
-const DEFAULT_OPENED_FILE_MODE: u32 = 0o755;
-
-enum FileType {
-    Dir,
-    File,
-}
-
-struct InnerWriter {
-    writer: opendal::Writer,
-    written: u64,
-}
-
-#[derive(Clone)]
-struct OpenedFile {
-    path: String,
-    metadata: Attr,
-}
-
-impl OpenedFile {
-    fn new(file_type: FileType, path: &str, uid: u32, gid: u32) -> OpenedFile {
-        let mut attr: Attr = unsafe { std::mem::zeroed() };
-        attr.uid = uid;
-        attr.gid = gid;
-        match file_type {
-            FileType::Dir => {
-                attr.nlink = 2;
-                attr.mode = libc::S_IFDIR | DEFAULT_OPENED_FILE_MODE;
-            }
-            FileType::File => {
-                attr.nlink = 1;
-                attr.mode = libc::S_IFREG | DEFAULT_OPENED_FILE_MODE;
-            }
-        }
-        OpenedFile {
-            path: path.to_string(),
-            metadata: attr,
-        }
-    }
-}
-
-fn opendal_error2error(error: opendal::Error) -> Error {
-    match error.kind() {
-        ErrorKind::Unsupported => Error::from(libc::EOPNOTSUPP),
-        ErrorKind::IsADirectory => Error::from(libc::EISDIR),
-        ErrorKind::NotFound => Error::from(libc::ENOENT),
-        ErrorKind::PermissionDenied => Error::from(libc::EACCES),
-        ErrorKind::AlreadyExists => Error::from(libc::EEXIST),
-        ErrorKind::NotADirectory => Error::from(libc::ENOTDIR),
-        ErrorKind::RangeNotSatisfied => Error::from(libc::EINVAL),
-        ErrorKind::RateLimited => Error::from(libc::EBUSY),
-        _ => Error::from(libc::ENOENT),
-    }
-}
-
-fn opendal_metadata2opened_file(
-    path: &str,
-    metadata: &opendal::Metadata,
-    uid: u32,
-    gid: u32,
-) -> OpenedFile {
-    let file_type = match metadata.mode() {
-        opendal::EntryMode::DIR => FileType::Dir,
-        _ => FileType::File,
-    };
-    OpenedFile::new(file_type, path, uid, gid)
-}
-
-/// Filesystem is a filesystem implementation with opendal backend,
-/// and will decode and process messages from VMs.
-pub struct Filesystem {
-    rt: Runtime,
-    core: Operator,
-    uid: u32,
-    gid: u32,
-    opened_files: Slab<OpenedFile>,
-    // Since we need to manually manage the allocation of inodes,
-    // we record the inode of each opened file here.
-    opened_files_map: Mutex<HashMap<String, u64>>,
-    opened_files_writer: tokio::sync::Mutex<HashMap<String, InnerWriter>>,
-}
-
-impl Filesystem {
-    pub fn new(core: Operator) -> Filesystem {
-        let rt = Builder::new_multi_thread()
-            .worker_threads(4)
-            .enable_all()
-            .build()
-            .unwrap();
-
-        // Here we set the uid and gid to 1000, which is the default value.
-        Filesystem {
-            rt,
-            core,
-            uid: 1000,
-            gid: 1000,
-            opened_files: Slab::new(),
-            opened_files_map: Mutex::new(HashMap::new()),
-            opened_files_writer: tokio::sync::Mutex::new(HashMap::new()),
-        }
-    }
-
-    pub fn handle_message(&self, mut r: Reader, w: Writer) -> Result<usize> {
-        let in_header: InHeader = r.read_obj().map_err(|e| {
-            new_vhost_user_fs_error("failed to decode protocol messages", 
Some(e.into()))
-        })?;
-        if in_header.len > (MAX_BUFFER_SIZE + BUFFER_HEADER_SIZE) {
-            // The message is too long here.
-            return Filesystem::reply_error(in_header.unique, w);
-        }
-        if let Ok(opcode) = Opcode::try_from(in_header.opcode) {
-            match opcode {
-                Opcode::Init => self.init(in_header, r, w),
-                Opcode::Destroy => self.destroy(in_header, r, w),
-                Opcode::Lookup => self.lookup(in_header, r, w),
-                Opcode::Getattr => self.getattr(in_header, r, w),
-                Opcode::Setattr => self.setattr(in_header, r, w),
-                Opcode::Create => self.create(in_header, r, w),
-                Opcode::Unlink => self.unlink(in_header, r, w),
-                Opcode::Release => self.release(in_header, r, w),
-                Opcode::Flush => self.flush(in_header, r, w),
-                Opcode::Forget => self.forget(in_header, r),
-                Opcode::Open => self.open(in_header, r, w),
-                Opcode::Read => self.read(in_header, r, w),
-                Opcode::Write => self.write(in_header, r, w),
-            }
-        } else {
-            Filesystem::reply_error(in_header.unique, w)
-        }
-    }
-}
-
-impl Filesystem {
-    fn reply_ok<T: ByteValued>(
-        out: Option<T>,
-        data: Option<&[u8]>,
-        unique: u64,
-        mut w: Writer,
-    ) -> Result<usize> {
-        let mut len = size_of::<OutHeader>();
-        if out.is_some() {
-            len += size_of::<T>();
-        }
-        if let Some(data) = data {
-            len += data.len();
-        }
-        let header = OutHeader {
-            unique,
-            error: 0, // Return no error.
-            len: len as u32,
-        };
-        w.write_all(header.as_slice()).map_err(|e| {
-            new_vhost_user_fs_error("failed to encode protocol messages", 
Some(e.into()))
-        })?;
-        if let Some(out) = out {
-            w.write_all(out.as_slice()).map_err(|e| {
-                new_vhost_user_fs_error("failed to encode protocol messages", 
Some(e.into()))
-            })?;
-        }
-        if let Some(data) = data {
-            w.write_all(data).map_err(|e| {
-                new_vhost_user_fs_error("failed to encode protocol messages", 
Some(e.into()))
-            })?;
-        }
-        Ok(w.bytes_written())
-    }
-
-    fn reply_error(unique: u64, mut w: Writer) -> Result<usize> {
-        let header = OutHeader {
-            unique,
-            error: libc::EIO, // Here we simply return I/O error.
-            len: size_of::<OutHeader>() as u32,
-        };
-        w.write_all(header.as_slice()).map_err(|e| {
-            new_vhost_user_fs_error("failed to encode protocol messages", 
Some(e.into()))
-        })?;
-        Ok(w.bytes_written())
-    }
-
-    fn bytes_to_str(buf: &[u8]) -> Result<&str> {
-        Filesystem::bytes_to_cstr(buf)?.to_str().map_err(|e| {
-            new_vhost_user_fs_error("failed to decode protocol messages", 
Some(e.into()))
-        })
-    }
-
-    fn bytes_to_cstr(buf: &[u8]) -> Result<&CStr> {
-        CStr::from_bytes_with_nul(buf).map_err(|e| {
-            new_vhost_user_fs_error("failed to decode protocol messages", 
Some(e.into()))
-        })
-    }
-
-    fn check_flags(&self, flags: u32) -> Result<(bool, bool)> {
-        let is_trunc = flags & libc::O_TRUNC as u32 != 0 || flags & 
libc::O_CREAT as u32 != 0;
-        let is_append = flags & libc::O_APPEND as u32 != 0;
-
-        let mode = flags & libc::O_ACCMODE as u32;
-        let is_write = mode == libc::O_WRONLY as u32 || mode == libc::O_RDWR 
as u32 || is_append;
-
-        let capability = self.core.info().full_capability();
-        if is_trunc && !capability.write {
-            Err(Error::from(libc::EACCES))?;
-        }
-        if is_append && !capability.write_can_append {
-            Err(Error::from(libc::EACCES))?;
-        }
-
-        Ok((is_write, is_append))
-    }
-}
-
-impl Filesystem {
-    fn init(&self, in_header: InHeader, mut r: Reader, w: Writer) -> 
Result<usize> {
-        let InitIn { major, minor, .. } = r.read_obj().map_err(|e| {
-            new_vhost_user_fs_error("failed to decode protocol messages", 
Some(e.into()))
-        })?;
-
-        if major != KERNEL_VERSION || minor < MIN_KERNEL_MINOR_VERSION {
-            return Filesystem::reply_error(in_header.unique, w);
-        }
-
-        let mut attr = OpenedFile::new(FileType::Dir, "/", self.uid, self.gid);
-        attr.metadata.ino = 1;
-        // We need to allocate the inode 1 for the root directory. The double 
insertion
-        // here makes 1 the first inode and avoids extra alignment and 
processing elsewhere.
-        self.opened_files
-            .insert(attr.clone())
-            .expect("failed to allocate inode");
-        self.opened_files
-            .insert(attr.clone())
-            .expect("failed to allocate inode");
-        let mut opened_files_map = self.opened_files_map.lock().unwrap();
-        opened_files_map.insert("/".to_string(), 1);
-
-        let out = InitOut {
-            major: KERNEL_VERSION,
-            minor: KERNEL_MINOR_VERSION,
-            max_write: MAX_BUFFER_SIZE,
-            ..Default::default()
-        };
-        Filesystem::reply_ok(Some(out), None, in_header.unique, w)
-    }
-
-    fn destroy(&self, _in_header: InHeader, _r: Reader, _w: Writer) -> 
Result<usize> {
-        // do nothing for destroy.
-        Ok(0)
-    }
-
-    fn flush(&self, _in_header: InHeader, _r: Reader, _w: Writer) -> 
Result<usize> {
-        // do nothing for flush.
-        Ok(0)
-    }
-
-    fn forget(&self, _in_header: InHeader, _r: Reader) -> Result<usize> {
-        // do nothing for forget.
-        Ok(0)
-    }
-
-    fn lookup(&self, in_header: InHeader, mut r: Reader, w: Writer) -> 
Result<usize> {
-        let name_len = in_header.len as usize - size_of::<InHeader>();
-        let mut buf = vec![0; name_len];
-        r.read_exact(&mut buf).map_err(|e| {
-            new_unexpected_error("failed to decode protocol messages", 
Some(e.into()))
-        })?;
-        let name = match Filesystem::bytes_to_str(buf.as_ref()) {
-            Ok(name) => name,
-            Err(_) => return Filesystem::reply_error(in_header.unique, w),
-        };
-
-        debug!("lookup: parent inode={} name={}", in_header.nodeid, name);
-
-        let parent_path = match self
-            .opened_files
-            .get(in_header.nodeid as usize)
-            .map(|f| f.path.clone())
-        {
-            Some(path) => path,
-            None => return Filesystem::reply_error(in_header.unique, w),
-        };
-
-        let path = format!("{parent_path}/{name}");
-        let metadata = match self.rt.block_on(self.do_get_metadata(&path)) {
-            Ok(metadata) => metadata,
-            Err(_) => return Filesystem::reply_error(in_header.unique, w),
-        };
-
-        let out = EntryOut {
-            nodeid: metadata.metadata.ino,
-            entry_valid: DEFAULT_TTL.as_secs(),
-            attr_valid: DEFAULT_TTL.as_secs(),
-            entry_valid_nsec: DEFAULT_TTL.subsec_nanos(),
-            attr_valid_nsec: DEFAULT_TTL.subsec_nanos(),
-            attr: metadata.metadata,
-            ..Default::default()
-        };
-        Filesystem::reply_ok(Some(out), None, in_header.unique, w)
-    }
-
-    fn getattr(&self, in_header: InHeader, _r: Reader, w: Writer) -> 
Result<usize> {
-        debug!("getattr: inode={}", in_header.nodeid);
-
-        let path = match self
-            .opened_files
-            .get(in_header.nodeid as usize)
-            .map(|f| f.path.clone())
-        {
-            Some(path) => path,
-            None => return Filesystem::reply_error(in_header.unique, w),
-        };
-
-        let metadata = match self.rt.block_on(self.do_get_metadata(&path)) {
-            Ok(metadata) => metadata,
-            Err(_) => return Filesystem::reply_error(in_header.unique, w),
-        };
-
-        let out = AttrOut {
-            attr_valid: DEFAULT_TTL.as_secs(),
-            attr_valid_nsec: DEFAULT_TTL.subsec_nanos(),
-            attr: metadata.metadata,
-            ..Default::default()
-        };
-        Filesystem::reply_ok(Some(out), None, in_header.unique, w)
-    }
-
-    fn setattr(&self, in_header: InHeader, _r: Reader, w: Writer) -> 
Result<usize> {
-        debug!("setattr: inode={}", in_header.nodeid);
-
-        // do nothing for setattr.
-        self.getattr(in_header, _r, w)
-    }
-
-    fn create(&self, in_header: InHeader, mut r: Reader, w: Writer) -> 
Result<usize> {
-        let CreateIn { flags, .. } = r.read_obj().map_err(|e| {
-            new_vhost_user_fs_error("failed to decode protocol messages", 
Some(e.into()))
-        })?;
-
-        let name_len = in_header.len as usize - size_of::<InHeader>() - 
size_of::<CreateIn>();
-        let mut buf = vec![0; name_len];
-        r.read_exact(&mut buf).map_err(|e| {
-            new_unexpected_error("failed to decode protocol messages", 
Some(e.into()))
-        })?;
-        let name = match Filesystem::bytes_to_str(buf.as_ref()) {
-            Ok(name) => name,
-            Err(_) => return Filesystem::reply_error(in_header.unique, w),
-        };
-
-        debug!("create: parent inode={} name={}", in_header.nodeid, name);
-
-        let parent_path = match self
-            .opened_files
-            .get(in_header.nodeid as usize)
-            .map(|f| f.path.clone())
-        {
-            Some(path) => path,
-            None => return Filesystem::reply_error(in_header.unique, w),
-        };
-
-        let path = format!("{parent_path}/{name}");
-        let mut attr = OpenedFile::new(FileType::File, &path, self.uid, 
self.gid);
-        let inode = self
-            .opened_files
-            .insert(attr.clone())
-            .expect("failed to allocate inode");
-        attr.metadata.ino = inode as u64;
-        let mut opened_files_map = self.opened_files_map.lock().unwrap();
-        opened_files_map.insert(path.to_string(), inode as u64);
-
-        match self.rt.block_on(self.do_set_writer(&path, flags)) {
-            Ok(writer) => writer,
-            Err(_) => return Filesystem::reply_error(in_header.unique, w),
-        };
-
-        let entry_out = EntryOut {
-            nodeid: attr.metadata.ino,
-            entry_valid: DEFAULT_TTL.as_secs(),
-            attr_valid: DEFAULT_TTL.as_secs(),
-            entry_valid_nsec: DEFAULT_TTL.subsec_nanos(),
-            attr_valid_nsec: DEFAULT_TTL.subsec_nanos(),
-            attr: attr.metadata,
-            ..Default::default()
-        };
-        let open_out = OpenOut {
-            ..Default::default()
-        };
-        Filesystem::reply_ok(
-            Some(entry_out),
-            Some(open_out.as_slice()),
-            in_header.unique,
-            w,
-        )
-    }
-
-    fn unlink(&self, in_header: InHeader, mut r: Reader, w: Writer) -> 
Result<usize> {
-        let name_len = in_header.len as usize - size_of::<InHeader>();
-        let mut buf = vec![0; name_len];
-        r.read_exact(&mut buf).map_err(|e| {
-            new_unexpected_error("failed to decode protocol messages", 
Some(e.into()))
-        })?;
-        let name = match Filesystem::bytes_to_str(buf.as_ref()) {
-            Ok(name) => name,
-            Err(_) => return Filesystem::reply_error(in_header.unique, w),
-        };
-
-        debug!("unlink: parent inode={} name={}", in_header.nodeid, name);
-
-        let parent_path = match self
-            .opened_files
-            .get(in_header.nodeid as usize)
-            .map(|f| f.path.clone())
-        {
-            Some(path) => path,
-            None => return Filesystem::reply_error(in_header.unique, w),
-        };
-
-        let path = format!("{parent_path}/{name}");
-        if self.rt.block_on(self.do_delete(&path)).is_err() {
-            return Filesystem::reply_error(in_header.unique, w);
-        }
-
-        let mut opened_files_map = self.opened_files_map.lock().unwrap();
-        opened_files_map.remove(&path);
-
-        Filesystem::reply_ok(None::<u8>, None, in_header.unique, w)
-    }
-
-    fn release(&self, in_header: InHeader, _r: Reader, w: Writer) -> 
Result<usize> {
-        debug!("release: inode={}", in_header.nodeid);
-
-        let path = match self
-            .opened_files
-            .get(in_header.nodeid as usize)
-            .map(|f| f.path.clone())
-        {
-            Some(path) => path,
-            None => return Filesystem::reply_error(in_header.unique, w),
-        };
-
-        if self.rt.block_on(self.do_release_writer(&path)).is_err() {
-            return Filesystem::reply_error(in_header.unique, w);
-        }
-
-        Filesystem::reply_ok(None::<u8>, None, in_header.unique, w)
-    }
-
-    fn open(&self, in_header: InHeader, mut r: Reader, w: Writer) -> 
Result<usize> {
-        debug!("open: inode={}", in_header.nodeid);
-
-        let OpenIn { flags, .. } = r.read_obj().map_err(|e| {
-            new_vhost_user_fs_error("failed to decode protocol messages", 
Some(e.into()))
-        })?;
-
-        let path = match self
-            .opened_files
-            .get(in_header.nodeid as usize)
-            .map(|f| f.path.clone())
-        {
-            Some(path) => path,
-            None => return Filesystem::reply_error(in_header.unique, w),
-        };
-
-        match self.rt.block_on(self.do_set_writer(&path, flags)) {
-            Ok(writer) => writer,
-            Err(_) => return Filesystem::reply_error(in_header.unique, w),
-        };
-
-        let out = OpenOut {
-            ..Default::default()
-        };
-        Filesystem::reply_ok(Some(out), None, in_header.unique, w)
-    }
-
-    fn read(&self, in_header: InHeader, mut r: Reader, mut w: Writer) -> 
Result<usize> {
-        let path = match self
-            .opened_files
-            .get(in_header.nodeid as usize)
-            .map(|f| f.path.clone())
-        {
-            Some(path) => path,
-            None => return Filesystem::reply_error(in_header.unique, w),
-        };
-
-        let ReadIn { offset, size, .. } = r.read_obj().map_err(|e| {
-            new_vhost_user_fs_error("failed to decode protocol messages", 
Some(e.into()))
-        })?;
-
-        debug!(
-            "read: inode={} offset={} size={}",
-            in_header.nodeid, offset, size
-        );
-
-        let data = match self.rt.block_on(self.do_read(&path, offset)) {
-            Ok(data) => data,
-            Err(_) => return Filesystem::reply_error(in_header.unique, w),
-        };
-        let len = data.len();
-        let buffer = BufferWrapper::new(data);
-
-        let mut data_writer = w.split_at(size_of::<OutHeader>()).unwrap();
-        data_writer.write_from_at(&buffer, len).map_err(|e| {
-            new_vhost_user_fs_error("failed to encode protocol messages", 
Some(e.into()))
-        })?;
-
-        let out = OutHeader {
-            len: (size_of::<OutHeader>() + len) as u32,
-            error: 0,
-            unique: in_header.unique,
-        };
-        w.write_all(out.as_slice()).map_err(|e| {
-            new_vhost_user_fs_error("failed to encode protocol messages", 
Some(e.into()))
-        })?;
-        Ok(out.len as usize)
-    }
-
-    fn write(&self, in_header: InHeader, mut r: Reader, w: Writer) -> 
Result<usize> {
-        debug!("write: inode={}", in_header.nodeid);
-
-        let path = match self
-            .opened_files
-            .get(in_header.nodeid as usize)
-            .map(|f| f.path.clone())
-        {
-            Some(path) => path,
-            None => return Filesystem::reply_error(in_header.unique, w),
-        };
-
-        let WriteIn { offset, size, .. } = r.read_obj().map_err(|e| {
-            new_vhost_user_fs_error("failed to decode protocol messages", 
Some(e.into()))
-        })?;
-
-        let buffer = BufferWrapper::new(Buffer::new());
-        r.read_to_at(&buffer, size as usize).map_err(|e| {
-            new_vhost_user_fs_error("failed to decode protocol messages", 
Some(e.into()))
-        })?;
-        let buffer = buffer.get_buffer();
-
-        match self.rt.block_on(self.do_write(&path, offset, buffer)) {
-            Ok(writer) => writer,
-            Err(_) => return Filesystem::reply_error(in_header.unique, w),
-        };
-
-        let out = WriteOut {
-            size,
-            ..Default::default()
-        };
-        Filesystem::reply_ok(Some(out), None, in_header.unique, w)
-    }
-}
-
-impl Filesystem {
-    async fn do_get_metadata(&self, path: &str) -> Result<OpenedFile> {
-        let metadata = 
self.core.stat(path).await.map_err(opendal_error2error)?;
-        let mut attr = opendal_metadata2opened_file(path, &metadata, self.uid, 
self.gid);
-        attr.metadata.size = metadata.content_length();
-        let mut opened_files_map = self.opened_files_map.lock().unwrap();
-        if let Some(inode) = opened_files_map.get(path) {
-            attr.metadata.ino = *inode;
-        } else {
-            let inode = self
-                .opened_files
-                .insert(attr.clone())
-                .expect("failed to allocate inode");
-            attr.metadata.ino = inode as u64;
-            opened_files_map.insert(path.to_string(), inode as u64);
-        }
-
-        Ok(attr)
-    }
-
-    async fn do_set_writer(&self, path: &str, flags: u32) -> Result<()> {
-        let (is_write, is_append) = self.check_flags(flags)?;
-        if !is_write {
-            return Ok(());
-        }
-
-        let writer = self
-            .core
-            .writer_with(path)
-            .append(is_append)
-            .await
-            .map_err(opendal_error2error)?;
-        let written = if is_append {
-            self.core
-                .stat(path)
-                .await
-                .map_err(opendal_error2error)?
-                .content_length()
-        } else {
-            0
-        };
-
-        let inner_writer = InnerWriter { writer, written };
-        let mut opened_file_writer = self.opened_files_writer.lock().await;
-        opened_file_writer.insert(path.to_string(), inner_writer);
-
-        Ok(())
-    }
-
-    async fn do_release_writer(&self, path: &str) -> Result<()> {
-        let mut opened_file_writer = self.opened_files_writer.lock().await;
-        let inner_writer = opened_file_writer
-            .get_mut(path)
-            .ok_or(Error::from(libc::EINVAL))?;
-        inner_writer
-            .writer
-            .close()
-            .await
-            .map_err(opendal_error2error)?;
-        opened_file_writer.remove(path);
-
-        Ok(())
-    }
-
-    async fn do_delete(&self, path: &str) -> Result<()> {
-        self.core.delete(path).await.map_err(opendal_error2error)?;
-
-        Ok(())
-    }
-
-    async fn do_read(&self, path: &str, offset: u64) -> Result<Buffer> {
-        let data = self
-            .core
-            .read_with(path)
-            .range(offset..)
-            .await
-            .map_err(opendal_error2error)?;
-
-        Ok(data)
-    }
-
-    async fn do_write(&self, path: &str, offset: u64, data: Buffer) -> 
Result<usize> {
-        let len = data.len();
-        let mut opened_file_writer = self.opened_files_writer.lock().await;
-        let inner_writer = opened_file_writer
-            .get_mut(path)
-            .ok_or(Error::from(libc::EINVAL))?;
-        if offset != inner_writer.written {
-            return Err(Error::from(libc::EINVAL));
-        }
-        inner_writer
-            .writer
-            .write_from(data)
-            .await
-            .map_err(opendal_error2error)?;
-        inner_writer.written += len as u64;
-
-        Ok(len)
-    }
-}
diff --git a/integrations/virtiofs/src/filesystem_message.rs 
b/integrations/virtiofs/src/filesystem_message.rs
deleted file mode 100644
index 50562aa70..000000000
--- a/integrations/virtiofs/src/filesystem_message.rs
+++ /dev/null
@@ -1,288 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-use vm_memory::ByteValued;
-
-use crate::error::*;
-
-/// Opcode represents the filesystem call that needs to be executed by VMs 
message.
-/// The corresponding value needs to be aligned with the specification.
-#[non_exhaustive]
-pub enum Opcode {
-    Lookup = 1,
-    Forget = 2,
-    Getattr = 3,
-    Setattr = 4,
-    Unlink = 10,
-    Open = 14,
-    Read = 15,
-    Write = 16,
-    Release = 18,
-    Flush = 25,
-    Init = 26,
-    Create = 35,
-    Destroy = 38,
-}
-
-impl TryFrom<u32> for Opcode {
-    type Error = Error;
-
-    fn try_from(value: u32) -> Result<Self, Self::Error> {
-        match value {
-            1 => Ok(Opcode::Lookup),
-            2 => Ok(Opcode::Forget),
-            3 => Ok(Opcode::Getattr),
-            4 => Ok(Opcode::Setattr),
-            10 => Ok(Opcode::Unlink),
-            14 => Ok(Opcode::Open),
-            15 => Ok(Opcode::Read),
-            16 => Ok(Opcode::Write),
-            18 => Ok(Opcode::Release),
-            25 => Ok(Opcode::Flush),
-            26 => Ok(Opcode::Init),
-            35 => Ok(Opcode::Create),
-            38 => Ok(Opcode::Destroy),
-            _ => Err(new_vhost_user_fs_error("failed to decode opcode", None)),
-        }
-    }
-}
-
-/// Attr represents the file attributes in virtiofs.
-///
-/// The fields of the struct need to conform to the specific format of the 
virtiofs message.
-/// Currently, we only need to align them exactly with virtiofsd.
-/// Reference: 
https://gitlab.com/virtio-fs/virtiofsd/-/blob/main/src/fuse.rs?ref_type=heads#L577
-#[repr(C)]
-#[derive(Debug, Default, Clone, Copy)]
-pub struct Attr {
-    pub ino: u64,
-    pub size: u64,
-    pub blocks: u64,
-    pub atime: u64,
-    pub mtime: u64,
-    pub ctime: u64,
-    pub atimensec: u32,
-    pub mtimensec: u32,
-    pub ctimensec: u32,
-    pub mode: u32,
-    pub nlink: u32,
-    pub uid: u32,
-    pub gid: u32,
-    pub rdev: u32,
-    pub blksize: u32,
-    pub flags: u32,
-}
-
-/// InHeader represents the incoming message header in the filesystem call.
-///
-/// The fields of the struct need to conform to the specific format of the 
virtiofs message.
-/// Currently, we only need to align them exactly with virtiofsd.
-/// Reference: 
https://gitlab.com/virtio-fs/virtiofsd/-/blob/main/src/fuse.rs?ref_type=heads#L1155
-#[repr(C)]
-#[derive(Debug, Default, Clone, Copy)]
-pub struct InHeader {
-    pub len: u32,
-    pub opcode: u32,
-    pub unique: u64,
-    pub nodeid: u64,
-    pub uid: u32,
-    pub gid: u32,
-    pub pid: u32,
-    pub total_extlen: u16,
-    pub padding: u16,
-}
-
-/// OutHeader represents the message header returned in the filesystem call.
-///
-/// The fields of the struct need to conform to the specific format of the 
virtiofs message.
-/// Currently, we only need to align them exactly with virtiofsd.
-/// Reference: 
https://gitlab.com/virtio-fs/virtiofsd/-/blob/main/src/fuse.rs?ref_type=heads#L1170
-#[repr(C)]
-#[derive(Debug, Default, Clone, Copy)]
-pub struct OutHeader {
-    pub len: u32,
-    pub error: i32,
-    pub unique: u64,
-}
-
-/// InitIn is used to parse the parameters passed in the Init filesystem call.
-///
-/// The fields of the struct need to conform to the specific format of the 
virtiofs message.
-/// Currently, we only need to align them exactly with virtiofsd.
-/// Reference: 
https://gitlab.com/virtio-fs/virtiofsd/-/blob/main/src/fuse.rs?ref_type=heads#L1030
-#[repr(C)]
-#[derive(Debug, Default, Clone, Copy)]
-pub struct InitIn {
-    pub major: u32,
-    pub minor: u32,
-    pub max_readahead: u32,
-    pub flags: u32,
-}
-
-/// InitOut is used to return the result of the Init filesystem call.
-///
-/// The fields of the struct need to conform to the specific format of the 
virtiofs message.
-/// Currently, we only need to align them exactly with virtiofsd.
-/// Reference: 
https://gitlab.com/virtio-fs/virtiofsd/-/blob/main/src/fuse.rs?ref_type=heads#L1048
-#[repr(C)]
-#[derive(Debug, Default, Clone, Copy)]
-pub struct InitOut {
-    pub major: u32,
-    pub minor: u32,
-    pub max_readahead: u32,
-    pub flags: u32,
-    pub max_background: u16,
-    pub congestion_threshold: u16,
-    pub max_write: u32,
-    pub time_gran: u32,
-    pub max_pages: u16,
-    pub map_alignment: u16,
-    pub flags2: u32,
-    pub unused: [u32; 7],
-}
-
-/// EntryOut is used to return the file entry in the filesystem call.
-///
-/// The fields of the struct need to conform to the specific format of the 
virtiofs message.
-/// Currently, we only need to align them exactly with virtiofsd.
-/// Reference: 
https://gitlab.com/virtio-fs/virtiofsd/-/blob/main/src/fuse.rs?ref_type=heads#L737
-#[repr(C)]
-#[derive(Debug, Default, Clone, Copy)]
-pub struct EntryOut {
-    pub nodeid: u64,
-    pub generation: u64,
-    pub entry_valid: u64,
-    pub attr_valid: u64,
-    pub entry_valid_nsec: u32,
-    pub attr_valid_nsec: u32,
-    pub attr: Attr,
-}
-
-/// AttrOut is used to return the file attributes in the filesystem call.
-///
-/// The fields of the struct need to conform to the specific format of the 
virtiofs message.
-/// Currently, we only need to align them exactly with virtiofsd.
-/// Reference: 
https://gitlab.com/virtio-fs/virtiofsd/-/blob/main/src/fuse.rs?ref_type=heads#L782
-#[repr(C)]
-#[derive(Debug, Default, Clone, Copy)]
-pub struct AttrOut {
-    pub attr_valid: u64,
-    pub attr_valid_nsec: u32,
-    pub dummy: u32,
-    pub attr: Attr,
-}
-
-/// CreateIn is used to parse the parameters passed in the Create filesystem 
call.
-///
-/// The fields of the struct need to conform to the specific format of the 
virtiofs message.
-/// Currently, we only need to align them exactly with virtiofsd.
-/// Reference: 
https://gitlab.com/virtio-fs/virtiofsd/-/blob/main/src/fuse.rs?ref_type=heads#L881
-#[repr(C)]
-#[derive(Debug, Default, Clone, Copy)]
-pub struct CreateIn {
-    pub flags: u32,
-    pub mode: u32,
-    pub umask: u32,
-    pub open_flags: u32,
-}
-
-/// OpenIn is used to parse the parameters passed in the Open filesystem call.
-///
-/// The fields of the struct need to conform to the specific format of the 
virtiofs message.
-/// Currently, we only need to align them exactly with virtiofsd.
-/// Reference: 
https://gitlab.com/virtio-fs/virtiofsd/-/blob/main/src/fuse.rs?ref_type=heads#873
-#[repr(C)]
-#[derive(Debug, Default, Clone, Copy)]
-pub struct OpenIn {
-    pub flags: u32,
-    pub open_flags: u32,
-}
-
-/// OpenOut is used to return the file descriptor in the filesystem call.
-///
-/// The fields of the struct need to conform to the specific format of the 
virtiofs message.
-/// Currently, we only need to align them exactly with virtiofsd.
-/// Reference: 
https://gitlab.com/virtio-fs/virtiofsd/-/blob/main/src/fuse.rs?ref_type=heads#L891
-#[repr(C)]
-#[derive(Debug, Default, Clone, Copy)]
-pub struct OpenOut {
-    pub fh: u64,
-    pub open_flags: u32,
-    pub padding: u32,
-}
-
-/// ReadIn is used to parse the parameters passed in the Read filesystem call.
-///
-/// The fields of the struct need to conform to the specific format of the 
virtiofs message.
-/// Currently, we only need to align them exactly with virtiofsd.
-/// Reference: 
https://gitlab.com/virtio-fs/virtiofsd/-/blob/main/src/fuse.rs?ref_type=heads#920
-#[repr(C)]
-#[derive(Debug, Default, Clone, Copy)]
-pub struct ReadIn {
-    pub fh: u64,
-    pub offset: u64,
-    pub size: u32,
-    pub read_flags: u32,
-    pub lock_owner: u64,
-    pub flags: u32,
-    pub padding: u32,
-}
-
-/// WriteIn is used to parse the parameters passed in the Write filesystem 
call.
-///
-/// The fields of the struct need to conform to the specific format of the 
virtiofs message.
-/// Currently, we only need to align them exactly with virtiofsd.
-/// Reference: 
https://gitlab.com/virtio-fs/virtiofsd/-/blob/main/src/fuse.rs?ref_type=heads#933
-#[repr(C)]
-#[derive(Debug, Default, Clone, Copy)]
-pub struct WriteIn {
-    pub fh: u64,
-    pub offset: u64,
-    pub size: u32,
-    pub write_flags: u32,
-    pub lock_owner: u64,
-    pub flags: u32,
-    pub padding: u32,
-}
-
-/// WriteOut is used to return the number of bytes written in the Write 
filesystem call.
-///
-/// The fields of the struct need to conform to the specific format of the 
virtiofs message.
-/// Currently, we only need to align them exactly with virtiofsd.
-/// Reference: 
https://gitlab.com/virtio-fs/virtiofsd/-/blob/main/src/fuse.rs?ref_type=heads#L946
-#[repr(C)]
-#[derive(Debug, Default, Clone, Copy)]
-pub struct WriteOut {
-    pub size: u32,
-    pub padding: u32,
-}
-
-/// We will use ByteValued to implement the encoding and decoding
-/// of these structures in shared memory.
-unsafe impl ByteValued for Attr {}
-unsafe impl ByteValued for InHeader {}
-unsafe impl ByteValued for OutHeader {}
-unsafe impl ByteValued for InitIn {}
-unsafe impl ByteValued for InitOut {}
-unsafe impl ByteValued for EntryOut {}
-unsafe impl ByteValued for AttrOut {}
-unsafe impl ByteValued for CreateIn {}
-unsafe impl ByteValued for OpenIn {}
-unsafe impl ByteValued for OpenOut {}
-unsafe impl ByteValued for ReadIn {}
-unsafe impl ByteValued for WriteIn {}
-unsafe impl ByteValued for WriteOut {}
diff --git a/integrations/virtiofs/src/lib.rs b/integrations/virtiofs/src/lib.rs
deleted file mode 100644
index b2b00907a..000000000
--- a/integrations/virtiofs/src/lib.rs
+++ /dev/null
@@ -1,25 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-mod buffer;
-mod error;
-mod filesystem;
-mod filesystem_message;
-mod virtiofs;
-mod virtiofs_util;
-
-pub use virtiofs::VirtioFs;
diff --git a/integrations/virtiofs/src/virtiofs.rs 
b/integrations/virtiofs/src/virtiofs.rs
deleted file mode 100644
index 094516ca3..000000000
--- a/integrations/virtiofs/src/virtiofs.rs
+++ /dev/null
@@ -1,329 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-use std::io;
-use std::sync::Arc;
-use std::sync::RwLock;
-
-use log::warn;
-use opendal::Operator;
-use vhost::vhost_user::Backend;
-use vhost::vhost_user::Listener;
-use vhost::vhost_user::message::VhostUserProtocolFeatures;
-use vhost::vhost_user::message::VhostUserVirtioFeatures;
-use vhost_user_backend::VhostUserBackend;
-use vhost_user_backend::VhostUserDaemon;
-use vhost_user_backend::VringMutex;
-use vhost_user_backend::VringState;
-use vhost_user_backend::VringT;
-use virtio_bindings::bindings::virtio_config::VIRTIO_F_VERSION_1;
-use virtio_bindings::bindings::virtio_ring::VIRTIO_RING_F_EVENT_IDX;
-use virtio_bindings::bindings::virtio_ring::VIRTIO_RING_F_INDIRECT_DESC;
-use virtio_queue::DescriptorChain;
-use virtio_queue::QueueOwnedT;
-use vm_memory::GuestAddressSpace;
-use vm_memory::GuestMemoryAtomic;
-use vm_memory::GuestMemoryLoadGuard;
-use vm_memory::GuestMemoryMmap;
-use vmm_sys_util::epoll::EventSet;
-use vmm_sys_util::eventfd::EventFd;
-
-use crate::error::*;
-use crate::filesystem::Filesystem;
-use crate::virtiofs_util::Reader;
-use crate::virtiofs_util::Writer;
-
-/// Marks an event from the high priority queue.
-const HIPRIO_QUEUE_EVENT: u16 = 0;
-/// Marks an event from the request queue.
-const REQ_QUEUE_EVENT: u16 = 1;
-/// The maximum queue size supported.
-const QUEUE_SIZE: usize = 32768;
-/// The number of request queues supported.
-/// The vitrofs spec allows for multiple request queues, but we'll only 
support one.
-const REQUEST_QUEUES: usize = 1;
-/// In addition to request queues there is one high priority queue.
-const NUM_QUEUES: usize = REQUEST_QUEUES + 1;
-
-/// VhostUserFsThread represents the actual worker process used to handle file 
system requests from VMs.
-struct VhostUserFsThread {
-    core: Filesystem,
-    mem: Option<GuestMemoryAtomic<GuestMemoryMmap>>,
-    vu_req: Option<Backend>,
-    event_idx: bool,
-    kill_event_fd: EventFd,
-}
-
-impl VhostUserFsThread {
-    fn new(core: Filesystem) -> Result<VhostUserFsThread> {
-        let event_fd = EventFd::new(libc::EFD_NONBLOCK).map_err(|err| {
-            new_unexpected_error("failed to create kill eventfd", 
Some(err.into()))
-        })?;
-        Ok(VhostUserFsThread {
-            core,
-            mem: None,
-            vu_req: None,
-            event_idx: false,
-            kill_event_fd: event_fd,
-        })
-    }
-
-    /// This is used when the backend has processed a request and needs to 
notify the frontend.
-    fn return_descriptor(
-        vring_state: &mut VringState,
-        head_index: u16,
-        event_idx: bool,
-        len: usize,
-    ) {
-        if vring_state.add_used(head_index, len as u32).is_err() {
-            warn!("Failed to add used to used queue.");
-        };
-        // Check if the used queue needs to be signaled.
-        if event_idx {
-            match vring_state.needs_notification() {
-                Ok(needs_notification) => {
-                    if needs_notification && 
vring_state.signal_used_queue().is_err() {
-                        warn!("Failed to signal used queue.");
-                    }
-                }
-                Err(_) => {
-                    if vring_state.signal_used_queue().is_err() {
-                        warn!("Failed to signal used queue.");
-                    };
-                }
-            }
-        } else if vring_state.signal_used_queue().is_err() {
-            warn!("Failed to signal used queue.");
-        }
-    }
-
-    /// Process filesystem requests one at a time in a serialized manner.
-    fn handle_event_serial(&self, device_event: u16, vrings: &[VringMutex]) -> 
Result<()> {
-        let mut vring_state = match device_event {
-            HIPRIO_QUEUE_EVENT => vrings[0].get_mut(),
-            REQ_QUEUE_EVENT => vrings[1].get_mut(),
-            _ => return Err(new_unexpected_error("failed to handle unknown 
event", None)),
-        };
-        if self.event_idx {
-            // If EVENT_IDX is enabled, we could keep calling process_queue()
-            // until it stops finding new request on the queue.
-            loop {
-                if vring_state.disable_notification().is_err() {
-                    warn!("Failed to disable used queue notification.");
-                }
-                self.process_queue_serial(&mut vring_state)?;
-                if let Ok(has_more) = vring_state.enable_notification() {
-                    if !has_more {
-                        break;
-                    }
-                } else {
-                    warn!("Failed to enable used queue notification.");
-                }
-            }
-        } else {
-            // Without EVENT_IDX, a single call is enough.
-            self.process_queue_serial(&mut vring_state)?;
-        }
-        Ok(())
-    }
-
-    /// Forwards filesystem messages to specific functions and
-    /// returns the filesystem request execution result.
-    fn process_queue_serial(&self, vring_state: &mut VringState) -> 
Result<bool> {
-        let mut used_any = false;
-        let mem = match &self.mem {
-            Some(m) => m.memory(),
-            None => return Err(new_unexpected_error("no memory configured", 
None)),
-        };
-        let avail_chains: 
Vec<DescriptorChain<GuestMemoryLoadGuard<GuestMemoryMmap>>> = vring_state
-            .get_queue_mut()
-            .iter(mem.clone())
-            .map_err(|_| new_unexpected_error("iterating through the queue 
failed", None))?
-            .collect();
-        for chain in avail_chains {
-            used_any = true;
-            let head_index = chain.head_index();
-            let reader = Reader::new(&mem, chain.clone())
-                .map_err(|_| new_unexpected_error("creating a queue reader 
failed", None))
-                .unwrap();
-            let writer = Writer::new(&mem, chain.clone())
-                .map_err(|_| new_unexpected_error("creating a queue writer 
failed", None))
-                .unwrap();
-            let len = self
-                .core
-                .handle_message(reader, writer)
-                .map_err(|_| new_unexpected_error("processing a queue request 
failed", None))
-                .unwrap();
-            VhostUserFsThread::return_descriptor(vring_state, head_index, 
self.event_idx, len);
-        }
-        Ok(used_any)
-    }
-}
-
-/// VhostUserFsBackend is a structure that implements the VhostUserBackend 
trait
-/// and implements concrete services for the vhost user backend server.
-struct VhostUserFsBackend {
-    thread: RwLock<VhostUserFsThread>,
-}
-
-impl VhostUserFsBackend {
-    fn new(core: Filesystem) -> Result<VhostUserFsBackend> {
-        let thread = RwLock::new(VhostUserFsThread::new(core)?);
-        Ok(VhostUserFsBackend { thread })
-    }
-
-    fn kill(&self) -> Result<()> {
-        self.thread
-            .read()
-            .unwrap()
-            .kill_event_fd
-            .write(1)
-            .map_err(|err| {
-                new_unexpected_error("failed to write to kill eventfd", 
Some(err.into()))
-            })
-    }
-}
-
-impl VhostUserBackend for VhostUserFsBackend {
-    type Bitmap = ();
-    type Vring = VringMutex;
-
-    /// Get number of queues supported.
-    fn num_queues(&self) -> usize {
-        NUM_QUEUES
-    }
-
-    /// Get maximum queue size supported.
-    fn max_queue_size(&self) -> usize {
-        QUEUE_SIZE
-    }
-
-    /// Get available virtio features.
-    fn features(&self) -> u64 {
-        // Align to the virtiofsd's features here.
-        (1 << VIRTIO_F_VERSION_1)
-            | (1 << VIRTIO_RING_F_INDIRECT_DESC)
-            | (1 << VIRTIO_RING_F_EVENT_IDX)
-            | VhostUserVirtioFeatures::PROTOCOL_FEATURES.bits()
-    }
-
-    /// Get available vhost protocol features.
-    fn protocol_features(&self) -> VhostUserProtocolFeatures {
-        // Align to the virtiofsd's protocol features here.
-        VhostUserProtocolFeatures::MQ
-            | VhostUserProtocolFeatures::BACKEND_REQ
-            | VhostUserProtocolFeatures::BACKEND_SEND_FD
-            | VhostUserProtocolFeatures::REPLY_ACK
-            | VhostUserProtocolFeatures::CONFIGURE_MEM_SLOTS
-    }
-
-    /// Enable or disabled the virtio EVENT_IDX feature.
-    fn set_event_idx(&self, enabled: bool) {
-        self.thread.write().unwrap().event_idx = enabled;
-    }
-
-    /// Update guest memory regions.
-    fn update_memory(&self, mem: GuestMemoryAtomic<GuestMemoryMmap>) -> 
io::Result<()> {
-        self.thread.write().unwrap().mem = Some(mem);
-        Ok(())
-    }
-
-    /// Set handler for communicating with the frontend by the backend 
communication channel.
-    fn set_backend_req_fd(&self, vu_req: Backend) {
-        self.thread.write().unwrap().vu_req = Some(vu_req);
-    }
-
-    /// Provide an optional exit EventFd for the specified worker thread.
-    fn exit_event(&self, _thread_index: usize) -> Option<EventFd> {
-        Some(
-            self.thread
-                .read()
-                .unwrap()
-                .kill_event_fd
-                .try_clone()
-                .unwrap(),
-        )
-    }
-
-    /// Handle IO events for backend registered file descriptors.
-    fn handle_event(
-        &self,
-        device_event: u16,
-        evset: EventSet,
-        vrings: &[Self::Vring],
-        _thread_id: usize,
-    ) -> io::Result<()> {
-        if evset != EventSet::IN {
-            return Err(new_unexpected_error(
-                "failed to handle event other than input event",
-                None,
-            )
-            .into());
-        }
-        let thread = self.thread.read().unwrap();
-        thread
-            .handle_event_serial(device_event, vrings)
-            .map_err(|err| err.into())
-    }
-}
-
-/// VirtioFS is a structure that represents the virtiofs service.
-/// It is used to run the virtiofs service with the given operator and socket 
path.
-/// The operator is used to interact with the backend storage system.
-/// The socket path is used to communicate with the QEMU and VMs.
-pub struct VirtioFs {
-    socket_path: String,
-    filesystem_backend: Arc<VhostUserFsBackend>,
-}
-
-impl VirtioFs {
-    pub fn new(core: Operator, socket_path: &str) -> Result<VirtioFs> {
-        let filesystem_core = Filesystem::new(core);
-        let filesystem_backend = 
Arc::new(VhostUserFsBackend::new(filesystem_core).unwrap());
-        Ok(VirtioFs {
-            socket_path: socket_path.to_string(),
-            filesystem_backend,
-        })
-    }
-
-    // Run the virtiofs service.
-    pub fn run(&self) -> Result<()> {
-        let listener = Listener::new(&self.socket_path, true)
-            .map_err(|_| new_unexpected_error("failed to create listener", 
None))?;
-        let mut daemon = VhostUserDaemon::new(
-            String::from("virtiofs-backend"),
-            self.filesystem_backend.clone(),
-            GuestMemoryAtomic::new(GuestMemoryMmap::new()),
-        )
-        .unwrap();
-        if daemon.start(listener).is_err() {
-            return Err(new_unexpected_error("failed to start daemon", None));
-        }
-        if daemon.wait().is_err() {
-            return Err(new_unexpected_error("failed to wait daemon", None));
-        }
-        Ok(())
-    }
-
-    // Kill the virtiofs service.
-    pub fn kill(&self) -> Result<()> {
-        if self.filesystem_backend.kill().is_err() {
-            return Err(new_unexpected_error("failed to kill backend", None));
-        }
-        Ok(())
-    }
-}
diff --git a/integrations/virtiofs/src/virtiofs_util.rs 
b/integrations/virtiofs/src/virtiofs_util.rs
deleted file mode 100644
index aac478f5d..000000000
--- a/integrations/virtiofs/src/virtiofs_util.rs
+++ /dev/null
@@ -1,492 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-use std::cmp::min;
-use std::collections::VecDeque;
-use std::io::Read;
-use std::io::Write;
-use std::io::{self};
-use std::mem::MaybeUninit;
-use std::mem::size_of;
-use std::ops::Deref;
-use std::ptr::copy_nonoverlapping;
-
-use virtio_queue::DescriptorChain;
-use vm_memory::Address;
-use vm_memory::ByteValued;
-use vm_memory::GuestMemory;
-use vm_memory::GuestMemoryMmap;
-use vm_memory::GuestMemoryRegion;
-use vm_memory::VolatileMemory;
-use vm_memory::VolatileSlice;
-use vm_memory::bitmap::Bitmap;
-use vm_memory::bitmap::BitmapSlice;
-
-use crate::buffer::ReadWriteAtVolatile;
-use crate::error::*;
-
-/// Used to consume and use data areas in shared memory between host and VMs.
-struct DescriptorChainConsumer<'a, B> {
-    buffers: VecDeque<VolatileSlice<'a, B>>,
-    bytes_consumed: usize,
-}
-
-impl<'a, B: BitmapSlice> DescriptorChainConsumer<'a, B> {
-    #[cfg(test)]
-    fn available_bytes(&self) -> usize {
-        self.buffers.iter().fold(0, |count, vs| count + vs.len())
-    }
-
-    fn bytes_consumed(&self) -> usize {
-        self.bytes_consumed
-    }
-
-    fn consume<F>(&mut self, count: usize, f: F) -> Result<usize>
-    where
-        F: FnOnce(&[&VolatileSlice<B>]) -> Result<usize>,
-    {
-        let mut len = 0;
-        let mut bufs = Vec::with_capacity(self.buffers.len());
-        for vs in &self.buffers {
-            if len >= count {
-                break;
-            }
-            bufs.push(vs);
-            let remain = count - len;
-            if remain < vs.len() {
-                len += remain;
-            } else {
-                len += vs.len();
-            }
-        }
-        if bufs.is_empty() {
-            return Ok(0);
-        }
-        let bytes_consumed = f(&bufs)?;
-        let total_bytes_consumed =
-            self.bytes_consumed
-                .checked_add(bytes_consumed)
-                .ok_or(new_vhost_user_fs_error(
-                    "the combined length of all the buffers in DescriptorChain 
would overflow",
-                    None,
-                ))?;
-        let mut remain = bytes_consumed;
-        while let Some(vs) = self.buffers.pop_front() {
-            if remain < vs.len() {
-                self.buffers.push_front(vs.offset(remain).unwrap());
-                break;
-            }
-            remain -= vs.len();
-        }
-        self.bytes_consumed = total_bytes_consumed;
-        Ok(bytes_consumed)
-    }
-
-    fn split_at(&mut self, offset: usize) -> 
Result<DescriptorChainConsumer<'a, B>> {
-        let mut remain = offset;
-        let pos = self.buffers.iter().position(|vs| {
-            if remain < vs.len() {
-                true
-            } else {
-                remain -= vs.len();
-                false
-            }
-        });
-        if let Some(at) = pos {
-            let mut other = self.buffers.split_off(at);
-            if remain > 0 {
-                let front = other.pop_front().expect("empty VecDeque after 
split");
-                self.buffers.push_back(
-                    front
-                        .subslice(0, remain)
-                        .map_err(|_| new_vhost_user_fs_error("volatile memory 
error", None))?,
-                );
-                other.push_front(
-                    front
-                        .offset(remain)
-                        .map_err(|_| new_vhost_user_fs_error("volatile memory 
error", None))?,
-                );
-            }
-            Ok(DescriptorChainConsumer {
-                buffers: other,
-                bytes_consumed: 0,
-            })
-        } else if remain == 0 {
-            Ok(DescriptorChainConsumer {
-                buffers: VecDeque::new(),
-                bytes_consumed: 0,
-            })
-        } else {
-            Err(new_vhost_user_fs_error(
-                "DescriptorChain split is out of bounds",
-                None,
-            ))
-        }
-    }
-}
-
-/// Provides a high-level interface for reading data in shared memory 
sequences.
-pub struct Reader<'a, B = ()> {
-    buffer: DescriptorChainConsumer<'a, B>,
-}
-
-impl<'a, B: Bitmap + BitmapSlice + 'static> Reader<'a, B> {
-    pub fn new<M>(
-        mem: &'a GuestMemoryMmap<B>,
-        desc_chain: DescriptorChain<M>,
-    ) -> Result<Reader<'a, B>>
-    where
-        M: Deref,
-        M::Target: GuestMemory + Sized,
-    {
-        let mut len: usize = 0;
-        let buffers = desc_chain
-            .readable()
-            .map(|desc| {
-                len = len
-                    .checked_add(desc.len() as usize)
-                    .ok_or(new_vhost_user_fs_error(
-                        "the combined length of all the buffers in 
DescriptorChain would overflow",
-                        None,
-                    ))?;
-                let region = 
mem.find_region(desc.addr()).ok_or(new_vhost_user_fs_error(
-                    "no memory region for this address range",
-                    None,
-                ))?;
-                let offset = desc
-                    .addr()
-                    .checked_sub(region.start_addr().raw_value())
-                    .unwrap();
-                region
-                    .deref()
-                    .get_slice(offset.raw_value() as usize, desc.len() as 
usize)
-                    .map_err(|err| {
-                        new_vhost_user_fs_error("volatile memory error", 
Some(err.into()))
-                    })
-            })
-            .collect::<Result<VecDeque<VolatileSlice<'a, B>>>>()?;
-        Ok(Reader {
-            buffer: DescriptorChainConsumer {
-                buffers,
-                bytes_consumed: 0,
-            },
-        })
-    }
-
-    pub fn read_obj<T: ByteValued>(&mut self) -> io::Result<T> {
-        let mut obj = MaybeUninit::<T>::uninit();
-        let buf =
-            unsafe { std::slice::from_raw_parts_mut(obj.as_mut_ptr() as *mut 
u8, size_of::<T>()) };
-        self.read_exact(buf)?;
-        Ok(unsafe { obj.assume_init() })
-    }
-
-    pub fn read_to_at<F: ReadWriteAtVolatile<B>>(
-        &mut self,
-        dst: F,
-        count: usize,
-    ) -> io::Result<usize> {
-        self.buffer
-            .consume(count, |bufs| dst.write_vectored_at_volatile(bufs))
-            .map_err(|err| err.into())
-    }
-
-    #[cfg(test)]
-    pub fn available_bytes(&self) -> usize {
-        self.buffer.available_bytes()
-    }
-
-    #[cfg(test)]
-    pub fn bytes_read(&self) -> usize {
-        self.buffer.bytes_consumed()
-    }
-}
-
-impl<B: BitmapSlice> io::Read for Reader<'_, B> {
-    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
-        self.buffer
-            .consume(buf.len(), |bufs| {
-                let mut rem = buf;
-                let mut total = 0;
-                for vs in bufs {
-                    let copy_len = min(rem.len(), vs.len());
-                    unsafe {
-                        copy_nonoverlapping(vs.ptr_guard().as_ptr(), 
rem.as_mut_ptr(), copy_len);
-                    }
-                    rem = &mut rem[copy_len..];
-                    total += copy_len;
-                }
-                Ok(total)
-            })
-            .map_err(|err| err.into())
-    }
-}
-
-/// Provides a high-level interface for writing data in shared memory 
sequences.
-pub struct Writer<'a, B = ()> {
-    buffer: DescriptorChainConsumer<'a, B>,
-}
-
-impl<'a, B: Bitmap + BitmapSlice + 'static> Writer<'a, B> {
-    pub fn new<M>(
-        mem: &'a GuestMemoryMmap<B>,
-        desc_chain: DescriptorChain<M>,
-    ) -> Result<Writer<'a, B>>
-    where
-        M: Deref,
-        M::Target: GuestMemory + Sized,
-    {
-        let mut len: usize = 0;
-        let buffers = desc_chain
-            .writable()
-            .map(|desc| {
-                len = len
-                    .checked_add(desc.len() as usize)
-                    .ok_or(new_vhost_user_fs_error(
-                        "the combined length of all the buffers in 
DescriptorChain would overflow",
-                        None,
-                    ))?;
-                let region = 
mem.find_region(desc.addr()).ok_or(new_vhost_user_fs_error(
-                    "no memory region for this address range",
-                    None,
-                ))?;
-                let offset = desc
-                    .addr()
-                    .checked_sub(region.start_addr().raw_value())
-                    .unwrap();
-                region
-                    .deref()
-                    .get_slice(offset.raw_value() as usize, desc.len() as 
usize)
-                    .map_err(|err| {
-                        new_vhost_user_fs_error("volatile memory error", 
Some(err.into()))
-                    })
-            })
-            .collect::<Result<VecDeque<VolatileSlice<'a, B>>>>()?;
-        Ok(Writer {
-            buffer: DescriptorChainConsumer {
-                buffers,
-                bytes_consumed: 0,
-            },
-        })
-    }
-
-    pub fn split_at(&mut self, offset: usize) -> Result<Writer<'a, B>> {
-        self.buffer.split_at(offset).map(|buffer| Writer { buffer })
-    }
-
-    pub fn write_from_at<F: ReadWriteAtVolatile<B>>(
-        &mut self,
-        src: F,
-        count: usize,
-    ) -> io::Result<usize> {
-        self.buffer
-            .consume(count, |bufs| src.read_vectored_at_volatile(bufs))
-            .map_err(|err| err.into())
-    }
-
-    #[cfg(test)]
-    pub fn available_bytes(&self) -> usize {
-        self.buffer.available_bytes()
-    }
-
-    pub fn bytes_written(&self) -> usize {
-        self.buffer.bytes_consumed()
-    }
-}
-
-impl<B: BitmapSlice> Write for Writer<'_, B> {
-    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
-        self.buffer
-            .consume(buf.len(), |bufs| {
-                let mut rem = buf;
-                let mut total = 0;
-                for vs in bufs {
-                    let copy_len = min(rem.len(), vs.len());
-                    unsafe {
-                        copy_nonoverlapping(rem.as_ptr(), 
vs.ptr_guard_mut().as_ptr(), copy_len);
-                    }
-                    vs.bitmap().mark_dirty(0, copy_len);
-                    rem = &rem[copy_len..];
-                    total += copy_len;
-                }
-                Ok(total)
-            })
-            .map_err(|err| err.into())
-    }
-
-    fn flush(&mut self) -> io::Result<()> {
-        Ok(())
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-    use virtio_queue::Queue;
-    use virtio_queue::QueueOwnedT;
-    use virtio_queue::QueueT;
-    use vm_memory::Bytes;
-    use vm_memory::GuestAddress;
-    use vm_memory::Le16;
-    use vm_memory::Le32;
-    use vm_memory::Le64;
-
-    const VIRTQ_DESC_F_NEXT: u16 = 0x1;
-    const VIRTQ_DESC_F_WRITE: u16 = 0x2;
-
-    enum DescriptorType {
-        Readable,
-        Writable,
-    }
-
-    // Helper structure for testing, used to define the layout of the 
descriptor chain.
-    #[derive(Copy, Clone, Debug, Default)]
-    #[repr(C)]
-    struct VirtqDesc {
-        addr: Le64,
-        len: Le32,
-        flags: Le16,
-        next: Le16,
-    }
-
-    // Helper structure for testing, used to define the layout of the 
available ring.
-    #[derive(Copy, Clone, Debug, Default)]
-    #[repr(C)]
-    struct VirtqAvail {
-        flags: Le16,
-        idx: Le16,
-        ring: Le16,
-    }
-
-    unsafe impl ByteValued for VirtqAvail {}
-    unsafe impl ByteValued for VirtqDesc {}
-
-    // Helper function for testing, used to create a descriptor chain with the 
specified descriptors.
-    fn create_descriptor_chain(
-        memory: &GuestMemoryMmap,
-        descriptor_array_addr: GuestAddress,
-        mut buffers_start_addr: GuestAddress,
-        descriptors: Vec<(DescriptorType, u32)>,
-    ) -> DescriptorChain<&GuestMemoryMmap> {
-        let descriptors_len = descriptors.len();
-        for (index, (type_, size)) in descriptors.into_iter().enumerate() {
-            let mut flags = 0;
-            if let DescriptorType::Writable = type_ {
-                flags |= VIRTQ_DESC_F_WRITE;
-            }
-            if index + 1 < descriptors_len {
-                flags |= VIRTQ_DESC_F_NEXT;
-            }
-
-            let desc = VirtqDesc {
-                addr: buffers_start_addr.raw_value().into(),
-                len: size.into(),
-                flags: flags.into(),
-                next: (index as u16 + 1).into(),
-            };
-
-            buffers_start_addr = buffers_start_addr.checked_add(size as 
u64).unwrap();
-
-            memory
-                .write_obj(
-                    desc,
-                    descriptor_array_addr
-                        .checked_add((index * 
std::mem::size_of::<VirtqDesc>()) as u64)
-                        .unwrap(),
-                )
-                .unwrap();
-        }
-
-        let avail_ring = descriptor_array_addr
-            .checked_add((descriptors_len * std::mem::size_of::<VirtqDesc>()) 
as u64)
-            .unwrap();
-        let avail = VirtqAvail {
-            flags: 0.into(),
-            idx: 1.into(),
-            ring: 0.into(),
-        };
-        memory.write_obj(avail, avail_ring).unwrap();
-
-        let mut queue = Queue::new(4).unwrap();
-        queue
-            .try_set_desc_table_address(descriptor_array_addr)
-            .unwrap();
-        queue.try_set_avail_ring_address(avail_ring).unwrap();
-        queue.set_ready(true);
-        queue.iter(memory).unwrap().next().unwrap()
-    }
-
-    #[test]
-    fn simple_chain_reader_test() {
-        let memory_start_addr = GuestAddress(0x0);
-        let memory = GuestMemoryMmap::from_ranges(&[(memory_start_addr, 
0x1000)]).unwrap();
-
-        let chain = create_descriptor_chain(
-            &memory,
-            GuestAddress(0x0),
-            GuestAddress(0x100),
-            vec![
-                (DescriptorType::Readable, 8),
-                (DescriptorType::Readable, 16),
-                (DescriptorType::Readable, 18),
-                (DescriptorType::Readable, 64),
-            ],
-        );
-
-        let mut reader = Reader::new(&memory, chain).unwrap();
-        assert_eq!(reader.available_bytes(), 106);
-        assert_eq!(reader.bytes_read(), 0);
-
-        let mut buffer = [0; 64];
-        reader.read_exact(&mut buffer).unwrap();
-        assert_eq!(reader.available_bytes(), 42);
-        assert_eq!(reader.bytes_read(), 64);
-        assert_eq!(reader.read(&mut buffer).unwrap(), 42);
-        assert_eq!(reader.available_bytes(), 0);
-        assert_eq!(reader.bytes_read(), 106);
-    }
-
-    #[test]
-    fn simple_chain_writer_test() {
-        let memory_start_addr = GuestAddress(0x0);
-        let memory = GuestMemoryMmap::from_ranges(&[(memory_start_addr, 
0x1000)]).unwrap();
-
-        let chain = create_descriptor_chain(
-            &memory,
-            GuestAddress(0x0),
-            GuestAddress(0x100),
-            vec![
-                (DescriptorType::Writable, 8),
-                (DescriptorType::Writable, 16),
-                (DescriptorType::Writable, 18),
-                (DescriptorType::Writable, 64),
-            ],
-        );
-
-        let mut writer = Writer::new(&memory, chain).unwrap();
-        assert_eq!(writer.available_bytes(), 106);
-        assert_eq!(writer.bytes_written(), 0);
-
-        let buffer = [0; 64];
-        writer.write_all(&buffer).unwrap();
-        assert_eq!(writer.available_bytes(), 42);
-        assert_eq!(writer.bytes_written(), 64);
-        assert_eq!(writer.write(&buffer).unwrap(), 42);
-        assert_eq!(writer.available_bytes(), 0);
-        assert_eq!(writer.bytes_written(), 106);
-    }
-}
diff --git a/website/docs/30-integrations/virtiofs.mdx 
b/website/docs/30-integrations/virtiofs.mdx
deleted file mode 100644
index e7ecd117b..000000000
--- a/website/docs/30-integrations/virtiofs.mdx
+++ /dev/null
@@ -1,10 +0,0 @@
----
-title: Virtiofs
----
-
-import GitHubReadme from '@site/components/GitHubReadme';
-import Content from '../../../integrations/virtiofs/README.md';
-
-<GitHubReadme basePath="integrations/virtiofs/">
-  <Content components={{ h1: 'h2' }} />
-</GitHubReadme>


Reply via email to