diff options
author | Vyacheslav Dubeyko <slava@dubeyko.com> | 2013-11-12 18:11:08 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-11-12 22:09:32 -0500 |
commit | 099e9245e04d50bb12ed621b4fa61df0a4c9dba9 (patch) | |
tree | afd87de0ccc84d5cd5c8854b1861b5a8b6800bec /fs/hfsplus/xattr.c | |
parent | b3b5b0f03cc4ea074ed0ac110d0afd17e0ccdf9e (diff) |
hfsplus: implement attributes file's header node initialization code
Implement functionality of AttributesFile's header node initialization.
Signed-off-by: Vyacheslav Dubeyko <slava@dubeyko.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Christoph Hellwig <hch@infradead.org>
Cc: Hin-Tak Leung <htl10@users.sourceforge.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/hfsplus/xattr.c')
-rw-r--r-- | fs/hfsplus/xattr.c | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/fs/hfsplus/xattr.c b/fs/hfsplus/xattr.c index bd8471fb9a6a..568a45cb1145 100644 --- a/fs/hfsplus/xattr.c +++ b/fs/hfsplus/xattr.c | |||
@@ -127,6 +127,71 @@ static int can_set_xattr(struct inode *inode, const char *name, | |||
127 | return 0; | 127 | return 0; |
128 | } | 128 | } |
129 | 129 | ||
130 | static void hfsplus_init_header_node(struct inode *attr_file, | ||
131 | u32 clump_size, | ||
132 | char *buf, size_t node_size) | ||
133 | { | ||
134 | struct hfs_bnode_desc *desc; | ||
135 | struct hfs_btree_header_rec *head; | ||
136 | u16 offset; | ||
137 | __be16 *rec_offsets; | ||
138 | u32 hdr_node_map_rec_bits; | ||
139 | char *bmp; | ||
140 | u32 used_nodes; | ||
141 | u32 used_bmp_bytes; | ||
142 | |||
143 | hfs_dbg(ATTR_MOD, "init_hdr_attr_file: clump %u, node_size %zu\n", | ||
144 | clump_size, node_size); | ||
145 | |||
146 | /* The end of the node contains list of record offsets */ | ||
147 | rec_offsets = (__be16 *)(buf + node_size); | ||
148 | |||
149 | desc = (struct hfs_bnode_desc *)buf; | ||
150 | desc->type = HFS_NODE_HEADER; | ||
151 | desc->num_recs = cpu_to_be16(HFSPLUS_BTREE_HDR_NODE_RECS_COUNT); | ||
152 | offset = sizeof(struct hfs_bnode_desc); | ||
153 | *--rec_offsets = cpu_to_be16(offset); | ||
154 | |||
155 | head = (struct hfs_btree_header_rec *)(buf + offset); | ||
156 | head->node_size = cpu_to_be16(node_size); | ||
157 | head->node_count = cpu_to_be32(i_size_read(attr_file) / node_size); | ||
158 | head->free_nodes = cpu_to_be32(be32_to_cpu(head->node_count) - 1); | ||
159 | head->clump_size = cpu_to_be32(clump_size); | ||
160 | head->attributes |= cpu_to_be32(HFS_TREE_BIGKEYS | HFS_TREE_VARIDXKEYS); | ||
161 | head->max_key_len = cpu_to_be16(HFSPLUS_ATTR_KEYLEN - sizeof(u16)); | ||
162 | offset += sizeof(struct hfs_btree_header_rec); | ||
163 | *--rec_offsets = cpu_to_be16(offset); | ||
164 | offset += HFSPLUS_BTREE_HDR_USER_BYTES; | ||
165 | *--rec_offsets = cpu_to_be16(offset); | ||
166 | |||
167 | hdr_node_map_rec_bits = 8 * (node_size - offset - (4 * sizeof(u16))); | ||
168 | if (be32_to_cpu(head->node_count) > hdr_node_map_rec_bits) { | ||
169 | u32 map_node_bits; | ||
170 | u32 map_nodes; | ||
171 | |||
172 | desc->next = cpu_to_be32(be32_to_cpu(head->leaf_tail) + 1); | ||
173 | map_node_bits = 8 * (node_size - sizeof(struct hfs_bnode_desc) - | ||
174 | (2 * sizeof(u16)) - 2); | ||
175 | map_nodes = (be32_to_cpu(head->node_count) - | ||
176 | hdr_node_map_rec_bits + | ||
177 | (map_node_bits - 1)) / map_node_bits; | ||
178 | be32_add_cpu(&head->free_nodes, 0 - map_nodes); | ||
179 | } | ||
180 | |||
181 | bmp = buf + offset; | ||
182 | used_nodes = | ||
183 | be32_to_cpu(head->node_count) - be32_to_cpu(head->free_nodes); | ||
184 | used_bmp_bytes = used_nodes / 8; | ||
185 | if (used_bmp_bytes) { | ||
186 | memset(bmp, 0xFF, used_bmp_bytes); | ||
187 | bmp += used_bmp_bytes; | ||
188 | used_nodes %= 8; | ||
189 | } | ||
190 | *bmp = ~(0xFF >> used_nodes); | ||
191 | offset += hdr_node_map_rec_bits / 8; | ||
192 | *--rec_offsets = cpu_to_be16(offset); | ||
193 | } | ||
194 | |||
130 | int __hfsplus_setxattr(struct inode *inode, const char *name, | 195 | int __hfsplus_setxattr(struct inode *inode, const char *name, |
131 | const void *value, size_t size, int flags) | 196 | const void *value, size_t size, int flags) |
132 | { | 197 | { |