extent.rs 13 KB

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