/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * Copyright (c) 2013 Red Hat, Inc. * All Rights Reserved.
*/ #ifndef __XFS_DA_FORMAT_H__ #define __XFS_DA_FORMAT_H__
/* * This structure is common to both leaf nodes and non-leaf nodes in the Btree. * * It is used to manage a doubly linked list of all blocks at the same * level in the Btree, and to identify which type of block this is.
*/ #define XFS_DA_NODE_MAGIC 0xfebe /* magic number: non-leaf blocks */ #define XFS_ATTR_LEAF_MAGIC 0xfbee /* magic number: attribute leaf blks */ #define XFS_DIR2_LEAF1_MAGIC 0xd2f1 /* magic number: v2 dirlf single blks */ #define XFS_DIR2_LEAFN_MAGIC 0xd2ff /* magic number: v2 dirlf multi blks */
typedefstruct xfs_da_blkinfo {
__be32 forw; /* previous block in list */
__be32 back; /* following block in list */
__be16 magic; /* validity check on block */
__be16 pad; /* unused */
} xfs_da_blkinfo_t;
/* * CRC enabled directory structure types * * The headers change size for the additional verification information, but * otherwise the tree layouts and contents are unchanged. Hence the da btree * code can use the struct xfs_da_blkinfo for manipulating the tree links and * magic numbers without modification for both v2 and v3 nodes.
*/ #define XFS_DA3_NODE_MAGIC 0x3ebe /* magic number: non-leaf blocks */ #define XFS_ATTR3_LEAF_MAGIC 0x3bee /* magic number: attribute leaf blks */ #define XFS_DIR3_LEAF1_MAGIC 0x3df1 /* magic number: v3 dirlf single blks */ #define XFS_DIR3_LEAFN_MAGIC 0x3dff /* magic number: v3 dirlf multi blks */
struct xfs_da3_blkinfo { /* * the node link manipulation code relies on the fact that the first * element of this structure is the struct xfs_da_blkinfo so it can * ignore the differences in the rest of the structures.
*/ struct xfs_da_blkinfo hdr;
__be32 crc; /* CRC of block */
__be64 blkno; /* first block of the buffer */
__be64 lsn; /* sequence number of last write */
uuid_t uuid; /* filesystem we belong to */
__be64 owner; /* inode that owns the block */
};
/* * This is the structure of the root and intermediate nodes in the Btree. * The leaf nodes are defined above. * * Entries are not packed. * * Since we have duplicate keys, use a binary search but always follow * all match in the block, not just the first match found.
*/ #define XFS_DA_NODE_MAXDEPTH 5 /* max depth of Btree */
typedefstruct xfs_da_node_entry {
__be32 hashval; /* hash value for this descendant */
__be32 before; /* Btree block before this key */
} xfs_da_node_entry_t;
/* * Directory version 2. * * There are 4 possible formats: * - shortform - embedded into the inode * - single block - data with embedded leaf at the end * - multiple data blocks, single leaf+freeindex block * - data blocks, node and leaf blocks (btree), freeindex blocks * * Note: many node blocks structures and constants are shared with the attr * code and defined in xfs_da_btree.h.
*/
/* * Directory Version 3 With CRCs. * * The tree formats are the same as for version 2 directories. The difference * is in the block header and dirent formats. In many cases the v3 structures * use v2 definitions as they are no different and this makes code sharing much * easier. * * Also, the xfs_dir3_*() functions handle both v2 and v3 formats - if the * format is v2 then they switch to the existing v2 code, or the format is v3 * they implement the v3 functionality. This means the existing dir2 is a mix of * xfs_dir2/xfs_dir3 calls and functions. The xfs_dir3 functions are called * where there is a difference in the formats, otherwise the code is unchanged. * * Where it is possible, the code decides what to do based on the magic numbers * in the blocks rather than feature bits in the superblock. This means the code * is as independent of the external XFS code as possible as doesn't require * passing struct xfs_mount pointers into places where it isn't really * necessary. * * Version 3 includes: * * - a larger block header for CRC and identification purposes and so the * offsets of all the structures inside the blocks are different. * * - new magic numbers to be able to detect the v2/v3 types on the fly.
*/
/* * Dirents in version 3 directories have a file type field. Additions to this * list are an on-disk format change, requiring feature bits. Valid values * are as follows:
*/ #define XFS_DIR3_FT_UNKNOWN 0 #define XFS_DIR3_FT_REG_FILE 1 #define XFS_DIR3_FT_DIR 2 #define XFS_DIR3_FT_CHRDEV 3 #define XFS_DIR3_FT_BLKDEV 4 #define XFS_DIR3_FT_FIFO 5 #define XFS_DIR3_FT_SOCK 6 #define XFS_DIR3_FT_SYMLINK 7 #define XFS_DIR3_FT_WHT 8
/* * Byte offset in data block and shortform entry.
*/ typedef uint16_t xfs_dir2_data_off_t; #define NULLDATAOFF 0xffffU typedef uint xfs_dir2_data_aoff_t; /* argument form */
/* * Offset in data space of a data entry.
*/ typedef uint32_t xfs_dir2_dataptr_t; #define XFS_DIR2_MAX_DATAPTR ((xfs_dir2_dataptr_t)0xffffffff) #define XFS_DIR2_NULL_DATAPTR ((xfs_dir2_dataptr_t)0)
/* * Byte offset in a directory.
*/ typedef xfs_off_t xfs_dir2_off_t;
/* * Directory block number (logical dirblk in file)
*/ typedef uint32_t xfs_dir2_db_t;
/* * Directory layout 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 xfs_dir2_sf_hdr header followed by zero or more xfs_dir2_sf_entry * structures. Due the different inode number storage size and the variable * length name field in the xfs_dir2_sf_entry all these structure are * variable length, and the accessors in this file should be used to iterate * over them.
*/ typedefstruct xfs_dir2_sf_hdr {
uint8_t count; /* count of entries */
uint8_t i8count; /* count of 8-byte inode #s */
uint8_t parent[8]; /* parent dir inode number */
} __packed xfs_dir2_sf_hdr_t;
typedefstruct xfs_dir2_sf_entry {
__u8 namelen; /* actual name length */
__u8 offset[2]; /* saved offset */
__u8 name[]; /* name, variable size */ /* * A single byte containing the file type field follows the inode * number for version 3 directory entries. * * A 64-bit or 32-bit inode number follows here, at a variable offset * after the name.
*/
} __packed xfs_dir2_sf_entry_t;
/* * Data block structures. * * A pure data block looks like the following drawing on disk: * * +-------------------------------------------------+ * | xfs_dir2_data_hdr_t | * +-------------------------------------------------+ * | xfs_dir2_data_entry_t OR xfs_dir2_data_unused_t | * | xfs_dir2_data_entry_t OR xfs_dir2_data_unused_t | * | xfs_dir2_data_entry_t OR xfs_dir2_data_unused_t | * | ... | * +-------------------------------------------------+ * | unused space | * +-------------------------------------------------+ * * As all the entries are variable size structures the accessors below should * be used to iterate over them. * * In addition to the pure data blocks for the data and node formats, * most structures are also used for the combined data/freespace "block" * format below.
*/
/* * Describe a free area in the data block. * * The freespace will be formatted as a xfs_dir2_data_unused_t.
*/ typedefstruct xfs_dir2_data_free {
__be16 offset; /* start of freespace */
__be16 length; /* length of freespace */
} xfs_dir2_data_free_t;
/* * Header for the data blocks. * * The code knows that XFS_DIR2_DATA_FD_COUNT is 3.
*/ typedefstruct xfs_dir2_data_hdr {
__be32 magic; /* XFS_DIR2_DATA_MAGIC or */ /* XFS_DIR2_BLOCK_MAGIC */
xfs_dir2_data_free_t bestfree[XFS_DIR2_DATA_FD_COUNT];
} xfs_dir2_data_hdr_t;
/* * define a structure for all the verification fields we are adding to the * directory block structures. This will be used in several structures. * The magic number must be the first entry to align with all the dir2 * structures so we determine how to decode them just by the magic number.
*/ struct xfs_dir3_blk_hdr {
__be32 magic; /* magic number */
__be32 crc; /* CRC of block */
__be64 blkno; /* first block of the buffer */
__be64 lsn; /* sequence number of last write */
uuid_t uuid; /* filesystem we belong to */
__be64 owner; /* inode that owns the block */
};
/* * Active entry in a data block. * * Aligned to 8 bytes. After the variable length name field there is a * 2 byte tag field, which can be accessed using xfs_dir3_data_entry_tag_p. * * For dir3 structures, there is file type field between the name and the tag. * This can only be manipulated by helper functions. It is packed hard against * the end of the name so any padding for rounding is between the file type and * the tag.
*/ typedefstruct xfs_dir2_data_entry {
__be64 inumber; /* inode number */
__u8 namelen; /* name length */
__u8 name[]; /* name bytes, no null */ /* __u8 filetype; */ /* type of inode we point to */ /* __be16 tag; */ /* starting offset of us */
} xfs_dir2_data_entry_t;
/* * Unused entry in a data block. * * Aligned to 8 bytes. Tag appears as the last 2 bytes and must be accessed * using xfs_dir2_data_unused_tag_p.
*/ typedefstruct xfs_dir2_data_unused {
__be16 freetag; /* XFS_DIR2_DATA_FREE_TAG */
__be16 length; /* total free length */ /* variable offset */
__be16 tag; /* starting offset of us */
} xfs_dir2_data_unused_t;
/* * Pointer to a freespace's tag word.
*/ staticinline __be16 *
xfs_dir2_data_unused_tag_p(struct xfs_dir2_data_unused *dup)
{ return (__be16 *)((char *)dup +
be16_to_cpu(dup->length) - sizeof(__be16));
}
/* * Leaf block structures. * * A pure leaf block looks like the following drawing on disk: * * +---------------------------+ * | xfs_dir2_leaf_hdr_t | * +---------------------------+ * | xfs_dir2_leaf_entry_t | * | xfs_dir2_leaf_entry_t | * | xfs_dir2_leaf_entry_t | * | xfs_dir2_leaf_entry_t | * | ... | * +---------------------------+ * | xfs_dir2_data_off_t | * | xfs_dir2_data_off_t | * | xfs_dir2_data_off_t | * | ... | * +---------------------------+ * | xfs_dir2_leaf_tail_t | * +---------------------------+ * * The xfs_dir2_data_off_t members (bests) and tail are at the end of the block * for single-leaf (magic = XFS_DIR2_LEAF1_MAGIC) blocks only, but not present * for directories with separate leaf nodes and free space blocks * (magic = XFS_DIR2_LEAFN_MAGIC). * * As all the entries are variable size structures the accessors below should * be used to iterate over them.
*/
/* * Offset of the leaf/node space. First block in this space * is the btree root.
*/ #define XFS_DIR2_LEAF_SPACE 1 #define XFS_DIR2_LEAF_OFFSET (XFS_DIR2_LEAF_SPACE * XFS_DIR2_SPACE_SIZE)
/* * Leaf block header.
*/ typedefstruct xfs_dir2_leaf_hdr {
xfs_da_blkinfo_t info; /* header for da routines */
__be16 count; /* count of entries */
__be16 stale; /* count of stale entries */
} xfs_dir2_leaf_hdr_t;
struct xfs_dir3_leaf_hdr { struct xfs_da3_blkinfo info; /* header for da routines */
__be16 count; /* count of entries */
__be16 stale; /* count of stale entries */
__be32 pad; /* 64 bit alignment */
};
/* * Leaf block entry.
*/ typedefstruct xfs_dir2_leaf_entry {
__be32 hashval; /* hash value of name */
__be32 address; /* address of data entry */
} xfs_dir2_leaf_entry_t;
/* * Single block format. * * The single block format looks like the following drawing on disk: * * +-------------------------------------------------+ * | xfs_dir2_data_hdr_t | * +-------------------------------------------------+ * | xfs_dir2_data_entry_t OR xfs_dir2_data_unused_t | * | xfs_dir2_data_entry_t OR xfs_dir2_data_unused_t | * | xfs_dir2_data_entry_t OR xfs_dir2_data_unused_t : * | ... | * +-------------------------------------------------+ * | unused space | * +-------------------------------------------------+ * | ... | * | xfs_dir2_leaf_entry_t | * | xfs_dir2_leaf_entry_t | * +-------------------------------------------------+ * | xfs_dir2_block_tail_t | * +-------------------------------------------------+ * * As all the entries are variable size structures the accessors below should * be used to iterate over them.
*/
typedefstruct xfs_dir2_block_tail {
__be32 count; /* count of leaf entries */
__be32 stale; /* count of stale lf entries */
} xfs_dir2_block_tail_t;
/* * Pointer to the leaf entries embedded in a data block (1-block format)
*/ staticinlinestruct xfs_dir2_leaf_entry *
xfs_dir2_block_leaf_p(struct xfs_dir2_block_tail *btp)
{ return ((struct xfs_dir2_leaf_entry *)btp) - be32_to_cpu(btp->count);
}
/* * Attribute storage layout * * Attribute lists are structured around Btrees where all the data * elements are in the leaf nodes. Attribute names are hashed into an int, * then that int is used as the index into the Btree. Since the hashval * of an attribute name may not be unique, we may have duplicate keys. The * internal links in the Btree are logical block offsets into the file. * * Struct leaf_entry's are packed from the top. Name/values grow from the * bottom but are not packed. The freemap contains run-length-encoded entries * for the free bytes after the leaf_entry's, but only the N largest such, * smaller runs are dropped. When the freemap doesn't show enough space * for an allocation, we compact the name/value area and try again. If we * still don't have enough space, then we have to split the block. The * name/value structs (both local and remote versions) must be 32bit aligned. * * Since we have duplicate hash keys, for each key that matches, compare * the actual name string. The root and intermediate node search always * takes the first-in-the-block key match found, so we should only have * to work "forw"ard. If none matches, continue with the "forw"ard leaf * nodes until the hash key changes or the attribute name is found. * * We store the fact that an attribute is a ROOT/USER/SECURE attribute in * the leaf_entry. The namespaces are independent only because we also look * at the namespace bit when we are looking for a matching attribute name. * * We also store an "incomplete" bit in the leaf_entry. It shows that an * attribute is in the middle of being created and should not be shown to * the user if we crash during the time that the bit is set. We clear the * bit when we have finished setting up the attribute. We do this because * we cannot create some large attributes inside a single transaction, and we * need some indication that we weren't finished if we crash in the middle.
*/ #define XFS_ATTR_LEAF_MAPSIZE 3 /* how many freespace slots */
/* * Attribute storage when stored inside the inode. * * Small attribute lists are packed as tightly as possible so as to fit into the * literal area of the inode. * * These "shortform" attribute forks consist of a single xfs_attr_sf_hdr header * followed by zero or more xfs_attr_sf_entry structures.
*/ struct xfs_attr_sf_hdr { /* constant-structure header block */
__be16 totsize; /* total bytes in shortform list */
__u8 count; /* count of active entries */
__u8 padding;
};
struct xfs_attr_sf_entry {
__u8 namelen; /* actual length of name (no NULL) */
__u8 valuelen; /* actual length of value (no NULL) */
__u8 flags; /* flags bits (XFS_ATTR_*) */
__u8 nameval[]; /* name & value bytes concatenated */
};
typedefstruct xfs_attr_leaf_map { /* RLE map of free bytes */
__be16 base; /* base of free region */
__be16 size; /* length of free region */
} xfs_attr_leaf_map_t;
typedefstruct xfs_attr_leaf_hdr { /* constant-structure header block */
xfs_da_blkinfo_t info; /* block type, links, etc. */
__be16 count; /* count of active leaf_entry's */
__be16 usedbytes; /* num bytes of names/values stored */
__be16 firstused; /* first used byte in name area */
__u8 holes; /* != 0 if blk needs compaction */
__u8 pad1;
xfs_attr_leaf_map_t freemap[XFS_ATTR_LEAF_MAPSIZE]; /* N largest free regions */
} xfs_attr_leaf_hdr_t;
typedefstruct xfs_attr_leaf_entry { /* sorted on key, not name */
__be32 hashval; /* hash value of name */
__be16 nameidx; /* index into buffer of name/value */
__u8 flags; /* LOCAL/ROOT/SECURE/INCOMPLETE flag */
__u8 pad2; /* unused pad byte */
} xfs_attr_leaf_entry_t;
typedefstruct xfs_attr_leaf_name_local {
__be16 valuelen; /* number of bytes in value */
__u8 namelen; /* length of name bytes */ /* * In Linux 6.5 this flex array was converted from nameval[1] to * nameval[]. Be very careful here about extra padding at the end; * see xfs_attr_leaf_entsize_local() for details.
*/
__u8 nameval[]; /* name/value bytes */
} xfs_attr_leaf_name_local_t;
typedefstruct xfs_attr_leaf_name_remote {
__be32 valueblk; /* block number of value bytes */
__be32 valuelen; /* number of bytes in value */
__u8 namelen; /* length of name bytes */ /* * In Linux 6.5 this flex array was converted from name[1] to name[]. * Be very careful here about extra padding at the end; see * xfs_attr_leaf_entsize_remote() for details.
*/
__u8 name[]; /* name bytes */
} xfs_attr_leaf_name_remote_t;
typedefstruct xfs_attr_leafblock {
xfs_attr_leaf_hdr_t hdr; /* constant-structure header block */
xfs_attr_leaf_entry_t entries[]; /* sorted on key, not name */ /* * The rest of the block contains the following structures after the * leaf entries, growing from the bottom up. The variables are never * referenced and definining them can actually make gcc optimize away * accesses to the 'entries' array above index 0 so don't do that. * * xfs_attr_leaf_name_local_t namelist; * xfs_attr_leaf_name_remote_t valuelist;
*/
} xfs_attr_leafblock_t;
/* * CRC enabled leaf structures. Called "version 3" structures to match the * version number of the directory and dablk structures for this feature, and * attr2 is already taken by the variable inode attribute fork size feature.
*/ struct xfs_attr3_leaf_hdr { struct xfs_da3_blkinfo info;
__be16 count;
__be16 usedbytes;
__be16 firstused;
__u8 holes;
__u8 pad1; struct xfs_attr_leaf_map freemap[XFS_ATTR_LEAF_MAPSIZE];
__be32 pad2; /* 64 bit alignment */
};
/* * The rest of the block contains the following structures after the * leaf entries, growing from the bottom up. The variables are never * referenced, the locations accessed purely from helper functions. * * struct xfs_attr_leaf_name_local * struct xfs_attr_leaf_name_remote
*/
};
/* * Special value to represent fs block size in the leaf header firstused field. * Only used when block size overflows the 2-bytes available on disk.
*/ #define XFS_ATTR3_LEAF_NULLOFF 0
/* * Alignment for namelist and valuelist entries (since they are mixed * there can be only one alignment value)
*/ #define XFS_ATTR_LEAF_NAME_ALIGN ((uint)sizeof(xfs_dablk_t))
/* * Calculate total bytes used (including trailing pad for alignment) for * a "local" name/value structure, a "remote" name/value structure, and * a pointer which might be either.
*/ staticinlineint xfs_attr_leaf_entsize_remote(int nlen)
{ /* * Prior to Linux 6.5, struct xfs_attr_leaf_name_remote ended with * name[1], which was used as a flexarray. The layout of this struct * is 9 bytes of fixed-length fields followed by a __u8 flex array at * offset 9. * * On most architectures, struct xfs_attr_leaf_name_remote had two * bytes of implicit padding at the end of the struct to make the * struct length 12. After converting name[1] to name[], there are * three implicit padding bytes and the struct size remains 12. * However, there are compiler configurations that do not add implicit * padding at all (m68k) and have been broken for years. * * This entsize computation historically added (the xattr name length) * to (the padded struct length - 1) and rounded that sum up to the * nearest multiple of 4 (NAME_ALIGN). IOWs, round_up(11 + nlen, 4). * This is encoded in the ondisk format, so we cannot change this. * * Compute the entsize from offsetof of the flexarray and manually * adding bytes for the implicit padding.
*/ const size_t remotesize =
offsetof(struct xfs_attr_leaf_name_remote, name) + 2;
staticinlineint xfs_attr_leaf_entsize_local(int nlen, int vlen)
{ /* * Prior to Linux 6.5, struct xfs_attr_leaf_name_local ended with * nameval[1], which was used as a flexarray. The layout of this * struct is 3 bytes of fixed-length fields followed by a __u8 flex * array at offset 3. * * struct xfs_attr_leaf_name_local had zero bytes of implicit padding * at the end of the struct to make the struct length 4. On most * architectures, after converting nameval[1] to nameval[], there is * one implicit padding byte and the struct size remains 4. However, * there are compiler configurations that do not add implicit padding * at all (m68k) and would break. * * This entsize computation historically added (the xattr name and * value length) to (the padded struct length - 1) and rounded that sum * up to the nearest multiple of 4 (NAME_ALIGN). IOWs, the formula is * round_up(3 + nlen + vlen, 4). This is encoded in the ondisk format, * so we cannot change this. * * Compute the entsize from offsetof of the flexarray and manually * adding bytes for the implicit padding.
*/ const size_t localsize =
offsetof(struct xfs_attr_leaf_name_local, nameval);
/* * Remote attribute block format definition * * There is one of these headers per filesystem block in a remote attribute. * This is done to ensure there is a 1:1 mapping between the attribute value * length and the number of blocks needed to store the attribute. This makes the * verification of a buffer a little more complex, but greatly simplifies the * allocation, reading and writing of these attributes as we don't have to guess * the number of blocks needed to store the attribute data.
*/ #define XFS_ATTR3_RMT_MAGIC 0x5841524d /* XARM */
/* * Parent pointer attribute format definition * * The xattr name contains the dirent name. * The xattr value encodes the parent inode number and generation to ease * opening parents by handle. * The xattr hashval is xfs_dir2_namehash() ^ p_ino
*/ struct xfs_parent_rec {
__be64 p_ino;
__be32 p_gen;
} __packed;
#endif/* __XFS_DA_FORMAT_H__ */
Messung V0.5
¤ Dauer der Verarbeitung: 0.13 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.