fix: storage tables grow (handles, open files, encrypted opens, grants: Slots/Vec, no 8/16 caps; release follows all narrowed grants); storage says FULL, init spawn STORAGE_BUSY (was NOT_FOUND), pm BUSY; cap slots per process 64 -> 255

This commit is contained in:
2026-10-28 16:17:36 +01:00
parent 3b71f29f4c
commit 1f2134fcec
19 changed files with 208 additions and 128 deletions

View File

@@ -12,9 +12,7 @@
use filecrypt::{CHUNK, Drbg, HEADER, Header, Key, OVERHEAD, PLAIN_CHUNK, area_key, chunk_offset, chunks, plain_len};
use crate::filesystem::{DirEntry, FileHandle, FileSystem};
/// The inner file system's handles this layer can track.
const MAX_HANDLES: usize = 16;
use crate::slots::Slots;
/// Where a path falls.
#[derive(Debug, PartialEq, Eq)]
@@ -66,7 +64,8 @@ pub struct Encrypted<F: FileSystem> {
user: [u8; USER_NAME],
user_len: usize,
rng: Option<Drbg>,
open: [Option<Open>; MAX_HANDLES],
/// Sealed files open, by the inner file system's handle.
open: Slots<Open>,
}
/// A user folder's name: 16 hex digits, or `guest`.
@@ -74,7 +73,7 @@ pub const USER_NAME: usize = 16;
impl<F: FileSystem> Encrypted<F> {
pub fn new(inner: F) -> Self {
Self { inner, master: None, user: [0; USER_NAME], user_len: 0, rng: None, open: [const { None }; MAX_HANDLES] }
Self { inner, master: None, user: [0; USER_NAME], user_len: 0, rng: None, open: Slots::new() }
}
pub fn inner(&self) -> &F {
@@ -114,10 +113,6 @@ impl<F: FileSystem> Encrypted<F> {
}
}
fn slot(&mut self, h: FileHandle) -> Option<&mut Option<Open>> {
self.open.get_mut(h.raw() as usize)
}
/// Chunk `index` of a file of `size` bytes, opened into `out`; its length.
fn read_chunk(inner: &mut F, h: FileHandle, key: &Key, size: usize, index: usize, out: &mut [u8; PLAIN_CHUNK]) -> Option<usize> {
let last = index + 1 == chunks(size);
@@ -153,10 +148,10 @@ impl<F: FileSystem> FileSystem for Encrypted<F> {
}
fn lock(&mut self) {
for (i, slot) in self.open.iter_mut().enumerate() {
if slot.take().is_some() {
self.inner.close(FileHandle::new(i as u16));
}
let open: alloc::vec::Vec<usize> = self.open.iter().map(|(i, _)| i).collect();
for i in open {
self.open.take(i);
self.inner.close(FileHandle::new(i as u16));
}
self.master = None;
self.rng = None;
@@ -183,7 +178,7 @@ impl<F: FileSystem> FileSystem for Encrypted<F> {
return None;
};
let key = header.file_key(&area);
*self.slot(h)? = Some(Open { key, size, pos: 0 });
self.open.put(h.raw() as usize, Open { key, size, pos: 0 });
Some(h)
}
@@ -203,12 +198,12 @@ impl<F: FileSystem> FileSystem for Encrypted<F> {
let _ = self.inner.delete(path);
return None;
}
*self.slot(h)? = Some(Open { key: file_key, size: 0, pos: 0 });
self.open.put(h.raw() as usize, Open { key: file_key, size: 0, pos: 0 });
Some(h)
}
fn read(&mut self, h: FileHandle, buf: &mut [u8]) -> Option<usize> {
let Some(Some(f)) = self.open.get(h.raw() as usize) else { return self.inner.read(h, buf) };
let Some(f) = self.open.get(h.raw() as usize) else { return self.inner.read(h, buf) };
let (key, size, mut pos) = (f.key.clone(), f.size, f.pos);
let mut done = 0;
let mut chunk = [0u8; PLAIN_CHUNK];
@@ -222,12 +217,12 @@ impl<F: FileSystem> FileSystem for Encrypted<F> {
pos += take;
}
chunk.fill(0);
self.slot(h)?.as_mut()?.pos = pos;
self.open.get_mut(h.raw() as usize)?.pos = pos;
Some(done)
}
fn write(&mut self, h: FileHandle, buf: &[u8]) -> Option<usize> {
let Some(Some(f)) = self.open.get(h.raw() as usize) else { return self.inner.write(h, buf) };
let Some(f) = self.open.get(h.raw() as usize) else { return self.inner.write(h, buf) };
let (key, old_size, pos) = (f.key.clone(), f.size, f.pos);
let new_size = old_size.max(pos + buf.len());
let (old_last, new_last) = (chunks(old_size) - 1, chunks(new_size) - 1);
@@ -253,34 +248,32 @@ impl<F: FileSystem> FileSystem for Encrypted<F> {
}
}
chunk.fill(0);
let f = self.slot(h)?.as_mut()?;
let f = self.open.get_mut(h.raw() as usize)?;
f.size = new_size;
f.pos = pos + buf.len();
Some(buf.len())
}
fn seek(&mut self, h: FileHandle, offset: usize) -> bool {
match self.slot(h) {
Some(Some(f)) if offset <= f.size => {
match self.open.get_mut(h.raw() as usize) {
Some(f) if offset <= f.size => {
f.pos = offset;
true
}
Some(Some(_)) => false,
_ => self.inner.seek(h, offset),
Some(_) => false,
None => self.inner.seek(h, offset),
}
}
fn close(&mut self, h: FileHandle) {
if let Some(slot) = self.slot(h) {
*slot = None;
}
self.open.take(h.raw() as usize);
self.inner.close(h);
}
fn file_size(&mut self, h: FileHandle) -> Option<usize> {
match self.open.get(h.raw() as usize) {
Some(Some(f)) => Some(f.size),
_ => self.inner.file_size(h),
Some(f) => Some(f.size),
None => self.inner.file_size(h),
}
}