extent.rs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. use super::Ext4;
  2. use crate::constants::*;
  3. use crate::ext4_defs::*;
  4. use crate::format_error;
  5. use crate::prelude::*;
  6. use core::cmp::min;
  7. #[derive(Debug)]
  8. struct ExtentSearchStep {
  9. /// The physical block where this extent node is stored.
  10. /// For a root node, this field is 0.
  11. pblock: PBlockId,
  12. /// Index of the found `ExtentIndex` or `Extent` if found, the position where the
  13. /// `ExtentIndex` or `Extent` should be inserted if not found.
  14. index: core::result::Result<usize, usize>,
  15. }
  16. impl ExtentSearchStep {
  17. /// Create a new extent search step
  18. fn new(pblock: PBlockId, index: core::result::Result<usize, usize>) -> Self {
  19. Self { pblock, index }
  20. }
  21. }
  22. impl Ext4 {
  23. /// Given a logic block id, find the corresponding fs block id.
  24. pub(super) fn extent_query(&self, inode_ref: &InodeRef, iblock: LBlockId) -> Result<PBlockId> {
  25. let path = self.find_extent(inode_ref, iblock);
  26. // Leaf is the last element of the path
  27. let leaf = path.last().unwrap();
  28. if let Ok(index) = leaf.index {
  29. // Note: block data must be defined here to keep it alive
  30. let block_data: Block;
  31. let ex_node = if leaf.pblock != 0 {
  32. // Load the extent node
  33. block_data = self.read_block(leaf.pblock);
  34. // Load the next extent header
  35. ExtentNode::from_bytes(&block_data.data)
  36. } else {
  37. // Root node
  38. inode_ref.inode.extent_root()
  39. };
  40. let ex = ex_node.extent_at(index);
  41. Ok(ex.start_pblock() + (iblock - ex.start_lblock()) as PBlockId)
  42. } else {
  43. Err(format_error!(
  44. ErrCode::ENOENT,
  45. "extent_query: extent not found"
  46. ))
  47. }
  48. }
  49. /// Given a logic block id, find the corresponding fs block id.
  50. /// Create a new extent if not found.
  51. pub(super) fn extent_query_or_create(
  52. &self,
  53. inode_ref: &mut InodeRef,
  54. iblock: LBlockId,
  55. block_count: u32,
  56. ) -> Result<PBlockId> {
  57. let path = self.find_extent(inode_ref, iblock);
  58. // Leaf is the last element of the path
  59. let leaf = path.last().unwrap();
  60. // Note: block data must be defined here to keep it alive
  61. let mut block_data: Block;
  62. let ex_node = if leaf.pblock != 0 {
  63. block_data = self.read_block(leaf.pblock);
  64. ExtentNodeMut::from_bytes(&mut block_data.data)
  65. } else {
  66. // Root node
  67. inode_ref.inode.extent_root_mut()
  68. };
  69. match leaf.index {
  70. Ok(index) => {
  71. // Found, return the corresponding fs block id
  72. let ex = ex_node.extent_at(index);
  73. Ok(ex.start_pblock() + (iblock - ex.start_lblock()) as PBlockId)
  74. }
  75. Err(_) => {
  76. // Not found, create a new extent
  77. let block_count = min(block_count, MAX_BLOCKS - iblock);
  78. // Allocate physical block
  79. let fblock = self.alloc_block(inode_ref)?;
  80. // Create a new extent
  81. let new_ext = Extent::new(iblock, fblock, block_count as u16);
  82. // Insert the new extent
  83. self.insert_extent(inode_ref, &path, &new_ext)?;
  84. Ok(fblock)
  85. }
  86. }
  87. }
  88. /// Get all data blocks recorded in the extent tree
  89. pub(super) fn extent_all_data_blocks(&self, inode_ref: &InodeRef) -> Vec<PBlockId> {
  90. let mut pblocks = Vec::new();
  91. let ex_node = inode_ref.inode.extent_root();
  92. self.get_all_pblocks_recursive(&ex_node, &mut pblocks);
  93. pblocks
  94. }
  95. /// Get all physical blocks for saving the extent tree
  96. pub(super) fn extent_all_tree_blocks(&self, inode_ref: &InodeRef) -> Vec<PBlockId> {
  97. let mut pblocks = Vec::new();
  98. let ex_node = inode_ref.inode.extent_root();
  99. self.get_all_nodes_recursive(&ex_node, &mut pblocks);
  100. pblocks
  101. }
  102. fn get_all_pblocks_recursive(&self, ex_node: &ExtentNode, pblocks: &mut Vec<PBlockId>) {
  103. if ex_node.header().depth() == 0 {
  104. // Leaf
  105. for i in 0..ex_node.header().entries_count() as usize {
  106. let ex = ex_node.extent_at(i);
  107. for j in 0..ex.block_count() {
  108. pblocks.push(ex.start_pblock() + j as PBlockId);
  109. }
  110. }
  111. } else {
  112. // Non-leaf
  113. for i in 0..ex_node.header().entries_count() as usize {
  114. let ex_idx = ex_node.extent_index_at(i);
  115. let child_block = self.read_block(ex_idx.leaf());
  116. let child_node = ExtentNode::from_bytes(&child_block.data);
  117. self.get_all_pblocks_recursive(&child_node, pblocks);
  118. }
  119. }
  120. }
  121. fn get_all_nodes_recursive(&self, ex_node: &ExtentNode, pblocks: &mut Vec<PBlockId>) {
  122. if ex_node.header().depth() != 0 {
  123. // Non-leaf
  124. for i in 0..ex_node.header().entries_count() as usize {
  125. let ex_idx = ex_node.extent_index_at(i);
  126. pblocks.push(ex_idx.leaf());
  127. let child_block = self.read_block(ex_idx.leaf());
  128. let child_node = ExtentNode::from_bytes(&child_block.data);
  129. self.get_all_nodes_recursive(&child_node, pblocks);
  130. }
  131. }
  132. }
  133. /// Find the given logic block id in the extent tree, return the search path
  134. fn find_extent(&self, inode_ref: &InodeRef, iblock: LBlockId) -> Vec<ExtentSearchStep> {
  135. let mut path: Vec<ExtentSearchStep> = Vec::new();
  136. let mut ex_node = inode_ref.inode.extent_root();
  137. let mut pblock = 0;
  138. let mut block_data: Block;
  139. // Go until leaf
  140. while ex_node.header().depth() > 0 {
  141. let index = ex_node.search_extent_index(iblock).expect("Must succeed");
  142. path.push(ExtentSearchStep::new(pblock, Ok(index)));
  143. // Get the target extent index
  144. let ex_idx = ex_node.extent_index_at(index);
  145. // Load the next extent node
  146. let next = ex_idx.leaf();
  147. // Note: block data cannot be released until the next assigment
  148. block_data = self.read_block(next);
  149. // Load the next extent header
  150. ex_node = ExtentNode::from_bytes(&block_data.data);
  151. pblock = next;
  152. }
  153. // Leaf
  154. let index = ex_node.search_extent(iblock);
  155. path.push(ExtentSearchStep::new(pblock, index));
  156. path
  157. }
  158. /// Insert a new extent into the extent tree.
  159. fn insert_extent(
  160. &self,
  161. inode_ref: &mut InodeRef,
  162. path: &Vec<ExtentSearchStep>,
  163. new_ext: &Extent,
  164. ) -> Result<()> {
  165. let leaf = path.last().unwrap();
  166. // 1. Check If leaf is root
  167. if leaf.pblock == 0 {
  168. let mut leaf_node = inode_ref.inode.extent_root_mut();
  169. // Insert the extent
  170. let res = leaf_node.insert_extent(new_ext, leaf.index.unwrap_err());
  171. self.write_inode_without_csum(inode_ref);
  172. // Handle split
  173. return if let Err(split) = res {
  174. self.split_root(inode_ref, &split)
  175. } else {
  176. Ok(())
  177. };
  178. }
  179. // 2. Leaf is not root, load the leaf node
  180. let mut leaf_block = self.read_block(leaf.pblock);
  181. let mut leaf_node = ExtentNodeMut::from_bytes(&mut leaf_block.data);
  182. // Insert the extent
  183. let res = leaf_node.insert_extent(new_ext, leaf.index.unwrap_err());
  184. self.write_block(&leaf_block);
  185. // Handle split
  186. if let Err(mut split) = res {
  187. // Handle split until root
  188. for parent in path.iter().rev().skip(1) {
  189. // The split node is at `parent.index.unwrap()`
  190. // Call `self.split` to store the split part and update `parent`
  191. let res = self.split(inode_ref, parent.pblock, parent.index.unwrap(), &split);
  192. // Handle split again
  193. if let Err(split_again) = res {
  194. // Insertion to parent also causes split, continue to solve
  195. split = split_again;
  196. } else {
  197. return Ok(());
  198. }
  199. }
  200. // Root node needs to be split
  201. self.split_root(inode_ref, &split)
  202. } else {
  203. Ok(())
  204. }
  205. }
  206. /// Split an extent node. Given the block id where the parent node is
  207. /// stored, and the child position that `parent_node.extent_at(child_pos)`
  208. /// points to the child.
  209. ///
  210. /// The child node has already been split by calling `insert_extent` or
  211. /// `insert_extent_index`, and the split part is stored in `split`.
  212. /// This function will create a new leaf node to store the split part.
  213. fn split(
  214. &self,
  215. inode_ref: &mut InodeRef,
  216. parent_pblock: PBlockId,
  217. child_pos: usize,
  218. split: &[FakeExtent],
  219. ) -> core::result::Result<(), Vec<FakeExtent>> {
  220. let right_bid = self.alloc_block(inode_ref).unwrap();
  221. let mut right_block = self.read_block(right_bid);
  222. let mut right_node = ExtentNodeMut::from_bytes(&mut right_block.data);
  223. // Insert the split half to right node
  224. right_node.init(0, 0);
  225. for (i, fake_extent) in split.iter().enumerate() {
  226. *right_node.fake_extent_mut_at(i) = *fake_extent;
  227. }
  228. right_node
  229. .header_mut()
  230. .set_entries_count(split.len() as u16);
  231. // Create an extent index pointing to the right node
  232. let extent_index =
  233. ExtentIndex::new(right_node.extent_index_at(0).start_lblock(), right_bid);
  234. let res;
  235. let parent_depth;
  236. if parent_pblock == 0 {
  237. // Parent is root
  238. let mut parent_node = inode_ref.inode.extent_root_mut();
  239. parent_depth = parent_node.header().depth();
  240. res = parent_node.insert_extent_index(&extent_index, child_pos + 1);
  241. self.write_inode_without_csum(inode_ref);
  242. } else {
  243. // Parent is not root
  244. let mut parent_block = self.read_block(parent_pblock);
  245. let mut parent_node = ExtentNodeMut::from_bytes(&mut parent_block.data);
  246. parent_depth = parent_node.header().depth();
  247. res = parent_node.insert_extent_index(&extent_index, child_pos + 1);
  248. self.write_block(&parent_block);
  249. }
  250. // Right node is the child of parent, so its depth is 1 less than parent
  251. right_node.header_mut().set_depth(parent_depth - 1);
  252. self.write_block(&right_block);
  253. res
  254. }
  255. /// Split the root extent node. This function will create 2 new leaf
  256. /// nodes and increase the height of the tree by 1.
  257. ///
  258. /// The root node has already been split by calling `insert_extent` or
  259. /// `insert_extent_index`, and the split part is stored in `split`.
  260. /// This function will create a new leaf node to store the split part.
  261. fn split_root(&self, inode_ref: &mut InodeRef, split: &[FakeExtent]) -> Result<()> {
  262. // Create left and right blocks
  263. let l_bid = self.alloc_block(inode_ref)?;
  264. let r_bid = self.alloc_block(inode_ref)?;
  265. let mut l_block = self.read_block(l_bid);
  266. let mut r_block = self.read_block(r_bid);
  267. // Load root, left, right nodes
  268. let mut root = inode_ref.inode.extent_root_mut();
  269. let mut left = ExtentNodeMut::from_bytes(&mut l_block.data);
  270. let mut right = ExtentNodeMut::from_bytes(&mut r_block.data);
  271. // Copy the left half to left node
  272. left.init(root.header().depth(), 0);
  273. for i in 0..root.header().entries_count() as usize {
  274. *left.fake_extent_mut_at(i) = *root.fake_extent_at(i);
  275. }
  276. left.header_mut()
  277. .set_entries_count(root.header().entries_count());
  278. // Copy the right half to right node
  279. right.init(root.header().depth(), 0);
  280. for (i, fake_extent) in split.iter().enumerate() {
  281. *right.fake_extent_mut_at(i) = *fake_extent;
  282. }
  283. right.header_mut().set_entries_count(split.len() as u16);
  284. // Update the root node
  285. let depth = root.header().depth() + 1;
  286. root.header_mut().set_depth(depth);
  287. root.header_mut().set_entries_count(2);
  288. *root.extent_index_mut_at(0) = ExtentIndex::new(left.extent_at(0).start_lblock(), l_bid);
  289. *root.extent_index_mut_at(1) = ExtentIndex::new(right.extent_at(0).start_lblock(), r_bid);
  290. // Sync to disk
  291. self.write_block(&l_block);
  292. self.write_block(&r_block);
  293. self.write_inode_without_csum(inode_ref);
  294. Ok(())
  295. }
  296. }