Class: XFS::Superblock

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

Overview

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

Constant Summary collapse

BBSHIFT =

Block I/O parameterization. A basic block (BB) is the lowest size of filesystem allocation, and must equal 512. Length units given to bio routines are in BB’s.

9
BBSIZE =
1 << BBSHIFT
XFS_INODE_BIG_CLUSTER_SIZE =
8192
XFS_NBBY =

number of bits in a byte

8
XFS_INODES_PER_CHUNK =
XFS_NBBY * 8
XFS_DINODE_MIN_LOG =
8
XFS_DINODE_MIN_SIZE =
1 << XFS_DINODE_MIN_LOG
DEF_BLOCK_CACHE_SIZE =
500
DEF_CLUSTER_CACHE_SIZE =
500
DEF_INODE_CACHE_SIZE =
500
DEF_AG_CACHE_SIZE =
10
XFS_SUPERBLOCK_MAGIC =
0x58465342
XFS_SUPERBLOCK_VERSION_1 =

5.3, 6.0.1, 6.1 */

1
XFS_SUPERBLOCK_VERSION_2 =

6.2 - attributes */

2
XFS_SUPERBLOCK_VERSION_3 =

6.2 - new inode version */

3
XFS_SUPERBLOCK_VERSION_4 =

6.2+ - bitmask version */

4
XFS_SUPERBLOCK_VERSION_5 =

CRC enabled filesystem */

5
XFS_SUPERBLOCK_VERSION_NUMBITS =
0x000f
XFS_SUPERBLOCK_VERSION_ALLFBITS =
0xfff0
XFS_SUPERBLOCK_VERSION_SASHFBITS =
0xf000
XFS_SUPERBLOCK_VERSION_REALFBITS =
0x0ff0
XFS_SUPERBLOCK_VERSION_ATTRBIT =
0x0010
XFS_SUPERBLOCK_VERSION_NLINKBIT =
0x0020
XFS_SUPERBLOCK_VERSION_QUOTABIT =
0x0040
XFS_SUPERBLOCK_VERSION_ALIGNBIT =
0x0080
XFS_SUPERBLOCK_VERSION_DALIGNBIT =
0x0100
XFS_SUPERBLOCK_VERSION_SHAREDBIT =
0x0200
XFS_SUPERBLOCK_VERSION_LOGV2BIT =
0x0400
XFS_SUPERBLOCK_VERSION_SECTORBIT =
0x0800
XFS_SUPERBLOCK_VERSION_EXTFLGBIT =
0x1000
XFS_SUPERBLOCK_VERSION_DIRV2BIT =
0x2000
XFS_SUPERBLOCK_VERSION_BORGBIT =

ASCII only case-insens. */

0x4000
XFS_SUPERBLOCK_VERSION_MOREBITSBIT =
0x8000
XFS_SUPERBLOCK_VERSION_OKSASHFBITS =
XFS_SUPERBLOCK_VERSION_EXTFLGBIT | XFS_SUPERBLOCK_VERSION_DIRV2BIT | XFS_SUPERBLOCK_VERSION_BORGBIT
XFS_SUPERBLOCK_VERSION_OKREALFBITS =
XFS_SUPERBLOCK_VERSION_ATTRBIT | XFS_SUPERBLOCK_VERSION_NLINKBIT | XFS_SUPERBLOCK_VERSION_QUOTABIT | XFS_SUPERBLOCK_VERSION_ALIGNBIT | XFS_SUPERBLOCK_VERSION_DALIGNBIT | XFS_SUPERBLOCK_VERSION_SHAREDBIT | XFS_SUPERBLOCK_VERSION_LOGV2BIT | XFS_SUPERBLOCK_VERSION_SECTORBIT | XFS_SUPERBLOCK_VERSION_MOREBITSBIT
XFS_SUPERBLOCK_VERSION_OKREALBITS =
XFS_SUPERBLOCK_VERSION_NUMBITS | XFS_SUPERBLOCK_VERSION_OKREALFBITS |
XFS_SUPERBLOCK_VERSION_OKSASHFBITS
XFS_SUPERBLOCK_VERSION2_REALFBITS =

