raft_engine/env/
default.rs1#[cfg(feature = "failpoints")]
4use std::io::{Error, ErrorKind};
5use std::io::{Read, Result as IoResult, Seek, SeekFrom, Write};
6use std::path::Path;
7use std::sync::Arc;
8
9use fail::fail_point;
10
11use crate::env::log_fd::LogFd;
12use crate::env::{FileSystem, Handle, Permission, WriteExt};
13
14pub struct LogFile {
17 inner: Arc<LogFd>,
18 offset: usize,
19}
20
21impl LogFile {
22 pub fn new(fd: Arc<LogFd>) -> Self {
24 Self {
25 inner: fd,
26 offset: 0,
27 }
28 }
29}
30
31impl Write for LogFile {
32 fn write(&mut self, buf: &[u8]) -> IoResult<usize> {
33 fail_point!("log_file::write::zero", |_| { Ok(0) });
34
35 let len = self.inner.write(self.offset, buf)?;
36
37 fail_point!("log_file::write::err", |_| {
38 Err(Error::new(ErrorKind::InvalidInput, "fp"))
39 });
40
41 self.offset += len;
42 Ok(len)
43 }
44
45 fn flush(&mut self) -> IoResult<()> {
46 Ok(())
47 }
48}
49
50impl Read for LogFile {
51 fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
52 fail_point!("log_file::read::err", |_| {
53 Err(Error::new(ErrorKind::InvalidInput, "fp"))
54 });
55
56 let len = self.inner.read(self.offset, buf)?;
57 self.offset += len;
58 Ok(len)
59 }
60}
61
62impl Seek for LogFile {
63 fn seek(&mut self, pos: SeekFrom) -> IoResult<u64> {
64 fail_point!("log_file::seek::err", |_| {
65 Err(std::io::Error::new(std::io::ErrorKind::Other, "fp"))
66 });
67 match pos {
68 SeekFrom::Start(offset) => self.offset = offset as usize,
69 SeekFrom::Current(i) => self.offset = (self.offset as i64 + i) as usize,
70 SeekFrom::End(i) => self.offset = (self.inner.file_size()? as i64 + i) as usize,
71 }
72 Ok(self.offset as u64)
73 }
74}
75
76impl WriteExt for LogFile {
77 fn truncate(&mut self, offset: usize) -> IoResult<()> {
78 fail_point!("log_file::truncate::err", |_| {
79 Err(Error::new(ErrorKind::InvalidInput, "fp"))
80 });
81
82 self.inner.truncate(offset)?;
83 self.offset = offset;
84 Ok(())
85 }
86
87 fn allocate(&mut self, offset: usize, size: usize) -> IoResult<()> {
88 fail_point!("log_file::allocate::err", |_| {
89 Err(Error::new(ErrorKind::InvalidInput, "fp"))
90 });
91
92 self.inner.allocate(offset, size)
93 }
94}
95
96pub struct DefaultFileSystem;
97
98impl FileSystem for DefaultFileSystem {
99 type Handle = LogFd;
100 type Reader = LogFile;
101 type Writer = LogFile;
102
103 fn create<P: AsRef<Path>>(&self, path: P) -> IoResult<Self::Handle> {
104 fail_point!("default_fs::create::err", |_| {
105 Err(Error::new(ErrorKind::InvalidInput, "fp"))
106 });
107
108 LogFd::create(path.as_ref())
109 }
110
111 fn open<P: AsRef<Path>>(&self, path: P, perm: Permission) -> IoResult<Self::Handle> {
112 fail_point!("default_fs::open::err", |_| {
113 Err(Error::new(ErrorKind::InvalidInput, "fp"))
114 });
115
116 LogFd::open(path.as_ref(), perm)
117 }
118
119 fn delete<P: AsRef<Path>>(&self, path: P) -> IoResult<()> {
120 fail_point!("default_fs::delete_skipped", |_| { Ok(()) });
121 std::fs::remove_file(path)
122 }
123
124 fn rename<P: AsRef<Path>>(&self, src_path: P, dst_path: P) -> IoResult<()> {
125 std::fs::rename(src_path, dst_path)
126 }
127
128 fn new_reader(&self, handle: Arc<Self::Handle>) -> IoResult<Self::Reader> {
129 Ok(LogFile::new(handle))
130 }
131
132 fn new_writer(&self, handle: Arc<Self::Handle>) -> IoResult<Self::Writer> {
133 Ok(LogFile::new(handle))
134 }
135}