Skip to content

Commit

Permalink
fix seek forward on read
Browse files Browse the repository at this point in the history
  • Loading branch information
radumarias committed May 2, 2024
1 parent f7d623c commit 6661e7e
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 42 deletions.
2 changes: 1 addition & 1 deletion src/crypto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use num_format::{Locale, ToFormattedString};
use openssl::sha::sha256;
use secrecy::{ExposeSecret, SecretString, SecretVec};
use thiserror::Error;
use tracing::{debug, error, instrument};
use tracing::{debug, error, info, instrument};
use strum_macros::{Display, EnumIter, EnumString};
use serde::{Deserialize, Serialize};
use openssl::error::ErrorStack;
Expand Down
54 changes: 18 additions & 36 deletions src/encryptedfs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer};
use thiserror::Error;
use tokio::sync::{Mutex, MutexGuard, RwLock};
use tokio_stream::wrappers::ReadDirStream;
use tracing::{debug, error, instrument, warn};
use tracing::{debug, error, info, instrument, warn};

use crate::arc_hashmap::{ArcHashMap, Guard};
use crate::{crypto, expire_value, stream_util};
Expand Down Expand Up @@ -974,12 +974,21 @@ impl EncryptedFs {
self.do_with_read_handle(handle, ReadHandleContextOperation::RecreateDecryptor { existing: ctx }).await?;
ctx = guard.get(&handle).unwrap().lock().await;
}
stream_util::read_seek_forward_exact(&mut ctx.decryptor.as_mut().unwrap(), offset)?;
let pos = ctx.pos;
let actual_file_size = fs::metadata(self.data_dir.join(CONTENTS_DIR).join(ino.to_string()))?.len();
debug!(pos = pos.to_formatted_string(&Locale::en), offset = offset.to_formatted_string(&Locale::en), file_size = ctx.attr.size.to_formatted_string(&Locale::en),
actual_file_size = actual_file_size.to_formatted_string(&Locale::en), "seeking");
let len = offset - pos;
stream_util::read_seek_forward_exact(&mut ctx.decryptor.as_mut().unwrap(), len)?;
ctx.pos += len;
}
if offset + buf.len() as u64 > ctx.attr.size {
buf = &mut buf[..(ctx.attr.size - offset) as usize];
}
ctx.decryptor.as_mut().unwrap().read_exact(&mut buf)?;
ctx.decryptor.as_mut().unwrap().read_exact(&mut buf).map_err(|err| {
error!(err = %err, pos = ctx.pos.to_formatted_string(&Locale::en), offset = offset.to_formatted_string(&Locale::en), file_size = ctx.attr.size.to_formatted_string(&Locale::en), "reading from decryptor");
err
})?;
ctx.pos += buf.len() as u64;

