diff options
author | Daniel Verkamp <dverkamp@chromium.org> | 2018-08-17 09:05:14 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-09-05 01:25:49 -0700 |
commit | 0e8f6fa96e454f8db36787eda91327e32e1b159a (patch) | |
tree | 5b3915d3d40ff885e6423d760726d1a3aadf30da /sys_util/src/lib.rs | |
parent | caa2e5a4ac45c5e107b6802db99c158083321bc4 (diff) | |
download | crosvm-0e8f6fa96e454f8db36787eda91327e32e1b159a.tar crosvm-0e8f6fa96e454f8db36787eda91327e32e1b159a.tar.gz crosvm-0e8f6fa96e454f8db36787eda91327e32e1b159a.tar.bz2 crosvm-0e8f6fa96e454f8db36787eda91327e32e1b159a.tar.lz crosvm-0e8f6fa96e454f8db36787eda91327e32e1b159a.tar.xz crosvm-0e8f6fa96e454f8db36787eda91327e32e1b159a.tar.zst crosvm-0e8f6fa96e454f8db36787eda91327e32e1b159a.zip |
sys_util: add safe wrapper for fallocate()
BUG=chromium:850998 TEST=None Change-Id: I1b6864f7d508cf7f24248a8cc9783af2d8b00891 Signed-off-by: Daniel Verkamp <dverkamp@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/1187016 Commit-Ready: ChromeOS CL Exonerator Bot <chromiumos-cl-exonerator@appspot.gserviceaccount.com> Reviewed-by: Stephen Barber <smbarber@chromium.org>
Diffstat (limited to 'sys_util/src/lib.rs')
-rw-r--r-- | sys_util/src/lib.rs | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/sys_util/src/lib.rs b/sys_util/src/lib.rs index 30b293d..1d0ff1a 100644 --- a/sys_util/src/lib.rs +++ b/sys_util/src/lib.rs @@ -151,6 +151,51 @@ pub fn flock(file: &AsRawFd, op: FlockOperation, nonblocking: bool) -> Result<() } } +/// The operation to perform with `fallocate`. +pub enum FallocateMode { + PunchHole, + ZeroRange, +} + +/// Safe wrapper for `fallocate()`. +pub fn fallocate( + file: &AsRawFd, + mode: FallocateMode, + keep_size: bool, + offset: u64, + len: u64 +) -> Result<()> { + let offset = if offset > libc::off_t::max_value() as u64 { + return Err(Error::new(libc::EINVAL)); + } else { + offset as libc::off_t + }; + + let len = if len > libc::off_t::max_value() as u64 { + return Err(Error::new(libc::EINVAL)); + } else { + len as libc::off_t + }; + + let mut mode = match mode { + FallocateMode::PunchHole => libc::FALLOC_FL_PUNCH_HOLE, + FallocateMode::ZeroRange => libc::FALLOC_FL_ZERO_RANGE, + }; + + if keep_size { + mode |= libc::FALLOC_FL_KEEP_SIZE; + } + + // Safe since we pass in a valid fd and fallocate mode, validate offset and len, + // and check the return value. + let ret = unsafe { libc::fallocate(file.as_raw_fd(), mode, offset, len) }; + if ret < 0 { + errno_result() + } else { + Ok(()) + } +} + /// Reaps a child process that has terminated. /// /// Returns `Ok(pid)` where `pid` is the process that was reaped or `Ok(0)` if none of the children |