Class: Lvm2Thin::SuperBlock

Inherits:
Object
  • Object
show all
Defined in:
lib/VolumeManager/LVM/thin/superblock.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#metadata_volumeObject

Returns the value of attribute metadata_volume.



3
4
5
# File 'lib/VolumeManager/LVM/thin/superblock.rb', line 3

def 
  @metadata_volume
end

#structObject

Returns the value of attribute struct.



5
6
7
# File 'lib/VolumeManager/LVM/thin/superblock.rb', line 5

def struct
  @struct
end

Class Method Details

.get(metadata_volume) ⇒ Object



7
8
9
10
11
12
13
14
15
16
# File 'lib/VolumeManager/LVM/thin/superblock.rb', line 7

def self.get()
  @superblock ||= begin
    superblock = SuperBlock.new
    superblock. = 
    superblock.seek 0
    superblock.struct = superblock.read_struct SUPERBLOCK
    raise "unknown lvm2 thin metadata magic number" if superblock.struct.magic != THIN_MAGIC
    superblock
  end
end

Instance Method Details

#data_block_address(blk_addr) ⇒ Object



36
37
38
# File 'lib/VolumeManager/LVM/thin/superblock.rb', line 36

def data_block_address(blk_addr)
  blk_addr * data_block_size
end

#data_block_sizeObject



32
33
34
# File 'lib/VolumeManager/LVM/thin/superblock.rb', line 32

def data_block_size
  @data_block_size ||= struct['data_block_size'] * 512
end

#data_mappingObject



60
61
62
# File 'lib/VolumeManager/LVM/thin/superblock.rb', line 60

def data_mapping
  @data_mapping ||= MappingTree.new self, data_mapping_address
end

#data_mapping_addressObject



56
57
58
# File 'lib/VolumeManager/LVM/thin/superblock.rb', line 56

def data_mapping_address
  @data_mapping_address ||= md_block_address(struct['data_mapping_root'])
end

#data_space_mapObject

lvm thin structures:



42
43
44
45
46
47
# File 'lib/VolumeManager/LVM/thin/superblock.rb', line 42

def data_space_map
  @data_space_map ||= begin
    seek SUPERBLOCK.offset('data_space_map_root')
    DataSpaceMap.new self, read_struct(SPACE_MAP)
  end
end

#device_block(device_address) ⇒ Object

address resolution / mapping:



74
75
76
# File 'lib/VolumeManager/LVM/thin/superblock.rb', line 74

def device_block(device_address)
  (device_address / data_block_size).to_i
end

#device_block_offset(device_address) ⇒ Object



78
79
80
# File 'lib/VolumeManager/LVM/thin/superblock.rb', line 78

def device_block_offset(device_address)
  device_address % data_block_size
end

#device_detailsObject



68
69
70
# File 'lib/VolumeManager/LVM/thin/superblock.rb', line 68

def device_details
  @device_details ||= BTree.new self, device_details_address, DEVICE_DETAILS
end

#device_details_addressObject



64
65
66
# File 'lib/VolumeManager/LVM/thin/superblock.rb', line 64

def device_details_address
  @device_details_address ||= md_block_address(struct['device_details_root'])
end

#device_to_data(device_id, pos, len) ⇒ Object

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 Also:



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/VolumeManager/LVM/thin/superblock.rb', line 89

def device_to_data(device_id, pos, len)
  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|
    current_blk = dev_blk + i
    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.zero?
        blk_start += dev_off
        blk_len    = data_block_size - dev_off - 1

      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
      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
  end

  data_blks
end

#entries_per_blockObject



28
29
30
# File 'lib/VolumeManager/LVM/thin/superblock.rb', line 28

def entries_per_block
  @entries_per_block ||= (md_block_size - BITMAP_HEADER.size) * 4
end

#md_block_address(blk_addr) ⇒ Object



24
25
26
# File 'lib/VolumeManager/LVM/thin/superblock.rb', line 24

def md_block_address(blk_addr)
  blk_addr * md_block_size
end

#md_block_sizeObject

superblock properties:



20
21
22
# File 'lib/VolumeManager/LVM/thin/superblock.rb', line 20

def md_block_size
  @md_block_size ||= struct['metadata_block_size'] * 512 # = 4096
end

#metadata_space_mapObject



49
50
51
52
53
54
# File 'lib/VolumeManager/LVM/thin/superblock.rb', line 49

def 
  @metadata_space_map ||= begin
    seek SUPERBLOCK.offset('metadata_space_map_root')
    MetadataSpaceMap.new self, read_struct(SPACE_MAP)
  end
end

#read(n) ⇒ Object



139
140
141
# File 'lib/VolumeManager/LVM/thin/superblock.rb', line 139

def read(n)
  @metadata_volume.disk.read n
end

#read_struct(struct) ⇒ Object



143
144
145
# File 'lib/VolumeManager/LVM/thin/superblock.rb', line 143

def read_struct(struct)
  OpenStruct.new(struct.decode(@metadata_volume.disk.read(struct.size)))
end

#read_structs(struct, num) ⇒ Object



147
148
149
150
151
# File 'lib/VolumeManager/LVM/thin/superblock.rb', line 147

def read_structs(struct, num)
  Array.new(num) do
    read_struct struct
  end
end

#seek(pos) ⇒ Object

metadata volume disk helpers:



135
136
137
# File 'lib/VolumeManager/LVM/thin/superblock.rb', line 135

def seek(pos)
  @metadata_volume.disk.seek pos
end