more code for infinite ptrs that i hope works (:

This commit is contained in:
husky 2023-08-19 01:37:51 -07:00
parent 2e5a154895
commit 4214816e3f
No known key found for this signature in database
GPG key ID: 6B3D8CB511646891

View file

@ -2,6 +2,7 @@
extern crate alloc; extern crate alloc;
use alloc::collections::VecDeque;
use alloc::vec; use alloc::vec;
use alloc::vec::Vec; use alloc::vec::Vec;
use vapfs::{BlockDevice, Index}; use vapfs::{BlockDevice, Index};
@ -295,19 +296,19 @@ pub fn next_journal_position(sb: &Superblock, bd: &mut dyn BlockDevice) -> Optio
} }
} }
/// Reads an indirect datablock from a list of 3 indirect datablocks. /// Returns the index of an indirectly indexed datablock, or 0 if it does not exist.
pub fn read_indirect_datablock(sb: &Superblock, bd: &mut dyn BlockDevice, dbas: [Index; 12], address: Index) -> Vec<u8> { pub fn get_indirect_datablock(sb: &Superblock, bd: &mut dyn BlockDevice, dbas: [Index; 12], address: Index) -> Index {
if address < 12 { if address < 12 {
return read_datablock(dbas[address as usize], sb, bd); dbas[address as usize]
} else { } else {
let mut n = address - 12; let n = address - 12;
let mut blocks_left = n / (sb.block_size as u64 - 8); let mut blocks_left = n / (sb.block_size as u64 - 8);
let mut indexes_left = n % (sb.block_size as u64 - 8); let mut indexes_left = n % (sb.block_size as u64 - 8);
let mut current_block = dbas[9]; // first indirect block let mut current_block = dbas[9]; // first indirect block
let mut visited = vec![]; let mut visited = vec![];
loop { loop {
if visited.contains(&current_block) { if visited.contains(&current_block) {
return vec![]; // we've looped around return 0;
} }
visited.push(current_block); visited.push(current_block);
let mut head = 0; let mut head = 0;
@ -329,7 +330,7 @@ pub fn read_indirect_datablock(sb: &Superblock, bd: &mut dyn BlockDevice, dbas:
} else { } else {
// if indexes_left == 0, we found the correct index // if indexes_left == 0, we found the correct index
if indexes_left == 0 { if indexes_left == 0 {
return read_datablock(ptr, sb, bd); return ptr;
} else { } else {
indexes_left -= 1; indexes_left -= 1;
} }
@ -358,7 +359,7 @@ pub fn read_indirect_datablock(sb: &Superblock, bd: &mut dyn BlockDevice, dbas:
} else { } else {
// if indexes_left == 0, we found the correct index // if indexes_left == 0, we found the correct index
if indexes_left == 0 { if indexes_left == 0 {
return read_datablock(ptr, sb, bd); return ptr;
} else { } else {
indexes_left -= 1; indexes_left -= 1;
} }
@ -531,44 +532,120 @@ pub fn schedule_multi_block_write(sb: &Superblock, bd: &mut dyn BlockDevice, con
// if using indirect blocks, fit the remaining entries into the indirect blocks // if using indirect blocks, fit the remaining entries into the indirect blocks
// layout is u64 count followed by u64 addresses // layout is u64 count followed by u64 addresses
let max_addresses_per_block = (sb.block_size as usize - core::mem::size_of::<u64>()) / core::mem::size_of::<u64>(); let max_addresses_per_block = (sb.block_size as usize - core::mem::size_of::<u64>()) / (core::mem::size_of::<u64>() * 2);
let mut indirect_block_count = (datablock_count - 9) / max_addresses_per_block as u64; let mut indirect_block_count = (datablock_count - 9) / max_addresses_per_block as u64;
// if the count is not a multiple of the max addresses per block, add one // if the count is not a multiple of the max addresses per block, add one
if (datablock_count - 9) % max_addresses_per_block as u64 != 0 { if (datablock_count - 9) % max_addresses_per_block as u64 != 0 {
indirect_block_count += 1; indirect_block_count += 1;
} }
// if the count is over 3, return None // if the count is over 3, we'll need to use nested indirect blocks
if indirect_block_count > 3 { // calculate how many layers of indirect blocks we'll need,
return None; // filling max_addresses per block until we have less than max_addresses_per_block left
// this will be the amount of layers required to store the data
let depth = {
let mut depth = 0;
let mut remaining = indirect_block_count;
while remaining > max_addresses_per_block as u64 {
remaining -= max_addresses_per_block as u64;
depth += 1;
} }
depth
};
// allocate the indirect blocks // allocate the indirect blocks
let indirect_blocks = find_count_unallocated_datablocks(sb, bd, indirect_block_count as usize)?; let indirect_blocks = find_count_unallocated_datablocks(sb, bd, indirect_block_count as usize + (depth * max_addresses_per_block))?;
for i in 0..indirect_block_count { for i in 0..(indirect_block_count as usize + (depth * max_addresses_per_block)) {
list_block.direct_block_addresses[9 + i as usize] = indirect_blocks[i as usize]; list_block.direct_block_addresses[9 + i] = indirect_blocks[i];
indirect_blocks_waiting_for_allocation_to_be_set.push(indirect_blocks[i as usize]); indirect_blocks_waiting_for_allocation_to_be_set.push(indirect_blocks[i]);
} }
// write the indirect blocks // write the indirect blocks
let mut indirect_block_data = vec![0; core::mem::size_of::<u64>() * max_addresses_per_block]; let mut indirect_block_data = vec![0; core::mem::size_of::<u64>() * max_addresses_per_block];
for i in 0..indirect_block_count { let mut indirect_blocks_from_previous_layer = VecDeque::new();
// write the count let mut indirect_blocks_from_previous_layer_alt = Vec::new();
let count = if i == indirect_block_count - 1 { let mut using_alt = false;
let count_per_layer = 16 / (max_addresses_per_block - 8);
for i in 0..(indirect_block_count as usize + (depth * max_addresses_per_block)) {
// we will write the indirect blocks that contain the data blocks first
// then we will write the indirect blocks that contain the indirect blocks
// are we writing the indirect blocks that contain the data blocks?
let writing_data_blocks = i < indirect_block_count as usize;
if writing_data_blocks {
let count = if i == (indirect_block_count - 1) as usize { // if we're at the last block, not all of the addresses will be used
(datablock_count - 9) % max_addresses_per_block as u64 (datablock_count - 9) % max_addresses_per_block as u64
} else { } else {
max_addresses_per_block as u64 max_addresses_per_block as u64 // otherwise, all of the addresses will be used
}; };
// add count
unsafe { core::ptr::write(indirect_block_data.as_mut_ptr() as *mut u64, count); } unsafe { core::ptr::write(indirect_block_data.as_mut_ptr() as *mut u64, count); }
// add addresses
// write the addresses
for j in 0..count { for j in 0..count {
unsafe { core::ptr::write((indirect_block_data.as_mut_ptr() as *mut u64).offset(1 + j as isize), allocated_blocks[(9 + i) as usize + j as usize]); } unsafe { core::ptr::write((indirect_block_data.as_mut_ptr() as *mut u64).add(8 + j as usize), allocated_blocks[9 + i * max_addresses_per_block + j as usize]); }
} }
// write the data // write the indirect block
if !unsafe { write_datablock(list_block.direct_block_addresses[9 + i as usize], sb, bd, &indirect_block_data) } { if !unsafe { write_datablock(indirect_blocks[i], sb, bd, &indirect_block_data) } {
return None; return None;
} }
indirect_blocks_from_previous_layer.push_back(indirect_blocks[i]);
} else {
// we're writing the indirect blocks that contain the indirect blocks
if !using_alt {
// write addresses from front of indirect_blocks_from_previous_layer
let count = if indirect_blocks_from_previous_layer.len() > max_addresses_per_block - 8 {
max_addresses_per_block - 8
} else {
indirect_blocks_from_previous_layer.len()
};
// add count
unsafe { core::ptr::write(indirect_block_data.as_mut_ptr() as *mut u64, count as u64); }
// add addresses
for j in 0..count {
unsafe { core::ptr::write((indirect_block_data.as_mut_ptr() as *mut u64).add(8 + j), indirect_blocks_from_previous_layer.pop_front().unwrap_or(0)); }
}
// write the indirect block
if !unsafe { write_datablock(indirect_blocks[i], sb, bd, &indirect_block_data) } {
return None;
}
// add the indirect block to the back of indirect_blocks_from_previous_layer_alt
indirect_blocks_from_previous_layer_alt.push(indirect_blocks[i]);
// if indirect_blocks_from_previous_layer is empty, switch to using_alt
if indirect_blocks_from_previous_layer.is_empty() {
using_alt = true;
}
} else {
// write addresses from front of indirect_blocks_from_previous_layer_alt
let count = if indirect_blocks_from_previous_layer_alt.len() > max_addresses_per_block - 8 {
max_addresses_per_block - 8
} else {
indirect_blocks_from_previous_layer_alt.len()
};
// add count
unsafe { core::ptr::write(indirect_block_data.as_mut_ptr() as *mut u64, count as u64); }
// add addresses
for j in 0..count {
unsafe { core::ptr::write((indirect_block_data.as_mut_ptr() as *mut u64).add(8 + j), indirect_blocks_from_previous_layer_alt.pop().unwrap_or(0)); }
}
// write the indirect block
if !unsafe { write_datablock(indirect_blocks[i], sb, bd, &indirect_block_data) } {
return None;
}
// add the indirect block to the back of indirect_blocks_from_previous_layer
indirect_blocks_from_previous_layer.push_back(indirect_blocks[i]);
// if indirect_blocks_from_previous_layer_alt is empty, switch to using_alt
if indirect_blocks_from_previous_layer_alt.is_empty() {
using_alt = false;
}
}
}
} }
} else { } else {
list_block.direct_block_addresses[..12].copy_from_slice(&allocated_blocks[..12]); list_block.direct_block_addresses[..12].copy_from_slice(&allocated_blocks[..12]);