Skip to content

Commit f99a892

Browse files
committed
api: enable io-uring based asynchronous IO
Enalbe io-uring based asynchronous IO. Signed-off-by: Jiang Liu <[email protected]>
1 parent 096ad2e commit f99a892

File tree

21 files changed

+410
-523
lines changed

21 files changed

+410
-523
lines changed

Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ vm-memory = { version = "0.7", features = ["backend-mmap", "backend-bitmap"] }
4646

4747
[features]
4848
default = ["fusedev"]
49-
#async-io = ["async-trait", "futures", "caps]
5049
async-io = ["async-trait", "futures", "tokio-uring"]
5150
fusedev = ["vmm-sys-util", "caps", "core-foundation-sys"]
5251
virtiofs = ["virtio-queue", "caps"]

src/api/filesystem/async_io.rs

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,24 @@
1-
// Copyright (C) 2021 Alibaba Cloud. All rights reserved.
1+
// Copyright (C) 2021-2022 Alibaba Cloud. All rights reserved.
22
// SPDX-License-Identifier: Apache-2.0
33

44
use std::ffi::CStr;
55
use std::future::Future;
66
use std::io;
77
use std::ops::Deref;
8-
use std::os::unix::io::RawFd;
98
use std::pin::Pin;
109
use std::sync::Arc;
1110
use std::time::Duration;
1211

1312
use async_trait::async_trait;
1413

1514
use super::{Context, Entry, FileSystem, ZeroCopyReader, ZeroCopyWriter};
16-
use crate::abi::fuse_abi::{stat64, OpenOptions, SetattrValid};
17-
use crate::api::CreateIn;
18-
use crate::async_util::{AsyncDrive, AsyncDriver};
15+
use crate::abi::fuse_abi::{stat64, CreateIn, OpenOptions, SetattrValid};
16+
use crate::transport::AsyncFileReadWriteVolatile;
1917

