192 lines · plain
1.. SPDX-License-Identifier: GPL-2.02 3Extended Attributes4-------------------5 6Extended attributes (xattrs) are typically stored in a separate data7block on the disk and referenced from inodes via ``inode.i_file_acl*``.8The first use of extended attributes seems to have been for storing file9ACLs and other security data (selinux). With the ``user_xattr`` mount10option it is possible for users to store extended attributes so long as11all attribute names begin with “user”; this restriction seems to have12disappeared as of Linux 3.0.13 14There are two places where extended attributes can be found. The first15place is between the end of each inode entry and the beginning of the16next inode entry. For example, if inode.i_extra_isize = 28 and17sb.inode_size = 256, then there are 256 - (128 + 28) = 100 bytes18available for in-inode extended attribute storage. The second place19where extended attributes can be found is in the block pointed to by20``inode.i_file_acl``. As of Linux 3.11, it is not possible for this21block to contain a pointer to a second extended attribute block (or even22the remaining blocks of a cluster). In theory it is possible for each23attribute's value to be stored in a separate data block, though as of24Linux 3.11 the code does not permit this.25 26Keys are generally assumed to be ASCIIZ strings, whereas values can be27strings or binary data.28 29Extended attributes, when stored after the inode, have a header30``ext4_xattr_ibody_header`` that is 4 bytes long:31 32.. list-table::33 :widths: 8 8 24 4034 :header-rows: 135 36 * - Offset37 - Type38 - Name39 - Description40 * - 0x041 - __le3242 - h_magic43 - Magic number for identification, 0xEA020000. This value is set by the44 Linux driver, though e2fsprogs doesn't seem to check it(?)45 46The beginning of an extended attribute block is in47``struct ext4_xattr_header``, which is 32 bytes long:48 49.. list-table::50 :widths: 8 8 24 4051 :header-rows: 152 53 * - Offset54 - Type55 - Name56 - Description57 * - 0x058 - __le3259 - h_magic60 - Magic number for identification, 0xEA020000.61 * - 0x462 - __le3263 - h_refcount64 - Reference count.65 * - 0x866 - __le3267 - h_blocks68 - Number of disk blocks used.69 * - 0xC70 - __le3271 - h_hash72 - Hash value of all attributes.73 * - 0x1074 - __le3275 - h_checksum76 - Checksum of the extended attribute block.77 * - 0x1478 - __u3279 - h_reserved[3]80 - Zero.81 82The checksum is calculated against the FS UUID, the 64-bit block number83of the extended attribute block, and the entire block (header +84entries).85 86Following the ``struct ext4_xattr_header`` or87``struct ext4_xattr_ibody_header`` is an array of88``struct ext4_xattr_entry``; each of these entries is at least 16 bytes89long. When stored in an external block, the ``struct ext4_xattr_entry``90entries must be stored in sorted order. The sort order is91``e_name_index``, then ``e_name_len``, and finally ``e_name``.92Attributes stored inside an inode do not need be stored in sorted order.93 94.. list-table::95 :widths: 8 8 24 4096 :header-rows: 197 98 * - Offset99 - Type100 - Name101 - Description102 * - 0x0103 - __u8104 - e_name_len105 - Length of name.106 * - 0x1107 - __u8108 - e_name_index109 - Attribute name index. There is a discussion of this below.110 * - 0x2111 - __le16112 - e_value_offs113 - Location of this attribute's value on the disk block where it is stored.114 Multiple attributes can share the same value. For an inode attribute115 this value is relative to the start of the first entry; for a block this116 value is relative to the start of the block (i.e. the header).117 * - 0x4118 - __le32119 - e_value_inum120 - The inode where the value is stored. Zero indicates the value is in the121 same block as this entry. This field is only used if the122 INCOMPAT_EA_INODE feature is enabled.123 * - 0x8124 - __le32125 - e_value_size126 - Length of attribute value.127 * - 0xC128 - __le32129 - e_hash130 - Hash value of attribute name and attribute value. The kernel doesn't131 update the hash for in-inode attributes, so for that case this value132 must be zero, because e2fsck validates any non-zero hash regardless of133 where the xattr lives.134 * - 0x10135 - char136 - e_name[e_name_len]137 - Attribute name. Does not include trailing NULL.138 139Attribute values can follow the end of the entry table. There appears to140be a requirement that they be aligned to 4-byte boundaries. The values141are stored starting at the end of the block and grow towards the142xattr_header/xattr_entry table. When the two collide, the overflow is143put into a separate disk block. If the disk block fills up, the144filesystem returns -ENOSPC.145 146The first four fields of the ``ext4_xattr_entry`` are set to zero to147mark the end of the key list.148 149Attribute Name Indices150~~~~~~~~~~~~~~~~~~~~~~151 152Logically speaking, extended attributes are a series of key=value pairs.153The keys are assumed to be NULL-terminated strings. To reduce the amount154of on-disk space that the keys consume, the beginning of the key string155is matched against the attribute name index. If a match is found, the156attribute name index field is set, and matching string is removed from157the key name. Here is a map of name index values to key prefixes:158 159.. list-table::160 :widths: 16 64161 :header-rows: 1162 163 * - Name Index164 - Key Prefix165 * - 0166 - (no prefix)167 * - 1168 - “user.”169 * - 2170 - “system.posix_acl_access”171 * - 3172 - “system.posix_acl_default”173 * - 4174 - “trusted.”175 * - 6176 - “security.”177 * - 7178 - “system.” (inline_data only?)179 * - 8180 - “system.richacl” (SuSE kernels only?)181 182For example, if the attribute key is “user.fubar”, the attribute name183index is set to 1 and the “fubar” name is recorded on disk.184 185POSIX ACLs186~~~~~~~~~~187 188POSIX ACLs are stored in a reduced version of the Linux kernel (and189libacl's) internal ACL format. The key difference is that the version190number is different (1) and the ``e_id`` field is only stored for named191user and group ACLs.192