/* 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 … #define XFS_ATTR_LEAF_MAGIC … #define XFS_DIR2_LEAF1_MAGIC … #define XFS_DIR2_LEAFN_MAGIC … 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 … #define XFS_ATTR3_LEAF_MAGIC … #define XFS_DIR3_LEAF1_MAGIC … #define XFS_DIR3_LEAFN_MAGIC … struct xfs_da3_blkinfo { … }; /* * 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 … xfs_da_node_hdr_t; struct xfs_da3_node_hdr { … }; #define XFS_DA3_NODE_CRC_OFF … xfs_da_node_entry_t; xfs_da_intnode_t; struct xfs_da3_intnode { … }; /* * 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. */ #define XFS_DIR2_BLOCK_MAGIC … #define XFS_DIR2_DATA_MAGIC … #define XFS_DIR2_FREE_MAGIC … /* * 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. */ #define XFS_DIR3_BLOCK_MAGIC … #define XFS_DIR3_DATA_MAGIC … #define XFS_DIR3_FREE_MAGIC … /* * 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 … #define XFS_DIR3_FT_REG_FILE … #define XFS_DIR3_FT_DIR … #define XFS_DIR3_FT_CHRDEV … #define XFS_DIR3_FT_BLKDEV … #define XFS_DIR3_FT_FIFO … #define XFS_DIR3_FT_SOCK … #define XFS_DIR3_FT_SYMLINK … #define XFS_DIR3_FT_WHT … #define XFS_DIR3_FT_MAX … #define XFS_DIR3_FTYPE_STR … /* * Byte offset in data block and shortform entry. */ xfs_dir2_data_off_t; #define NULLDATAOFF … xfs_dir2_data_aoff_t; /* argument form */ /* * Offset in data space of a data entry. */ xfs_dir2_dataptr_t; #define XFS_DIR2_MAX_DATAPTR … #define XFS_DIR2_NULL_DATAPTR … /* * Byte offset in a directory. */ xfs_dir2_off_t; /* * Directory block number (logical dirblk in file) */ xfs_dir2_db_t; #define XFS_INO32_SIZE … #define XFS_INO64_SIZE … #define XFS_INO64_DIFF … #define XFS_DIR2_MAX_SHORT_INUM … /* * 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. */ xfs_dir2_sf_hdr_t; xfs_dir2_sf_entry_t; static inline int xfs_dir2_sf_hdr_size(int i8count) { … } static inline xfs_dir2_data_aoff_t xfs_dir2_sf_get_offset(xfs_dir2_sf_entry_t *sfep) { … } static inline void xfs_dir2_sf_put_offset(xfs_dir2_sf_entry_t *sfep, xfs_dir2_data_aoff_t off) { … } static inline struct xfs_dir2_sf_entry * xfs_dir2_sf_firstentry(struct xfs_dir2_sf_hdr *hdr) { … } /* * 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. */ #define XFS_DIR2_DATA_ALIGN_LOG … #define XFS_DIR2_DATA_ALIGN … #define XFS_DIR2_DATA_FREE_TAG … #define XFS_DIR2_DATA_FD_COUNT … /* * Directory address space divided into sections, * spaces separated by 32GB. */ #define XFS_DIR2_MAX_SPACES … #define XFS_DIR2_SPACE_SIZE … #define XFS_DIR2_DATA_SPACE … #define XFS_DIR2_DATA_OFFSET … /* * Describe a free area in the data block. * * The freespace will be formatted as a xfs_dir2_data_unused_t. */ xfs_dir2_data_free_t; /* * Header for the data blocks. * * The code knows that XFS_DIR2_DATA_FD_COUNT is 3. */ 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 { … }; struct xfs_dir3_data_hdr { … }; #define XFS_DIR3_DATA_CRC_OFF … /* * 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. */ 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. */ xfs_dir2_data_unused_t; /* * Pointer to a freespace's tag word. */ static inline __be16 * xfs_dir2_data_unused_tag_p(struct xfs_dir2_data_unused *dup) { … } /* * 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 … #define XFS_DIR2_LEAF_OFFSET … /* * Leaf block header. */ xfs_dir2_leaf_hdr_t; struct xfs_dir3_leaf_hdr { … }; /* * Leaf block entry. */ xfs_dir2_leaf_entry_t; /* * Leaf block tail. */ xfs_dir2_leaf_tail_t; /* * Leaf block. */ xfs_dir2_leaf_t; struct xfs_dir3_leaf { … }; #define XFS_DIR3_LEAF_CRC_OFF … /* * Get address of the bests array in the single-leaf block. */ static inline __be16 * xfs_dir2_leaf_bests_p(struct xfs_dir2_leaf_tail *ltp) { … } /* * Free space block definitions for the node format. */ /* * Offset of the freespace index. */ #define XFS_DIR2_FREE_SPACE … #define XFS_DIR2_FREE_OFFSET … xfs_dir2_free_hdr_t; xfs_dir2_free_t; struct xfs_dir3_free_hdr { … }; struct xfs_dir3_free { … }; #define XFS_DIR3_FREE_CRC_OFF … /* * 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. */ xfs_dir2_block_tail_t; /* * Pointer to the leaf entries embedded in a data block (1-block format) */ static inline struct xfs_dir2_leaf_entry * xfs_dir2_block_leaf_p(struct xfs_dir2_block_tail *btp) { … } /* * 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 … /* * 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 { … }; struct xfs_attr_sf_entry { … }; xfs_attr_leaf_map_t; xfs_attr_leaf_hdr_t; xfs_attr_leaf_entry_t; xfs_attr_leaf_name_local_t; xfs_attr_leaf_name_remote_t; 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 { … }; #define XFS_ATTR3_LEAF_CRC_OFF … struct xfs_attr3_leafblock { … }; /* * 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 … /* * Flags used in the leaf_entry[i].flags field. */ #define XFS_ATTR_LOCAL_BIT … #define XFS_ATTR_ROOT_BIT … #define XFS_ATTR_SECURE_BIT … #define XFS_ATTR_PARENT_BIT … #define XFS_ATTR_INCOMPLETE_BIT … #define XFS_ATTR_LOCAL … #define XFS_ATTR_ROOT … #define XFS_ATTR_SECURE … #define XFS_ATTR_PARENT … #define XFS_ATTR_INCOMPLETE … #define XFS_ATTR_NSP_ONDISK_MASK … /* Private attr namespaces not exposed to userspace */ #define XFS_ATTR_PRIVATE_NSP_MASK … #define XFS_ATTR_ONDISK_MASK … #define XFS_ATTR_NAMESPACE_STR … /* * Alignment for namelist and valuelist entries (since they are mixed * there can be only one alignment value) */ #define XFS_ATTR_LEAF_NAME_ALIGN … static inline int xfs_attr3_leaf_hdr_size(struct xfs_attr_leafblock *leafp) { … } static inline struct xfs_attr_leaf_entry * xfs_attr3_leaf_entryp(xfs_attr_leafblock_t *leafp) { … } /* * Cast typed pointers for "local" and "remote" name/value structs. */ static inline char * xfs_attr3_leaf_name(xfs_attr_leafblock_t *leafp, int idx) { … } static inline xfs_attr_leaf_name_remote_t * xfs_attr3_leaf_name_remote(xfs_attr_leafblock_t *leafp, int idx) { … } static inline xfs_attr_leaf_name_local_t * xfs_attr3_leaf_name_local(xfs_attr_leafblock_t *leafp, int idx) { … } /* * 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. */ static inline int xfs_attr_leaf_entsize_remote(int nlen) { … } static inline int xfs_attr_leaf_entsize_local(int nlen, int vlen) { … } static inline int xfs_attr_leaf_entsize_local_max(int bsize) { … } /* * 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 … struct xfs_attr3_rmt_hdr { … }; #define XFS_ATTR3_RMT_CRC_OFF … unsigned int xfs_attr3_rmt_buf_space(struct xfs_mount *mp); /* Number of bytes in a directory block. */ static inline unsigned int xfs_dir2_dirblock_bytes(struct xfs_sb *sbp) { … } xfs_failaddr_t xfs_da3_blkinfo_verify(struct xfs_buf *bp, struct xfs_da3_blkinfo *hdr3); /* * 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 { … } __packed; #endif /* __XFS_DA_FORMAT_H__ */