direct access for journal entries
This commit is contained in:
		
							parent
							
								
									999336ff9e
								
							
						
					
					
						commit
						3b9b8a6c47
					
				
					 2 changed files with 150 additions and 10 deletions
				
			
		
							
								
								
									
										27
									
								
								src/lib.rs
									
										
									
									
									
								
							
							
						
						
									
										27
									
								
								src/lib.rs
									
										
									
									
									
								
							|  | @ -4,7 +4,7 @@ extern crate alloc; | |||
| 
 | ||||
| use alloc::vec::Vec; | ||||
| use vapfs::{BlockDevice, Index}; | ||||
| use crate::structs::{Inode, Superblock}; | ||||
| use crate::structs::{Inode, JournalEntry, Superblock}; | ||||
| 
 | ||||
| pub mod btree; | ||||
| pub mod structs; | ||||
|  | @ -204,3 +204,28 @@ pub unsafe fn set_inode_allocation_status(index: Index, sb: &Superblock, bd: &mu | |||
|     let write_count = bd.write_blocks(&bitmap_buf); | ||||
|     write_count == bitmap_length as usize | ||||
| } | ||||
| 
 | ||||
| /// Reads a journal entry by index
 | ||||
| pub fn read_journal_entry(index: Index, sb: &Superblock, bd: &mut dyn BlockDevice) -> Option<JournalEntry> { | ||||
|     let mut buf: [u8; core::mem::size_of::<JournalEntry>()] = [0; core::mem::size_of::<JournalEntry>()]; | ||||
|     bd.seek((sb.first_journal_block * sb.block_size as u64) + (index * core::mem::size_of::<JournalEntry>() as u64)); | ||||
|     let read_count = bd.read_blocks(&mut buf); | ||||
|     if read_count < core::mem::size_of::<JournalEntry>() { | ||||
|         return None; | ||||
|     } | ||||
|     let mut entry = unsafe { core::ptr::read(buf.as_ptr() as *const JournalEntry) }; | ||||
|     entry.convert_big_endian_to_native(); | ||||
|     Some(entry) | ||||
| } | ||||
| 
 | ||||
| /// Performs a direct write of a journal entry to the block device.
 | ||||
| /// # Safety
 | ||||
| /// unsafe because it assumes that the entry is correctly formatted and that everything has been performed correctly
 | ||||
