vmbfs/
single_file_backing.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Implements a backing store for the vmbus file system that provides a single
5//! file.
6
7use crate::backing::FileError;
8use crate::backing::FileInfo;
9use crate::backing::VmbfsIo;
10use inspect::InspectMut;
11use std::fs::File;
12use std::io::Read;
13use std::io::Seek;
14use thiserror::Error;
15
16/// A backing store for the vmbus file system that provides a single file.
17#[derive(InspectMut)]
18pub struct VmbfsSingleFileBacking {
19    path: String,
20    file: File,
21}
22
23/// An error indicating that the input file name is invalid.
24#[derive(Debug, Error)]
25#[error("invalid path")]
26pub struct InvalidFileName;
27
28impl VmbfsSingleFileBacking {
29    /// Returns a new instance that provides access to the given file via the
30    /// given name.
31    ///
32    /// Fails if the input file name contains a '/' or a '\'.
33    pub fn new(name: &str, file: File) -> Result<Self, InvalidFileName> {
34        if name.contains('/') || name.contains('\\') {
35            return Err(InvalidFileName);
36        }
37        let path = format!("/{name}");
38        Ok(Self { path, file })
39    }
40}
41
42impl VmbfsIo for VmbfsSingleFileBacking {
43    fn file_info(&mut self, path: &str) -> Result<FileInfo, FileError> {
44        if path != self.path {
45            return Err(FileError::NotFound);
46        }
47        let metadata = self.file.metadata()?;
48        Ok(FileInfo {
49            directory: false,
50            file_size: metadata.len(),
51        })
52    }
53
54    fn read_file(&mut self, path: &str, offset: u64, buf: &mut [u8]) -> Result<(), FileError> {
55        if path != self.path {
56            return Err(FileError::NotFound);
57        }
58        self.file.seek(std::io::SeekFrom::Start(offset))?;
59        self.file.read_exact(buf)?;
60        Ok(())
61    }
62}