ctx.attr.atime = SystemTime::now();
Expand Down Expand Up @@ -1339,17 +1348,7 @@ impl EncryptedFs {

// copy existing data until new size
debug!("copying data until new size");
let mut buf = vec![0; BUF_SIZE];
let mut pos = 0_u64;
loop {
let len = min(buf.len(), (size - pos) as usize);
decryptor.read_exact(&mut buf[..len])?;
encryptor.write_all(&buf[..len])?;
pos += len as u64;
if pos == size {
break;
}
}
stream_util::copy_exact(&mut decryptor, &mut encryptor, size)?;
debug!("rename from tmp file");
tokio::fs::rename(tmp_path, self.data_dir.join(CONTENTS_DIR).join(attr.ino.to_string())).await?;
} else {
Expand All @@ -1370,29 +1369,12 @@ impl EncryptedFs {

// copy existing data
debug!("copying existing data");
let mut buf = vec![0; BUF_SIZE];
let mut pos = 0_u64;
loop {
let len = min(buf.len(), (attr.size - pos) as usize);
decryptor.read_exact(&mut buf[..len])?;
encryptor.write_all(&buf[..len])?;
pos += len as u64;
if pos == attr.size {
break;
}
}
stream_util::copy_exact(&mut decryptor, &mut encryptor, attr.size)?;
attr.size = size;

// now fill up with zeros until new size
debug!("filling up with zeros until new size");
let buf = vec![0; BUF_SIZE];
loop {
let len = min(buf.len(), (size - attr.size) as usize);
encryptor.write_all(&buf[..len])?;
attr.size += len as u64;
if attr.size == size {
break;
}
}
stream_util::fill_zeros(&mut encryptor, size - attr.size)?;

encryptor.finish()?;
debug!("rename from tmp file");
Expand Down Expand Up @@ -1583,7 +1565,7 @@ impl EncryptedFs {
let new_key = crypto::derive_key(&new_password, &cipher, salt)?;
tokio::fs::remove_file(enc_file.clone()).await?;
let mut encryptor = crypto::create_encryptor(OpenOptions::new().read(true).write(true).create(true).truncate(true).open(enc_file.clone())?,
&cipher, &new_key);
&cipher, &new_key);
bincode::serialize_into(&mut encryptor, &key_store)?;

Ok(())
Expand Down Expand Up @@ -1809,7 +1791,7 @@ impl EncryptedFs {
let key = SecretVec::new(key);
let key_store = KeyStore::new(key);
let mut encryptor = crypto::create_encryptor(OpenOptions::new().read(true).write(true).create(true).open(path)?,
cipher, &derived_key);
cipher, &derived_key);
bincode::serialize_into(&mut encryptor, &key_store)?;
Ok(key_store.key)
}
Expand Down
4 changes: 3 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,9 @@ pub fn log_init(level: Level) -> WorkerGuard {
.pretty()
.init()
} else {
builder.init();
builder
.pretty()
.init()
}

guard
Expand Down
30 changes: 26 additions & 4 deletions src/stream_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::cmp::min;
use std::io;
use std::io::{Read, Write};
use num_format::{Locale, ToFormattedString};
use tracing::{debug, instrument};
use tracing::{debug, error, info, instrument};

#[cfg(test)]
const BUF_SIZE: usize = 256 * 1024;
Expand All @@ -25,9 +25,12 @@ pub fn read_seek_forward_exact(mut r: impl Read, len: u64) -> io::Result<()> {
} else {
buffer.len()
};
debug!(read_len = read_len.to_formatted_string(&Locale::en), "reading");
debug!(pos, read_len = read_len.to_formatted_string(&Locale::en), "reading");
if read_len > 0 {
r.read_exact(&mut buffer[..read_len])?;
r.read_exact(&mut buffer[..read_len]).map_err(|err| {
error!("error reading from file pos {} len {}", pos.to_formatted_string(&Locale::en), read_len.to_formatted_string(&Locale::en));
err
})?;
pos += read_len as u64;
if pos == len {
break;
Expand All @@ -52,7 +55,7 @@ pub fn copy_exact(r: &mut impl Read, w: &mut impl Write, len: u64) -> io::Result
let buf_len = min(buffer.len(), (len - read_pos) as usize);
debug!("reading from file pos {} buf_len {}", read_pos.to_formatted_string(&Locale::en), buf_len.to_formatted_string(&Locale::en));
r.read_exact(&mut buffer[..buf_len]).map_err(|err| {
debug!("error reading from file pos {} len {}", read_pos.to_formatted_string(&Locale::en), buf_len.to_formatted_string(&Locale::en));
error!("error reading from file pos {} len {}", read_pos.to_formatted_string(&Locale::en), buf_len.to_formatted_string(&Locale::en));
err
})?;
w.write_all(&buffer[..buf_len])?;
Expand All @@ -62,4 +65,23 @@ pub fn copy_exact(r: &mut impl Read, w: &mut impl Write, len: u64) -> io::Result
}
}
Ok(())
}

#[instrument(skip(w, len), fields(len = len.to_formatted_string(& Locale::en)))]
pub fn fill_zeros(w: &mut impl Write, len: u64) -> io::Result<()> {
debug!("");
if len == 0 {
return Ok(());
}
let mut buffer = vec![0; BUF_SIZE];
let mut written = 0_u64;
loop {
let buf_len = min(buffer.len(), (len - written) as usize);
w.write_all(&buffer[..buf_len])?;
written += buf_len as u64;
if written == len {
break;
}
}
Ok(())
}

0 comments on commit 6661e7e

Please sign in to comment.