There are two words to hold XFS “feature” bits: the original word, version_number, and features2. Whenever a bit is set in features2, the feature bit XFS_SUPERBLOCK_VERSION_MOREBITSBIT must be set.

These defines represent bits in sb_features2.

0x00ffffff
XFS_SUPERBLOCK_VERSION2_RESERVED1BIT =

Mask: features */

0x00000001
XFS_SUPERBLOCK_VERSION2_LAZYSBCOUNTBIT =

Superblk counters */

0x00000002
XFS_SUPERBLOCK_VERSION2_RESERVED4BIT =
0x00000004
XFS_SUPERBLOCK_VERSION2_ATTR2BIT =

Inline attr rework */

0x00000008
XFS_SUPERBLOCK_VERSION2_PARENTBIT =

parent pointers */

0x00000010
XFS_SUPERBLOCK_VERSION2_PROJID32BIT =

32 bit project id */

0x00000080
XFS_SUPERBLOCK_VERSION2_CRCBIT =

metadata CRCs */

0x00000100
XFS_SUPERBLOCK_VERSION2_FTYPE =

inode type in dir */

0x00000200
XFS_SUPERBLOCK_VERSION2_OKREALFBITS =
XFS_SUPERBLOCK_VERSION2_LAZYSBCOUNTBIT |
XFS_SUPERBLOCK_VERSION2_ATTR2BIT | XFS_SUPERBLOCK_VERSION2_PROJID32BIT | XFS_SUPERBLOCK_VERSION2_FTYPE
XFS_SUPERBLOCK_VERSION2_OKSASHFBITS =
0
XFS_SUPERBLOCK_VERSION2_OKREALBITS =
XFS_SUPERBLOCK_VERSION2_OKREALFBITS | XFS_SUPERBLOCK_VERSION2_OKSASHFBITS
XFS_SB_FEAT_INCOMPAT_FTYPE =
1

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(stream, agno = 0) ⇒ Superblock

Returns a new instance of Superblock.



171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
# File 'lib/fs/xfs/superblock.rb', line 171

def initialize(stream, agno = 0)
  raise "XFS::Superblock.initialize: Nil stream" if stream.nil?
  @stream = stream

  #
  # Seek, read & decode the superblock structure
  # TODO: FIGURE OUT OFFSET OF SUPERBLOCK for the specified AG number.
  # TODO: @stream.seek(SUPERBLOCK_OFFSET)
  #
  @sb = SUPERBLOCK.decode(@stream.read(SUPERBLOCK_SIZE))
  validate_sb(agno)

  @block_size             = @sb['block_size']

  @block_cache            = LruHash.new(DEF_BLOCK_CACHE_SIZE)
  @cluster_cache          = LruHash.new(DEF_CLUSTER_CACHE_SIZE)
  @inode_cache            = LruHash.new(DEF_INODE_CACHE_SIZE)
  @allocation_group_cache = LruHash.new(DEF_AG_CACHE_SIZE)

  # expose for testing.
  @block_count            = @sb['data_blocks']
  @inode_count            = @sb['inode_count']
  @inode_size             = @sb['inode_size']
  @root_inode             = @sb['root_inode_num']

  # Inode file size members can't be trusted, so use sector count instead.
  # MiqDisk exposes block_size, which for our purposes is sector_size.
  @sector_size            = @stream.blockSize

  # Preprocess some members.
  @sb['fs_name'].delete!("\000")
  @allocation_group_count           = @sb['ag_count']
  @allocation_group_blocks          = @sb['ag_blocks']
  @groups_count, @last_group_blocks = @sb['data_blocks'].divmod(@allocation_group_blocks)
  @groups_count += 1 if @last_group_blocks > 0
  @filesystem_id                    = UUIDTools::UUID.parse_raw(@sb['uuid'])
  @volume_name                      = @sb['fs_name']
  @ialloc_inos                      = (@sb['inodes_per_blk']..XFS_INODES_PER_CHUNK).max
  @ialloc_blks                      = @ialloc_inos >> @sb['inodes_per_blk_log']
