Class: VirtFS::BlockIO
- Inherits:
-
Object
- Object
- VirtFS::BlockIO
- Defined in:
- lib/virtfs/block_io.rb
Overview
Block IO Adapter, used internally by VirtFS to perform read and write operations via an underlying ‘block-like’ interface.
The class requires a handle to an object defining #raw_read and #raw_write methods facilitating raw block access.
This class behaves similarily to a tradional disk device, providing a ‘seek’ position at which read/write operations occur after which the pos is updated
Constant Summary collapse
- MIN_BLOCKS_TO_CACHE =
64
Instance Attribute Summary collapse
-
#offset ⇒ Object
Optional absolute block offset, always applied.
Instance Method Summary collapse
-
#close ⇒ Object
Close block device, after this no additional read/writes can occur.
-
#initialize(io_obj) ⇒ BlockIO
constructor
BlockIO initializer.
-
#read(len) ⇒ Array<Byte>?
Read len bytes from the block device and update seek_pos.
-
#seek(amt, whence = IO::SEEK_SET) ⇒ Object
Advance seek pointer via the specified mechanism.
-
#size ⇒ Integer
Size of block device.
-
#write(buf, len) ⇒ Integer?
Write buffer of specified length to block device and update seek_pos.
Constructor Details
#initialize(io_obj) ⇒ BlockIO
BlockIO initializer
21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/virtfs/block_io.rb', line 21 def initialize(io_obj) @io_obj = io_obj @block_size = @io_obj.block_size # Size of block in bytes @size = @io_obj.size # Size of file in bytes @size_in_blocks = @size / @block_size # Size of file in blocks @start_byte_addr = 0 @end_byte_addr = @size - 1 @lba_end = @size_in_blocks - 1 @seek_pos = 0 @cache_range = Range.new(-1, -1) @offset = 0 end |
Instance Attribute Details
#offset ⇒ Object
Optional absolute block offset, always applied
15 16 17 |
# File 'lib/virtfs/block_io.rb', line 15 def offset @offset end |
Instance Method Details
#close ⇒ Object
Close block device, after this no additional read/writes can occur
103 104 105 |
# File 'lib/virtfs/block_io.rb', line 103 def close @io_obj.close end |
#read(len) ⇒ Array<Byte>?
Read len bytes from the block device and update seek_pos
39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/virtfs/block_io.rb', line 39 def read(len) return nil if @seek_pos >= @end_byte_addr len = @end_byte_addr - @seek_pos if (@seek_pos + len) > @end_byte_addr start_sector, start_offset = @seek_pos.divmod(@block_size) end_sector = (@seek_pos + len - 1) / @block_size num_sector = end_sector - start_sector + 1 rbuf = bread_cached(start_sector, num_sector) @seek_pos += len rbuf[start_offset, len] end |
#seek(amt, whence = IO::SEEK_SET) ⇒ Object
Advance seek pointer via the specified mechanism
85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/virtfs/block_io.rb', line 85 def seek(amt, whence = IO::SEEK_SET) case whence when IO::SEEK_CUR @seek_pos += amt when IO::SEEK_END @seek_pos = @end_byte_addr + amt when IO::SEEK_SET @seek_pos = amt + @start_byte_addr end @seek_pos end |
#size ⇒ Integer
Returns size of block device.
98 99 100 |
# File 'lib/virtfs/block_io.rb', line 98 def size @size end |
#write(buf, len) ⇒ Integer?
Write buffer of specified length to block device and update seek_pos
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/virtfs/block_io.rb', line 58 def write(buf, len) return nil if @seek_pos >= @end_byte_addr len = @end_byte_addr - @seek_pos if (@seek_pos + len) > @end_byte_addr start_sector, start_offset = @seek_pos.divmod(@block_size) end_sector = (@seek_pos + len - 1) / @block_size num_sector = end_sector - start_sector + 1 rbuf = bread(start_sector, num_sector) rbuf[start_offset, len] = buf[0, len] bwrite(start_sector, num_sector, rbuf) @seek_pos += len len end |