4 * Mikulas Patocka (mikulas@artax.karlin.mff.cuni.cz), 1998-1999
6 * handling extended attributes
11 /* Remove external extended attributes. ano specifies whether a is a
12 direct sector where eas starts or an anode */
14 void hpfs_ea_ext_remove(struct super_block
*s
, secno a
, int ano
, unsigned len
)
18 char ex
[4 + 255 + 1 + 8];
19 struct extended_attribute
*ea
= (struct extended_attribute
*)ex
;
21 hpfs_error(s
, "EAs don't end correctly, %s %08x, len %08x",
22 ano
? "anode" : "sectors", a
, len
);
25 if (hpfs_ea_read(s
, a
, ano
, pos
, 4, ex
)) return;
26 if (ea_indirect(ea
)) {
27 if (ea_valuelen(ea
) != 8) {
28 hpfs_error(s
, "ea_indirect(ea) set while ea->valuelen!=8, %s %08x, pos %08x",
29 ano
? "anode" : "sectors", a
, pos
);
32 if (hpfs_ea_read(s
, a
, ano
, pos
+ 4, ea
->namelen
+ 9, ex
+4))
34 hpfs_ea_remove(s
, ea_sec(ea
), ea_in_anode(ea
), ea_len(ea
));
36 pos
+= ea
->namelen
+ ea_valuelen(ea
) + 5;
38 if (!ano
) hpfs_free_sectors(s
, a
, (len
+511) >> 9);
40 struct buffer_head
*bh
;
42 if ((anode
= hpfs_map_anode(s
, a
, &bh
))) {
43 hpfs_remove_btree(s
, &anode
->btree
);
45 hpfs_free_sectors(s
, a
, 1);
50 static char *get_indirect_ea(struct super_block
*s
, int ano
, secno a
, int size
)
53 if (!(ret
= kmalloc(size
+ 1, GFP_NOFS
))) {
54 printk("HPFS: out of memory for EA\n");
57 if (hpfs_ea_read(s
, a
, ano
, 0, size
, ret
)) {
65 static void set_indirect_ea(struct super_block
*s
, int ano
, secno a
,
66 const char *data
, int size
)
68 hpfs_ea_write(s
, a
, ano
, 0, size
, data
);
71 /* Read an extended attribute named 'key' into the provided buffer */
73 int hpfs_read_ea(struct super_block
*s
, struct fnode
*fnode
, char *key
,
79 char ex
[4 + 255 + 1 + 8];
80 struct extended_attribute
*ea
;
81 struct extended_attribute
*ea_end
= fnode_end_ea(fnode
);
82 for (ea
= fnode_ea(fnode
); ea
< ea_end
; ea
= next_ea(ea
))
83 if (!strcmp(ea
->name
, key
)) {
86 if (ea_valuelen(ea
) >= size
)
88 memcpy(buf
, ea_data(ea
), ea_valuelen(ea
));
89 buf
[ea_valuelen(ea
)] = 0;
92 a
= le32_to_cpu(fnode
->ea_secno
);
93 len
= le32_to_cpu(fnode
->ea_size_l
);
94 ano
= fnode_in_anode(fnode
);
97 ea
= (struct extended_attribute
*)ex
;
99 hpfs_error(s
, "EAs don't end correctly, %s %08x, len %08x",
100 ano
? "anode" : "sectors", a
, len
);
103 if (hpfs_ea_read(s
, a
, ano
, pos
, 4, ex
)) return -EIO
;
104 if (hpfs_ea_read(s
, a
, ano
, pos
+ 4, ea
->namelen
+ 1 + (ea_indirect(ea
) ? 8 : 0), ex
+ 4))
106 if (!strcmp(ea
->name
, key
)) {
109 if (ea_valuelen(ea
) >= size
)
111 if (hpfs_ea_read(s
, a
, ano
, pos
+ 4 + ea
->namelen
+ 1, ea_valuelen(ea
), buf
))
113 buf
[ea_valuelen(ea
)] = 0;
116 pos
+= ea
->namelen
+ ea_valuelen(ea
) + 5;
120 if (ea_len(ea
) >= size
)
122 if (hpfs_ea_read(s
, ea_sec(ea
), ea_in_anode(ea
), 0, ea_len(ea
), buf
))
128 /* Read an extended attribute named 'key' */
129 char *hpfs_get_ea(struct super_block
*s
, struct fnode
*fnode
, char *key
, int *size
)
135 struct extended_attribute
*ea
;
136 struct extended_attribute
*ea_end
= fnode_end_ea(fnode
);
137 for (ea
= fnode_ea(fnode
); ea
< ea_end
; ea
= next_ea(ea
))
138 if (!strcmp(ea
->name
, key
)) {
140 return get_indirect_ea(s
, ea_in_anode(ea
), ea_sec(ea
), *size
= ea_len(ea
));
141 if (!(ret
= kmalloc((*size
= ea_valuelen(ea
)) + 1, GFP_NOFS
))) {
142 printk("HPFS: out of memory for EA\n");
145 memcpy(ret
, ea_data(ea
), ea_valuelen(ea
));
146 ret
[ea_valuelen(ea
)] = 0;
149 a
= le32_to_cpu(fnode
->ea_secno
);
150 len
= le32_to_cpu(fnode
->ea_size_l
);
151 ano
= fnode_in_anode(fnode
);
154 char ex
[4 + 255 + 1 + 8];
155 ea
= (struct extended_attribute
*)ex
;
157 hpfs_error(s
, "EAs don't end correctly, %s %08x, len %08x",
158 ano
? "anode" : "sectors", a
, len
);
161 if (hpfs_ea_read(s
, a
, ano
, pos
, 4, ex
)) return NULL
;
162 if (hpfs_ea_read(s
, a
, ano
, pos
+ 4, ea
->namelen
+ 1 + (ea_indirect(ea
) ? 8 : 0), ex
+ 4))
164 if (!strcmp(ea
->name
, key
)) {
166 return get_indirect_ea(s
, ea_in_anode(ea
), ea_sec(ea
), *size
= ea_len(ea
));
167 if (!(ret
= kmalloc((*size
= ea_valuelen(ea
)) + 1, GFP_NOFS
))) {
168 printk("HPFS: out of memory for EA\n");
171 if (hpfs_ea_read(s
, a
, ano
, pos
+ 4 + ea
->namelen
+ 1, ea_valuelen(ea
), ret
)) {
175 ret
[ea_valuelen(ea
)] = 0;
178 pos
+= ea
->namelen
+ ea_valuelen(ea
) + 5;
184 * Update or create extended attribute 'key' with value 'data'. Note that
185 * when this ea exists, it MUST have the same size as size of data.
186 * This driver can't change sizes of eas ('cause I just don't need it).
189 void hpfs_set_ea(struct inode
*inode
, struct fnode
*fnode
, const char *key
,
190 const char *data
, int size
)
192 fnode_secno fno
= inode
->i_ino
;
193 struct super_block
*s
= inode
->i_sb
;
198 struct extended_attribute
*ea
;
199 struct extended_attribute
*ea_end
= fnode_end_ea(fnode
);
200 for (ea
= fnode_ea(fnode
); ea
< ea_end
; ea
= next_ea(ea
))
201 if (!strcmp(ea
->name
, key
)) {
202 if (ea_indirect(ea
)) {
203 if (ea_len(ea
) == size
)
204 set_indirect_ea(s
, ea_in_anode(ea
), ea_sec(ea
), data
, size
);
205 } else if (ea_valuelen(ea
) == size
) {
206 memcpy(ea_data(ea
), data
, size
);
210 a
= le32_to_cpu(fnode
->ea_secno
);
211 len
= le32_to_cpu(fnode
->ea_size_l
);
212 ano
= fnode_in_anode(fnode
);
215 char ex
[4 + 255 + 1 + 8];
216 ea
= (struct extended_attribute
*)ex
;
218 hpfs_error(s
, "EAs don't end correctly, %s %08x, len %08x",
219 ano
? "anode" : "sectors", a
, len
);
222 if (hpfs_ea_read(s
, a
, ano
, pos
, 4, ex
)) return;
223 if (hpfs_ea_read(s
, a
, ano
, pos
+ 4, ea
->namelen
+ 1 + (ea_indirect(ea
) ? 8 : 0), ex
+ 4))
225 if (!strcmp(ea
->name
, key
)) {
226 if (ea_indirect(ea
)) {
227 if (ea_len(ea
) == size
)
228 set_indirect_ea(s
, ea_in_anode(ea
), ea_sec(ea
), data
, size
);
231 if (ea_valuelen(ea
) == size
)
232 hpfs_ea_write(s
, a
, ano
, pos
+ 4 + ea
->namelen
+ 1, size
, data
);
236 pos
+= ea
->namelen
+ ea_valuelen(ea
) + 5;
238 if (!le16_to_cpu(fnode
->ea_offs
)) {
239 /*if (le16_to_cpu(fnode->ea_size_s)) {
240 hpfs_error(s, "fnode %08x: ea_size_s == %03x, ea_offs == 0",
241 inode->i_ino, le16_to_cpu(fnode->ea_size_s));
244 fnode
->ea_offs
= cpu_to_le16(0xc4);
246 if (le16_to_cpu(fnode
->ea_offs
) < 0xc4 || le16_to_cpu(fnode
->ea_offs
) + le16_to_cpu(fnode
->acl_size_s
) + le16_to_cpu(fnode
->ea_size_s
) > 0x200) {
247 hpfs_error(s
, "fnode %08lx: ea_offs == %03x, ea_size_s == %03x",
248 (unsigned long)inode
->i_ino
,
249 le16_to_cpu(fnode
->ea_offs
), le16_to_cpu(fnode
->ea_size_s
));
252 if ((le16_to_cpu(fnode
->ea_size_s
) || !le32_to_cpu(fnode
->ea_size_l
)) &&
253 le16_to_cpu(fnode
->ea_offs
) + le16_to_cpu(fnode
->acl_size_s
) + le16_to_cpu(fnode
->ea_size_s
) + strlen(key
) + size
+ 5 <= 0x200) {
254 ea
= fnode_end_ea(fnode
);
256 ea
->namelen
= strlen(key
);
257 ea
->valuelen_lo
= size
;
258 ea
->valuelen_hi
= size
>> 8;
259 strcpy(ea
->name
, key
);
260 memcpy(ea_data(ea
), data
, size
);
261 fnode
->ea_size_s
= cpu_to_le16(le16_to_cpu(fnode
->ea_size_s
) + strlen(key
) + size
+ 5);
264 /* Most the code here is 99.9993422% unused. I hope there are no bugs.
265 But what .. HPFS.IFS has also bugs in ea management. */
266 if (le16_to_cpu(fnode
->ea_size_s
) && !le32_to_cpu(fnode
->ea_size_l
)) {
268 struct buffer_head
*bh
;
270 if (!(n
= hpfs_alloc_sector(s
, fno
, 1, 0))) return;
271 if (!(data
= hpfs_get_sector(s
, n
, &bh
))) {
272 hpfs_free_sectors(s
, n
, 1);
275 memcpy(data
, fnode_ea(fnode
), le16_to_cpu(fnode
->ea_size_s
));
276 fnode
->ea_size_l
= cpu_to_le32(le16_to_cpu(fnode
->ea_size_s
));
277 fnode
->ea_size_s
= cpu_to_le16(0);
278 fnode
->ea_secno
= cpu_to_le32(n
);
279 fnode
->flags
&= ~FNODE_anode
;
280 mark_buffer_dirty(bh
);
283 pos
= le32_to_cpu(fnode
->ea_size_l
) + 5 + strlen(key
) + size
;
284 len
= (le32_to_cpu(fnode
->ea_size_l
) + 511) >> 9;
285 if (pos
>= 30000) goto bail
;
286 while (((pos
+ 511) >> 9) > len
) {
288 secno q
= hpfs_alloc_sector(s
, fno
, 1, 0);
290 fnode
->ea_secno
= cpu_to_le32(q
);
291 fnode
->flags
&= ~FNODE_anode
;
293 } else if (!fnode_in_anode(fnode
)) {
294 if (hpfs_alloc_if_possible(s
, le32_to_cpu(fnode
->ea_secno
) + len
)) {
297 /* Aargh... don't know how to create ea anodes :-( */
298 /*struct buffer_head *bh;
301 if (!(anode = hpfs_alloc_anode(s, fno, &a_s, &bh)))
303 anode->up = cpu_to_le32(fno);
304 anode->btree.fnode_parent = 1;
305 anode->btree.n_free_nodes--;
306 anode->btree.n_used_nodes++;
307 anode->btree.first_free = cpu_to_le16(le16_to_cpu(anode->btree.first_free) + 12);
308 anode->u.external[0].disk_secno = cpu_to_le32(le32_to_cpu(fnode->ea_secno));
309 anode->u.external[0].file_secno = cpu_to_le32(0);
310 anode->u.external[0].length = cpu_to_le32(len);
311 mark_buffer_dirty(bh);
313 fnode->flags |= FNODE_anode;
314 fnode->ea_secno = cpu_to_le32(a_s);*/
317 if (!(new_sec
= hpfs_alloc_sector(s
, fno
, 1, 1 - ((pos
+ 511) >> 9))))
319 for (i
= 0; i
< len
; i
++) {
320 struct buffer_head
*bh1
, *bh2
;
322 if (!(b1
= hpfs_map_sector(s
, le32_to_cpu(fnode
->ea_secno
) + i
, &bh1
, len
- i
- 1))) {
323 hpfs_free_sectors(s
, new_sec
, (pos
+ 511) >> 9);
326 if (!(b2
= hpfs_get_sector(s
, new_sec
+ i
, &bh2
))) {
328 hpfs_free_sectors(s
, new_sec
, (pos
+ 511) >> 9);
333 mark_buffer_dirty(bh2
);
336 hpfs_free_sectors(s
, le32_to_cpu(fnode
->ea_secno
), len
);
337 fnode
->ea_secno
= cpu_to_le32(new_sec
);
338 len
= (pos
+ 511) >> 9;
341 if (fnode_in_anode(fnode
)) {
342 if (hpfs_add_sector_to_btree(s
, le32_to_cpu(fnode
->ea_secno
),
354 if (hpfs_ea_write(s
, le32_to_cpu(fnode
->ea_secno
), fnode_in_anode(fnode
), le32_to_cpu(fnode
->ea_size_l
), 4, h
)) goto bail
;
355 if (hpfs_ea_write(s
, le32_to_cpu(fnode
->ea_secno
), fnode_in_anode(fnode
), le32_to_cpu(fnode
->ea_size_l
) + 4, h
[1] + 1, key
)) goto bail
;
356 if (hpfs_ea_write(s
, le32_to_cpu(fnode
->ea_secno
), fnode_in_anode(fnode
), le32_to_cpu(fnode
->ea_size_l
) + 5 + h
[1], size
, data
)) goto bail
;
357 fnode
->ea_size_l
= cpu_to_le32(pos
);
359 hpfs_i(inode
)->i_ea_size
+= 5 + strlen(key
) + size
;
362 if (le32_to_cpu(fnode
->ea_secno
))
363 if (fnode_in_anode(fnode
)) hpfs_truncate_btree(s
, le32_to_cpu(fnode
->ea_secno
), 1, (le32_to_cpu(fnode
->ea_size_l
) + 511) >> 9);
364 else hpfs_free_sectors(s
, le32_to_cpu(fnode
->ea_secno
) + ((le32_to_cpu(fnode
->ea_size_l
) + 511) >> 9), len
- ((le32_to_cpu(fnode
->ea_size_l
) + 511) >> 9));
365 else fnode
->ea_secno
= fnode
->ea_size_l
= cpu_to_le32(0);