end

Instance Attribute Details

#agbnoObject (readonly)

Returns the value of attribute agbno.



155
156
157
# File 'lib/fs/xfs/superblock.rb', line 155

def agbno
  @agbno
end

#aginoObject (readonly)

Returns the value of attribute agino.



155
156
157
# File 'lib/fs/xfs/superblock.rb', line 155

def agino
  @agino
end

#agnoObject (readonly)

Returns the value of attribute agno.



155
156
157
# File 'lib/fs/xfs/superblock.rb', line 155

def agno
  @agno
end

#allocation_group_countObject (readonly)

Returns the value of attribute allocation_group_count.



155
156
157
# File 'lib/fs/xfs/superblock.rb', line 155

def allocation_group_count
  @allocation_group_count
end

#block_countObject (readonly)

///////////////////////////////////////////////////////////////////////// // initialize



153
154
155
# File 'lib/fs/xfs/superblock.rb', line 153

def block_count
  @block_count
end

#block_sizeObject (readonly)

Returns the value of attribute block_size.



154
155
156
# File 'lib/fs/xfs/superblock.rb', line 154

def block_size
  @block_size
end

#filesystem_idObject (readonly)

///////////////////////////////////////////////////////////////////////// // initialize



153
154
155
# File 'lib/fs/xfs/superblock.rb', line 153

def filesystem_id
  @filesystem_id
end

#groups_countObject (readonly)

///////////////////////////////////////////////////////////////////////// // initialize



153
154
155
# File 'lib/fs/xfs/superblock.rb', line 153

def groups_count
  @groups_count
end

#ialloc_blksObject (readonly)

Returns the value of attribute ialloc_blks.



155
156
157
# File 'lib/fs/xfs/superblock.rb', line 155

def ialloc_blks
  @ialloc_blks
end

#ialloc_inosObject (readonly)

Returns the value of attribute ialloc_inos.



155
156
157
# File 'lib/fs/xfs/superblock.rb', line 155

def ialloc_inos
  @ialloc_inos
end

#inode_countObject (readonly)

///////////////////////////////////////////////////////////////////////// // initialize



153
154
155
# File 'lib/fs/xfs/superblock.rb', line 153

def inode_count
  @inode_count
end

#inode_sizeObject (readonly)

Returns the value of attribute inode_size.



154
155
156
# File 'lib/fs/xfs/superblock.rb', line 154

def inode_size
  @inode_size
end

#root_inodeObject (readonly)

Returns the value of attribute root_inode.



154
155
156
# File 'lib/fs/xfs/superblock.rb', line 154

def root_inode
  @root_inode
end

#sbObject (readonly)

Returns the value of attribute sb.



154
155
156
# File 'lib/fs/xfs/superblock.rb', line 154

def sb
  @sb
end

#sector_sizeObject (readonly)

Returns the value of attribute sector_size.



154
155
156
# File 'lib/fs/xfs/superblock.rb', line 154

def sector_size
  @sector_size
end

#streamObject (readonly)

///////////////////////////////////////////////////////////////////////// // initialize



153
154
155
# File 'lib/fs/xfs/superblock.rb', line 153

def stream
  @stream
end

#volume_nameObject (readonly)

///////////////////////////////////////////////////////////////////////// // initialize



153
154
155
# File 'lib/fs/xfs/superblock.rb', line 153

def volume_name
  @volume_name
end

Instance Method Details

#ag_daddr(agno, d) ⇒ Object



336
337
338
# File 'lib/fs/xfs/superblock.rb', line 336

def ag_daddr(agno, d)
  agb_to_daddr(agno, 0) + d
end

#agb_to_daddr(agno, agbno) ⇒ Object



320
321
322
# File 'lib/fs/xfs/superblock.rb', line 320

def agb_to_daddr(agno, agbno)
  fsb_to_bb(agno * @allocation_group_blocks + agbno)
