mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2025-02-06 02:25:23 +00:00
sys_util: add FileAllocate trait
This trait provides a generic interface for allocating space on the filesystem within a given file. It is equivalent to the fallocate(2) system call with the default mode (mode = 0). BUG=chromium:858815 TEST=cargo build --features=composite-disk Change-Id: I2f4e8aceb4878790e8dec2e3d539071915efd205 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2015828 Reviewed-by: Dylan Reid <dgreid@chromium.org> Tested-by: kokoro <noreply+kokoro@google.com> Commit-Queue: Daniel Verkamp <dverkamp@chromium.org>
This commit is contained in:
parent
e43d300aef
commit
977f873a41
5 changed files with 59 additions and 5 deletions
|
@ -13,7 +13,9 @@ use crate::{create_disk_file, DiskFile, DiskGetLen, ImageType};
|
|||
use data_model::VolatileSlice;
|
||||
use protos::cdisk_spec;
|
||||
use remain::sorted;
|
||||
use sys_util::{AsRawFds, FileReadWriteAtVolatile, FileSetLen, FileSync, PunchHole, WriteZeroesAt};
|
||||
use sys_util::{
|
||||
AsRawFds, FileAllocate, FileReadWriteAtVolatile, FileSetLen, FileSync, PunchHole, WriteZeroesAt,
|
||||
};
|
||||
|
||||
#[sorted]
|
||||
#[derive(Debug)]
|
||||
|
@ -292,6 +294,27 @@ impl PunchHole for CompositeDiskFile {
|
|||
}
|
||||
}
|
||||
|
||||
impl FileAllocate for CompositeDiskFile {
|
||||
fn allocate(&mut self, offset: u64, length: u64) -> io::Result<()> {
|
||||
let range = offset..(offset + length);
|
||||
let disks = self.disks_in_range(&range);
|
||||
for disk in disks {
|
||||
let intersection = range_intersection(&range, &disk.range());
|
||||
if intersection.start >= intersection.end {
|
||||
continue;
|
||||
}
|
||||
let result = disk.file.allocate(
|
||||
intersection.start - disk.offset,
|
||||
intersection.end - intersection.start,
|
||||
);
|
||||
if result.is_err() {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl WriteZeroesAt for CompositeDiskFile {
|
||||
fn write_zeroes_at(&mut self, offset: u64, length: usize) -> io::Result<usize> {
|
||||
let cursor_location = offset;
|
||||
|
|
|
@ -10,7 +10,8 @@ use std::io::{self, Read, Seek, SeekFrom, Write};
|
|||
use libc::EINVAL;
|
||||
use remain::sorted;
|
||||
use sys_util::{
|
||||
AsRawFds, FileReadWriteAtVolatile, FileSetLen, FileSync, PunchHole, SeekHole, WriteZeroesAt,
|
||||
AsRawFds, FileAllocate, FileReadWriteAtVolatile, FileSetLen, FileSync, PunchHole, SeekHole,
|
||||
WriteZeroesAt,
|
||||
};
|
||||
|
||||
mod qcow;
|
||||
|
@ -64,6 +65,7 @@ pub trait DiskFile:
|
|||
+ FileReadWriteAtVolatile
|
||||
+ PunchHole
|
||||
+ WriteZeroesAt
|
||||
+ FileAllocate
|
||||
+ Send
|
||||
+ AsRawFds
|
||||
+ Debug
|
||||
|
@ -76,6 +78,7 @@ impl<
|
|||
+ PunchHole
|
||||
+ FileReadWriteAtVolatile
|
||||
+ WriteZeroesAt
|
||||
+ FileAllocate
|
||||
+ Send
|
||||
+ AsRawFds
|
||||
+ Debug,
|
||||
|
|
|
@ -10,8 +10,8 @@ use data_model::{VolatileMemory, VolatileSlice};
|
|||
use libc::{EINVAL, ENOSPC, ENOTSUP};
|
||||
use remain::sorted;
|
||||
use sys_util::{
|
||||
error, FileReadWriteAtVolatile, FileReadWriteVolatile, FileSetLen, FileSync, PunchHole,
|
||||
SeekHole, WriteZeroesAt,
|
||||
error, FileAllocate, FileReadWriteAtVolatile, FileReadWriteVolatile, FileSetLen, FileSync,
|
||||
PunchHole, SeekHole, WriteZeroesAt,
|
||||
};
|
||||
|
||||
use std::cmp::{max, min};
|
||||
|
@ -1582,6 +1582,15 @@ impl DiskGetLen for QcowFile {
|
|||
}
|
||||
}
|
||||
|
||||
impl FileAllocate for QcowFile {
|
||||
fn allocate(&mut self, offset: u64, len: u64) -> io::Result<()> {
|
||||
// Call write_cb with a do-nothing callback, which will have the effect
|
||||
// of allocating all clusters in the specified range.
|
||||
self.write_cb(offset, len as usize, |_file, _offset, _count| Ok(()))?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl PunchHole for QcowFile {
|
||||
fn punch_hole(&mut self, offset: u64, length: u64) -> std::io::Result<()> {
|
||||
let mut remaining = length;
|
||||
|
|
|
@ -8,6 +8,8 @@ use std::os::unix::io::{AsRawFd, RawFd};
|
|||
|
||||
use data_model::VolatileSlice;
|
||||
|
||||
use crate::{fallocate, FallocateMode};
|
||||
|
||||
/// A trait for flushing the contents of a file to disk.
|
||||
/// This is equivalent to File's `sync_all` method, but
|
||||
/// wrapped in a trait so that it can be implemented for
|
||||
|
@ -54,6 +56,20 @@ impl FileGetLen for File {
|
|||
}
|
||||
}
|
||||
|
||||
/// A trait for allocating disk space in a sparse file.
|
||||
/// This is equivalent to fallocate() with no special flags.
|
||||
pub trait FileAllocate {
|
||||
/// Allocate storage for the region of the file starting at `offset` and extending `len` bytes.
|
||||
fn allocate(&mut self, offset: u64, len: u64) -> Result<()>;
|
||||
}
|
||||
|
||||
impl FileAllocate for File {
|
||||
fn allocate(&mut self, offset: u64, len: u64) -> Result<()> {
|
||||
fallocate(self, FallocateMode::Allocate, true, offset, len)
|
||||
.map_err(|e| Error::from_raw_os_error(e.errno()))
|
||||
}
|
||||
}
|
||||
|
||||
/// A trait similar to `Read` and `Write`, but uses volatile memory as buffers.
|
||||
pub trait FileReadWriteVolatile {
|
||||
/// Read bytes from this file into the given slice, returning the number of bytes read on
|
||||
|
|
|
@ -64,7 +64,8 @@ pub use crate::timerfd::*;
|
|||
pub use poll_token_derive::*;
|
||||
|
||||
pub use crate::file_traits::{
|
||||
AsRawFds, FileGetLen, FileReadWriteAtVolatile, FileReadWriteVolatile, FileSetLen, FileSync,
|
||||
AsRawFds, FileAllocate, FileGetLen, FileReadWriteAtVolatile, FileReadWriteVolatile, FileSetLen,
|
||||
FileSync,
|
||||
};
|
||||
pub use crate::guest_memory::Error as GuestMemoryError;
|
||||
pub use crate::mmap::Error as MmapError;
|
||||
|
@ -175,6 +176,7 @@ pub fn flock(file: &dyn AsRawFd, op: FlockOperation, nonblocking: bool) -> Resul
|
|||
pub enum FallocateMode {
|
||||
PunchHole,
|
||||
ZeroRange,
|
||||
Allocate,
|
||||
}
|
||||
|
||||
/// Safe wrapper for `fallocate()`.
|
||||
|
@ -200,6 +202,7 @@ pub fn fallocate(
|
|||
let mut mode = match mode {
|
||||
FallocateMode::PunchHole => libc::FALLOC_FL_PUNCH_HOLE,
|
||||
FallocateMode::ZeroRange => libc::FALLOC_FL_ZERO_RANGE,
|
||||
FallocateMode::Allocate => 0,
|
||||
};
|
||||
|
||||
if keep_size {
|
||||
|
|
Loading…
Reference in a new issue