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:
@@ -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),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user