end

#agb_to_fsb(agno, agbno) ⇒ Object



312
313
314
# File 'lib/fs/xfs/superblock.rb', line 312

def agb_to_fsb(agno, agbno)
  agno << @sb['ag_blocks_log'] | agbno
end

#agbno_to_real_block(agno, agbno) ⇒ Object



316
317
318
# File 'lib/fs/xfs/superblock.rb', line 316

def agbno_to_real_block(agno, agbno)
  agno * @allocation_group_blocks + agbno
end

#agf_daddrObject



324
325
326
# File 'lib/fs/xfs/superblock.rb', line 324

def agf_daddr
  1 << (@sb['sector_size_log'] - BBSHIFT)
end

#agfl_daddrObject



332
333
334
# File 'lib/fs/xfs/superblock.rb', line 332

def agfl_daddr
  3 << (@sb['sector_size_log'] - BBSHIFT)
end

#agi_daddrObject



328
329
330
# File 'lib/fs/xfs/superblock.rb', line 328

def agi_daddr
  2 << (@sb['sector_size_log'] - BBSHIFT)
end

#agino_to_agbno(inode) ⇒ Object



348
349
350
# File 'lib/fs/xfs/superblock.rb', line 348

def agino_to_agbno(inode)
  inode >> ino_offset_bits
end

#agino_to_ino(agno, inode) ⇒ Object



344
345
346
# File 'lib/fs/xfs/superblock.rb', line 344

def agino_to_ino(agno, inode)
  agno << ino_agino_bits | inode
end

#agino_to_offset(inode) ⇒ Object



352
353
354
# File 'lib/fs/xfs/superblock.rb', line 352

def agino_to_offset(inode)
  inode & ino_mask(ino_offset_bits)
end

#b_to_bb(bytes) ⇒ Object

//////////////////////////////////////////////////////////////////////////// // Class helpers & accessors.



215
216
217
# File 'lib/fs/xfs/superblock.rb', line 215

def b_to_bb(bytes)
  (bytes + BBSIZE - 1) >> BBSHIFT
end

#b_to_bbt(bytes) ⇒ Object



219
220
221
# File 'lib/fs/xfs/superblock.rb', line 219

def b_to_bbt(bytes)
  bytes >> BBSHIFT
end

#b_to_fsbt(byte) ⇒ Object



292
293
294
# File 'lib/fs/xfs/superblock.rb', line 292

def b_to_fsbt(byte)
  byte >> @sb['block_size_log']
end

#bb_to_b(bbs) ⇒ Object



223
224
225
# File 'lib/fs/xfs/superblock.rb', line 223

def bb_to_b(bbs)
  bbs << BBSHIFT
end

#dumpObject

Dump object.



499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
# File 'lib/fs/xfs/superblock.rb', line 499

