diff --git a/block/src/async_io.rs b/block/src/async_io.rs index 07448d4d1..7aa8a4f48 100644 --- a/block/src/async_io.rs +++ b/block/src/async_io.rs @@ -2,7 +2,8 @@ // // SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause -use std::os::fd::RawFd; +use std::marker::PhantomData; +use std::os::fd::{AsRawFd, OwnedFd, RawFd}; use thiserror::Error; use vmm_sys_util::eventfd::EventFd; @@ -21,6 +22,39 @@ pub enum DiskFileError { pub type DiskFileResult = std::result::Result; +/// A wrapper for [`RawFd`] capturing the lifetime of a corresponding [`DiskFile`]. +/// +/// This fulfills the same role as [`BorrowedFd`] but is tailored to the limitations +/// by some implementations of [`DiskFile`], which wrap the effective [`File`] +/// in an `Arc>`, making the use of [`BorrowedFd`] impossible. +/// +/// [`BorrowedFd`]: std::os::fd::BorrowedFd +#[derive(Copy, Clone, Debug)] +pub struct BorrowedDiskFd<'fd> { + raw_fd: RawFd, + _lifetime: PhantomData<&'fd OwnedFd>, +} + +impl BorrowedDiskFd<'_> { + pub(super) fn new(raw_fd: RawFd) -> Self { + Self { + raw_fd, + _lifetime: PhantomData, + } + } +} + +impl AsRawFd for BorrowedDiskFd<'_> { + fn as_raw_fd(&self) -> RawFd { + self.raw_fd + } +} + +/// Abstraction over the effective [`File`] backing up a block device, +/// with support for synchronous and asynchronous I/O. +/// +/// This allows abstracting over raw image formats as well as structured +/// image formats. pub trait DiskFile: Send { fn size(&mut self) -> DiskFileResult; fn new_async_io(&self, ring_depth: u32) -> DiskFileResult>; @@ -28,11 +62,10 @@ pub trait DiskFile: Send { DiskTopology::default() } /// Returns the file descriptor of the underlying disk image file. - // Impl Note: - // This must be `RawFd` instead of `BorrowedFd` or `&File`, as some - // implementations wrap the file in an `Arc>`, which makes it - // impossible to return a reference. - fn fd(&mut self) -> RawFd; + /// + /// The file descriptor is supposed to be used for `fcntl()` calls but no + /// other operation. + fn fd(&mut self) -> BorrowedDiskFd; } #[derive(Error, Debug)] diff --git a/block/src/fixed_vhd_async.rs b/block/src/fixed_vhd_async.rs index 9ba72984e..dd12a7291 100644 --- a/block/src/fixed_vhd_async.rs +++ b/block/src/fixed_vhd_async.rs @@ -8,7 +8,7 @@ use std::os::unix::io::{AsRawFd, RawFd}; use vmm_sys_util::eventfd::EventFd; use crate::async_io::{ - AsyncIo, AsyncIoError, AsyncIoResult, DiskFile, DiskFileError, DiskFileResult, + AsyncIo, AsyncIoError, AsyncIoResult, BorrowedDiskFd, DiskFile, DiskFileError, DiskFileResult, }; use crate::fixed_vhd::FixedVhd; use crate::raw_async::RawFileAsync; @@ -34,8 +34,8 @@ impl DiskFile for FixedVhdDiskAsync { ) as Box) } - fn fd(&mut self) -> RawFd { - self.0.as_raw_fd() + fn fd(&mut self) -> BorrowedDiskFd { + BorrowedDiskFd::new(self.0.as_raw_fd()) } } diff --git a/block/src/fixed_vhd_sync.rs b/block/src/fixed_vhd_sync.rs index 1120aa37b..107a805bd 100644 --- a/block/src/fixed_vhd_sync.rs +++ b/block/src/fixed_vhd_sync.rs @@ -8,7 +8,7 @@ use std::os::unix::io::{AsRawFd, RawFd}; use vmm_sys_util::eventfd::EventFd; use crate::async_io::{ - AsyncIo, AsyncIoError, AsyncIoResult, DiskFile, DiskFileError, DiskFileResult, + AsyncIo, AsyncIoError, AsyncIoResult, BorrowedDiskFd, DiskFile, DiskFileError, DiskFileResult, }; use crate::fixed_vhd::FixedVhd; use crate::raw_sync::RawFileSync; @@ -34,8 +34,8 @@ impl DiskFile for FixedVhdDiskSync { ) as Box) } - fn fd(&mut self) -> RawFd { - self.0.as_raw_fd() + fn fd(&mut self) -> BorrowedDiskFd { + BorrowedDiskFd::new(self.0.as_raw_fd()) } } diff --git a/block/src/qcow_sync.rs b/block/src/qcow_sync.rs index 7c086cd7d..d17d26ca7 100644 --- a/block/src/qcow_sync.rs +++ b/block/src/qcow_sync.rs @@ -5,12 +5,14 @@ use std::collections::VecDeque; use std::fs::File; use std::io::{Seek, SeekFrom}; -use std::os::fd::{AsRawFd, RawFd}; +use std::os::fd::AsRawFd; use std::sync::{Arc, Mutex, MutexGuard}; use vmm_sys_util::eventfd::EventFd; -use crate::async_io::{AsyncIo, AsyncIoResult, DiskFile, DiskFileError, DiskFileResult}; +use crate::async_io::{ + AsyncIo, AsyncIoResult, BorrowedDiskFd, DiskFile, DiskFileError, DiskFileResult, +}; use crate::qcow::{QcowFile, RawFile, Result as QcowResult}; use crate::AsyncAdaptor; @@ -37,9 +39,9 @@ impl DiskFile for QcowDiskSync { Ok(Box::new(QcowSync::new(self.qcow_file.clone())) as Box) } - fn fd(&mut self) -> RawFd { + fn fd(&mut self) -> BorrowedDiskFd { let lock = self.qcow_file.lock().unwrap(); - lock.as_raw_fd() + BorrowedDiskFd::new(lock.as_raw_fd()) } } diff --git a/block/src/raw_async.rs b/block/src/raw_async.rs index 7fd6d80d1..889d47057 100644 --- a/block/src/raw_async.rs +++ b/block/src/raw_async.rs @@ -10,7 +10,7 @@ use io_uring::{opcode, types, IoUring}; use vmm_sys_util::eventfd::EventFd; use crate::async_io::{ - AsyncIo, AsyncIoError, AsyncIoResult, DiskFile, DiskFileError, DiskFileResult, + AsyncIo, AsyncIoError, AsyncIoResult, BorrowedDiskFd, DiskFile, DiskFileError, DiskFileResult, }; use crate::DiskTopology; @@ -47,8 +47,8 @@ impl DiskFile for RawFileDisk { } } - fn fd(&mut self) -> RawFd { - self.file.as_raw_fd() + fn fd(&mut self) -> BorrowedDiskFd { + BorrowedDiskFd::new(self.file.as_raw_fd()) } } diff --git a/block/src/raw_async_aio.rs b/block/src/raw_async_aio.rs index c9d94f963..e203593e5 100644 --- a/block/src/raw_async_aio.rs +++ b/block/src/raw_async_aio.rs @@ -13,7 +13,7 @@ use vmm_sys_util::aio; use vmm_sys_util::eventfd::EventFd; use crate::async_io::{ - AsyncIo, AsyncIoError, AsyncIoResult, DiskFile, DiskFileError, DiskFileResult, + AsyncIo, AsyncIoError, AsyncIoResult, BorrowedDiskFd, DiskFile, DiskFileError, DiskFileResult, }; use crate::DiskTopology; @@ -50,8 +50,8 @@ impl DiskFile for RawFileDiskAio { } } - fn fd(&mut self) -> RawFd { - self.file.as_raw_fd() + fn fd(&mut self) -> BorrowedDiskFd { + BorrowedDiskFd::new(self.file.as_raw_fd()) } } diff --git a/block/src/raw_sync.rs b/block/src/raw_sync.rs index ea716a0e4..4de40c544 100644 --- a/block/src/raw_sync.rs +++ b/block/src/raw_sync.rs @@ -10,7 +10,7 @@ use std::os::unix::io::{AsRawFd, RawFd}; use vmm_sys_util::eventfd::EventFd; use crate::async_io::{ - AsyncIo, AsyncIoError, AsyncIoResult, DiskFile, DiskFileError, DiskFileResult, + AsyncIo, AsyncIoError, AsyncIoResult, BorrowedDiskFd, DiskFile, DiskFileError, DiskFileResult, }; use crate::DiskTopology; @@ -44,8 +44,8 @@ impl DiskFile for RawFileDiskSync { } } - fn fd(&mut self) -> RawFd { - self.file.as_raw_fd() + fn fd(&mut self) -> BorrowedDiskFd { + BorrowedDiskFd::new(self.file.as_raw_fd()) } } diff --git a/block/src/vhdx_sync.rs b/block/src/vhdx_sync.rs index a5b62ee0b..5d12f2ab5 100644 --- a/block/src/vhdx_sync.rs +++ b/block/src/vhdx_sync.rs @@ -4,12 +4,14 @@ use std::collections::VecDeque; use std::fs::File; -use std::os::fd::{AsRawFd, RawFd}; +use std::os::fd::AsRawFd; use std::sync::{Arc, Mutex, MutexGuard}; use vmm_sys_util::eventfd::EventFd; -use crate::async_io::{AsyncIo, AsyncIoResult, DiskFile, DiskFileError, DiskFileResult}; +use crate::async_io::{ + AsyncIo, AsyncIoResult, BorrowedDiskFd, DiskFile, DiskFileError, DiskFileResult, +}; use crate::vhdx::{Result as VhdxResult, Vhdx}; use crate::AsyncAdaptor; @@ -37,9 +39,9 @@ impl DiskFile for VhdxDiskSync { ) } - fn fd(&mut self) -> RawFd { + fn fd(&mut self) -> BorrowedDiskFd { let lock = self.vhdx_file.lock().unwrap(); - lock.as_raw_fd() + BorrowedDiskFd::new(lock.as_raw_fd()) } }