feat(compression): implement transparent LZ4 chunk compression with V1 backwards compatibility

This commit is contained in:
2026-09-07 21:59:42 +02:00
parent a9c3dd25a3
commit 2d14c64c3e
7 changed files with 279 additions and 22 deletions
+13 -4
View File
@@ -86,6 +86,7 @@ pub struct SanctumFile {
meta: SanctumMetaData,
// (chunk_index, decrypted_payload, is_dirty)
cached_chunk: Option<(u32, Vec<u8>, bool)>,
format_version: u32,
}
impl Debug for SanctumFile {
@@ -94,6 +95,7 @@ impl Debug for SanctumFile {
.field("node_id", &self.node_id)
.field("file_size", &self.file_size)
.field("cursor", &self.cursor)
.field("format_version", &self.format_version)
.finish()
}
}
@@ -103,6 +105,7 @@ impl SanctumFile {
node: NodeRecord,
db: Database,
dek: Arc<Zeroizing<[u8; 32]>>,
format_version: u32,
) -> Self {
let meta = SanctumMetaData {
is_dir: node.is_dir,
@@ -119,14 +122,16 @@ impl SanctumFile {
dek,
meta,
cached_chunk: None,
format_version,
}
}
/// Schreibt den aktuell im RAM gehaltenen Chunk verschlüsselt in die SQLite-Datenbank zurück.
fn flush_cached_chunk(&mut self) -> Result<(), FsError> {
if let Some((idx, ref data, true)) = self.cached_chunk {
let (ciphertext, nonce, tag) =
encrypt_chunk(&self.dek, self.node_id, idx, data).map_err(|e| {
encrypt_chunk(&self.dek, self.node_id, idx, data, self.format_version).map_err(|e| {
error!("Verschlüsselungsfehler beim Chunk-Flush: {e}");
FsError::GeneralFailure
})?;
@@ -166,6 +171,7 @@ impl SanctumFile {
&record.ciphertext,
&record.nonce,
&record.tag,
self.format_version,
)
.map_err(|e| {
error!("AEAD-Entschlüsselungsfehler bei Chunk #{chunk_index}: {e}");
@@ -339,13 +345,15 @@ impl DavFile for SanctumFile {
pub struct SanctumFs {
db: Database,
dek: Arc<Zeroizing<[u8; 32]>>,
format_version: u32,
}
impl SanctumFs {
pub fn new(db: Database, dek: Zeroizing<[u8; 32]>) -> Self {
pub fn new(db: Database, dek: Zeroizing<[u8; 32]>, format_version: u32) -> Self {
Self {
db,
dek: Arc::new(dek),
format_version,
}
}
@@ -432,7 +440,7 @@ impl DavFileSystem for SanctumFs {
}
};
let file = SanctumFile::new(node, self.db.clone(), self.dek.clone());
let file = SanctumFile::new(node, self.db.clone(), self.dek.clone(), self.format_version);
Ok(Box::new(file) as Box<dyn DavFile>)
})
}
@@ -678,11 +686,12 @@ impl DavFileSystem for SanctumFs {
&record.ciphertext,
&record.nonce,
&record.tag,
self.format_version,
)
.map_err(|_| FsError::GeneralFailure)?;
let (new_ct, new_nonce, new_tag) =
encrypt_chunk(&self.dek, dest_node.id, idx, &plaintext)
encrypt_chunk(&self.dek, dest_node.id, idx, &plaintext, self.format_version)
.map_err(|_| FsError::GeneralFailure)?;
self.db