def dump
  out = "\#<#{self.class}:0x#{format('%08x', object_id)}>\n"
  out << "Magic number            : #{format('%0x', @sb['magic_num'])}\n"
  out << "Block size              : #{@sb['block_size']} (#{@block_size} bytes)\n"
  out << "Number of blocks        : #{@sb['data_blocks']}\n"
  out << "Real-time blocks        : #{@sb['realtime_blocks']}\n"
  out << "Real-time extents       : #{@sb['realtime_extents']}\n"
  out << "UUID                    : #{@filesystem_id}\n"
  out << "Journal Log Start block : #{@sb['log_start']}\n"
  out << "Root Inode #            : #{@sb['root_inode_num']}\n"
  out << "RealTime Bitmap Inode#  : #{@sb['bitmap_inode_num']}\n"
  out << "RealTime Summary Inode# : #{@sb['summary_inode_num']}\n"
  out << "RT Extent Size (Blocks) : #{@sb['realtime_ext_size']}\n"
  out << "Alloc Group Size        : #{@sb['ag_blocks']}\n"
  out << "# of Alloc Groups       : #{@sb['ag_count']}\n"
  out << "# of RT Bitmap Blocks   : #{@sb['bitmap_blocks']}\n"
  out << "# of Journal Log Blocks : #{@sb['log_blocks']}\n"
  out << "Filesystem Version #    : #{sb_version_num}\n"
  out << "Disk Sector Size        : #{@sb['sector_size']} bytes\n"
  out << "Inode Size              : #{@sb['inode_size']} bytes\n"
  out << "Inodes Per Block        : #{@sb['inodes_per_blk']}\n"
  out << "Filesystem Name         : #{@sb['fs_name']}\n"
  out << "Log Base2 of Block size : #{@sb['block_size_log']}\n"
  out << "Log Base2 of Sector size : #{@sb['sector_size_log']}\n"
  out << "Log Base2 of Inode size : #{@sb['inode_size_log']}\n"
  out << "Log Base2 of Inodes/Blk : #{@sb['inodes_per_blk_log']}\n"
  out << "Log Base2 AllocGrp size : #{@sb['ag_blocks_log']}\n"
  out << "Log Base2 RT Extent sz  : #{@sb['rt_ext_size_log']}\n"
  out << "In Progress Flag        : #{@sb['in_progress']}\n"
  out << "Inode Space Max Percent : #{@sb['inode_max_pct']}\n"
  out << "Inodes Allocated on FS  : #{@sb['inode_count']}\n"
  out << "Free Inodes on FS       : #{@sb['inode_free_count']}\n"
  out << "Free Data Blocks on FS  : #{@sb['free_data_blocks']}\n"
  out << "Free RT Extents on FS   : #{@sb['free_rt_extents']}\n"
  out << "Inode # for User Quotas : #{@sb['user_quota_ino']}\n"
  out << "Inode # for Grp Quotas  : #{@sb['group_quota_ino']}\n"
  out << "Quota Flags             : #{@sb['quota_flags']}\n"
  out << "Miscellaneous Flags     : #{@sb['misc_flags']}\n"
  out << "Shared Version #        : #{@sb['shared_vers_no']}\n"
  out << "Inode Chunk Alignment   : #{@sb['inode_alignment']}\n"
  out << "Stripe or Raid Unit     : #{@sb['stripe_unit']}\n"
  out << "Stripe or Raid Width    : #{@sb['stripe_width']}\n"
  out << "Log Base2 Dir Block     : #{@sb['dir_block_log']}\n"
  out << "Log Base2 Log Sect Size : #{@sb['log_sect_size_log']}\n"
  out << "External Log Sect Size  : #{@sb['log_sector_size']}\n"
  out << "Log Device Stripe Size  : #{@sb['log_stripe_unit_sz']}\n"
  out << "Additional Version Flgs : #{@sb['features_2']}\n"
  out << "Compat Features         : #{@sb['features_compat']}\n"
  out << "R/O Compat Features     : #{@sb['features_ro_compat']}\n"
  out << "Incompat Features       : #{@sb['features_incompat']}\n"
  out << "Log Incompat Features   : #{@sb['features_log_incompat']}\n"
  out << "Superblock CRC          : #{@sb['superblock_crc']}\n"
  out << "Inode # Project Quotas  : #{@sb['proj_quota_ino']}\n"
  out << "Last Write Sequence     : #{@sb['last_write_seq']}\n"
  out
end

#fragment_sizeObject



248
249
250
# File 'lib/fs/xfs/superblock.rb', line 248

def fragment_size
  1024 << @sb['fragment_size']
end

#free_bytesObject



256
257
258
# File 'lib/fs/xfs/superblock.rb', line 256

def free_bytes
  @sb['free_data_blocks'] * @block_size
end

#fsb_to_agbno(fsbno) ⇒ Object



280
281
282
# File 'lib/fs/xfs/superblock.rb', line 280

def fsb_to_agbno(fsbno)
  fsbno & mask32lo(@sb['ag_blocks_log'])
end

#fsb_to_agno(fsbno) ⇒ Object



276
277
278
# File 'lib/fs/xfs/superblock.rb', line 276

