rage-mount: Use os-thread-local to cache read buffers

This commit is contained in:
Jack Grigg 2020-08-30 21:08:50 +01:00
parent 59c9997f78
commit 1e2ddf7c7b
4 changed files with 48 additions and 22 deletions

11
Cargo.lock generated
View file

@ -1591,6 +1591,16 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
[[package]]
name = "os-thread-local"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd7fc7fa9ea7dc8907f9b10e730106ed0011926e7f5abb382530ac91d1af2b7c"
dependencies = [
"libc",
"winapi",
]
[[package]] [[package]]
name = "os_str_bytes" name = "os_str_bytes"
version = "6.1.0" version = "6.1.0"
@ -1903,6 +1913,7 @@ dependencies = [
"libc", "libc",
"log", "log",
"man", "man",
"os-thread-local",
"pinentry", "pinentry",
"rust-embed", "rust-embed",
"tar", "tar",

View file

@ -71,6 +71,7 @@ ctrlc = { version = "3.2", optional = true }
fuse_mt = { version = "0.6.0", optional = true } fuse_mt = { version = "0.6.0", optional = true }
fuser = { version = "0.11.1", optional = true } fuser = { version = "0.11.1", optional = true }
libc = { version = "0.2", optional = true } libc = { version = "0.2", optional = true }
os-thread-local = { version = "0.1.3", optional = true }
tar = { version = "0.4", optional = true } tar = { version = "0.4", optional = true }
time = { version = "0.3.7", optional = true } time = { version = "0.3.7", optional = true }
zip = { version = "0.6.2", optional = true } zip = { version = "0.6.2", optional = true }
@ -83,7 +84,7 @@ man = "0.3"
[features] [features]
default = ["ssh"] default = ["ssh"]
mount = ["ctrlc", "fuse_mt", "fuser", "libc", "tar", "time", "zip"] mount = ["ctrlc", "fuse_mt", "fuser", "libc", "os-thread-local", "tar", "time", "zip"]
ssh = ["age/ssh"] ssh = ["age/ssh"]
unstable = ["age/unstable"] unstable = ["age/unstable"]

View file

@ -1,5 +1,7 @@
use age::{armor::ArmoredReader, stream::StreamReader}; use age::{armor::ArmoredReader, stream::StreamReader};
use fuse_mt::*; use fuse_mt::*;
use os_thread_local::ThreadLocal;
use std::cell::RefCell;
use std::collections::HashMap; use std::collections::HashMap;
use std::fs::File; use std::fs::File;
use std::io::{self, BufReader, Read, Seek, SeekFrom}; use std::io::{self, BufReader, Read, Seek, SeekFrom};
@ -111,6 +113,7 @@ pub struct AgeTarFs {
file_map: HashMap<PathBuf, (FileAttr, u64)>, file_map: HashMap<PathBuf, (FileAttr, u64)>,
open_dirs: Mutex<(HashMap<u64, PathBuf>, u64)>, open_dirs: Mutex<(HashMap<u64, PathBuf>, u64)>,
open_files: Mutex<(HashMap<u64, OpenFile>, u64)>, open_files: Mutex<(HashMap<u64, OpenFile>, u64)>,
read_buf: ThreadLocal<RefCell<Vec<u8>>>,
} }
impl AgeTarFs { impl AgeTarFs {
@ -145,6 +148,7 @@ impl AgeTarFs {
file_map, file_map,
open_dirs: Mutex::new((HashMap::new(), 0)), open_dirs: Mutex::new((HashMap::new(), 0)),
open_files: Mutex::new((HashMap::new(), 0)), open_files: Mutex::new((HashMap::new(), 0)),
read_buf: ThreadLocal::new(|| RefCell::new(vec![])),
}) })
} }
} }
@ -268,14 +272,17 @@ impl FilesystemMT for AgeTarFs {
return callback(Err(libc::EIO)); return callback(Err(libc::EIO));
} }
// Read bytes self.read_buf.with(|buf| {
let to_read = usize::min(size as usize, (file_size - offset) as usize); let mut buf = buf.borrow_mut();
let mut buf = vec![];
buf.resize(to_read, 0); // Read bytes
match inner.read_exact(&mut buf) { let to_read = usize::min(size as usize, (file_size - offset) as usize);
Ok(_) => callback(Ok(&buf)), buf.resize(to_read, 0);
Err(_) => callback(Err(libc::EIO)), match inner.read_exact(&mut buf) {
} Ok(_) => callback(Ok(&buf)),
Err(_) => callback(Err(libc::EIO)),
}
})
} else { } else {
callback(Err(libc::EBADF)) callback(Err(libc::EBADF))
} }

View file

@ -1,5 +1,7 @@
use age::{armor::ArmoredReader, stream::StreamReader}; use age::{armor::ArmoredReader, stream::StreamReader};
use fuse_mt::*; use fuse_mt::*;
use os_thread_local::ThreadLocal;
use std::cell::RefCell;
use std::collections::HashMap; use std::collections::HashMap;
use std::fs::File; use std::fs::File;
use std::io::{self, BufReader, Read}; use std::io::{self, BufReader, Read};
@ -89,6 +91,7 @@ pub struct AgeZipFs {
dir_map: HashMap<PathBuf, Vec<DirectoryEntry>>, dir_map: HashMap<PathBuf, Vec<DirectoryEntry>>,
open_dirs: Mutex<(HashMap<u64, PathBuf>, u64)>, open_dirs: Mutex<(HashMap<u64, PathBuf>, u64)>,
open_files: Mutex<(HashMap<u64, usize>, u64)>, open_files: Mutex<(HashMap<u64, usize>, u64)>,
read_buf: ThreadLocal<RefCell<Vec<u8>>>,
} }
impl AgeZipFs { impl AgeZipFs {
@ -117,6 +120,7 @@ impl AgeZipFs {
dir_map, dir_map,
open_dirs: Mutex::new((HashMap::new(), 0)), open_dirs: Mutex::new((HashMap::new(), 0)),
open_files: Mutex::new((HashMap::new(), 0)), open_files: Mutex::new((HashMap::new(), 0)),
read_buf: ThreadLocal::new(|| RefCell::new(vec![])),
}) })
} }
} }
@ -232,20 +236,23 @@ impl FilesystemMT for AgeZipFs {
return callback(Err(libc::EINVAL)); return callback(Err(libc::EINVAL));
} }
// Skip to offset self.read_buf.with(|buf| {
let mut buf = vec![]; let mut buf = buf.borrow_mut();
buf.resize(offset as usize, 0);
if zf.read_exact(&mut buf).is_err() {
return callback(Err(libc::EIO));
}
// Read bytes // Skip to offset
let to_read = usize::min(size as usize, (zf.size() - offset) as usize); buf.resize(offset as usize, 0);
buf.resize(to_read, 0); if zf.read_exact(&mut buf).is_err() {
match zf.read_exact(&mut buf) { return callback(Err(libc::EIO));
Ok(_) => callback(Ok(&buf)), }
Err(_) => callback(Err(libc::EIO)),
} // Read bytes
let to_read = usize::min(size as usize, (zf.size() - offset) as usize);
buf.resize(to_read, 0);
match zf.read_exact(&mut buf) {
Ok(_) => callback(Ok(&buf)),
Err(_) => callback(Err(libc::EIO)),
}
})
} }
None => callback(Err(libc::EBADF)), None => callback(Err(libc::EBADF)),
} }