]>
Commit | Line | Data |
---|---|---|
2cb7cef9 BS |
1 | From: Tao Ma <tao.ma@oracle.com> |
2 | Subject: [PATCH 05/16] Add the basic xattr disk layout in ocfs2_fs.h | |
3 | Patch-mainline: 2.6.28? | |
4 | References: FATE302067 | |
5 | ||
6 | Ocfs2 uses a very flexible structure for storing extended attributes on | |
7 | disk. Small amount of attributes are stored directly in the inode block - up | |
8 | to 256 bytes worth. If that fills up, attributes are also stored in an | |
9 | external block, linked to from the inode block. That block can in turn | |
10 | expand to a btree, capable of storing large numbers of attributes. | |
11 | ||
12 | Individual attribute values are stored inline if they're small enough | |
13 | (currently about 80 bytes, this can be changed though), and otherwise are | |
14 | expanded to a btree. The theoretical limit to the size of an individual | |
15 | attribute is about the same as an inode, though the kernel's upper bound on | |
16 | the size of an attributes data is far smaller. | |
17 | ||
18 | Signed-off-by: Tao Ma <tao.ma@oracle.com> | |
19 | Signed-off-by: Mark Fasheh <mfasheh@suse.com> | |
20 | --- | |
21 | fs/ocfs2/ocfs2_fs.h | 118 +++++++++++++++++++++++++++++++++++++++++++++++++++ | |
22 | 1 files changed, 118 insertions(+), 0 deletions(-) | |
23 | ||
24 | diff --git a/fs/ocfs2/ocfs2_fs.h b/fs/ocfs2/ocfs2_fs.h | |
25 | index 4f61985..1b46505 100644 | |
26 | --- a/fs/ocfs2/ocfs2_fs.h | |
27 | +++ b/fs/ocfs2/ocfs2_fs.h | |
28 | @@ -64,6 +64,7 @@ | |
29 | #define OCFS2_INODE_SIGNATURE "INODE01" | |
30 | #define OCFS2_EXTENT_BLOCK_SIGNATURE "EXBLK01" | |
31 | #define OCFS2_GROUP_DESC_SIGNATURE "GROUP01" | |
32 | +#define OCFS2_XATTR_BLOCK_SIGNATURE "XATTR01" | |
33 | ||
34 | /* Compatibility flags */ | |
35 | #define OCFS2_HAS_COMPAT_FEATURE(sb,mask) \ | |
36 | @@ -715,6 +716,123 @@ struct ocfs2_group_desc | |
37 | /*40*/ __u8 bg_bitmap[0]; | |
38 | }; | |
39 | ||
40 | +/* | |
41 | + * On disk extended attribute structure for OCFS2. | |
42 | + */ | |
43 | + | |
44 | +/* | |
45 | + * ocfs2_xattr_entry indicates one extend attribute. | |
46 | + * | |
47 | + * Note that it can be stored in inode, one block or one xattr bucket. | |
48 | + */ | |
49 | +struct ocfs2_xattr_entry { | |
50 | + __le32 xe_name_hash; /* hash value of xattr prefix+suffix. */ | |
51 | + __le16 xe_name_offset; /* byte offset from the 1st etnry in the local | |
52 | + local xattr storage(inode, xattr block or | |
53 | + xattr bucket). */ | |
54 | + __u8 xe_name_len; /* xattr name len, does't include prefix. */ | |
55 | + __u8 xe_type; /* the low 7 bits indicates the name prefix's | |
56 | + * type and the highest 1 bits indicate whether | |
57 | + * the EA is stored in the local storage. */ | |
58 | + __le64 xe_value_size; /* real xattr value length. */ | |
59 | +}; | |
60 | + | |
61 | +/* | |
62 | + * On disk structure for xattr header. | |
63 | + * | |
64 | + * One ocfs2_xattr_header describes how many ocfs2_xattr_entry records in | |
65 | + * the local xattr storage. | |
66 | + */ | |
67 | +struct ocfs2_xattr_header { | |
68 | + __le16 xh_count; /* contains the count of how | |
69 | + many records are in the | |
70 | + local xattr storage. */ | |
71 | + __le16 xh_reserved1; | |
72 | + __le32 xh_reserved2; | |
73 | + __le64 xh_csum; | |
74 | + struct ocfs2_xattr_entry xh_entries[0]; /* xattr entry list. */ | |
75 | +}; | |
76 | + | |
77 | +/* | |
78 | + * On disk structure for xattr value root. | |
79 | + * | |
80 | + * It is used when one extended attribute's size is larger, and we will save it | |
81 | + * in an outside cluster. It will stored in a b-tree like file content. | |
82 | + */ | |
83 | +struct ocfs2_xattr_value_root { | |
84 | +/*00*/ __le32 xr_clusters; /* clusters covered by xattr value. */ | |
85 | + __le32 xr_reserved0; | |
86 | + __le64 xr_last_eb_blk; /* Pointer to last extent block */ | |
87 | +/*10*/ struct ocfs2_extent_list xr_list; /* Extent record list */ | |
88 | +}; | |
89 | + | |
90 | +/* | |
91 | + * On disk structure for xattr tree root. | |
92 | + * | |
93 | + * It is used when there are too many extended attributes for one file. These | |
94 | + * attributes will be organized and stored in an indexed-btree. | |
95 | + */ | |
96 | +struct ocfs2_xattr_tree_root { | |
97 | +/*00*/ __le32 xt_clusters; /* clusters covered by xattr. */ | |
98 | + __le32 xt_reserved0; | |
99 | + __le64 xt_last_eb_blk; /* Pointer to last extent block */ | |
100 | +/*10*/ struct ocfs2_extent_list xt_list; /* Extent record list */ | |
101 | +}; | |
102 | + | |
103 | +#define OCFS2_XATTR_INDEXED 0x1 | |
104 | + | |
105 | +/* | |
106 | + * On disk structure for xattr block. | |
107 | + */ | |
108 | +struct ocfs2_xattr_block { | |
109 | +/*00*/ __u8 xb_signature[8]; /* Signature for verification */ | |
110 | + __le16 xb_suballoc_slot; /* Slot suballocator this | |
111 | + block belongs to. */ | |
112 | + __le16 xb_suballoc_bit; /* Bit offset in suballocator | |
113 | + block group */ | |
114 | + __le32 xb_fs_generation; /* Must match super block */ | |
115 | +/*10*/ __le64 xb_blkno; /* Offset on disk, in blocks */ | |
116 | + __le64 xb_csum; | |
117 | +/*20*/ __le16 xb_flags; /* Indicates whether this block contains | |
118 | + real xattr or a xattr tree. */ | |
119 | + __le16 xb_reserved0; | |
120 | + __le32 xb_reserved1; | |
121 | + __le64 xb_reserved2; | |
122 | +/*30*/ union { | |
123 | + struct ocfs2_xattr_header xb_header; /* xattr header if this | |
124 | + block contains xattr */ | |
125 | + struct ocfs2_xattr_tree_root xb_root;/* xattr tree root if this | |
126 | + block cotains xattr | |
127 | + tree. */ | |
128 | + } xb_attrs; | |
129 | +}; | |
130 | + | |
131 | +#define OCFS2_XATTR_ENTRY_LOCAL 0x80 | |
132 | +#define OCFS2_XATTR_TYPE_MASK 0x7F | |
133 | +static inline void ocfs2_xattr_set_local(struct ocfs2_xattr_entry *xe, | |
134 | + int local) | |
135 | +{ | |
136 | + if (local) | |
137 | + xe->xe_type |= OCFS2_XATTR_ENTRY_LOCAL; | |
138 | + else | |
139 | + xe->xe_type &= ~OCFS2_XATTR_ENTRY_LOCAL; | |
140 | +} | |
141 | + | |
142 | +static inline int ocfs2_xattr_is_local(struct ocfs2_xattr_entry *xe) | |
143 | +{ | |
144 | + return xe->xe_type & OCFS2_XATTR_ENTRY_LOCAL; | |
145 | +} | |
146 | + | |
147 | +static inline void ocfs2_xattr_set_type(struct ocfs2_xattr_entry *xe, int type) | |
148 | +{ | |
149 | + xe->xe_type |= type & OCFS2_XATTR_TYPE_MASK; | |
150 | +} | |
151 | + | |
152 | +static inline int ocfs2_xattr_get_type(struct ocfs2_xattr_entry *xe) | |
153 | +{ | |
154 | + return xe->xe_type & OCFS2_XATTR_TYPE_MASK; | |
155 | +} | |
156 | + | |
157 | #ifdef __KERNEL__ | |
158 | static inline int ocfs2_fast_symlink_chars(struct super_block *sb) | |
159 | { | |
160 | -- | |
161 | 1.5.4.5 | |
162 |