lib/VolumeManager/LVM/thin/superblock.rb in manageiq-smartstate-0.1.4 vs lib/VolumeManager/LVM/thin/superblock.rb in manageiq-smartstate-0.1.5
- old
+ new
@@ -77,38 +77,55 @@
def device_block_offset(device_address)
device_address % data_block_size
end
- # return array of tuples containing data volume addresses and lengths to
- # read from them to read the specified device offset & length
+ # Return array of tuples device block ids, data block ids, addresses, and lengths to
+ # read from them to read the specified device offset & length.
+ #
+ # Note: data blocks may not amount to total requested length (if requesting
+ # data from unallocated space).
+ #
+ # @see DataMap#block?
def device_to_data(device_id, pos, len)
- dev_blk = device_block(pos)
- dev_off = device_block_offset(pos)
+ dev_blk = device_block(pos)
+ dev_off = device_block_offset(pos)
+ data_map = data_mapping.map_for(device_id)
total_len = 0
data_blks = []
num_data_blks = (len / data_block_size).to_i + 1
0.upto(num_data_blks - 1) do |i|
- data_blk = data_mapping.map_for(device_id).data_block(dev_blk + i)
+ current_blk = dev_blk + i
+ blk_len = 0
- blk_start = data_blk * data_block_size
- blk_len = 0
+ if data_map.block?(current_blk)
+ data_blk = data_map.data_block(current_blk)
+ blk_start = data_blk * data_block_size
- if i == 0
- blk_start += dev_off
- blk_len = data_block_size - dev_off - 1
+ if i.zero?
+ blk_start += dev_off
+ blk_len = data_block_size - dev_off - 1
- elsif i == num_data_blks - 1
- blk_len = len - total_len
+ elsif i == num_data_blks - 1
+ blk_len = len - total_len
+ else
+ blk_len = data_block_size
+ end
+
+ data_blks << [current_blk, data_blk, blk_start, blk_len]
+
+ # Missing block may be caused by trying to read beyond end of
+ # LVM device (too large pos or len):
else
- blk_len = data_block_size
+ remaining = (len - total_len)
+ blk_len = remaining > data_block_size ? data_block_size : remaining
+ data_blks << [current_blk, nil, nil, blk_len]
end
total_len += blk_len
- data_blks << [blk_start, blk_len]
end
data_blks
end