Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion _test_image.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ set -e
tmp_dir=$(mktemp -d)
trap "rm -r \"$tmp_dir\"" EXIT
echo "hello world" > "$tmp_dir"/test.txt
for i in {1..100};do
for i in {1..1000};do
echo "hello world" >> "$tmp_dir"/test.txt
done
for i in {1..100};do
echo "hello world$i" > "$tmp_dir"/test$i.txt
for j in {1..20};do
setfattr -n user.name$j -v value${i}_$j "$tmp_dir"/test$i.txt
Expand Down
38 changes: 24 additions & 14 deletions ext4/block.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@


class BlockIOBlocks(object):
def __init__(self, blockio):
self.blockio = blockio
def __init__(self, blockio: "BlockIO"):
self.blockio: BlockIO = blockio
self._null_block: bytearray = bytearray(self.block_size)

@property
def block_size(self):
Expand Down Expand Up @@ -37,10 +38,16 @@ def __contains__(self, ee_block):

def __getitem__(self, ee_block):
for extent in self.blockio.extents:
if ee_block in extent.blocks:
return extent.blocks[ee_block]
if ee_block not in extent.blocks:
continue

block = extent.blocks[ee_block]
if block is None:
break

return bytearray(self.block_size)
return block

return self._null_block


class BlockIO(io.RawIOBase):
Expand Down Expand Up @@ -112,16 +119,19 @@ def peek(self, size: int = 0) -> bytes:
start_index = self.cursor // self.block_size
end_index = (self.cursor + size - 1) // self.block_size
start_offset = self.cursor % self.block_size
data = b""
for i in range(start_index, end_index + 1):
block = self.blocks[i]
if block is None:
block = bytearray(self.block_size)
end_offset = ((self.cursor + size - 1) % self.block_size) + 1
blocks_list: list[memoryview] = []

for i in range(start_index, end_index + 1):
block: bytes | bytearray = self.blocks[i]
view = memoryview(block)
if i == start_index:
block = block[start_offset:]
view = view[start_offset:]

data += block
if i == end_index:
trim = end_offset - (start_offset if i == start_index else 0)
view = view[:trim]

data = data[:size]
return data
blocks_list.append(view)

return b"".join(blocks_list)
3 changes: 3 additions & 0 deletions test.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,9 @@ def _assert(source: str, debug: Callable[[], Any] | None = None): # pyright: ig
b = inode.open()
_assert("isinstance(b, ext4.BlockIO)")
_assert("b.readable()")
_assert("not b.peek(0)")
size = volume.block_size + 1
_assert(f"len(b.peek({size})) == {size}")
_assert("b.seekable()")
_assert("b.seek(1) == 1")
_assert("b.seek(0) == 0")
Expand Down