def fsb_to_agno(fsbno)
  fsbno >> @sb['ag_blocks_log']
end

#fsb_to_b(fsbno) ⇒ Object



268
269
270
# File 'lib/fs/xfs/superblock.rb', line 268

def fsb_to_b(fsbno)
  fsbno << @sb['block_size_log']
end

#fsb_to_bb(fsbno) ⇒ Object



272
273
274
# File 'lib/fs/xfs/superblock.rb', line 272

def fsb_to_bb(fsbno)
  fsbno << (@sb['block_size_log'] - BBSHIFT)
end

#fsb_to_daddr(fsbno) ⇒ Object



284
285
286
# File 'lib/fs/xfs/superblock.rb', line 284

def fsb_to_daddr(fsbno)
  agb_to_daddr(fsb_to_agno(fsbno), fsb_to_agbno(fsbno))
end

#fss_to_bb(sectno) ⇒ Object



288
289
290
# File 'lib/fs/xfs/superblock.rb', line 288

def fss_to_bb(sectno)
  sectno << (@sb['sector_size_log'] - BBSHIFT)
end

#get_ag(agno) ⇒ Object



432
433
434
435
436
437
438
439
# File 'lib/fs/xfs/superblock.rb', line 432

def get_ag(agno)
  unless @allocation_group_cache.key?(agno)
    blk_num  = ag_daddr(agno, agf_daddr)
    @stream.seek(fsb_to_b(blk_num))
    @allocation_group_cache[agno] = AllocationGroup.new(@stream, agno, @sb)
  end
  @allocation_group_cache[agno]
end

#get_agblock(agno) ⇒ Object



449
450
451
# File 'lib/fs/xfs/superblock.rb', line 449

def get_agblock(agno)
  get_ag(agno).agblock
end

#get_agf(agno) ⇒ Object



445
446
447
# File 'lib/fs/xfs/superblock.rb', line 445

def get_agf(agno)
  get_ag(agno).agf
end

#get_agi(agno) ⇒ Object



441
442
443
# File 'lib/fs/xfs/superblock.rb', line 441

def get_agi(agno)
  get_ag(agno).agi
end

#get_block(block) ⇒ Object



481
482
483
484
485
486
487
488
489
# File 'lib/fs/xfs/superblock.rb', line 481

def get_block(block)
  raise "XFS::Superblock.get_block: block is nil" if block.nil?
  @block_cache[block] = MemoryBuffer.create(@block_size) if block == 0
  unless @block_cache.key?(block)
    @stream.seek(fsb_to_b(block))
    @block_cache[block] = @stream.read(@block_size)
  end
  @block_cache[block]
end

#get_cluster(block) ⇒ Object



471
472
473
474
475
476
477
478
479
# File 'lib/fs/xfs/superblock.rb', line 471

def get_cluster(block)
  raise "XFS::Superblock.get_cluster: block is nil" if block.nil?
  @cluster_cache[block] = MemoryBuffer.create(@block_size * icluster_size_fsb) if block == 0
  unless @cluster_cache.key?(block)
    @stream.seek(fsb_to_b(block))
    @cluster_cache[block] = @stream.read(@block_size * icluster_size_fsb)
  end
  @cluster_cache[block]
end

#get_inode(inode) ⇒ Object



457
458
459
460
461
462
463
464
465
466
467
468
469
# File 'lib/fs/xfs/superblock.rb', line 457

def get_inode(inode)
  unless @inode_cache.key?(inode)
    inode_map = InodeMap.new(inode, self)
    if icluster_size_fsb == 1
      buf = get_block(inode_map.inode_blkno)
    else
      buf = get_cluster(inode_map.inode_blkno)
    end
    @inode_cache[inode] = Inode.new(buf, inode_map.inode_boffset, self, inode)
  end

  @inode_cache[inode]
end

#good_version?Boolean

Returns:

  • (Boolean)


397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
# File 'lib/fs/xfs/superblock.rb', line 397

