1 // Copyright 2018 The ChromiumOS Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 use std::cmp::min;
6 use std::fs::File;
7 use std::io;
8 use std::os::unix::fs::FileExt;
9
10 use super::fallocate;
11 use super::FallocateMode;
12
file_punch_hole(file: &File, offset: u64, length: u64) -> io::Result<()>13 pub(crate) fn file_punch_hole(file: &File, offset: u64, length: u64) -> io::Result<()> {
14 fallocate(file, FallocateMode::PunchHole, true, offset, length as u64)
15 .map_err(|e| io::Error::from_raw_os_error(e.errno()))
16 }
17
file_write_zeroes_at(file: &File, offset: u64, length: usize) -> io::Result<usize>18 pub(crate) fn file_write_zeroes_at(file: &File, offset: u64, length: usize) -> io::Result<usize> {
19 // Try to use fallocate() first.
20 if fallocate(file, FallocateMode::ZeroRange, true, offset, length as u64).is_ok() {
21 return Ok(length);
22 }
23
24 // fall back to write()
25 // fallocate() failed; fall back to writing a buffer of zeroes
26 // until we have written up to length.
27 let buf_size = min(length, 0x10000);
28 let buf = vec![0u8; buf_size];
29 let mut nwritten: usize = 0;
30 while nwritten < length {
31 let remaining = length - nwritten;
32 let write_size = min(remaining, buf_size);
33 nwritten += file.write_at(&buf[0..write_size], offset + nwritten as u64)?;
34 }
35 Ok(length)
36 }
37