xref: /OK3568_Linux_fs/kernel/Documentation/filesystems/ext4/attributes.rst (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun.. SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun
3*4882a593SmuzhiyunExtended Attributes
4*4882a593Smuzhiyun-------------------
5*4882a593Smuzhiyun
6*4882a593SmuzhiyunExtended attributes (xattrs) are typically stored in a separate data
7*4882a593Smuzhiyunblock on the disk and referenced from inodes via ``inode.i_file_acl*``.
8*4882a593SmuzhiyunThe first use of extended attributes seems to have been for storing file
9*4882a593SmuzhiyunACLs and other security data (selinux). With the ``user_xattr`` mount
10*4882a593Smuzhiyunoption it is possible for users to store extended attributes so long as
11*4882a593Smuzhiyunall attribute names begin with “user”; this restriction seems to have
12*4882a593Smuzhiyundisappeared as of Linux 3.0.
13*4882a593Smuzhiyun
14*4882a593SmuzhiyunThere are two places where extended attributes can be found. The first
15*4882a593Smuzhiyunplace is between the end of each inode entry and the beginning of the
16*4882a593Smuzhiyunnext inode entry. For example, if inode.i\_extra\_isize = 28 and
17*4882a593Smuzhiyunsb.inode\_size = 256, then there are 256 - (128 + 28) = 100 bytes
18*4882a593Smuzhiyunavailable for in-inode extended attribute storage. The second place
19*4882a593Smuzhiyunwhere extended attributes can be found is in the block pointed to by
20*4882a593Smuzhiyun``inode.i_file_acl``. As of Linux 3.11, it is not possible for this
21*4882a593Smuzhiyunblock to contain a pointer to a second extended attribute block (or even
22*4882a593Smuzhiyunthe remaining blocks of a cluster). In theory it is possible for each
23*4882a593Smuzhiyunattribute's value to be stored in a separate data block, though as of
24*4882a593SmuzhiyunLinux 3.11 the code does not permit this.
25*4882a593Smuzhiyun
26*4882a593SmuzhiyunKeys are generally assumed to be ASCIIZ strings, whereas values can be
27*4882a593Smuzhiyunstrings or binary data.
28*4882a593Smuzhiyun
29*4882a593SmuzhiyunExtended attributes, when stored after the inode, have a header
30*4882a593Smuzhiyun``ext4_xattr_ibody_header`` that is 4 bytes long:
31*4882a593Smuzhiyun
32*4882a593Smuzhiyun.. list-table::
33*4882a593Smuzhiyun   :widths: 8 8 24 40
34*4882a593Smuzhiyun   :header-rows: 1
35*4882a593Smuzhiyun
36*4882a593Smuzhiyun   * - Offset
37*4882a593Smuzhiyun     - Type
38*4882a593Smuzhiyun     - Name
39*4882a593Smuzhiyun     - Description
40*4882a593Smuzhiyun   * - 0x0
41*4882a593Smuzhiyun     - \_\_le32
42*4882a593Smuzhiyun     - h\_magic
43*4882a593Smuzhiyun     - Magic number for identification, 0xEA020000. This value is set by the
44*4882a593Smuzhiyun       Linux driver, though e2fsprogs doesn't seem to check it(?)
45*4882a593Smuzhiyun
46*4882a593SmuzhiyunThe beginning of an extended attribute block is in
47*4882a593Smuzhiyun``struct ext4_xattr_header``, which is 32 bytes long:
48*4882a593Smuzhiyun
49*4882a593Smuzhiyun.. list-table::
50*4882a593Smuzhiyun   :widths: 8 8 24 40
51*4882a593Smuzhiyun   :header-rows: 1
52*4882a593Smuzhiyun
53*4882a593Smuzhiyun   * - Offset
54*4882a593Smuzhiyun     - Type
55*4882a593Smuzhiyun     - Name
56*4882a593Smuzhiyun     - Description
57*4882a593Smuzhiyun   * - 0x0
58*4882a593Smuzhiyun     - \_\_le32
59*4882a593Smuzhiyun     - h\_magic
60*4882a593Smuzhiyun     - Magic number for identification, 0xEA020000.
61*4882a593Smuzhiyun   * - 0x4
62*4882a593Smuzhiyun     - \_\_le32
63*4882a593Smuzhiyun     - h\_refcount
64*4882a593Smuzhiyun     - Reference count.
65*4882a593Smuzhiyun   * - 0x8
66*4882a593Smuzhiyun     - \_\_le32
67*4882a593Smuzhiyun     - h\_blocks
68*4882a593Smuzhiyun     - Number of disk blocks used.
69*4882a593Smuzhiyun   * - 0xC
70*4882a593Smuzhiyun     - \_\_le32
71*4882a593Smuzhiyun     - h\_hash
72*4882a593Smuzhiyun     - Hash value of all attributes.
73*4882a593Smuzhiyun   * - 0x10
74*4882a593Smuzhiyun     - \_\_le32
75*4882a593Smuzhiyun     - h\_checksum
76*4882a593Smuzhiyun     - Checksum of the extended attribute block.
77*4882a593Smuzhiyun   * - 0x14
78*4882a593Smuzhiyun     - \_\_u32
79*4882a593Smuzhiyun     - h\_reserved[3]
80*4882a593Smuzhiyun     - Zero.
81*4882a593Smuzhiyun
82*4882a593SmuzhiyunThe checksum is calculated against the FS UUID, the 64-bit block number
83*4882a593Smuzhiyunof the extended attribute block, and the entire block (header +
84*4882a593Smuzhiyunentries).
85*4882a593Smuzhiyun
86*4882a593SmuzhiyunFollowing the ``struct ext4_xattr_header`` or
87*4882a593Smuzhiyun``struct ext4_xattr_ibody_header`` is an array of
88*4882a593Smuzhiyun``struct ext4_xattr_entry``; each of these entries is at least 16 bytes
89*4882a593Smuzhiyunlong. When stored in an external block, the ``struct ext4_xattr_entry``
90*4882a593Smuzhiyunentries must be stored in sorted order. The sort order is
91*4882a593Smuzhiyun``e_name_index``, then ``e_name_len``, and finally ``e_name``.
92*4882a593SmuzhiyunAttributes stored inside an inode do not need be stored in sorted order.
93*4882a593Smuzhiyun
94*4882a593Smuzhiyun.. list-table::
95*4882a593Smuzhiyun   :widths: 8 8 24 40
96*4882a593Smuzhiyun   :header-rows: 1
97*4882a593Smuzhiyun
98*4882a593Smuzhiyun   * - Offset
99*4882a593Smuzhiyun     - Type
100*4882a593Smuzhiyun     - Name
101*4882a593Smuzhiyun     - Description
102*4882a593Smuzhiyun   * - 0x0
103*4882a593Smuzhiyun     - \_\_u8
104*4882a593Smuzhiyun     - e\_name\_len
105*4882a593Smuzhiyun     - Length of name.
106*4882a593Smuzhiyun   * - 0x1
107*4882a593Smuzhiyun     - \_\_u8
108*4882a593Smuzhiyun     - e\_name\_index
109*4882a593Smuzhiyun     - Attribute name index. There is a discussion of this below.
110*4882a593Smuzhiyun   * - 0x2
111*4882a593Smuzhiyun     - \_\_le16
112*4882a593Smuzhiyun     - e\_value\_offs
113*4882a593Smuzhiyun     - Location of this attribute's value on the disk block where it is stored.
114*4882a593Smuzhiyun       Multiple attributes can share the same value. For an inode attribute
115*4882a593Smuzhiyun       this value is relative to the start of the first entry; for a block this
116*4882a593Smuzhiyun       value is relative to the start of the block (i.e. the header).
117*4882a593Smuzhiyun   * - 0x4
118*4882a593Smuzhiyun     - \_\_le32
119*4882a593Smuzhiyun     - e\_value\_inum
120*4882a593Smuzhiyun     - The inode where the value is stored. Zero indicates the value is in the
121*4882a593Smuzhiyun       same block as this entry. This field is only used if the
122*4882a593Smuzhiyun       INCOMPAT\_EA\_INODE feature is enabled.
123*4882a593Smuzhiyun   * - 0x8
124*4882a593Smuzhiyun     - \_\_le32
125*4882a593Smuzhiyun     - e\_value\_size
126*4882a593Smuzhiyun     - Length of attribute value.
127*4882a593Smuzhiyun   * - 0xC
128*4882a593Smuzhiyun     - \_\_le32
129*4882a593Smuzhiyun     - e\_hash
130*4882a593Smuzhiyun     - Hash value of attribute name and attribute value. The kernel doesn't
131*4882a593Smuzhiyun       update the hash for in-inode attributes, so for that case this value
132*4882a593Smuzhiyun       must be zero, because e2fsck validates any non-zero hash regardless of
133*4882a593Smuzhiyun       where the xattr lives.
134*4882a593Smuzhiyun   * - 0x10
135*4882a593Smuzhiyun     - char
136*4882a593Smuzhiyun     - e\_name[e\_name\_len]
137*4882a593Smuzhiyun     - Attribute name. Does not include trailing NULL.
138*4882a593Smuzhiyun
139*4882a593SmuzhiyunAttribute values can follow the end of the entry table. There appears to
140*4882a593Smuzhiyunbe a requirement that they be aligned to 4-byte boundaries. The values
141*4882a593Smuzhiyunare stored starting at the end of the block and grow towards the
142*4882a593Smuzhiyunxattr\_header/xattr\_entry table. When the two collide, the overflow is
143*4882a593Smuzhiyunput into a separate disk block. If the disk block fills up, the
144*4882a593Smuzhiyunfilesystem returns -ENOSPC.
145*4882a593Smuzhiyun
146*4882a593SmuzhiyunThe first four fields of the ``ext4_xattr_entry`` are set to zero to
147*4882a593Smuzhiyunmark the end of the key list.
148*4882a593Smuzhiyun
149*4882a593SmuzhiyunAttribute Name Indices
150*4882a593Smuzhiyun~~~~~~~~~~~~~~~~~~~~~~
151*4882a593Smuzhiyun
152*4882a593SmuzhiyunLogically speaking, extended attributes are a series of key=value pairs.
153*4882a593SmuzhiyunThe keys are assumed to be NULL-terminated strings. To reduce the amount
154*4882a593Smuzhiyunof on-disk space that the keys consume, the beginning of the key string
155*4882a593Smuzhiyunis matched against the attribute name index. If a match is found, the
156*4882a593Smuzhiyunattribute name index field is set, and matching string is removed from
157*4882a593Smuzhiyunthe key name. Here is a map of name index values to key prefixes:
158*4882a593Smuzhiyun
159*4882a593Smuzhiyun.. list-table::
160*4882a593Smuzhiyun   :widths: 16 64
161*4882a593Smuzhiyun   :header-rows: 1
162*4882a593Smuzhiyun
163*4882a593Smuzhiyun   * - Name Index
164*4882a593Smuzhiyun     - Key Prefix
165*4882a593Smuzhiyun   * - 0
166*4882a593Smuzhiyun     - (no prefix)
167*4882a593Smuzhiyun   * - 1
168*4882a593Smuzhiyun     - “user.”
169*4882a593Smuzhiyun   * - 2
170*4882a593Smuzhiyun     - “system.posix\_acl\_access”
171*4882a593Smuzhiyun   * - 3
172*4882a593Smuzhiyun     - “system.posix\_acl\_default”
173*4882a593Smuzhiyun   * - 4
174*4882a593Smuzhiyun     - “trusted.”
175*4882a593Smuzhiyun   * - 6
176*4882a593Smuzhiyun     - “security.”
177*4882a593Smuzhiyun   * - 7
178*4882a593Smuzhiyun     - “system.” (inline\_data only?)
179*4882a593Smuzhiyun   * - 8
180*4882a593Smuzhiyun     - “system.richacl” (SuSE kernels only?)
181*4882a593Smuzhiyun
182*4882a593SmuzhiyunFor example, if the attribute key is “user.fubar”, the attribute name
183*4882a593Smuzhiyunindex is set to 1 and the “fubar” name is recorded on disk.
184*4882a593Smuzhiyun
185*4882a593SmuzhiyunPOSIX ACLs
186*4882a593Smuzhiyun~~~~~~~~~~
187*4882a593Smuzhiyun
188*4882a593SmuzhiyunPOSIX ACLs are stored in a reduced version of the Linux kernel (and
189*4882a593Smuzhiyunlibacl's) internal ACL format. The key difference is that the version
190*4882a593Smuzhiyunnumber is different (1) and the ``e_id`` field is only stored for named
191*4882a593Smuzhiyunuser and group ACLs.
192