def good_version?
  #
  # We always support version 1-3
  #
  if sb_version_num >= XFS_SUPERBLOCK_VERSION_1 &&
     sb_version_num <= XFS_SUPERBLOCK_VERSION_3
    return 1
  end
  #
  # We support version 4 if all feature bits are supported
  #
  if sb_version_num == XFS_SUPERBLOCK_VERSION_4
    return good_version_4?(@sb)
  end
  return 1 if sb_version_num == XFS_SUPERBLOCK_VERSION_5
end

#good_version_4?(sb) ⇒ Boolean

Returns:

  • (Boolean)


387
388
389
390
391
392
393
394
395
# File 'lib/fs/xfs/superblock.rb', line 387

def good_version_4?(sb)
  if (sb['version_number'] & ~XFS_SUPERBLOCK_VERSION_OKREALBITS) ||
     ((sb['version_number'] & XFS_SUPERBLOCK_VERSION_MOREBITSBIT) &&
     (sb['features_2'] & ~XFS_SUPERBLOCK_VERSION2_OKREALBITS))
    return 0
  end
  return 0 if sb['shared_vers_no'] > XFS_SB_MAX_SHARED_VN
  1
end

#got_bit?(field, bit) ⇒ Boolean

//////////////////////////////////////////////////////////////////////////// // Utility functions.

Returns:

  • (Boolean)


494
495
496
# File 'lib/fs/xfs/superblock.rb', line 494

def got_bit?(field, bit)
  field & bit == bit
end

#icluster_size_fsbObject



426
427
428
429
430
# File 'lib/fs/xfs/superblock.rb', line 426

def icluster_size_fsb
  cluster_size = inode_cluster_size
  return 1 if @block_size > cluster_size
  cluster_size >> @sb['block_size_log']
end

#incompatible_feature?(feature) ⇒ Boolean

Returns:

  • (Boolean)


231
232
233
# File 'lib/fs/xfs/superblock.rb', line 231

def incompatible_feature?(feature)
  (@sb['features_incompat'] & feature) != 0
end

#ino_agbno_bitsObject



360
361
362
# File 'lib/fs/xfs/superblock.rb', line 360

def ino_agbno_bits
  @sb['ag_blocks_log']
end

#ino_agino_bitsObject



364
365
366
# File 'lib/fs/xfs/superblock.rb', line 364

def ino_agino_bits
  @sb['inodes_per_blk_log'] + @sb['ag_blocks_log']
end

#ino_mask(k) ⇒ Object



260
261
262
# File 'lib/fs/xfs/superblock.rb', line 260

def ino_mask(k)
  ((1 << k) - 1) & 0xffffffff
end

#ino_offset_bitsObject



356
357
358
# File 'lib/fs/xfs/superblock.rb', line 356

def ino_offset_bits
  @sb['inodes_per_blk_log']
end

#ino_to_agbno(inode) ⇒ Object



304
305
306
# File 'lib/fs/xfs/superblock.rb', line 304

def ino_to_agbno(inode)
  inode >> ino_offset_bits & ino_mask(ino_agbno_bits)
end

#ino_to_agino(inode) ⇒ Object



300
301
302
# File 'lib/fs/xfs/superblock.rb', line 300

def ino_to_agino(inode)
  inode & ino_mask(ino_agino_bits)
end

#ino_to_agno(inode) ⇒ Object



296
297
298
# File 'lib/fs/xfs/superblock.rb', line 296

def ino_to_agno(inode)
  inode >> ino_agino_bits
end

#ino_to_fsb(inode) ⇒ Object



340
341
342
# File 'lib/fs/xfs/superblock.rb', line 340

def ino_to_fsb(inode)
  agb_to_fsb(ino_to_agno(inode), ino_to_agbno(inode))
end

#ino_to_offset(inode) ⇒ Object



308
309
310
# File 'lib/fs/xfs/superblock.rb', line 308

def ino_to_offset(inode)
  inode & ino_mask(ino_offset_bits)
end

#inode_align_maskObject



