Add `O_DIRECT` support for virtiofs regular-file I/O
This commit is contained in:
parent
52a6e5c291
commit
eb785e45fc
|
|
@ -88,14 +88,16 @@ impl FileOps for VirtioFsFile {
|
|||
&self,
|
||||
offset: usize,
|
||||
writer: &mut VmWriter,
|
||||
_status_flags: StatusFlags,
|
||||
status_flags: StatusFlags,
|
||||
) -> Result<usize> {
|
||||
let fh = self.open_handle.fh();
|
||||
let file_flags = self.open_handle.file_flags();
|
||||
let file_flags = self.open_handle.access_mode() as u32 | status_flags.bits();
|
||||
|
||||
match self.cache_policy {
|
||||
CachePolicy::Cached => self.inode.cached_read_at(offset, writer, fh, file_flags),
|
||||
CachePolicy::Direct => self.inode.direct_read_at(offset, writer, fh, file_flags),
|
||||
if self.cache_policy == CachePolicy::Cached && !status_flags.contains(StatusFlags::O_DIRECT)
|
||||
{
|
||||
self.inode.cached_read_at(offset, writer, fh, file_flags)
|
||||
} else {
|
||||
self.inode.direct_read_at(offset, writer, fh, file_flags)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -105,8 +107,11 @@ impl FileOps for VirtioFsFile {
|
|||
reader: &mut VmReader,
|
||||
status_flags: StatusFlags,
|
||||
) -> Result<usize> {
|
||||
let fh = self.open_handle.fh();
|
||||
let file_flags = self.open_handle.access_mode() as u32 | status_flags.bits();
|
||||
|
||||
let write_offset = if status_flags.contains(StatusFlags::O_APPEND) {
|
||||
self.inode.revalidate_attr(self.open_handle.fh())?;
|
||||
self.inode.revalidate_attr(fh)?;
|
||||
WriteOffset::Append
|
||||
} else {
|
||||
WriteOffset::Absolute(offset)
|
||||
|
|
@ -117,21 +122,14 @@ impl FileOps for VirtioFsFile {
|
|||
// bytes that precede the user write. Keep append writes on the direct
|
||||
// path until writeback can issue precise positional ranges without
|
||||
// append semantics.
|
||||
if self.cache_policy == CachePolicy::Cached && !status_flags.contains(StatusFlags::O_APPEND)
|
||||
if self.cache_policy == CachePolicy::Cached
|
||||
&& !status_flags.intersects(StatusFlags::O_APPEND | StatusFlags::O_DIRECT)
|
||||
{
|
||||
self.inode.cached_write_at(
|
||||
write_offset,
|
||||
reader,
|
||||
self.open_handle.fh(),
|
||||
self.open_handle.file_flags(),
|
||||
)
|
||||
self.inode
|
||||
.cached_write_at(write_offset, reader, fh, file_flags)
|
||||
} else {
|
||||
self.inode.direct_write_at(
|
||||
write_offset,
|
||||
reader,
|
||||
self.open_handle.fh(),
|
||||
self.open_handle.file_flags(),
|
||||
)
|
||||
self.inode
|
||||
.direct_write_at(write_offset, reader, fh, file_flags)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -351,6 +351,7 @@ impl VirtioFsInode {
|
|||
OpenOperation::new(OpenReq::new((access_mode as u32) | status_flags.bits())),
|
||||
)?;
|
||||
let cache_policy = if self.inner.read().page_cache().is_some()
|
||||
&& !status_flags.contains(StatusFlags::O_DIRECT)
|
||||
&& !open_out
|
||||
.open_flags()
|
||||
.contains(FuseOpenFlags::FOPEN_DIRECT_IO)
|
||||
|
|
|
|||
|
|
@ -55,6 +55,11 @@ impl VirtioFsOpenHandle {
|
|||
self.access_mode as u32 | self.status_flags.bits()
|
||||
}
|
||||
|
||||
/// Returns the access mode.
|
||||
pub(super) fn access_mode(&self) -> AccessMode {
|
||||
self.access_mode
|
||||
}
|
||||
|
||||
/// Returns the `FUSE_OPEN` reply flags.
|
||||
pub(super) fn open_flags(&self) -> FuseOpenFlags {
|
||||
self.open_flags
|
||||
|
|
|
|||
Loading…
Reference in New Issue