Module: XFS
- Included in:
- FileObject
- Defined in:
- lib/fs/MiqFS/modules/XFS.rb,
lib/fs/xfs/inode.rb,
lib/fs/xfs/directory.rb,
lib/fs/xfs/inode_map.rb,
lib/fs/xfs/superblock.rb,
lib/fs/xfs/directory_entry.rb,
lib/fs/xfs/allocation_group.rb,
lib/fs/xfs/bmap_btree_block.rb,
lib/fs/xfs/bmap_btree_record.rb,
lib/fs/xfs/short_form_header.rb,
lib/fs/xfs/bmap_btree_root_node.rb,
lib/fs/xfs/directory_block_tail.rb,
lib/fs/xfs/directory_data_header.rb,
lib/fs/xfs/directory2_data_header.rb,
lib/fs/xfs/directory3_data_header.rb,
lib/fs/xfs/short_form_directory_entry.rb
Overview
XFS file system interface to MiqFS.
Defined Under Namespace
Classes: AllocationGroup, BmapBTreeBlock, BmapBTreeRecord, BmapBTreeRootNode, Directory, Directory2DataHeader, Directory3DataHeader, DirectoryBlockTail, DirectoryDataHeader, DirectoryEntry, FileObject, Inode, InodeMap, ShortFormDirectoryEntry, ShortFormHeader, Superblock
Constant Summary collapse
- TIMESTAMP =
BinaryStruct.new([ 'I', 'seconds', # timestamp seconds 'I', 'nanoseconds', # timestamp nanoseconds ])
- INODE =
BinaryStruct.new([ 'S>', 'magic', # Inode Magic Number 'S>', 'file_mode', # Mode and Type of file 'C', 'version', # Inode Version 'C', 'format', # Format of Data Fork Data 'S>', 'old_num_links', # Old Number of Links to File 'I>', 'uid', # Owner's User Id 'I>', 'gid', # Owner's Group Id 'I>', 'num_links', # Number of Links to File 'S>', 'projid_low', # Lower Part of Owner's Project Id 'S>', 'projid_high', # Higher Part of Owner's Project Id 'a6', 'pad', # Unused, Zeroed Space 'S>', 'flush_iterator', # Incremented on Flush 'I>', 'atime_secs', # time last accessed seconds 'I>', 'atime_nsecs', # time last accessed nanoseconds 'I>', 'mtime_secs', # time last modified seconds 'I>', 'mtime_nsecs', # time last modified nanoseconds 'I>', 'ctime_secs', # time created / inode modified seconds 'I>', 'ctime_nsecs', # time created / inode modified nanoseconds 'Q>', 'size', # number of bytes in file 'Q>', 'nblocks', # Number of direct & btree blocks used 'I>', 'extent_size', # Basic/Minimum extent size for file 'I>', 'num_extents', # Number of extents in data fork 'S>', 'attr_num_extents', # Number of extents in attribute fork 'C', 'attr_fork_offset', # Attribute Fork Offset, <<3 for 64b align 'c', 'attr_fork_format', # Format of Attribute Fork's Data 'I>', 'dmig_event_mask', # DMIG event mask 'S>', 'dmig_state_info', # DMIG state info 'S>', 'flags', # random flags, XFS_DIFLAG_... 'I>', 'gen_num', # generation number 'I>', 'next_unlinked', # agi unlinked list ptr ])
- EXTENDED_INODE =
BinaryStruct.new([ 'S>', 'magic', # Inode Magic Number 'S>', 'file_mode', # Mode and Type of file 'C', 'version', # Inode Version 'C', 'format', # Format of Data Fork Data 'S>', 'old_num_links', # Old Number of Links to File 'I>', 'uid', # Owner's User Id 'I>', 'gid', # Owner's Group Id 'I>', 'num_links', # Number of Links to File 'S>', 'projid_low', # Lower Part of Owner's Project Id 'S>', 'projid_high', # Higher Part of Owner's Project Id 'a6', 'pad', # Unused, Zeroed Space 'S>', 'flush_iterator', # Incremented on Flush 'I>', 'atime_secs', # time last accessed seconds 'I>', 'atime_nsecs', # time last accessed nanoseconds 'I>', 'mtime_secs', # time last modified seconds 'I>', 'mtime_nsecs', # time last modified nanoseconds 'I>', 'ctime_secs', # time created / inode modified seconds 'I>', 'ctime_nsecs', # time created / inode modified nanoseconds 'Q>', 'size', # number of bytes in file 'Q>', 'nblocks', # Number of direct & btree blocks used 'I>', 'extent_size', # Basic/Minimum extent size for file 'I>', 'num_extents', # Number of extents in data fork 'S>', 'attr_num_extents', # Number of extents in attribute fork 'C', 'attr_fork_offset', # Attribute Fork Offset, <<3 for 64b align 'c', 'attr_fork_format', # Format of Attribute Fork's Data 'I>', 'dmig_event_mask', # DMIG event mask 'S>', 'dmig_state_info', # DMIG state info 'S>', 'flags', # random flags, XFS_DIFLAG_... 'I>', 'gen_num', # generation number 'I>', 'next_unlinked', # agi unlinked list ptr 'I>', 'crc', # CRC of the inode 'Q>', 'change_count', # number of attribute changes 'Q>', 'lsn', # flush sequence 'Q>', 'flags2', # more random flags 'a16', 'pad2', # more padding for future expansion 'I>', 'crtime_secs', # time created seconds 'I>', 'crtime_nsecs', # time created nanoseconds 'Q>', 'inode_number', # inode number 'a16', 'uuid', # UUID of the filesystem ])
- SIZEOF_INODE =
INODE.size
- SIZEOF_EXTENDED_INODE =
EXTENDED_INODE.size
- DIRECTORY_LEAF_ENTRY =
BinaryStruct.new([ 'I>', 'hashval', # hash value of name 'I>', 'address', # address of data entry ])
- SIZEOF_DIRECTORY_LEAF_ENTRY =
DIRECTORY_LEAF_ENTRY.size
- SUPERBLOCK =
//////////////////////////////////////////////////////////////////////////// // Data definitions. Linux 2.6.2 from Fedora Core 6.
BinaryStruct.new([ 'L>', 'magic_num', # magic number of the filesystem 'L>', 'block_size', # size of a basic unit of space allocation in bytes 'Q>', 'data_blocks', # total Number of blocks available for data and metadata 'Q>', 'realtime_blocks', # number of blocks on the real-time disk device 'Q>', 'realtime_extents', # Number of extents on the real-time disk device 'a16', 'uuid', # UUID for the filesystem 'Q>', 'log_start', # first block for the journal log if internal (0 if external) 'Q>', 'root_inode_num', # root inode number for the filesystem 'Q>', 'bitmap_inode_num', # bitmap inode number for real-time extents 'Q>', 'summary_inode_num', # summary inode number for real-time bitmap 'L>', 'realtime_ext_size', # real-time extent size in blocks 'L>', 'ag_blocks', # size of each allocation group in blocks 'L>', 'ag_count', # number of allocation groups in the filesystem 'L>', 'bitmap_blocks', # number of real-time bitmap blocks 'L>', 'log_blocks', # number of blocks for the journaling log 'S>', 'version_number', # Filesystem version number 'S>', 'sector_size', # underlying disk sector size in bytes 'S>', 'inode_size', # size of the inode in bytes 'S>', 'inodes_per_blk', # number of inodes per block 'a12', 'fs_name', # name for the filesystem 'C', 'block_size_log', # log base 2 of block_size 'C', 'sector_size_log', # log base 2 of sector_size 'C', 'inode_size_log', # log base 2 of inode_size 'C', 'inodes_per_blk_log', # log base 2 of inodes_per_blk 'C', 'ag_blocks_log', # log base 2 of ag_blocks (rounded up) 'C', 'rt_ext_size_log', # log base 2 of realtime_ext_size 'C', 'in_progress', # flag specifying that the filesystem is being created 'C', 'inode_max_pct', # maximum percentage of filesystem space that can be used for inodes 'Q>', 'inode_count', # global count for number of inodes allocated on the filesystem 'Q>', 'inode_free_count', # global count of free inodes on the filesystem. 'Q>', 'free_data_blocks', # global count of free data blocks on the filesystem 'Q>', 'free_rt_extents', # global count of free real-time extents on the filesystem 'Q>', 'user_quota_ino', # inode number for user quotas 'Q>', 'group_quota_ino', # inode number for group quotas 'S>', 'quota_flags', # quota flags 'C', 'misc_flags', # miscellaneous flags 'C', 'shared_vers_no', # shared version number 'L>', 'inode_alignment', # inode chunk alignment in blocks 'L>', 'stripe_unit', # underlying stripe or raid unit in blocks 'L>', 'stripe_width', # underlying stripe or raid width in blocks 'C', 'dir_block_log', # log base 2 multiplier that determines the # granularity of directory block allocations in fsblocks 'C', 'log_sect_size_log', # log base 2 of the log subvolume's sector size 'S>', 'log_sector_size', # the log's sector size in bytes if the filesystem uses an external log device 'L>', 'log_stripe_unit_sz', # the log device's stripe or raid unit size. 'L>', 'features_2', # add'l version flags if XFS_SUPERBLOCK_VERSION_MOREBITSBIT is set in version_number # version 5 superblock fields start here 'L>', 'features_compat', 'L>', 'features_ro_compat', 'L>', 'features_incompat', 'L>', 'features_log_incompat', 'L>', 'superblock_crc', # superblock crc 'L>', 'padding', 'Q>', 'proj_quota_ino', # inode number for project quotas 'q>', 'last_write_seq', # last write sequence ])
- SUPERBLOCK_SIZE =
512- DEF_CACHE_SIZE =
Default directory cache size.
500- DIRECTORY2_DATA_ENTRY =
//////////////////////////////////////////////////////////////////////////// // Data definitions.
Active entry in a data block. Aligned to 8 bytes. A variable length name field follows the length. After the name there is a 2 byte tag field. For dir3 structures, there is a 1 byte file type field between the name and the tag. It is packed hard against the end of the name so any padding for rounding is between the file type and the tag.
BinaryStruct.new([ 'Q>', 'inumber', # inode number 'C', 'name_len', # name length ])
- SIZEOF_DIRECTORY2_DATA_ENTRY =
DIRECTORY2_DATA_ENTRY.size
- DIRECTORY2_DATA_TAG =
BinaryStruct.new([ 'S>', 'tag', # tag ])
- SIZEOF_DIRECTORY2_DATA_TAG =
DIRECTORY2_DATA_TAG.size
- DIRECTORY2_UNUSED_ENTRY =
BinaryStruct.new([ 'S>', 'freetag', # 0xFFFF if unused 'S>', 'length', # length of this free entry ])
- SIZEOF_DIRECTORY2_UNUSED_ENTRY =
DIRECTORY2_UNUSED_ENTRY.size
- AG_FREESPACE =
////////////////////////////////////////////////////////////////////////////
BinaryStruct.new([ # Common allocation group header information 'I>', 'magic_num', # magic number of the filesystem 'I>', 'version_num', # header version 'I>', 'seq_no', # sequence # starting from 0 'I>', 'length', # size in blocks of a.g. # Freespace Information # 'I>2', 'root_blocks', # Root Blocks 'I>', 'spare0', # spare field 'I>2', 'btree_levels', # btree levels 'I>', 'spare1', # spare field 'I>', 'fl_first', # first freelist block's index 'I>', 'fl_last', # last freelist block's index 'I>', 'fl_count', # count of blocks in freelist 'I>', 'free_blocks', # total free blocks 'L>', 'longest', # longest free space 'L>', 'btree_blocks', # # of blocks held in alloc group free btrees 'a16', 'uuid', # Filesystem uuid # # Reserve some contiguous space for future logged fields before we add # the unlogged fields. This makes the range logging via flags and # structure offsets much simpler. # 'Q>16', 'spare64', # underlying disk sector size in bytes # # Unlogged fields, written during buffer writeback. # 'Q>', 'last_write_seq', # last write sequence 'I>', 'crc', # CRC of alloc group free space sector 'I>', 'spare2', # name for the filesystem ])
- AG_INODEINFO =
BinaryStruct.new([ # Common allocation group header information 'I>', 'magic_num', # magic number of the filesystem 'I>', 'version_num', # header version 'I>', 'seq_no', # sequence # starting from 0 'I>', 'length', # size in blocks of a.g. # # Inode information # Inodes are mapped by interpretting the inode number, so no # mapping data is needed here. # 'I>', 'count', # count of allocated inodes 'I>', 'root', # root of inode btree 'I>', 'level', # levels in inode btree 'I>', 'free_count', # number of free inodes 'I>', 'new_inode', # new inode just allocated 'I>', 'dir_inode', # last directory inode chunk # # Hash table of inodes which have been unlinked but are # still being referenced. # 'I>64', 'unlinked_hash', # the hash 'a16', 'uuid', # Filesystem uuid 'I>', 'crc', # CRC of alloc group inode info sector 'I>', 'pad32', # 'Q>', 'last_write_seq', # last write sequence 'I>', 'free_root', # root of the free inode btree 'I>', 'free_level', # levels in free inode btree ])
- AG_FREELIST =
The third AG block contains the AG FreeList, an array of block pointers to blocks owned by the allocation btree code.
BinaryStruct.new([ 'I>', 'magic_num', # magic number of the filesystem 'I>', 'seq_no', # sequence # starting from 0 'a16', 'uuid', # Filesystem uuid 'Q>', 'last_write_seq', # last write sequence 'I>', 'crc', # CRC of alloc group inode info sector 'I>', 'bno', # actually XFS_AGFL_SIZE ])
- AG_FL_STRUCT_SIZE =
AG_FREELIST.size
- BTREE_BLOCK_SHORT_NOCRC =
////////////////////////////////////////////////////////////////////////////
BinaryStruct.new([ # Common BTree Block header information 'I>', 'magic_num', # magic number of the btree block type 'S>', 'level', # level number. 0 is a leaf 'S>', 'num_recs', # current # of data records # # Short Section # 'I>', 'left_sibling', # 'I>', 'right_sibling', # ])
- SIZEOF_BTREE_BLOCK_SHORT_NOCRC =
BTREE_BLOCK_SHORT_NOCRC.size
- BTREE_BLOCK_SHORT =
BinaryStruct.new([ # Common BTree Block header information 'I>', 'magic_num', # magic number of the btree block type 'S>', 'level', # level number. 0 is a leaf 'S>', 'num_recs', # current # of data records # # Short Section # 'I>', 'left_sibling', # 'I>', 'right_sibling', # 'Q>', 'block_num', # 'Q>', 'lsn', # 'a16', 'uuid', # 'I>', 'owner', # 'I>', 'crc', # ])
- SIZEOF_BTREE_BLOCK_SHORT =
BTREE_BLOCK_SHORT.size
- BTREE_BLOCK_LONG_NOCRC =
BinaryStruct.new([ # Common BTree Block header information 'I>', 'magic_num', # magic number of the btree block type 'S>', 'level', # level number. 0 is a leaf 'S>', 'num_recs', # current # of data records # # Long Section # 'Q>', 'left_sibling', # 'Q>', 'right_sibling', # ])
- SIZEOF_BTREE_BLOCK_LONG_NOCRC =
BTREE_BLOCK_LONG_NOCRC.size
- BTREE_BLOCK_LONG =
BinaryStruct.new([ # Common BTree Block header information 'I>', 'magic_num', # magic number of the btree block type 'S>', 'level', # level number. 0 is a leaf 'S>', 'num_recs', # current # of data records # # Long Section # 'Q>', 'left_sibling', # 'Q>', 'right_sibling', # 'Q>', 'block_num', # 'Q>', 'lsn', # 'a16', 'uuid', # 'Q>', 'owner', # 'I>', 'crc', # 'I>', 'pad', # ])
- SIZEOF_BTREE_BLOCK_LONG =
BTREE_BLOCK_LONG.size
- BMAP_BTREE_REC =
BinaryStruct.new([ 'Q>', 'l0', 'Q>', 'l1', ])
- SIZEOF_BMAP_BTREE_REC =
16- DIRECTORY_SHORTERFORM_HEADER =
Directory Entry when stored internal to an inode. Small directories are packed as tightly as possible so as to fit into the literal area of the inode. These “shortform” directories consist of a single header followed by zero or more dir entries. Due to the different inode number storage size and the variable length name field in the dir entry all these structures are variable length, and the accessors in this file should be used to iterate over them.
BinaryStruct.new([ 'C', 'entry_count', # count of entries 'C', 'i8byte_count', # count of 8-byte inode #s 'I>', 'parent_ino_4byte', # parent dir inode # stored as 4 8-bit values ])
- SIZEOF_DIRECTORY_SHORTERFORM_HEADER =
DIRECTORY_SHORTERFORM_HEADER.size
- DIRECTORY_SHORTFORM_HEADER =
BinaryStruct.new([ 'C', 'entry_count', # count of entries 'C', 'i8byte_count', # count of 8-byte inode #s 'Q>', 'parent_ino_8byte', # parent dir inode # stored as 8 8-bit values ])
- SIZEOF_DIRECTORY_SHORTFORM_HEADER =
DIRECTORY_SHORTFORM_HEADER.size
- BMAP_BTREE_ROOT_NODE_HEADER =
BinaryStruct.new([ 'S>', 'level', # B+Tree Level 'S>', 'entry_count', # Number of Key and Pointer Array Elements ])
- SIZEOF_BMAP_BTREE_ROOT_NODE_HEADER =
BMAP_BTREE_ROOT_NODE_HEADER.size
- BMAP_BTREE_ROOT_NODE_ENTRIES =
Note that the following 3 entries are used simply to compute the maximum number of records possible in the on-disk inode.
BinaryStruct.new([ 'Q>', 'starting_offset', # starting offset of the block 'Q>', 'block_number', # block number of the entry ])
- SIZEOF_BMAP_BTREE_ROOT_NODE_ENTRIES =
BMAP_BTREE_ROOT_NODE_ENTRIES.size
- BMAP_BTREE_ROOT_NODE_OFFSET =
BinaryStruct.new([ 'Q>', 'starting_offset', # starting offset of the block ])
- SIZEOF_BMAP_BTREE_ROOT_NODE_OFFSET =
BMAP_BTREE_ROOT_NODE_OFFSET.size
- BMAP_BTREE_ROOT_NODE_BLOCK =
BinaryStruct.new([ 'Q>', 'block_number', # block number of the entry ])
- SIZEOF_BMAP_BTREE_ROOT_NODE_BLOCK =
BMAP_BTREE_ROOT_NODE_BLOCK.size
- DIRECTORY_BLOCK_TAIL =
xfs_dir2_data_hdr consists of the magic number followed by 3 copies of the xfs_dir2_data_free structure
BinaryStruct.new([ 'I>', 'count', # total number of leaf entries 'I>', 'stale', # total number of free entries ])
- SIZEOF_DIRECTORY_BLOCK_TAIL =
DIRECTORY_BLOCK_TAIL.size
- DIRECTORY_DATA_FREE =
BinaryStruct.new([ 'S>', 'offset', # start of freespace 'S>', 'length', # length of freespace ])
- SIZEOF_DIRECTORY_DATA_FREE =
DIRECTORY_DATA_FREE.size
- DIRECTORY2_DATA_HEADER =
xfs_dir2_data_hdr consists of the magic number followed by 3 copies of the xfs_dir2_data_free structure
BinaryStruct.new([ 'I>', 'magic', # magic number ])
- SIZEOF_DIRECTORY2_DATA_HEADER =
DIRECTORY2_DATA_HEADER.size
- DIRECTORY3_DATA_HEADER =
BinaryStruct.new([ 'I>', 'magic', # magic number 'I>', 'crc', # CRC of block 'Q>', 'block_number', # first block of the buffer 'Q>', 'last_write_sequence', # sequence number of last write 'a16', 'uuid', # filesystem we belong to 'Q>', 'owner', # inode that owns the block ])
- SIZEOF_DIRECTORY3_DATA_HEADER =
DIRECTORY3_DATA_HEADER.size
- DIRECTORY3_DATA_PAD =
BinaryStruct.new([ 'I>', 'padding', # padding ])
- SIZEOF_DIRECTORY3_DATA_PAD =
DIRECTORY3_DATA_PAD.size
- SHORT_FORM_DIRECTORY_ENTRY =
//////////////////////////////////////////////////////////////////////////// // Data definitions.
Short Form Directory Entry in a Short Form Inode.
BinaryStruct.new([ 'C', 'name_length', # name length 'C', 'offset_byte0', 'C', 'offset_byte1', ])
- SIZEOF_SHORT_FORM_DIRECTORY_ENTRY =
SHORT_FORM_DIRECTORY_ENTRY.size
- SHORT_FORM_SHORT_INO =
BinaryStruct.new([ 'I>', 'inode_num', # 4 byte inode number ])
- SIZEOF_SHORT_FORM_SHORT_INO =
SHORT_FORM_SHORT_INO.size
- SHORT_FORM_LONG_INO =
BinaryStruct.new([ 'Q>', 'inode_num', # 8 byte inode number ])
- SIZEOF_SHORT_FORM_LONG_INO =
SHORT_FORM_LONG_INO.size
Instance Attribute Summary collapse
-
#cache_hits ⇒ Object
Members (these become members of an MiqFS instance).
-
#dir_cache ⇒ Object
Members (these become members of an MiqFS instance).
-
#entry_cache ⇒ Object
Members (these become members of an MiqFS instance).
-
#rootDir ⇒ Object
Members (these become members of an MiqFS instance).
-
#superblock ⇒ Object
Members (these become members of an MiqFS instance).
Instance Method Summary collapse
-
#fs_dirEntries(p) ⇒ Object
Returns String array of all names, sans path.
-
#fs_dirMkdir(_p) ⇒ Object
Make a directory.
-
#fs_dirRmdir(_p) ⇒ Object
Remove a directory.
-
#fs_fileAtime(p) ⇒ Object
Returns Ruby Time object.
-
#fs_fileAtime_obj(fobj) ⇒ Object
Returns a Ruby Time object.
-
#fs_fileClose(fobj) ⇒ Object
Write changes & destroy.
-
#fs_fileCtime(p) ⇒ Object
Returns Ruby Time object.
-
#fs_fileCtime_obj(fobj) ⇒ Object
Returns a Ruby Time object.
-
#fs_fileDelete(_p) ⇒ Object
Delete file.
-
#fs_fileDirectory?(p) ⇒ Boolean
Returns true if name is a directory.
-
#fs_fileExists?(p) ⇒ Boolean
Returns true if name exists, false if not.
-
#fs_fileFile?(p) ⇒ Boolean
Returns true if name is a regular file.
-
#fs_fileMtime(p) ⇒ Object
Returns Ruby Time object.
-
#fs_fileMtime_obj(fobj) ⇒ Object
Returns a Ruby Time obect.
-
#fs_fileOpen(p, mode = "r") ⇒ Object
New FileObject instance.
-
#fs_fileRead(fobj, len) ⇒ Object
Returns a Ruby String object.
-
#fs_fileSeek(fobj, offset, whence) ⇒ Object
Returns current file position.
-
#fs_fileSize(p) ⇒ Object
Returns size in bytes.
-
#fs_fileSize_obj(fobj) ⇒ Object
In these, fobj is a FileObject.
- #fs_fileWrite(_fobj, _buf, _len) ⇒ Object
-
#fs_freeBytes ⇒ Object
Returns free space on file system in bytes.
-
#fs_init ⇒ Object
File system interface.
-
#fs_isSymLink?(p) ⇒ Boolean
Return true if p is a path to a symbolic link.
-
#ifs_getDir(p, miqfs = nil) ⇒ Object
Return a Directory object for a path.
-
#ifs_getDirR(names, miqfs) ⇒ Object
Return Directory recursively for given directory or nil if not exist.
-
#ifs_getFile(p, miqfs = nil) ⇒ Object
Return a DirectoryEntry for a given file or nil if not exist.
-
#ifs_putFile(_p, _miqfs = nil) ⇒ Object
Create a directory entry.
-
#unnormalizePath(p) ⇒ Object
Wack leading drive letter & colon.
Instance Attribute Details
#cache_hits ⇒ Object
Members (these become members of an MiqFS instance).
13 14 15 |
# File 'lib/fs/MiqFS/modules/XFS.rb', line 13 def cache_hits @cache_hits end |
#dir_cache ⇒ Object
Members (these become members of an MiqFS instance).
13 14 15 |
# File 'lib/fs/MiqFS/modules/XFS.rb', line 13 def dir_cache @dir_cache end |
#entry_cache ⇒ Object
Members (these become members of an MiqFS instance).
13 14 15 |
# File 'lib/fs/MiqFS/modules/XFS.rb', line 13 def entry_cache @entry_cache end |
#rootDir ⇒ Object
Members (these become members of an MiqFS instance).
13 14 15 |
# File 'lib/fs/MiqFS/modules/XFS.rb', line 13 def rootDir @rootDir end |
#superblock ⇒ Object
Members (these become members of an MiqFS instance).
13 14 15 |
# File 'lib/fs/MiqFS/modules/XFS.rb', line 13 def superblock @superblock end |
Instance Method Details
#fs_dirEntries(p) ⇒ Object
Returns String array of all names, sans path. TODO
66 67 68 69 70 71 |
# File 'lib/fs/MiqFS/modules/XFS.rb', line 66 def fs_dirEntries(p) # Get path directory. dir = ifs_getDir(p) return nil if dir.nil? dir.glob_names end |
#fs_dirMkdir(_p) ⇒ Object
Make a directory. Parent must exist. TODO
75 76 77 |
# File 'lib/fs/MiqFS/modules/XFS.rb', line 75 def fs_dirMkdir(_p) raise "Write functionality is not yet supported on XFS." end |
#fs_dirRmdir(_p) ⇒ Object
Remove a directory. TODO
81 82 83 |
# File 'lib/fs/MiqFS/modules/XFS.rb', line 81 def fs_dirRmdir(_p) raise "Write functionality is not yet supported on XFS." end |
#fs_fileAtime(p) ⇒ Object
Returns Ruby Time object.
123 124 125 126 127 |
# File 'lib/fs/MiqFS/modules/XFS.rb', line 123 def fs_fileAtime(p) de = ifs_getFile(p) return nil if de.nil? @superblock.get_inode(de.inode).aTime end |
#fs_fileAtime_obj(fobj) ⇒ Object
Returns a Ruby Time object.
156 157 158 |
# File 'lib/fs/MiqFS/modules/XFS.rb', line 156 def fs_fileAtime_obj(fobj) fobj.inode.access_time end |
#fs_fileClose(fobj) ⇒ Object
Write changes & destroy.
195 196 197 198 199 200 |
# File 'lib/fs/MiqFS/modules/XFS.rb', line 195 def fs_fileClose(fobj) # TODO: unrem when write is supported. # fobj.inode.close fobj.inode.rewind nil end |
#fs_fileCtime(p) ⇒ Object
Returns Ruby Time object.
130 131 132 133 134 |
# File 'lib/fs/MiqFS/modules/XFS.rb', line 130 def fs_fileCtime(p) de = ifs_getFile(p) return nil if de.nil? @superblock.get_inode(de.inode).cTime end |
#fs_fileCtime_obj(fobj) ⇒ Object
Returns a Ruby Time object.
161 162 163 |
# File 'lib/fs/MiqFS/modules/XFS.rb', line 161 def fs_fileCtime_obj(fobj) fobj.inode.create_time end |
#fs_fileDelete(_p) ⇒ Object
Delete file.
118 119 120 |
# File 'lib/fs/MiqFS/modules/XFS.rb', line 118 def fs_fileDelete(_p) raise "Write functionality is not yet supported on XFS." end |
#fs_fileDirectory?(p) ⇒ Boolean
Returns true if name is a directory.
104 105 106 107 108 |
# File 'lib/fs/MiqFS/modules/XFS.rb', line 104 def fs_fileDirectory?(p) de = ifs_getFile(p) return false if de.nil? de.file_type == Inode::FT_DIRECTORY end |
#fs_fileExists?(p) ⇒ Boolean
Returns true if name exists, false if not.
90 91 92 93 94 |
# File 'lib/fs/MiqFS/modules/XFS.rb', line 90 def fs_fileExists?(p) de = ifs_getFile(p) return false if de.nil? true end |
#fs_fileFile?(p) ⇒ Boolean
Returns true if name is a regular file.
97 98 99 100 101 |
# File 'lib/fs/MiqFS/modules/XFS.rb', line 97 def fs_fileFile?(p) de = ifs_getFile(p) return false if de.nil? de.file_type == Inode::FT_FILE end |
#fs_fileMtime(p) ⇒ Object
Returns Ruby Time object.
137 138 139 140 141 |
# File 'lib/fs/MiqFS/modules/XFS.rb', line 137 def fs_fileMtime(p) de = ifs_getFile(p) return nil if de.nil? @superblock.get_inode(de.inode).mTime end |
#fs_fileMtime_obj(fobj) ⇒ Object
Returns a Ruby Time obect.
166 167 168 |
# File 'lib/fs/MiqFS/modules/XFS.rb', line 166 def fs_fileMtime_obj(fobj) fobj.inode.modification_time end |
#fs_fileOpen(p, mode = "r") ⇒ Object
New FileObject instance. NOTE: FileObject must have access to XFS members. This is kind of like a ‘skip this’ thing. XFS methods use stuff owned by MiqFS, so this is necessary.
174 175 176 177 178 |
# File 'lib/fs/MiqFS/modules/XFS.rb', line 174 def fs_fileOpen(p, mode = "r") fobj = FileObject.new(p, self) fobj.open(mode) fobj end |
#fs_fileRead(fobj, len) ⇒ Object
Returns a Ruby String object.
186 187 188 |
# File 'lib/fs/MiqFS/modules/XFS.rb', line 186 def fs_fileRead(fobj, len) fobj.inode.read(len) end |
#fs_fileSeek(fobj, offset, whence) ⇒ Object
Returns current file position.
181 182 183 |
# File 'lib/fs/MiqFS/modules/XFS.rb', line 181 def fs_fileSeek(fobj, offset, whence) fobj.inode.seek(offset, whence) end |
#fs_fileSize(p) ⇒ Object
Returns size in bytes.
111 112 113 114 115 |
# File 'lib/fs/MiqFS/modules/XFS.rb', line 111 def fs_fileSize(p) de = ifs_getFile(p) return nil if de.nil? @superblock.get_inode(de.inode).length end |
#fs_fileSize_obj(fobj) ⇒ Object
In these, fobj is a FileObject.
151 152 153 |
# File 'lib/fs/MiqFS/modules/XFS.rb', line 151 def fs_fileSize_obj(fobj) fobj.inode.length end |
#fs_fileWrite(_fobj, _buf, _len) ⇒ Object
190 191 192 |
# File 'lib/fs/MiqFS/modules/XFS.rb', line 190 def fs_fileWrite(_fobj, _buf, _len) raise "Write functionality is not yet supported on XFS." end |
#fs_freeBytes ⇒ Object
Returns free space on file system in bytes.
56 57 58 |
# File 'lib/fs/MiqFS/modules/XFS.rb', line 56 def fs_freeBytes @superblock.free_bytes end |
#fs_init ⇒ Object
File system interface.
41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/fs/MiqFS/modules/XFS.rb', line 41 def fs_init self.fsType = "XFS" # Initialize bs & read root dir. @dobj.seek(0, IO::SEEK_SET) self.superblock = Superblock.new(@dobj) @fs_id = superblock.filesystem_id.to_s @volName = superblock.volume_name self.rootDir = Directory.new(superblock, superblock.root_inode) self.entry_cache = LruHash.new(DEF_CACHE_SIZE) self.dir_cache = LruHash.new(DEF_CACHE_SIZE) self.cache_hits = 0 end |
#fs_isSymLink?(p) ⇒ Boolean
Return true if p is a path to a symbolic link.
144 145 146 147 148 |
# File 'lib/fs/MiqFS/modules/XFS.rb', line 144 def fs_isSymLink?(p) de = ifs_getFile(p) return false if de.nil? de.symlink? end |
#ifs_getDir(p, miqfs = nil) ⇒ Object
Return a Directory object for a path. Raise error if path doesn’t exist.
254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 |
# File 'lib/fs/MiqFS/modules/XFS.rb', line 254 def ifs_getDir(p, miqfs = nil) # If this is being called from a FileObject instance, then MiqFS owns contained instance members. # If this is being called from an XFS module method, then self owns contained instance members. miqfs = self if miqfs.nil? # Wack leading drive. p = unnormalizePath(p) # Get an array of directory names, kill off the first (it's always empty). names = p.split(/[\\\/]/) names.shift dir = ifs_getDirR(names, miqfs) $log.info("Directory '#{p}' not found") if dir.nil? dir end |
#ifs_getDirR(names, miqfs) ⇒ Object
Return Directory recursively for given directory or nil if not exist.
272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 |
# File 'lib/fs/MiqFS/modules/XFS.rb', line 272 def ifs_getDirR(names, miqfs) return miqfs.rootDir if names.empty? # Check for this path in the cache. fname = names.join('/') if miqfs.dir_cache.key?(fname) miqfs.cache_hits += 1 return miqfs.dir_cache[fname] end name = names.pop pdir = ifs_getDirR(names, miqfs) return nil if pdir.nil? de = pdir.find_entry(name, Inode::FT_DIRECTORY) return nil if de.nil? miqfs.entry_cache[fname] = de dir = Directory.new(miqfs.superblock, de.inode) return nil if dir.nil? miqfs.dir_cache[fname] = dir end |
#ifs_getFile(p, miqfs = nil) ⇒ Object
Return a DirectoryEntry for a given file or nil if not exist.
205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 |
# File 'lib/fs/MiqFS/modules/XFS.rb', line 205 def ifs_getFile(p, miqfs = nil) # If this is being called from a FileObject instance, then MiqFS owns contained instance members. # If this is being called from an XFS module method, then self owns contained instance members. miqfs = self if miqfs.nil? # Preprocess path. p = unnormalizePath(p) dir, fname = File.split(p) # Fix for FB#835: if fil == root then fil needs to be "." fname = "." if fname == "/" || fname == "\\" # Check for this file in the cache. cache_name = "#{dir == '/' ? '' : dir}/#{fname}" if miqfs.entry_cache.key?(cache_name) miqfs.cache_hits += 1 return miqfs.entry_cache[cache_name] end # Look for file in dir, but don't error if it doesn't exist. # NOTE: if p is a directory that's ok, find it. begin directory_object = ifs_getDir(dir, miqfs) directory_entry = directory_object.nil? ? nil : directory_object.find_entry(fname) rescue RuntimeError directory_entry = nil end miqfs.entry_cache[cache_name] = directory_entry end |
#ifs_putFile(_p, _miqfs = nil) ⇒ Object
Create a directory entry.
236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 |
# File 'lib/fs/MiqFS/modules/XFS.rb', line 236 def ifs_putFile(_p, _miqfs = nil) raise "Write functionality is not yet supported on XFS." # If this is being called from a FileObject instance, then MiqFS owns contained instance members. # If this is being called from an XFS module method, then self owns contained instance members. # miqfs = self if miqfs.nil? # Preprocess path. # p = unnormalizePath(p) # dir, fil = File.split(p) # Parent directory must exist. # dirObj = ifs_getDir(dir, miqfs) # return nil if dir.nil? # dirObj.createFile(fil) end |
#unnormalizePath(p) ⇒ Object
Wack leading drive letter & colon.
297 298 299 |
# File 'lib/fs/MiqFS/modules/XFS.rb', line 297 def unnormalizePath(p) p[1] == 58 ? p[2, p.size] : p end |