Class: XFS::InodeMap

Inherits:
Object
  • Object
show all
Defined in:
lib/fs/xfs/inode_map.rb

Overview

//////////////////////////////////////////////////////////////////////////// // Class.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(inode, sb) ⇒ InodeMap

Returns a new instance of InodeMap.



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/fs/xfs/inode_map.rb', line 28

def initialize(inode, sb)
  #
  # Split up the inode number into its parts
  #
  @inode_number   = inode
  @agno           = sb.ino_to_agno(inode)
  @agino          = sb.ino_to_agino(inode)
  @agbno          = sb.agino_to_agbno(@agino)

  valid_inode_number?(inode, sb) || return
  #
  # If the inode cluster size is the same as the blocksize or
  # smaller we get to the block by simple arithmetic
  #
  blocks_per_cluster = sb.icluster_size_fsb
  @inode_length = sb.fsb_to_bb(blocks_per_cluster)
  if blocks_per_cluster == 1
    offset = sb.ino_to_offset(inode)
    @inode_blkno  = sb.agbno_to_real_block(@agno, @agbno)
    @inode_boffset = offset << sb['inode_size_log']
    return
  elsif sb.inode_align_mask
    #
    # If the inode chunks are aligned then use simple math to
    # find the location.  Otherwise we have to do a btree
    # lookup to find the location.
    #
    offset_agbno = @agbno & (sb.inode_align_mask - 1)
    chunk_agbno  = @agbno - offset_agbno
  else
    start_ino    = imap_lookup(@agno, @agino)
    chunk_agbno  = sb.agino_to_agbno(start_ino)
    offset_agbno = @agbno - chunk_agbno
  end

  @cluster_agbno = chunk_agbno + (offset_agbno / blocks_per_cluster) * blocks_per_cluster
  offset = (@agbno - @cluster_agbno) * sb.sb['inodes_per_blk'] + sb.ino_to_offset(inode)
  @inode_blkno  = sb.agbno_to_real_block(@agno, @cluster_agbno)
  @inode_boffset = offset << sb.sb['inode_size_log']
  valid_inode_size?(sb) || return
end

Instance Attribute Details

#inode_blknoObject (readonly)

Returns the value of attribute inode_blkno.



8
9
10
# File 'lib/fs/xfs/inode_map.rb', line 8

def inode_blkno
  @inode_blkno
end

#inode_boffsetObject (readonly)

Returns the value of attribute inode_boffset.



8
9
10
# File 'lib/fs/xfs/inode_map.rb', line 8

def inode_boffset
  @inode_boffset
end

#inode_lengthObject (readonly)

Returns the value of attribute inode_length.



8
9
10
# File 'lib/fs/xfs/inode_map.rb', line 8

def inode_length
  @inode_length
end

Instance Method Details

#dumpObject

imap_lookup



87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/fs/xfs/inode_map.rb', line 87

def dump
  out = "\#<#{self.class}:0x#{format('%08x', object_id)}>\n"
  out += "Inode Number : #{@inode_number}\n"
  out += "Alloc Grp Num: #{@agno}\n"
  out += "AG Ino       : #{@agino}\n"
  out += "AG Block Num : #{@agbno}\n"
  out += "Inode Length : #{@inode_length}\n"
  out += "Inode Blkno  : #{@inode_blkno}\n"
  out += "InoBlk Offset: #{@inode_boffset}\n"
  out += "Cluster AGBNO: #{@cluster_agbno}\n"
  out
end

#imap_lookup(agno, agino) ⇒ Object

initialize



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/fs/xfs/inode_map.rb', line 70

def imap_lookup(agno, agino)
  ag = get_ag(agno)
  cursor = InodeBtreeCursor.new(@sb, ag.agi, agno, XFS_BTNUM_INO)
  cursor.block_ptr = ag.agblock
  error = inobt_lookup(cursor, agino, XFS_LOOKUP_LE)
  raise "XFS::Superblock.imap_lookup: #{error}" if error
  inode_rec = inode_btree_record(cursor)
  if inode_rec.nil?
    raise "XFS::Superblock.imap_lookup: Error #{cursor.error} getting InodeBtreeRecord for inode #{agino}"
  end
  if inode_rec.start_ino > agino ||
     inode_rec.start_ino + @ialloc_inos <= agino
    raise "XFS::Superblock.imap_lookup: InodeBtreeRecord does not contain required inode #{agino}"
  end
  inode_rec.start_ino
end

#valid_inode_number?(inode, sb) ⇒ Boolean

Returns:

  • (Boolean)


18
19
20
21
22
23
24
25
26
# File 'lib/fs/xfs/inode_map.rb', line 18

def valid_inode_number?(inode, sb)
  if (@agno >= sb.sb['ag_count']) ||
     (@agbno >= sb.sb['ag_blocks']) ||
     sb.agino_to_ino(@agno, @agino) != inode
    $log.error "XFS::InodeMap - Bad Inode number #{inode} for agno #{@agno} agcount #{sb.sb['ag_count']}, agbno #{@agbno}, agblocks #{sb.sb['ag_blocks']}, agino #{@agino}, agino_to_ino #{sb.agino_to_ino(@agno, @agino)}" if $log
    raise "XFS::InodeMap - Bad Inode number #{inode}"
  end
  true
end

#valid_inode_size?(sb) ⇒ Boolean

Returns:

  • (Boolean)


10
11
12
13
14
15
16
# File 'lib/fs/xfs/inode_map.rb', line 10

def valid_inode_size?(sb)
  if (@inode_blkno + @inode_length) > sb.fsb_to_bb(sb.block_count)
    $log.error "XFS::InodeMap - Inode #{@inode_blkno} too large for filesystem" if $log
    raise "XFS::InodeMap - Inode #{@inode_blkno} too large for filesystem"
  end
  true
end