2018
/// A trait for directly copying data from the fuse transport into a `File` without first storing it
2119
/// in an intermediate buffer in asynchronous mode.
22-
#[async_trait]
23-
pub trait AsyncZeroCopyReader<D: AsyncDrive = AsyncDriver>: ZeroCopyReader {
20+
#[async_trait(?Send)]
21+
pub trait AsyncZeroCopyReader: ZeroCopyReader {
2422
/// Copies at most `count` bytes from `self` directly into `f` at offset `off` without storing
2523
/// it in any intermediate buffers. If the return value is `Ok(n)` then it must be guaranteed
2624
/// that `0 <= n <= count`. If `n` is `0`, then it can indicate one of 3 possibilities:
@@ -36,17 +34,16 @@ pub trait AsyncZeroCopyReader<D: AsyncDrive = AsyncDriver>: ZeroCopyReader {
3634
/// an error of the kind `io::ErrorKind::WriteZero`.
3735
async fn async_read_to(
3836
&mut self,
39-
drive: D,
40-
f: RawFd,
37+
f: Arc<dyn AsyncFileReadWriteVolatile>,
4138
count: usize,
4239
off: u64,
4340
) -> io::Result<usize>;
4441
}
4542

4643
/// A trait for directly copying data from a `RawFd` into the fuse transport without first storing
4744
/// it in an intermediate buffer in asynchronous mode.
48-
#[async_trait]
49-
pub trait AsyncZeroCopyWriter<D: AsyncDrive = AsyncDriver>: ZeroCopyWriter {
45+
#[async_trait(?Send)]
46+
pub trait AsyncZeroCopyWriter: ZeroCopyWriter {
5047
/// Copies at most `count` bytes from `f` at offset `off` directly into `self` without storing
5148
/// it in any intermediate buffers. If the return value is `Ok(n)` then it must be guaranteed
5249
/// that `0 <= n <= count`. If `n` is `0`, then it can indicate one of 3 possibilities:
@@ -62,8 +59,7 @@ pub trait AsyncZeroCopyWriter<D: AsyncDrive = AsyncDriver>: ZeroCopyWriter {
6259
/// error of the kind `io::ErrorKind::UnexpectedEof`.
6360
async fn async_write_from(
6461
&mut self,
65-
drive: D,
66-
f: RawFd,
62+
f: Arc<dyn AsyncFileReadWriteVolatile>,
6763
count: usize,
6864
off: u64,
6965
) -> io::Result<usize>;
@@ -72,7 +68,7 @@ pub trait AsyncZeroCopyWriter<D: AsyncDrive = AsyncDriver>: ZeroCopyWriter {
7268
/// The main trait that connects a file system with a transport with asynchronous IO.
7369
#[allow(unused_variables)]
7470
#[async_trait]
75-
pub trait AsyncFileSystem<D: AsyncDrive = AsyncDriver>: FileSystem {
71+
pub trait AsyncFileSystem: FileSystem {
7672
/// Look up a directory entry by name and get its attributes.
7773
///
7874
/// If this call is successful then the lookup count of the `Inode` associated with the returned
@@ -362,7 +358,7 @@ pub trait AsyncFileSystem<D: AsyncDrive = AsyncDriver>: FileSystem {
362358
ctx: &Context,
363359
inode: Self::Inode,
364360
handle: Self::Handle,
365-
w: &mut (dyn AsyncZeroCopyWriter<D> + Send),
361+
w: &mut (dyn AsyncZeroCopyWriter + Send),
366362
size: u32,
367363
offset: u64,
368364
lock_owner: Option<u64>,
@@ -394,7 +390,7 @@ pub trait AsyncFileSystem<D: AsyncDrive = AsyncDriver>: FileSystem {
394390
ctx: &Context,
395391
inode: Self::Inode,
396392
handle: Self::Handle,
397-
r: &mut (dyn AsyncZeroCopyReader<D> + Send),
393+
r: &mut (dyn AsyncZeroCopyReader + Send),
398394
size: u32,
399395
offset: u64,
400396
lock_owner: Option<u64>,
@@ -845,7 +841,7 @@ type OpenFuture<'async_trait, H> =
845841
type CreateFuture<'async_trait, H> =
846842
Box<dyn Future<Output = io::Result<(Entry, Option<H>, OpenOptions)>> + Send + 'async_trait>;
847843

848-
impl<FS: AsyncFileSystem<D>, D: AsyncDrive> AsyncFileSystem<D> for Arc<FS> {
844+
impl<FS: AsyncFileSystem> AsyncFileSystem for Arc<FS> {
849845
fn async_lookup<'a, 'b, 'c, 'async_trait>(
850846
&'a self,
851847
ctx: &'b Context,
@@ -927,7 +923,7 @@ impl<FS: AsyncFileSystem<D>, D: AsyncDrive> AsyncFileSystem<D> for Arc<FS> {
927923
ctx: &'b Context,
928924
inode: Self::Inode,
929925
handle: Self::Handle,
930-
w: &'c mut (dyn AsyncZeroCopyWriter<D> + Send),
926+
w: &'c mut (dyn AsyncZeroCopyWriter + Send),
931927
size: u32,
932928
offset: u64,
933929
lock_owner: Option<u64>,
@@ -948,7 +944,7 @@ impl<FS: AsyncFileSystem<D>, D: AsyncDrive> AsyncFileSystem<D> for Arc<FS> {
948944
ctx: &'b Context,
949945
inode: Self::Inode,
950946
handle: Self::Handle,
951-
r: &'c mut (dyn AsyncZeroCopyReader<D> + Send),
947+
r: &'c mut (dyn AsyncZeroCopyReader + Send),
952948
size: u32,
953949
offset: u64,
954950
lock_owner: Option<u64>,

src/api/filesystem/mod.rs

Lines changed: 3 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (C) 2020 Alibaba Cloud. All rights reserved.
1+
// Copyright (C) 2020-2022 Alibaba Cloud. All rights reserved.
22
// Copyright 2019 The Chromium OS Authors. All rights reserved.
33
// Use of this source code is governed by a BSD-style license that can be
44
// found in the LICENSE-BSD-3-Clause file.
@@ -22,9 +22,9 @@ pub use fuse::ROOT_ID;
2222

2323
use crate::abi::fuse_abi::{ino64_t, stat64};
2424

25-
#[cfg(feature = "async_io")]
25+
#[cfg(feature = "async-io")]
2626
mod async_io;
27-
#[cfg(feature = "async_io")]
27+
#[cfg(feature = "async-io")]
2828
pub use async_io::{AsyncFileSystem, AsyncZeroCopyReader, AsyncZeroCopyWriter};
2929

3030
mod sync_io;
@@ -383,10 +383,6 @@ pub struct Context {
383383

384384
/// The thread group ID of the calling process.
385385
pub pid: libc::pid_t,
386-
387-
#[cfg(feature = "async_io")]
388-
/// Asynchronous event drive
389-
pub drive: usize,
390386
}
391387

392388
impl Context {
@@ -402,38 +398,6 @@ impl From<&fuse::InHeader> for Context {
402398
uid: source.uid,
403399
gid: source.gid,
404400
pid: source.pid as i32,
405-
#[cfg(feature = "async_io")]
406-
drive: 0,
407-
}
408-
}
409-
}
410-
411-
// The design is very ugly, but it helps to avoid adding a generic type parameter "D: AsyncDrive"
412-
// to the FileSystem trait.
413-
#[cfg(feature = "async_io")]
414-
impl Context {
415-
/// Set the asynchronous event drive.
416-
///
417-
/// ## Safety
418-
/// The caller must ensure that the the referenced `drive` has a longer lifetime than the
419-
/// `Context` object.
420-
pub(crate) unsafe fn set_drive<D: crate::async_util::AsyncDrive>(&mut self, drive: &D) {
421-
// The generic type `D` has bound as "Clone + Send". `D` is Send, then `&D` is Sync,
422-
// so it's safe to call drive.clone() in get_drive() only if the caller ensures `drive`
423-
// has longer lifetime than this `Context` object.
424-
self.drive = drive as *const D as *const u8 as usize;
425-
}
426-
427-
/// Get an asynchronous event drive.
428-
///
429-
/// If `get_drive()` returns None, it means async io has been disabled for the associated
430-
/// fuse request.
431-
pub fn get_drive<D: crate::async_util::AsyncDrive>(&self) -> Option<D> {
432-
if self.drive == 0 {
433-
None
434-
} else {
435-
let drive = unsafe { &*(self.drive as *const u8 as *const D) };
436-
Some(drive.clone())
437401
}
438402
}
439403
}

src/api/filesystem/sync_io.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
1-
// Copyright (C) 2021 Alibaba Cloud. All rights reserved.
1+
// Copyright (C) 2021-2022 Alibaba Cloud. All rights reserved.
22
// Copyright 2019 The Chromium OS Authors. All rights reserved.
33
// Use of this source code is governed by a BSD-style license that can be
44
// found in the LICENSE-BSD-3-Clause file.
55

6+
use std::ffi::CStr;
7+
use std::io;
8+
use std::mem;
9+
use std::ops::Deref;
10+
use std::sync::Arc;
11+
use std::time::Duration;
12+
613
use super::{
714
Context, DirEntry, Entry, FileLock, GetxattrReply, IoctlData, ListxattrReply, ZeroCopyReader,
815
ZeroCopyWriter,
@@ -12,12 +19,6 @@ use crate::abi::fuse_abi::{stat64, statvfs64, CreateIn, FsOptions, OpenOptions,
1219
pub use crate::abi::virtio_fs::RemovemappingOne;
1320
#[cfg(feature = "virtiofs")]
1421
use crate::transport::FsCacheReqHandler;
15-
use std::ffi::CStr;
16-
use std::io;
17-
use std::mem;
18-
use std::ops::Deref;
19-
use std::sync::Arc;
20-
use std::time::Duration;
2122

2223
/// The main trait that connects a file system with a transport.
2324
#[allow(unused_variables)]
@@ -1336,7 +1337,7 @@ impl<FS: FileSystem> FileSystem for Arc<FS> {
13361337
.poll(ctx, inode, handle, khandle, flags, events)
13371338
}
13381339

1339-
/// TODO: support this
1340+
/// Send notify reply.
13401341
fn notify_reply(&self) -> io::Result<()> {
13411342
self.deref().notify_reply()
13421343
}

src/api/mod.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@
1212
//! - [struct Vfs](vfs/struct.Vfs.html), a simple union file system to help organize multiple
1313
//! backend file systems.
1414
15-
pub use super::abi::fuse_abi::CreateIn;
16-
1715
mod pseudo_fs;
1816

1917
pub mod vfs;

0 commit comments

Comments
 (0)