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