This commit is contained in:
LordaeronESZ 2026-02-11 14:51:57 +01:00 committed by GitHub
commit 217852c72e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 76 additions and 25 deletions

View File

@ -1694,6 +1694,7 @@ impl InodeImpl {
.unwrap()
.read()
.unwrap()
.unwrap()
.start,
)
};
@ -2011,7 +2012,7 @@ impl<'a> DeviceRangeReader<'a> {
///
/// Note that the returned device range size may be smaller than the requested range
/// due to possible inconsecutive block allocation.
pub fn read(&mut self) -> Result<Range<Ext2Bid>> {
pub fn read(&mut self) -> Result<Option<Range<Ext2Bid>>> {
let bid_path = BidPath::from(self.range.start);
let max_cnt = self
.range
@ -2023,9 +2024,28 @@ impl<'a> DeviceRangeReader<'a> {
let mut device_range: Option<Range<Ext2Bid>> = None;
for i in start_idx..start_idx + max_cnt {
let device_bid = match &self.indirect_block {
None => self.block_ptrs.direct(i),
None => match bid_path {
BidPath::Direct(_) => self.block_ptrs.direct(i),
_ => 0,
},
Some(indirect_block) => indirect_block.read_bid(i)?,
};
// Skip sparse blocks which are not allocated
if device_bid == 0 {
match device_range {
Some(ref mut range) => {
// End the current range when hitting a sparse block
break;
}
None => {
// Skip leading sparse blocks, advance the logical range
self.range.start += 1;
continue;
}
}
}
match device_range {
Some(ref mut range) => {
if device_bid == range.end {
@ -2039,7 +2059,16 @@ impl<'a> DeviceRangeReader<'a> {
}
}
}
let device_range = device_range.unwrap();
let device_range = match device_range {
Some(range) => range,
None => {
if !self.range.is_empty() {
self.update_indirect_block()?;
}
return Ok(None);
}
};
// Updates the range
self.range.start += device_range.len() as Ext2Bid;
@ -2048,7 +2077,7 @@ impl<'a> DeviceRangeReader<'a> {
self.update_indirect_block()?;
}
Ok(device_range)
Ok(Some(device_range))
}
fn update_indirect_block(&mut self) -> Result<()> {
@ -2059,30 +2088,49 @@ impl<'a> DeviceRangeReader<'a> {
}
BidPath::Indirect(_) => {
let indirect_bid = self.block_ptrs.indirect();
let indirect_block = self.indirect_blocks.find(indirect_bid)?;
self.indirect_block = Some(indirect_block.clone());
if indirect_bid == 0 {
self.indirect_block = None;
} else {
let indirect_block = self.indirect_blocks.find(indirect_bid)?;
self.indirect_block = Some(indirect_block.clone());
}
}
BidPath::DbIndirect(lvl1_idx, _) => {
let lvl1_indirect_bid = {
let db_indirect_block =
self.indirect_blocks.find(self.block_ptrs.db_indirect())?;
db_indirect_block.read_bid(lvl1_idx as usize)?
};
let lvl1_indirect_block = self.indirect_blocks.find(lvl1_indirect_bid)?;
self.indirect_block = Some(lvl1_indirect_block.clone())
let db_indirect_bid = self.block_ptrs.db_indirect();
if db_indirect_bid == 0 {
self.indirect_block = None;
} else {
let db_indirect_block = self.indirect_blocks.find(db_indirect_bid)?;
let lvl1_indirect_bid = db_indirect_block.read_bid(lvl1_idx as usize)?;
if lvl1_indirect_bid == 0 {
self.indirect_block = None;
} else {
let lvl1_indirect_block = self.indirect_blocks.find(lvl1_indirect_bid)?;
self.indirect_block = Some(lvl1_indirect_block.clone());
}
}
}
BidPath::TbIndirect(lvl1_idx, lvl2_idx, _) => {
let lvl2_indirect_bid = {
let lvl1_indirect_bid = {
let tb_indirect_block =
self.indirect_blocks.find(self.block_ptrs.tb_indirect())?;
tb_indirect_block.read_bid(lvl1_idx as usize)?
};
let lvl1_indirect_block = self.indirect_blocks.find(lvl1_indirect_bid)?;
lvl1_indirect_block.read_bid(lvl2_idx as usize)?
};
let lvl2_indirect_block = self.indirect_blocks.find(lvl2_indirect_bid)?;
self.indirect_block = Some(lvl2_indirect_block.clone())
let tb_indirect_bid = self.block_ptrs.tb_indirect();
if tb_indirect_bid == 0 {
self.indirect_block = None;
} else {
let tb_indirect_block = self.indirect_blocks.find(tb_indirect_bid)?;
let lvl1_indirect_bid = tb_indirect_block.read_bid(lvl1_idx as usize)?;
if lvl1_indirect_bid == 0 {
self.indirect_block = None;
} else {
let lvl1_indirect_block = self.indirect_blocks.find(lvl1_indirect_bid)?;
let lvl2_indirect_bid = lvl1_indirect_block.read_bid(lvl2_idx as usize)?;
if lvl2_indirect_bid == 0 {
self.indirect_block = None;
} else {
let lvl2_indirect_block =
self.indirect_blocks.find(lvl2_indirect_bid)?;
self.indirect_block = Some(lvl2_indirect_block.clone());
}
}
}
}
}
@ -2099,7 +2147,10 @@ impl Iterator for DeviceRangeReader<'_> {
}
let range = self.read().unwrap();
Some(range)
match range {
Some(range) => Some(range),
None => self.next(),
}
}
}