kolibrios-fun/kernel/trunk/fs/xfs.inc
Ivan Baravy 06d05066a3 [xfs] Support XFS nrext64 feature bit
This feature is _not_ enabled by default by mkfs.xfs at the moment.
That said, make KolibriOS ready for the future. By the way, fix two
bugs in support of XFSv5 disk format.

git-svn-id: svn://kolibrios.org@9889 a494cfbc-eb01-0410-851d-a64ba20cac60
2023-01-02 00:55:53 +00:00

610 lines
22 KiB
PHP

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2013-2022. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision$
; file types from stat.h
S_IFMT = 0170000o ; These bits determine file type
S_IFDIR = 0040000o ; Directory
S_IFCHR = 0020000o ; Character device
S_IFBLK = 0060000o ; Block device
S_IFREG = 0100000o ; Regular file
S_IFIFO = 0010000o ; FIFO
S_IFLNK = 0120000o ; Symbolic link
S_IFSOCK = 0140000o ; Socket
; XFS null constant: empty fields must be all ones, not zeros!
XFS_NULL = -1
XFS_SECT_SB = 0
; signatures of file system structures
XFS_AGF_MAGIC = 'XAGF'
XFS_DINODE_MAGIC = 'IN'
XFS_BMAP_MAGIC = 'BMAP'
XFS_DA_NODE_MAGIC = 0xbefe
XFS_DIR2_LEAF1_MAGIC = 0xf1d2
XFS_DIR2_LEAFN_MAGIC = 0xffd2
XFS_DIR2_BLOCK_MAGIC = 'XD2B'
XFS_DIR2_DATA_MAGIC = 'XD2D'
XFS_BMAP3_MAGIC = 'BMA3'
XFS_DA3_NODE_MAGIC = 0xbe3e ; non-leaf blocks
XFS_DIR3_LEAF1_MAGIC = 0xf13d ; v3 dir single blks
XFS_DIR3_LEAFN_MAGIC = 0xff3d ; v3 dir multi blks
XFS_DIR3_BLOCK_MAGIC = 'XDB3' ; single block dirs
XFS_DIR3_DATA_MAGIC = 'XDD3' ; multiblock dirs
XFS_SB_MAGIC = 'XFSB'
XFS_SB_VERSION_NUMBITS = 0x000f
XFS_SB_VERSION_ALLFBITS = 0xfff0
XFS_SB_VERSION_REALFBITS = 0x0ff0
XFS_SB_VERSION_ATTRBIT = 0x0010
XFS_SB_VERSION_NLINKBIT = 0x0020
XFS_SB_VERSION_QUOTABIT = 0x0040
XFS_SB_VERSION_ALIGNBIT = 0x0080
XFS_SB_VERSION_DALIGNBIT = 0x0100
XFS_SB_VERSION_SHAREDBIT = 0x0200
XFS_SB_VERSION_LOGV2BIT = 0x0400
XFS_SB_VERSION_SECTORBIT = 0x0800
XFS_SB_VERSION_EXTFLGBIT = 0x1000
XFS_SB_VERSION_DIRV2BIT = 0x2000
XFS_SB_VERSION_BORGBIT = 0x4000 ; ASCII only case-insensitive
XFS_SB_VERSION_MOREBITSBIT = 0x8000
XFS_SB_VERSION_SUPPORTED = XFS_SB_VERSION_NUMBITS OR \
XFS_SB_VERSION_ATTRBIT OR \
XFS_SB_VERSION_NLINKBIT OR \
XFS_SB_VERSION_QUOTABIT OR \
XFS_SB_VERSION_ALIGNBIT OR \
XFS_SB_VERSION_LOGV2BIT OR \
XFS_SB_VERSION_SECTORBIT OR \
XFS_SB_VERSION_EXTFLGBIT OR \
XFS_SB_VERSION_DIRV2BIT OR \
XFS_SB_VERSION_MOREBITSBIT
XFS_SB_VERSION2_RESERVED1BIT = 0x00000001
XFS_SB_VERSION2_LAZYSBCOUNTBIT = 0x00000002 ; Superblk counters
XFS_SB_VERSION2_RESERVED4BIT = 0x00000004
XFS_SB_VERSION2_ATTR2BIT = 0x00000008 ; Inline attr rework
XFS_SB_VERSION2_PARENTBIT = 0x00000010 ; parent pointers in xattr
XFS_SB_VERSION2_PROJID32BIT = 0x00000080 ; 32 bit project id
XFS_SB_VERSION2_CRCBIT = 0x00000100 ; metadata CRCs
XFS_SB_VERSION2_FTYPE = 0x00000200 ; inode type in dir
XFS_SB_VERSION2_SUPPORTED = XFS_SB_VERSION2_LAZYSBCOUNTBIT OR \
XFS_SB_VERSION2_ATTR2BIT OR \
XFS_SB_VERSION2_PARENTBIT OR \
XFS_SB_VERSION2_PROJID32BIT OR \
XFS_SB_VERSION2_CRCBIT OR \
XFS_SB_VERSION2_FTYPE
XFS_SB_FEAT_INCOMPAT_FTYPE = 0x01 ; filetype in dirent
XFS_SB_FEAT_INCOMPAT_SPINODES = 0x02 ; sparse inode chunks
XFS_SB_FEAT_INCOMPAT_META_UUID = 0x04 ; metadata UUID
XFS_SB_FEAT_INCOMPAT_BIGTIME = 0x08 ; large timestamps
XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR = 0x10 ; e.g. for upgrade to nrext64
XFS_SB_FEAT_INCOMPAT_NREXT64 = 0x20 ; 64bit extent counters
XFS_SB_FEAT_INCOMPAT_SUPPORTED = XFS_SB_FEAT_INCOMPAT_FTYPE OR \
XFS_SB_FEAT_INCOMPAT_SPINODES OR \
XFS_SB_FEAT_INCOMPAT_META_UUID OR \
XFS_SB_FEAT_INCOMPAT_BIGTIME OR \
XFS_SB_FEAT_INCOMPAT_NREXT64
; bitfield lengths for packed extent
; MSB to LSB / left to right
BMBT_EXNTFLAG_BITLEN = 1
BMBT_STARTOFF_BITLEN = 54
BMBT_STARTBLOCK_BITLEN = 52
BMBT_BLOCKCOUNT_BITLEN = 21
XFS_DIR2_DATA_ALIGN_LOG = 3
XFS_DIR2_DATA_ALIGN = 1 SHL XFS_DIR2_DATA_ALIGN_LOG
XFS_DIR2_SPACE_SIZE = (1 SHL (32 + XFS_DIR2_DATA_ALIGN_LOG))
XFS_DIR2_DATA_OFFSET = 0*XFS_DIR2_SPACE_SIZE
XFS_DIR2_LEAF_OFFSET = 1*XFS_DIR2_SPACE_SIZE
XFS_DIR2_FREE_OFFSET = 2*XFS_DIR2_SPACE_SIZE
; data section magic constants for directories (xfs_dir2_data.h)
XFS_DIR2_DATA_FD_COUNT = 3
; valid inode formats
; enum xfs_dinode_fmt (xfs_dinode.h)
XFS_DINODE_FMT_DEV = 0
XFS_DINODE_FMT_LOCAL = 1
XFS_DINODE_FMT_EXTENTS = 2
XFS_DINODE_FMT_BTREE = 3
XFS_DINODE_FMT_UUID = 4
; size of the unlinked inode hash table in the agi
XFS_AGI_UNLINKED_BUCKETS = 64
; possible extent states
; enum xfs_exntst_t (xfs_bmap_btree.h)
XFS_EXT_NORM = 0
XFS_EXT_UNWRITTEN = 1
XFS_EXT_DMAPI_OFFLINE = 2
XFS_EXT_INVALID = 3
; values for inode core flags / di_flags (xfs_dinode.h)
XFS_DIFLAG_REALTIME_BIT = 0 ; file's blocks come from rt area
XFS_DIFLAG_PREALLOC_BIT = 1 ; file space has been preallocated
XFS_DIFLAG_NEWRTBM_BIT = 2 ; for rtbitmap inode, new format
XFS_DIFLAG_NODUMP_BIT = 7 ; do not dump
XFS_DIFLAG_REALTIME = (1 SHL XFS_DIFLAG_REALTIME_BIT)
XFS_DIFLAG_PREALLOC = (1 SHL XFS_DIFLAG_PREALLOC_BIT)
XFS_DIFLAG_NEWRTBM = (1 SHL XFS_DIFLAG_NEWRTBM_BIT)
XFS_DIFLAG_NODUMP = (1 SHL XFS_DIFLAG_NODUMP_BIT)
; superblock _ondisk_ structure (xfs_sb.h)
; this is _not_ the partition structure
; for XFS partition structure see XFS below
struct xfs_sb
sb_magicnum dd ? ; signature, must be XFS_SB_MAGIC
sb_blocksize dd ? ; block is the minimal file system unit, in bytes
sb_dblocks DQ ? ; number of data blocks
sb_rblocks DQ ? ; number of realtime blocks
sb_rextents DQ ? ; number of realtime extents
sb_uuid rb 16 ; file system unique identifier
sb_logstart DQ ? ; starting block of log (for internal journal)
sb_rootino DQ ? ; root inode number
sb_rbmino DQ ? ; bitmap inode for realtime extents
sb_rsumino DQ ? ; summary inode for rt bitmap
sb_rextsize dd ? ; realtime extent size, blocks
sb_agblocks dd ? ; size of an allocation group (the last one may be smaller!)
sb_agcount dd ? ; number of allocation groups
sb_rbmblocks dd ? ; number of rt bitmap blocks
sb_logblocks dd ? ; number of log blocks
sb_versionnum dw ? ; header version
sb_sectsize dw ? ; volume sector size in bytes
sb_inodesize dw ? ; inode size, bytes
sb_inopblock dw ? ; inodes per block
sb_fname rb 12 ; inodes per block (aka label)
sb_blocklog db ? ; log2 of sb_blocksize
sb_sectlog db ? ; log2 of sb_blocksize
sb_inodelog db ? ; log2 of sb_inodesize
sb_inopblog db ? ; log2 of sb_inopblock
sb_agblklog db ? ; log2 of sb_agblocks (rounded up!)
sb_rextslog db ? ; log2 of sb_rextents
sb_inprogress db ? ; mkfs is in progress, don't mount
sb_imax_pct db ? ; max % of fs for inode space
; statistics
sb_icount DQ ? ; allocated inodes
sb_ifree DQ ? ; free inodes
sb_fdblocks DQ ? ; free data blocks
sb_frextents DQ ? ; free realtime extents
sb_uquotino DQ ? ; user quota inode
sb_gquotino DQ ? ; group quota inode
sb_qflags dw ? ; quota flags
sb_flags db ? ; misc. flags
sb_shared_vn db ? ; shared version number
sb_inoalignmt dd ? ; inode chunk alignment, fsblocks
sb_unit dd ? ; stripe or raid unit
sb_width dd ? ; stripe or raid width
sb_dirblklog db ? ; log2 of dir block size (fsbs)
sb_logsectlog db ? ; log2 of the log sector size
sb_logsectsize dw ? ; sector size for the log, bytes
sb_logsunit dd ? ; stripe unit size for the log
sb_features2 dd ? ; additional feature bits
sb_bad_features2 dd ?
sb_features_compat dd ?
sb_features_ro_compat dd ?
sb_features_incompat dd ?
sb_features_log_incompat dd ?
sb_crc dd ? ; superblock crc
sb_spino_align dd ? ; sparse inode chunk alignment
sb_pquotino DQ ? ; project quota inode
sb_lsn DQ ? ; last write sequence
sb_meta_uuid rb 16 ; metadata file system unique id
ends
; inode core structure: basic information about file
struct xfs_dinode_core
di_magic dw ? ; inode magic = XFS_DINODE_MAGIC
di_mode dw ? ; mode and type of file
di_version db ? ; inode version
di_format db ? ; format of di_c data
di_onlink dw ? ; old number of links to file
di_uid dd ? ; owner's user id
di_gid dd ? ; owner's group id
di_nlink dd ? ; number of links to file
di_projid dd ? ; owner's project id
di_big_nextents DQ ? ; iff NREXT64 is set
di_atime DQ ; time last accessed
di_mtime DQ ; time last modified
di_ctime DQ ; time created/inode modified
di_size DQ ? ; number of bytes in file
di_nblocks DQ ? ; number of direct & btree blocks used
di_extsize dd ? ; basic/minimum extent size for file
union
struct
di_nextents dd ? ; number of extents in data fork
di_anextents dw ? ; number of extents in attribute fork
ends
struct
di_big_anextents dd ? ; attr extent counter is 32bit for NREXT64
di_nrext64_pad dw ?
ends
ends
di_forkoff db ? ; attr fork offs, <<3 for 64b align
di_aformat db ? ; format of attr fork's data
di_dmevmask dd ? ; DMIG event mask
di_dmstate dw ? ; DMIG state info
di_flags dw ? ; random flags, XFS_DIFLAG_...
di_gen dd ? ; generation number
di_next_unlinked dd ? ; unlinked but still used inode (if any, XFS_NULL otherwise)
ends
struct xfs_dinode3_core xfs_dinode_core
di_crc dd ? ; CRC of the inode
di_changecount DQ ? ; number of attribute changes
di_lsn DQ ? ; flush sequence
di_flags2 DQ ? ; more random flags
di_cowextsize dd ? ; basic cow extent size for file
di_pad2 rb 12 ; more padding for future expansion
; fields only written to during inode creation
di_crtime DQ ; time created
di_ino DQ ? ; inode number
di_uuid rb 16 ; UUID of the filesystem
ends
struct xfs_dir2_sf_hdr
count db ?
i8count db ?
parent DQ ? ; parent inode number, 4 or 8 bytes
ends
struct xfs_dir2_sf_entry
namelen db ? ; actual name length (ASCII)
offset rb 2 ; saved offset
name db ? ; name, variable size
inumber DQ ? ; 4 or 8 bytes
ends
struct xfs_dir2_sf
hdr xfs_dir2_sf_hdr
entries xfs_dir2_sf_entry
ends
; active entry in a data block
; aligned to 8 bytes
; tag appears as the last 2 bytes
struct xfs_dir2_data_entry
inumber DQ ?
namelen db ?
name db ? ; name bytes array without terminator
; tag dw ? ; starting offset of the entry
ends
; unused entry in a data block
struct xfs_dir2_data_unused
freetag dw ? ; XFS_DIR2_DATA_FREE_TAG aka XFS_NULL
length dw ? ; total free length
; tag dw ? ; starting offset of the entry
ends
; generic data entry
struct xfs_dir2_data_union
union
xentry xfs_dir2_data_entry
unused xfs_dir2_data_unused
ends
ends
; describe a free area in the data block
; the freespace will be formatted as a xfs_dir2_data_unused_t
struct xfs_dir2_data_free
offset dw ? ; start of freespace
length dw ? ; length of freespace
ends
; header for the data blocks
; always at the beginning of a directory-sized block
; the code knows that XFS_DIR2_DATA_FD_COUNT is 3
struct xfs_dir2_data_hdr
magic dd ? ; XFS_DIR2_DATA_MAGIC or XFS_DIR2_BLOCK_MAGIC
bestfree xfs_dir2_data_free
bestfree2 xfs_dir2_data_free
bestfree3 xfs_dir2_data_free
ends
struct xfs_dir3_data_hdr xfs_dir2_data_hdr
magic3 dd ?
crc dd ?
blkno DQ ?
lsn DQ ?
uuid rb 16
owner DQ ?
ends
; leaf block entry
struct xfs_dir2_leaf_entry
hashval dd ? ; hash value of name
address dd ? ; address of data entry
ends
; the tail of directory block
struct xfs_dir2_block_tail
count dd ? ; count of leaf entries
stale dd ? ; count of stale leaf entries
ends
; generic single-block structure, for xfs_db
struct xfs_dir2_block
hdr xfs_dir2_data_hdr ; magic XFS_DIR2_DATA_MAGIC
u xfs_dir2_data_union
; leaf xfs_dir2_leaf_entry
; tail xfs_dir2_block_tail
ends
struct xfs_da_blkinfo
forw dd ? ; previous block in list
back dd ? ; following block in list
magic dw ? ; validity check on block
pad dw ? ; unused
ends
struct xfs_dir2_leaf_hdr
info xfs_da_blkinfo
count dw ?
stale dw ?
ends
struct xfs_da3_blkinfo xfs_da_blkinfo
crc dd ? ; CRC of block
blkno DQ ? ; first block of the buffer
lsn DQ ? ; sequence number of last write
uuid rb 16 ; filesystem we belong to
owner DQ ? ; inode that owns the block
ends
struct xfs_dir3_leaf_hdr
info xfs_da3_blkinfo
count dw ?
stale dw ?
pad dd ?
ends
; bests and tail are at the end of the block for single-leaf only
; (magic = XFS_DIR2_LEAF1_MAGIC not XFS_DIR2_LEAFN_MAGIC)
struct xfs_dir2_leaf
hdr xfs_dir2_leaf_hdr
ents xfs_dir2_leaf_entry
; bests dw ?
; tail xfs_dir2_leaf_tail
ends
struct xfs_dir3_leaf
hdr xfs_dir3_leaf_hdr
ents xfs_dir2_leaf_entry
; bests
; tail
ends
struct xfs_dir2_free_hdr
magic dd ? ; XFS_DIR2_FREE_MAGIC
firstdb dd ? ; db of first entry
nvalid dd ? ; count of valid entries
nused dd ? ; count of used entries
ends
struct xfs_da_node_hdr
info xfs_da_blkinfo
count dw ?
level dw ?
ends
struct xfs_da_node_entry
hashval dd ? ; hash value for this descendant
before dd ? ; Btree block before this key
ends
struct xfs_da_intnode
hdr xfs_da_node_hdr
btree xfs_da_node_entry
ends
struct xfs_da3_node_hdr
info xfs_da3_blkinfo
count dw ?
level dw ?
pad dd ?
ends
struct xfs_da3_intnode
hdr xfs_da3_node_hdr
btree xfs_da_node_entry
ends
; packet extent
struct xfs_bmbt_rec
l0 DQ ?
l1 DQ ?
ends
; unpacked extent
struct xfs_bmbt_irec
br_startoff DQ ?
br_startblock DQ ?
br_blockcount dd ?
br_state dd ?
ends
struct xfs_dir2_bmx
bmx xfs_bmbt_rec
ends
; bmap root header
struct xfs_bmdr_block
bb_level dw ? ; 0 is a leaf
bb_numrecs dw ? ; current number of data records
ends
; key structure for non-leaf levels of the tree
struct xfs_bmbt_key
br_startoff DQ ? ; starting file offset
ends
struct xfs_bmdr_ptr DQ
ends
struct xfs_bmbt_ptr DQ
ends
; long form header: bmap btrees
; xfs_btree_lblock is xfs_bmbt_block (xfs_btree.h)
struct xfs_bmbt_block
bb_magic dd ? ; magic number for block type
bb_level dw ? ; 0 is a leaf
bb_numrecs dw ? ; current number of data records
bb_leftsib DQ ? ; left sibling block or NULLDFSBNO
bb_rightsib DQ ? ; right sibling block or NULLDFSBNO
ends
struct xfs_bmbt3_block xfs_bmbt_block
bb_blkno DQ ?
bb_lsn DQ ?
bb_uuid rb 16
bb_owner DQ ?
bb_crc dd ?
bb_pad dd ?
ends
struct xfs_inode
di_core xfs_dinode_core ; main info, aka core
ends
; internal data for every XFS partition
; this _is_ XFS partition structure
; most fields are unpacked or bswap'ed values of the superblock, see xfs_sb structure above
struct XFS PARTITION
Lock MUTEX ? ; access mutex
sectsize dd ?
blocksize dd ?
dirblocksize dd ?
inodesize dd ?
rootino DQ ?
versionnum dd ?
version dd ?
features2 dd ?
inopblock dd ?
blkpdirblk dd ?
blocklog dd ?
sectlog dd ?
inodelog dd ?
inopblog dd ?
agblklog dd ?
sectpblog dd ?
dirblklog dd ? ; in fsblocks
sectpblock dd ?
agblocks dd ?
dir2_leaf_offset_blocks DQ ?
dir2_free_offset_blocks DQ ?
agblockmask DQ ?
inode_core_size dd ?
features_incompat dd ?
ftype_size dd ?
dir_block_magic dd ?
dir_data_magic dd ?
dir_leaf1_magic dw ?
dir_leafn_magic dw ?
da_node_magic dw ?
bmap_magic dd ?
bmbt_block_size dd ?
dir_block_size dd ?
dir_data_size dd ?
dir_leaf1_size dd ?
dir_leafn_size dd ?
da_node_size dd ?
da_blkinfo_size dd ?
conv_time_to_kos_epoch dd ?
nextents_offset dd ?
; helpers, temporary vars, etc
; should go to file descriptor and local vars?
cur_block dd ?
cur_block_data dd ?
cur_inode dd ?
cur_sect dd ?
cur_dirblock dd ?
tmp_inode dd ?
extent xfs_bmbt_irec
bytes_to_read dd ?
bytes_read dd ?
bytes_left_in_file DQ ?
file_offset DQ ?
file_buffer dd ?
entries_read dd ?
requested_cnt dd ?
dir_sf_self_done dd ?
dir_sf_parent_done dd ?
entries_left_in_dir dd ?
entries_to_skip dd ?
max_dirblockaddr dd ?
cur_inode_save dd ?
shortform_inodelen dd ?
bdfe_nameenc dd ?
bdfe_len dd ?
bdfe_process dd ?
inode_self DQ ?
bdfe_buf dd ?
eof dd ?
offset_begin DQ ?
offset_end DQ ?
ends
struct f70s0arg
sf dd ?
offset DQ ?
count dd ?
buf dd ?
zero db ?
path dd ?
ends
struct f70s1arg
sf dd ?
start_idx dd ?
encoding dd ?
count dd ?
buf dd ?
zero db ?
path dd ?
ends
struct f70s5arg
sf dd ?
dd ?
xflags dd ? ; name flags is already used
dd ?
buf dd ?
zero db ?
path dd ?
ends
struct bdfe_hdr
version dd ?
read_cnt dd ?
total_cnt dd ?
zeroed rd 5
ends
struct bdfe
attr dd ?
nameenc dd ?
ctime dd ?
cdate dd ?
atime dd ?
adate dd ?
mtime dd ?
mdate dd ?
size DQ ?
name db ?
ends