add patch improve-code-readability-in-ext4_iget
[ext4-patch-queue.git] / import-extended-attributes-chapter-from-wiki-page
blobae77c2fb621ab1aded81db898c511c0b9178baf7
1 ext4: import extended attributes chapter from wiki page
3 From: Darrick J. Wong <darrick.wong@oracle.com>
5 Import the chapter about extended attributes from the on-disk format wiki
6 page into the kernel documentation.
8 Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
9 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
10 ---
11  .../filesystems/ext4/ondisk/attributes.rst         |  191 ++++++++++++++++++++
12  Documentation/filesystems/ext4/ondisk/dynamic.rst  |    1 
13  2 files changed, 192 insertions(+)
14  create mode 100644 Documentation/filesystems/ext4/ondisk/attributes.rst
17 diff --git a/Documentation/filesystems/ext4/ondisk/attributes.rst b/Documentation/filesystems/ext4/ondisk/attributes.rst
18 new file mode 100644
19 index 000000000000..0b01b67b81fe
20 --- /dev/null
21 +++ b/Documentation/filesystems/ext4/ondisk/attributes.rst
22 @@ -0,0 +1,191 @@
23 +.. SPDX-License-Identifier: GPL-2.0
25 +Extended Attributes
26 +-------------------
28 +Extended attributes (xattrs) are typically stored in a separate data
29 +block on the disk and referenced from inodes via ``inode.i_file_acl*``.
30 +The first use of extended attributes seems to have been for storing file
31 +ACLs and other security data (selinux). With the ``user_xattr`` mount
32 +option it is possible for users to store extended attributes so long as
33 +all attribute names begin with “user”; this restriction seems to have
34 +disappeared as of Linux 3.0.
36 +There are two places where extended attributes can be found. The first
37 +place is between the end of each inode entry and the beginning of the
38 +next inode entry. For example, if inode.i\_extra\_isize = 28 and
39 +sb.inode\_size = 256, then there are 256 - (128 + 28) = 100 bytes
40 +available for in-inode extended attribute storage. The second place
41 +where extended attributes can be found is in the block pointed to by
42 +``inode.i_file_acl``. As of Linux 3.11, it is not possible for this
43 +block to contain a pointer to a second extended attribute block (or even
44 +the remaining blocks of a cluster). In theory it is possible for each
45 +attribute's value to be stored in a separate data block, though as of
46 +Linux 3.11 the code does not permit this.
48 +Keys are generally assumed to be ASCIIZ strings, whereas values can be
49 +strings or binary data.
51 +Extended attributes, when stored after the inode, have a header
52 +``ext4_xattr_ibody_header`` that is 4 bytes long:
54 +.. list-table::
55 +   :widths: 1 1 1 77
56 +   :header-rows: 1
58 +   * - Offset
59 +     - Type
60 +     - Name
61 +     - Description
62 +   * - 0x0
63 +     - \_\_le32
64 +     - h\_magic
65 +     - Magic number for identification, 0xEA020000. This value is set by the
66 +       Linux driver, though e2fsprogs doesn't seem to check it(?)
68 +The beginning of an extended attribute block is in
69 +``struct ext4_xattr_header``, which is 32 bytes long:
71 +.. list-table::
72 +   :widths: 1 1 1 77
73 +   :header-rows: 1
75 +   * - Offset
76 +     - Type
77 +     - Name
78 +     - Description
79 +   * - 0x0
80 +     - \_\_le32
81 +     - h\_magic
82 +     - Magic number for identification, 0xEA020000.
83 +   * - 0x4
84 +     - \_\_le32
85 +     - h\_refcount
86 +     - Reference count.
87 +   * - 0x8
88 +     - \_\_le32
89 +     - h\_blocks
90 +     - Number of disk blocks used.
91 +   * - 0xC
92 +     - \_\_le32
93 +     - h\_hash
94 +     - Hash value of all attributes.
95 +   * - 0x10
96 +     - \_\_le32
97 +     - h\_checksum
98 +     - Checksum of the extended attribute block.
99 +   * - 0x14
100 +     - \_\_u32
101 +     - h\_reserved[2]
102 +     - Zero.
104 +The checksum is calculated against the FS UUID, the 64-bit block number
105 +of the extended attribute block, and the entire block (header +
106 +entries).
108 +Following the ``struct ext4_xattr_header`` or
109 +``struct ext4_xattr_ibody_header`` is an array of
110 +``struct ext4_xattr_entry``; each of these entries is at least 16 bytes
111 +long. When stored in an external block, the ``struct ext4_xattr_entry``
112 +entries must be stored in sorted order. The sort order is
113 +``e_name_index``, then ``e_name_len``, and finally ``e_name``.
114 +Attributes stored inside an inode do not need be stored in sorted order.
116 +.. list-table::
117 +   :widths: 1 1 1 77
118 +   :header-rows: 1
120 +   * - Offset
121 +     - Type
122 +     - Name
123 +     - Description
124 +   * - 0x0
125 +     - \_\_u8
126 +     - e\_name\_len
127 +     - Length of name.
128 +   * - 0x1
129 +     - \_\_u8
130 +     - e\_name\_index
131 +     - Attribute name index. There is a discussion of this below.
132 +   * - 0x2
133 +     - \_\_le16
134 +     - e\_value\_offs
135 +     - Location of this attribute's value on the disk block where it is stored.
136 +       Multiple attributes can share the same value. For an inode attribute
137 +       this value is relative to the start of the first entry; for a block this
138 +       value is relative to the start of the block (i.e. the header).
139 +   * - 0x4
140 +     - \_\_le32
141 +     - e\_value\_inum
142 +     - The inode where the value is stored. Zero indicates the value is in the
143 +       same block as this entry. This field is only used if the
144 +       INCOMPAT\_EA\_INODE feature is enabled.
145 +   * - 0x8
146 +     - \_\_le32
147 +     - e\_value\_size
148 +     - Length of attribute value.
149 +   * - 0xC
150 +     - \_\_le32
151 +     - e\_hash
152 +     - Hash value of attribute name and attribute value. The kernel doesn't
153 +       update the hash for in-inode attributes, so for that case this value
154 +       must be zero, because e2fsck validates any non-zero hash regardless of
155 +       where the xattr lives.
156 +   * - 0x10
157 +     - char
158 +     - e\_name[e\_name\_len]
159 +     - Attribute name. Does not include trailing NULL.
161 +Attribute values can follow the end of the entry table. There appears to
162 +be a requirement that they be aligned to 4-byte boundaries. The values
163 +are stored starting at the end of the block and grow towards the
164 +xattr\_header/xattr\_entry table. When the two collide, the overflow is
165 +put into a separate disk block. If the disk block fills up, the
166 +filesystem returns -ENOSPC.
168 +The first four fields of the ``ext4_xattr_entry`` are set to zero to
169 +mark the end of the key list.
171 +Attribute Name Indices
172 +~~~~~~~~~~~~~~~~~~~~~~
174 +Logically speaking, extended attributes are a series of key=value pairs.
175 +The keys are assumed to be NULL-terminated strings. To reduce the amount
176 +of on-disk space that the keys consume, the beginning of the key string
177 +is matched against the attribute name index. If a match is found, the
178 +attribute name index field is set, and matching string is removed from
179 +the key name. Here is a map of name index values to key prefixes:
181 +.. list-table::
182 +   :widths: 1 79
183 +   :header-rows: 1
185 +   * - Name Index
186 +     - Key Prefix
187 +   * - 0
188 +     - (no prefix)
189 +   * - 1
190 +     - “user.”
191 +   * - 2
192 +     - “system.posix\_acl\_access”
193 +   * - 3
194 +     - “system.posix\_acl\_default”
195 +   * - 4
196 +     - “trusted.”
197 +   * - 6
198 +     - “security.”
199 +   * - 7
200 +     - “system.” (inline\_data only?)
201 +   * - 8
202 +     - “system.richacl” (SuSE kernels only?)
204 +For example, if the attribute key is “user.fubar”, the attribute name
205 +index is set to 1 and the “fubar” name is recorded on disk.
207 +POSIX ACLs
208 +~~~~~~~~~~
210 +POSIX ACLs are stored in a reduced version of the Linux kernel (and
211 +libacl's) internal ACL format. The key difference is that the version
212 +number is different (1) and the ``e_id`` field is only stored for named
213 +user and group ACLs.
214 diff --git a/Documentation/filesystems/ext4/ondisk/dynamic.rst b/Documentation/filesystems/ext4/ondisk/dynamic.rst
215 index f2f14822b0f5..bb0c84333341 100644
216 --- a/Documentation/filesystems/ext4/ondisk/dynamic.rst
217 +++ b/Documentation/filesystems/ext4/ondisk/dynamic.rst
218 @@ -9,3 +9,4 @@ allocated to files.
219  .. include:: inodes.rst
220  .. include:: ifork.rst
221  .. include:: directory.rst
222 +.. include:: attributes.rst