Class: RawBlockIO
- Inherits:
-
Object
- Object
- RawBlockIO
- Defined in:
- lib/disk/modules/RawBlockIO.rb
Constant Summary collapse
- MIN_SECTORS_TO_CACHE =
64
Instance Attribute Summary collapse
-
#size ⇒ Object
readonly
Returns the value of attribute size.
Instance Method Summary collapse
- #bread(startSector, numSectors) ⇒ Object
- #breadCached(startSector, numSectors) ⇒ Object
- #bwrite(startSector, numSectors, buf) ⇒ Object
- #close ⇒ Object
-
#initialize(filename, mode = "r") ⇒ RawBlockIO
constructor
A new instance of RawBlockIO.
- #read(len) ⇒ Object
- #seek(amt, whence = IO::SEEK_SET) ⇒ Object
- #write(buf, len) ⇒ Object
Constructor Details
#initialize(filename, mode = "r") ⇒ RawBlockIO
Returns a new instance of RawBlockIO.
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
# File 'lib/disk/modules/RawBlockIO.rb', line 7 def initialize(filename, mode = "r") # We must start with a block special file raise "RawBlockIO: #{filename} is not a blockSpecial file" unless File.stat(filename).ftype == 'blockSpecial' @rawDisk_file = File.open(filename, mode) # Enable directio (raw) if supported if defined? File::DIRECT require 'fcntl' @rawDisk_file.fcntl(Fcntl::F_SETFL, File::DIRECT) end @blockSize = 512 @filename = filename @mode = mode @size = LinuxBlockDevice.size(@rawDisk_file.fileno) @sizeInBlocks = @size / @blockSize @startByteAddr = 0 @endByteAddr = @size - 1 @lbaEnd = @sizeInBlocks - 1 @seekPos = 0 $log.debug "RawBlockIO: opened #{@filename}, size = #{@size} (#{@sizeInBlocks} blocks)" end |
Instance Attribute Details
#size ⇒ Object (readonly)
Returns the value of attribute size.
75 76 77 |
# File 'lib/disk/modules/RawBlockIO.rb', line 75 def size @size end |
Instance Method Details
#bread(startSector, numSectors) ⇒ Object
81 82 83 84 85 86 87 88 |
# File 'lib/disk/modules/RawBlockIO.rb', line 81 def bread(startSector, numSectors) # $log.debug "RawBlockIO.bread: startSector = #{startSector}, numSectors = #{numSectors}, @lbaEnd = #{@lbaEnd}" return nil if startSector > @lbaEnd numSectors = @sizeInBlocks - startSector if (startSector + numSectors) > @sizeInBlocks @rawDisk_file.sysseek(startSector * @blockSize, IO::SEEK_SET) @rawDisk_file.sysread(numSectors * @blockSize, @cache) end |
#breadCached(startSector, numSectors) ⇒ Object
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/disk/modules/RawBlockIO.rb', line 98 def breadCached(startSector, numSectors) # $log.debug "RawBlockIO.breadCached: startSector = #{startSector}, numSectors = #{numSectors}" if @cacheRange.nil? || !@cacheRange.include?(startSector) || !@cacheRange.include?(startSector + numSectors - 1) sectorsToRead = [MIN_SECTORS_TO_CACHE, numSectors].max @cache = MemoryBuffer.create_aligned(@blockSize, @blockSize * sectorsToRead) bread(startSector, sectorsToRead) sectorsRead = @cache.length / @blockSize endSector = startSector + sectorsRead - 1 @cacheRange = Range.new(startSector, endSector) end sectorOffset = startSector - @cacheRange.first bufferOffset = sectorOffset * @blockSize length = numSectors * @blockSize # $log.debug "RawBlockIO.breadCached: bufferOffset = #{bufferOffset}, length = #{length}" @cache[bufferOffset, length] end |
#bwrite(startSector, numSectors, buf) ⇒ Object
90 91 92 93 94 95 96 |
# File 'lib/disk/modules/RawBlockIO.rb', line 90 def bwrite(startSector, numSectors, buf) return nil if startSector > @lbaEnd numSectors = @sizeInBlocks - startSector if (startSector + numSectors) > @sizeInBlocks @rawDisk_file.sysseek(startSector * @blockSize, IO::SEEK_SET) @rawDisk_file.syswrite(buf, numSectors * @blockSize) end |
#close ⇒ Object
77 78 79 |
# File 'lib/disk/modules/RawBlockIO.rb', line 77 def close @rawDisk_file.close end |
#read(len) ⇒ Object
32 33 34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/disk/modules/RawBlockIO.rb', line 32 def read(len) return nil if @seekPos >= @endByteAddr len = @endByteAddr - @seekPos if (@seekPos + len) > @endByteAddr startSector, startOffset = @seekPos.divmod(@blockSize) endSector = (@seekPos + len - 1) / @blockSize numSector = endSector - startSector + 1 rBuf = breadCached(startSector, numSector) @seekPos += len rBuf[startOffset, len] end |
#seek(amt, whence = IO::SEEK_SET) ⇒ Object
63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/disk/modules/RawBlockIO.rb', line 63 def seek(amt, whence = IO::SEEK_SET) case whence when IO::SEEK_CUR @seekPos += amt when IO::SEEK_END @seekPos = @endByteAddr + amt when IO::SEEK_SET @seekPos = amt + @startByteAddr end @seekPos end |
#write(buf, len) ⇒ Object
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/disk/modules/RawBlockIO.rb', line 46 def write(buf, len) return nil if @seekPos >= @endByteAddr len = @endByteAddr - @seekPos if (@seekPos + len) > @endByteAddr startSector, startOffset = @seekPos.divmod(@blockSize) endSector = (@seekPos + len - 1) / @blockSize numSector = endSector - startSector + 1 rBuf = bread(startSector, numSector) rBuf[startOffset, len] = buf[0, len] bwrite(startSector, numSector, rBuf) @seekPos += len len end |