378
379
380
381
382
383
384
385
# File 'lib/fs/xfs/superblock.rb', line 378

def inode_align_mask
  if version_has_align? &&
     @sb['inode_alignment'] >> b_to_fsbt(XFS_INODE_BIG_CLUSTER_SIZE)
    return @sb['inode_alignment']
  else
    return 0
  end
end

#inode_btree_recordObject



453
454
455
# File 'lib/fs/xfs/superblock.rb', line 453

def inode_btree_record
  InodeBtreeRecord.new(cursor)
end

#inode_cluster_sizeObject



414
415
416
417
418
419
420
421
422
423
424
# File 'lib/fs/xfs/superblock.rb', line 414

def inode_cluster_size
  cluster_size = XFS_INODE_BIG_CLUSTER_SIZE
  if version_has_crc?
    new_size = cluster_size
    new_size *= inode_size / XFS_DINODE_MIN_SIZE
    if @sb['inode_alignment'] >= b_to_fsbt(new_size)
      cluster_size = new_size
    end
  end
  cluster_size
end

#mask32lo(n) ⇒ Object



264
265
266
# File 'lib/fs/xfs/superblock.rb', line 264

def mask32lo(n)
  (((1 << n) & 0xffffffff) - 1) & 0xffffffff
end

#offbno_to_agino(block, offset) ⇒ Object



368
369
370
# File 'lib/fs/xfs/superblock.rb', line 368

def offbno_to_agino(block, offset)
  (block << @sb['inodes_per_blk_log']) | offset
end

#sb_version_numObject



227
228
229
# File 'lib/fs/xfs/superblock.rb', line 227

def sb_version_num
  @sb['version_number'] & XFS_SUPERBLOCK_VERSION_NUMBITS
end

#validate_sb(agno) ⇒ Object



157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'lib/fs/xfs/superblock.rb', line 157

def validate_sb(agno)
  # Grab some quick facts & make sure there's nothing wrong. Tight qualification.
  if @sb['magic_num'] != XFS_SUPERBLOCK_MAGIC
    raise "XFS::Superblock.initialize: Invalid magic number=[#{@sb['magic_num']}] in AG #{agno}"
  end
  unless good_version?
    $log.warn "XFS::Superblock.initialize: Bad Superblock version # #{@sb['version_number']} in AG #{agno}"
    $log.warn "Attempting to access filesystem"
  end
  if agno == 0 && @sb['in_progress'] != 0
    $log.warn "XFS::Superblock.initialize: mkfs not completed successfully. Attempting to access filesystem"
  end
end

#version_has_align?Boolean

Returns:

  • (Boolean)


372
373
374
375
376
# File 'lib/fs/xfs/superblock.rb', line 372

def version_has_align?
  (sb_version_num == XFS_SUPERBLOCK_VERSION_5) ||
    ((sb_version_num >= XFS_SUPERBLOCK_VERSION_4) &&
    ((@sb['version_number'] & XFS_SUPERBLOCK_VERSION_ALIGNBIT) != 0))
end

#version_has_crc?Boolean

Returns:

  • (Boolean)


244
245
246
# File 'lib/fs/xfs/superblock.rb', line 244

def version_has_crc?
  sb_version_num == XFS_SUPERBLOCK_VERSION_5
end

#version_has_ftype?Boolean

Returns:

  • (Boolean)


239
240
241
242
# File 'lib/fs/xfs/superblock.rb', line 239

def version_has_ftype?
  (version_has_crc? && incompatible_feature?(XFS_SB_FEAT_INCOMPAT_FTYPE)) ||
    (version_has_more_bits? && ((@sb['features_2'] & XFS_SUPERBLOCK_VERSION2_FTYPE) != 0))
end

#version_has_more_bits?Boolean

Returns:

  • (Boolean)


235
236
237
# File 'lib/fs/xfs/superblock.rb', line 235

def version_has_more_bits?
  version_has_crc? || (@sb['version_number'] & XFS_SUPERBLOCK_VERSION_MOREBITSBIT != 0)
end