| pub unsafe fn write_journal_entry(index: Index, sb: &Superblock, bd: &mut dyn BlockDevice, mut entry: JournalEntry) -> bool { | ||||
|     entry.convert_native_to_big_endian(); | ||||
|     let mut buf: [u8; core::mem::size_of::<JournalEntry>()] = [0; core::mem::size_of::<JournalEntry>()]; | ||||
|     core::ptr::write(buf.as_mut_ptr() as *mut JournalEntry, entry); | ||||
|     bd.seek((sb.first_journal_block * sb.block_size as u64) + (index * core::mem::size_of::<JournalEntry>() as u64)); | ||||
|     let write_count = bd.write_blocks(&buf); | ||||
|     write_count == core::mem::size_of::<JournalEntry>() | ||||
| } | ||||
							
								
								
									
										133
									
								
								src/structs.rs
									
										
									
									
									
								
							
							
						
						
									
										133
									
								
								src/structs.rs
									
										
									
									
									
								
							|  | @ -288,12 +288,55 @@ pub enum InodeFlags { | |||
| /// # JournalEntry
 | ||||
| /// A Journal Entry
 | ||||
| #[repr(C)] | ||||
| pub struct JournalHeader { | ||||
| pub struct JournalEntry { | ||||
|     pub flags: u32, | ||||
|     pub operation: JournalOperation, | ||||
|     /// JournalOperation
 | ||||
|     pub operation: u32, | ||||
|     /// crc32 hash of the content with flags set to zero, used to verify journal was fully written without verifying the stage
 | ||||
|     pub zeroed_content_crc32: u32, | ||||
|     pub content: JournalEntry, | ||||
|     pub content: JournalEntryContents, | ||||
| } | ||||
| 
 | ||||
| impl JournalEntry { | ||||
|     /// in-place conversion from the storage representation (big endian) to the native representation
 | ||||
|     pub fn convert_big_endian_to_native(&mut self) { | ||||
|         #[cfg(target_endian = "little")] | ||||
|         { | ||||
|             self.flags = u32::from_be(self.flags); | ||||
|             self.operation = u32::from_be(self.operation); | ||||
|             self.zeroed_content_crc32 = u32::from_be(self.zeroed_content_crc32); | ||||
|             match self.operation { | ||||
|                 0 => { // SingleBlockWrite
 | ||||
|                     unsafe { self.content.block_write.convert_big_endian_to_native() }; | ||||
|                 } | ||||
|                 1 => { // MultiblockWrite
 | ||||
|                     unsafe { self.content.multiblock_write.convert_big_endian_to_native() }; | ||||
|                 } | ||||
| 
 | ||||
|                 _ => {} | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /// in-place conversion from the native representation to the storage representation (big endian)
 | ||||
|     pub fn convert_native_to_big_endian(&mut self) { | ||||
|         #[cfg(target_endian = "little")] | ||||
|         { | ||||
|             self.flags = u32::to_be(self.flags); | ||||
|             self.operation = u32::to_be(self.operation); | ||||
|             self.zeroed_content_crc32 = u32::to_be(self.zeroed_content_crc32); | ||||
|             match self.operation { | ||||
|                 0 => { // SingleBlockWrite
 | ||||
|                     unsafe { self.content.block_write.convert_native_to_big_endian() }; | ||||
|                 } | ||||
|                 1 => { // MultiblockWrite
 | ||||
|                     unsafe { self.content.multiblock_write.convert_native_to_big_endian() }; | ||||
|                 } | ||||
| 
 | ||||
|                 _ => {} | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| /// # JournalOperation
 | ||||
|  | @ -326,8 +369,8 @@ pub enum JournalOperation { | |||
| #[repr(C)] | ||||
| #[derive(Copy, Clone)] | ||||
| pub struct JournalBlockWrite { | ||||
|     /// flags stating how far the write has progressed
 | ||||
|     pub flags: JBRFlags, | ||||
|     /// JBRFlags stating how far the write has progressed
 | ||||
|     pub flags: u32, | ||||
|     /// are we writing to an inode instead of a data block?
 | ||||
|     pub target_is_inode: bool, | ||||
|     /// block number of target
 | ||||
|  | @ -338,6 +381,30 @@ pub struct JournalBlockWrite { | |||
|     pub source_block_crc32: u32, | ||||
| } | ||||
| 
 | ||||
| impl JournalBlockWrite { | ||||
|     /// in-place conversion from the storage representation (big endian) to the native representation
 | ||||
|     pub fn convert_big_endian_to_native(&mut self) { | ||||
|         #[cfg(target_endian = "little")] | ||||
|         { | ||||
|             self.flags = u32::from_be(self.flags); | ||||
|             self.target_block = u64::from_be(self.target_block); | ||||
|             self.source_block = u64::from_be(self.source_block); | ||||
|             self.source_block_crc32 = u32::from_be(self.source_block_crc32); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /// in-place conversion from the native representation to the storage representation (big endian)
 | ||||
|     pub fn convert_native_to_big_endian(&mut self) { | ||||
|         #[cfg(target_endian = "little")] | ||||
|         { | ||||
|             self.flags = u32::to_be(self.flags); | ||||
|             self.target_block = u64::to_be(self.target_block); | ||||
|             self.source_block = u64::to_be(self.source_block); | ||||
|             self.source_block_crc32 = u32::to_be(self.source_block_crc32); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| /// # JBRFlags
 | ||||
| /// Flags field of a JournalBlockWrite
 | ||||
| #[repr(u32)] | ||||
|  | @ -375,8 +442,8 @@ pub enum JBRFlags { | |||
| #[repr(C)] | ||||
| #[derive(Copy, Clone)] | ||||
| pub struct JournalMultiblockWrite { | ||||
|     /// flags stating how far the write has progressed
 | ||||
|     pub flags: JMWFlags, | ||||
|     /// JMWFlags stating how far the write has progressed
 | ||||
|     pub flags: u32, | ||||
|     /// block number of first target block
 | ||||
|     pub target_block: Index, | ||||
|     /// number of target blocks
 | ||||
|  | @ -387,6 +454,32 @@ pub struct JournalMultiblockWrite { | |||
|     pub list_block_crc32: u32, | ||||
| } | ||||
| 
 | ||||
| impl JournalMultiblockWrite { | ||||
|     /// in-place conversion from the storage representation (big endian) to the native representation
 | ||||
|     pub fn convert_big_endian_to_native(&mut self) { | ||||
|         #[cfg(target_endian = "little")] | ||||
|         { | ||||
|             self.flags = u32::from_be(self.flags); | ||||
|             self.target_block = u64::from_be(self.target_block); | ||||
|             self.target_block_count = u64::from_be(self.target_block_count); | ||||
|             self.list_block = u64::from_be(self.list_block); | ||||
|             self.list_block_crc32 = u32::from_be(self.list_block_crc32); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /// in-place conversion from the native representation to the storage representation (big endian)
 | ||||
|     pub fn convert_native_to_big_endian(&mut self) { | ||||
|         #[cfg(target_endian = "little")] | ||||
|         { | ||||
|             self.flags = u32::to_be(self.flags); | ||||
|             self.target_block = u64::to_be(self.target_block); | ||||
|             self.target_block_count = u64::to_be(self.target_block_count); | ||||
|             self.list_block = u64::to_be(self.list_block); | ||||
|             self.list_block_crc32 = u32::to_be(self.list_block_crc32); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| /// # JMWFlags
 | ||||
| /// Flags field of a JournalMultiblockWrite
 | ||||
| #[repr(u32)] | ||||
|  | @ -417,10 +510,32 @@ pub struct ListBlock { | |||
|     pub direct_block_addresses: [Index; 12], | ||||
| } | ||||
| 
 | ||||
| /// # JournalEntry
 | ||||
| impl ListBlock { | ||||
|     /// in-place conversion from the storage representation (big endian) to the native representation
 | ||||
|     pub fn convert_big_endian_to_native(&mut self) { | ||||
|         #[cfg(target_endian = "little")] | ||||
|         { | ||||
|             for i in 0..12 { | ||||
|                 self.direct_block_addresses[i] = u64::from_be(self.direct_block_addresses[i]); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /// in-place conversion from the native representation to the storage representation (big endian)
 | ||||
|     pub fn convert_native_to_big_endian(&mut self) { | ||||
|         #[cfg(target_endian = "little")] | ||||
|         { | ||||
|             for i in 0..12 { | ||||
|                 self.direct_block_addresses[i] = u64::to_be(self.direct_block_addresses[i]); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| /// # JournalEntryContents
 | ||||
| /// union of all possible journal entries
 | ||||
| #[repr(C)] | ||||
| pub union JournalEntry { | ||||
| pub union JournalEntryContents { | ||||
|     pub block_write: JournalBlockWrite, | ||||
|     pub multiblock_write: JournalMultiblockWrite, | ||||
| } | ||||
		Loading…
	
	Add table
		
		Reference in a new issue