|  | @@ -54,6 +54,8 @@ pub enum Error {
 | 
	
		
			
				|  |  |      IncorrectSize { expected: usize, actual: usize },
 | 
	
		
			
				|  |  |      NoBlockKey,
 | 
	
		
			
				|  |  |      NotOpen(u64),
 | 
	
		
			
				|  |  | +    InvalidHandle { handle: u64, inode: u64 },
 | 
	
		
			
				|  |  | +    NoHandlesAvailable(u64),
 | 
	
		
			
				|  |  |      NoBlockPath,
 | 
	
		
			
				|  |  |      InodeNotFound(u64),
 | 
	
		
			
				|  |  |      Custom(Box<dyn std::fmt::Debug + Send + Sync>),
 | 
	
	
		
			
				|  | @@ -77,6 +79,12 @@ impl Display for Error {
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |              Error::NoBlockKey => write!(f, "no block key is present"),
 | 
	
		
			
				|  |  |              Error::NotOpen(inode) => write!(f, "inode {inode} is not open"),
 | 
	
		
			
				|  |  | +            Error::InvalidHandle { handle, inode } => {
 | 
	
		
			
				|  |  | +                write!(f, "invalid handle {handle} for inode {inode}")
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            Error::NoHandlesAvailable(inode) => {
 | 
	
		
			
				|  |  | +                write!(f, "no handles are available for inode {inode}")
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  |              Error::NoBlockPath => write!(f, "no block path was specified"),
 | 
	
		
			
				|  |  |              Error::InodeNotFound(inode) => write!(f, "inode {inode} could not be found"),
 | 
	
		
			
				|  |  |              Error::Custom(err) => err.fmt(f),
 | 
	
	
		
			
				|  | @@ -211,6 +219,26 @@ pub trait MetaAccess: AsRef<BlockMeta> + AsMut<BlockMeta> {
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +impl AsRef<BlockMeta> for &BlockMeta {
 | 
	
		
			
				|  |  | +    fn as_ref(&self) -> &BlockMeta {
 | 
	
		
			
				|  |  | +        self
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +impl AsRef<BlockMeta> for &mut BlockMeta {
 | 
	
		
			
				|  |  | +    fn as_ref(&self) -> &BlockMeta {
 | 
	
		
			
				|  |  | +        self
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +impl AsMut<BlockMeta> for &mut BlockMeta {
 | 
	
		
			
				|  |  | +    fn as_mut(&mut self) -> &mut BlockMeta {
 | 
	
		
			
				|  |  | +        self
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +impl MetaAccess for &mut BlockMeta {}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  /// Extensions to the `Read` trait.
 | 
	
		
			
				|  |  |  trait ReadExt: Read {
 | 
	
		
			
				|  |  |      /// Reads repeatedly until one of the following occur:
 | 
	
	
		
			
				|  | @@ -364,7 +392,8 @@ pub struct BlockMetaBody {
 | 
	
		
			
				|  |  |      secrets: Ciphertext<BlockMetaSecrets>,
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      #[serde(skip)]
 | 
	
		
			
				|  |  | -    /// The path in the blocktree where this block is located.
 | 
	
		
			
				|  |  | +    /// The path in the blocktree where this block is located. This is initialized in
 | 
	
		
			
				|  |  | +    /// BlockStream::new.
 | 
	
		
			
				|  |  |      path: BlockPath,
 | 
	
		
			
				|  |  |      #[serde(skip)]
 | 
	
		
			
				|  |  |      /// The cleartext block key.
 | 
	
	
		
			
				|  | @@ -379,6 +408,7 @@ impl BlockMetaBody {
 | 
	
		
			
				|  |  |          let block_key = SymKey::generate(SymKeyKind::default())?;
 | 
	
		
			
				|  |  |          let mut readcaps = BTreeMap::new();
 | 
	
		
			
				|  |  |          readcaps.insert(creds.principal(), creds.ser_encrypt(&block_key)?);
 | 
	
		
			
				|  |  | +        let secrets = BlockMetaSecrets::default();
 | 
	
		
			
				|  |  |          Ok(BlockMetaBody {
 | 
	
		
			
				|  |  |              path: BlockPath::default(),
 | 
	
		
			
				|  |  |              inherit: None,
 | 
	
	
		
			
				|  | @@ -386,9 +416,9 @@ impl BlockMetaBody {
 | 
	
		
			
				|  |  |              writecap: creds.writecap().map(|e| e.to_owned()),
 | 
	
		
			
				|  |  |              integrity: None,
 | 
	
		
			
				|  |  |              signing_key: creds.public_sign().to_owned(),
 | 
	
		
			
				|  |  | -            secrets: block_key.ser_encrypt(&BlockMetaSecrets::default())?,
 | 
	
		
			
				|  |  | +            secrets: block_key.ser_encrypt(&secrets)?,
 | 
	
		
			
				|  |  |              block_key: Some(block_key),
 | 
	
		
			
				|  |  | -            secrets_struct: None,
 | 
	
		
			
				|  |  | +            secrets_struct: Some(secrets),
 | 
	
		
			
				|  |  |          })
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 |