xref: /linux/Documentation/filesystems/ext4/attributes.rst (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
18a98ec7cSDarrick J. Wong.. SPDX-License-Identifier: GPL-2.0
28a98ec7cSDarrick J. Wong
38a98ec7cSDarrick J. WongExtended Attributes
48a98ec7cSDarrick J. Wong-------------------
58a98ec7cSDarrick J. Wong
68a98ec7cSDarrick J. WongExtended attributes (xattrs) are typically stored in a separate data
78a98ec7cSDarrick J. Wongblock on the disk and referenced from inodes via ``inode.i_file_acl*``.
88a98ec7cSDarrick J. WongThe first use of extended attributes seems to have been for storing file
98a98ec7cSDarrick J. WongACLs and other security data (selinux). With the ``user_xattr`` mount
108a98ec7cSDarrick J. Wongoption it is possible for users to store extended attributes so long as
118a98ec7cSDarrick J. Wongall attribute names begin with “user”; this restriction seems to have
128a98ec7cSDarrick J. Wongdisappeared as of Linux 3.0.
138a98ec7cSDarrick J. Wong
148a98ec7cSDarrick J. WongThere are two places where extended attributes can be found. The first
158a98ec7cSDarrick J. Wongplace is between the end of each inode entry and the beginning of the
16*3103084aSWang Jianjiannext inode entry. For example, if inode.i_extra_isize = 28 and
17*3103084aSWang Jianjiansb.inode_size = 256, then there are 256 - (128 + 28) = 100 bytes
188a98ec7cSDarrick J. Wongavailable for in-inode extended attribute storage. The second place
198a98ec7cSDarrick J. Wongwhere extended attributes can be found is in the block pointed to by
208a98ec7cSDarrick J. Wong``inode.i_file_acl``. As of Linux 3.11, it is not possible for this
218a98ec7cSDarrick J. Wongblock to contain a pointer to a second extended attribute block (or even
228a98ec7cSDarrick J. Wongthe remaining blocks of a cluster). In theory it is possible for each
238a98ec7cSDarrick J. Wongattribute's value to be stored in a separate data block, though as of
248a98ec7cSDarrick J. WongLinux 3.11 the code does not permit this.
258a98ec7cSDarrick J. Wong
268a98ec7cSDarrick J. WongKeys are generally assumed to be ASCIIZ strings, whereas values can be
278a98ec7cSDarrick J. Wongstrings or binary data.
288a98ec7cSDarrick J. Wong
298a98ec7cSDarrick J. WongExtended attributes, when stored after the inode, have a header
308a98ec7cSDarrick J. Wong``ext4_xattr_ibody_header`` that is 4 bytes long:
318a98ec7cSDarrick J. Wong
328a98ec7cSDarrick J. Wong.. list-table::
338a98ec7cSDarrick J. Wong   :widths: 8 8 24 40
348a98ec7cSDarrick J. Wong   :header-rows: 1
358a98ec7cSDarrick J. Wong
368a98ec7cSDarrick J. Wong   * - Offset
378a98ec7cSDarrick J. Wong     - Type
388a98ec7cSDarrick J. Wong     - Name
398a98ec7cSDarrick J. Wong     - Description
408a98ec7cSDarrick J. Wong   * - 0x0
41*3103084aSWang Jianjian     - __le32
42*3103084aSWang Jianjian     - h_magic
438a98ec7cSDarrick J. Wong     - Magic number for identification, 0xEA020000. This value is set by the
448a98ec7cSDarrick J. Wong       Linux driver, though e2fsprogs doesn't seem to check it(?)
458a98ec7cSDarrick J. Wong
468a98ec7cSDarrick J. WongThe beginning of an extended attribute block is in
478a98ec7cSDarrick J. Wong``struct ext4_xattr_header``, which is 32 bytes long:
488a98ec7cSDarrick J. Wong
498a98ec7cSDarrick J. Wong.. list-table::
508a98ec7cSDarrick J. Wong   :widths: 8 8 24 40
518a98ec7cSDarrick J. Wong   :header-rows: 1
528a98ec7cSDarrick J. Wong
538a98ec7cSDarrick J. Wong   * - Offset
548a98ec7cSDarrick J. Wong     - Type
558a98ec7cSDarrick J. Wong     - Name
568a98ec7cSDarrick J. Wong     - Description
578a98ec7cSDarrick J. Wong   * - 0x0
58*3103084aSWang Jianjian     - __le32
59*3103084aSWang Jianjian     - h_magic
608a98ec7cSDarrick J. Wong     - Magic number for identification, 0xEA020000.
618a98ec7cSDarrick J. Wong   * - 0x4
62*3103084aSWang Jianjian     - __le32
63*3103084aSWang Jianjian     - h_refcount
648a98ec7cSDarrick J. Wong     - Reference count.
658a98ec7cSDarrick J. Wong   * - 0x8
66*3103084aSWang Jianjian     - __le32
67*3103084aSWang Jianjian     - h_blocks
688a98ec7cSDarrick J. Wong     - Number of disk blocks used.
698a98ec7cSDarrick J. Wong   * - 0xC
70*3103084aSWang Jianjian     - __le32
71*3103084aSWang Jianjian     - h_hash
728a98ec7cSDarrick J. Wong     - Hash value of all attributes.
738a98ec7cSDarrick J. Wong   * - 0x10
74*3103084aSWang Jianjian     - __le32
75*3103084aSWang Jianjian     - h_checksum
768a98ec7cSDarrick J. Wong     - Checksum of the extended attribute block.
778a98ec7cSDarrick J. Wong   * - 0x14
78*3103084aSWang Jianjian     - __u32
79*3103084aSWang Jianjian     - h_reserved[3]
808a98ec7cSDarrick J. Wong     - Zero.
818a98ec7cSDarrick J. Wong
828a98ec7cSDarrick J. WongThe checksum is calculated against the FS UUID, the 64-bit block number
838a98ec7cSDarrick J. Wongof the extended attribute block, and the entire block (header +
848a98ec7cSDarrick J. Wongentries).
858a98ec7cSDarrick J. Wong
868a98ec7cSDarrick J. WongFollowing the ``struct ext4_xattr_header`` or
878a98ec7cSDarrick J. Wong``struct ext4_xattr_ibody_header`` is an array of
888a98ec7cSDarrick J. Wong``struct ext4_xattr_entry``; each of these entries is at least 16 bytes
898a98ec7cSDarrick J. Wonglong. When stored in an external block, the ``struct ext4_xattr_entry``
908a98ec7cSDarrick J. Wongentries must be stored in sorted order. The sort order is
918a98ec7cSDarrick J. Wong``e_name_index``, then ``e_name_len``, and finally ``e_name``.
928a98ec7cSDarrick J. WongAttributes stored inside an inode do not need be stored in sorted order.
938a98ec7cSDarrick J. Wong
948a98ec7cSDarrick J. Wong.. list-table::
958a98ec7cSDarrick J. Wong   :widths: 8 8 24 40
968a98ec7cSDarrick J. Wong   :header-rows: 1
978a98ec7cSDarrick J. Wong
988a98ec7cSDarrick J. Wong   * - Offset
998a98ec7cSDarrick J. Wong     - Type
1008a98ec7cSDarrick J. Wong     - Name
1018a98ec7cSDarrick J. Wong     - Description
1028a98ec7cSDarrick J. Wong   * - 0x0
103*3103084aSWang Jianjian     - __u8
104*3103084aSWang Jianjian     - e_name_len
1058a98ec7cSDarrick J. Wong     - Length of name.
1068a98ec7cSDarrick J. Wong   * - 0x1
107*3103084aSWang Jianjian     - __u8
108*3103084aSWang Jianjian     - e_name_index
1098a98ec7cSDarrick J. Wong     - Attribute name index. There is a discussion of this below.
1108a98ec7cSDarrick J. Wong   * - 0x2
111*3103084aSWang Jianjian     - __le16
112*3103084aSWang Jianjian     - e_value_offs
1138a98ec7cSDarrick J. Wong     - Location of this attribute's value on the disk block where it is stored.
1148a98ec7cSDarrick J. Wong       Multiple attributes can share the same value. For an inode attribute
1158a98ec7cSDarrick J. Wong       this value is relative to the start of the first entry; for a block this
1168a98ec7cSDarrick J. Wong       value is relative to the start of the block (i.e. the header).
1178a98ec7cSDarrick J. Wong   * - 0x4
118*3103084aSWang Jianjian     - __le32
119*3103084aSWang Jianjian     - e_value_inum
1208a98ec7cSDarrick J. Wong     - The inode where the value is stored. Zero indicates the value is in the
1218a98ec7cSDarrick J. Wong       same block as this entry. This field is only used if the
122*3103084aSWang Jianjian       INCOMPAT_EA_INODE feature is enabled.
1238a98ec7cSDarrick J. Wong   * - 0x8
124*3103084aSWang Jianjian     - __le32
125*3103084aSWang Jianjian     - e_value_size
1268a98ec7cSDarrick J. Wong     - Length of attribute value.
1278a98ec7cSDarrick J. Wong   * - 0xC
128*3103084aSWang Jianjian     - __le32
129*3103084aSWang Jianjian     - e_hash
1308a98ec7cSDarrick J. Wong     - Hash value of attribute name and attribute value. The kernel doesn't
1318a98ec7cSDarrick J. Wong       update the hash for in-inode attributes, so for that case this value
1328a98ec7cSDarrick J. Wong       must be zero, because e2fsck validates any non-zero hash regardless of
1338a98ec7cSDarrick J. Wong       where the xattr lives.
1348a98ec7cSDarrick J. Wong   * - 0x10
1358a98ec7cSDarrick J. Wong     - char
136*3103084aSWang Jianjian     - e_name[e_name_len]
1378a98ec7cSDarrick J. Wong     - Attribute name. Does not include trailing NULL.
1388a98ec7cSDarrick J. Wong
1398a98ec7cSDarrick J. WongAttribute values can follow the end of the entry table. There appears to
1408a98ec7cSDarrick J. Wongbe a requirement that they be aligned to 4-byte boundaries. The values
1418a98ec7cSDarrick J. Wongare stored starting at the end of the block and grow towards the
142*3103084aSWang Jianjianxattr_header/xattr_entry table. When the two collide, the overflow is
1438a98ec7cSDarrick J. Wongput into a separate disk block. If the disk block fills up, the
1448a98ec7cSDarrick J. Wongfilesystem returns -ENOSPC.
1458a98ec7cSDarrick J. Wong
1468a98ec7cSDarrick J. WongThe first four fields of the ``ext4_xattr_entry`` are set to zero to
1478a98ec7cSDarrick J. Wongmark the end of the key list.
1488a98ec7cSDarrick J. Wong
1498a98ec7cSDarrick J. WongAttribute Name Indices
1508a98ec7cSDarrick J. Wong~~~~~~~~~~~~~~~~~~~~~~
1518a98ec7cSDarrick J. Wong
1528a98ec7cSDarrick J. WongLogically speaking, extended attributes are a series of key=value pairs.
1538a98ec7cSDarrick J. WongThe keys are assumed to be NULL-terminated strings. To reduce the amount
1548a98ec7cSDarrick J. Wongof on-disk space that the keys consume, the beginning of the key string
1558a98ec7cSDarrick J. Wongis matched against the attribute name index. If a match is found, the
1568a98ec7cSDarrick J. Wongattribute name index field is set, and matching string is removed from
1578a98ec7cSDarrick J. Wongthe key name. Here is a map of name index values to key prefixes:
1588a98ec7cSDarrick J. Wong
1598a98ec7cSDarrick J. Wong.. list-table::
1608a98ec7cSDarrick J. Wong   :widths: 16 64
1618a98ec7cSDarrick J. Wong   :header-rows: 1
1628a98ec7cSDarrick J. Wong
1638a98ec7cSDarrick J. Wong   * - Name Index
1648a98ec7cSDarrick J. Wong     - Key Prefix
1658a98ec7cSDarrick J. Wong   * - 0
1668a98ec7cSDarrick J. Wong     - (no prefix)
1678a98ec7cSDarrick J. Wong   * - 1
1688a98ec7cSDarrick J. Wong     - “user.”
1698a98ec7cSDarrick J. Wong   * - 2
170*3103084aSWang Jianjian     - “system.posix_acl_access1718a98ec7cSDarrick J. Wong   * - 3
172*3103084aSWang Jianjian     - “system.posix_acl_default1738a98ec7cSDarrick J. Wong   * - 4
1748a98ec7cSDarrick J. Wong     - “trusted.”
1758a98ec7cSDarrick J. Wong   * - 6
1768a98ec7cSDarrick J. Wong     - “security.”
1778a98ec7cSDarrick J. Wong   * - 7
178*3103084aSWang Jianjian     - “system.” (inline_data only?)
1798a98ec7cSDarrick J. Wong   * - 8
1808a98ec7cSDarrick J. Wong     - “system.richacl” (SuSE kernels only?)
1818a98ec7cSDarrick J. Wong
1828a98ec7cSDarrick J. WongFor example, if the attribute key is “user.fubar”, the attribute name
1838a98ec7cSDarrick J. Wongindex is set to 1 and the “fubar” name is recorded on disk.
1848a98ec7cSDarrick J. Wong
1858a98ec7cSDarrick J. WongPOSIX ACLs
1868a98ec7cSDarrick J. Wong~~~~~~~~~~
1878a98ec7cSDarrick J. Wong
1888a98ec7cSDarrick J. WongPOSIX ACLs are stored in a reduced version of the Linux kernel (and
1898a98ec7cSDarrick J. Wonglibacl's) internal ACL format. The key difference is that the version
1908a98ec7cSDarrick J. Wongnumber is different (1) and the ``e_id`` field is only stored for named
1918a98ec7cSDarrick J. Wonguser and group ACLs.
192