4 * Mikulas Patocka (mikulas@artax.karlin.mff.cuni.cz), 1998-1999
6 * handling extended attributes
9 #include <linux/string.h>
12 /* Remove external extended attributes. ano specifies wheter a is a
13 direct sector where eas start or an anode */
15 void hpfs_ea_ext_remove(struct super_block
*s
, secno a
, int ano
, unsigned len
)
19 char ex
[4 + 255 + 1 + 8];
20 struct extended_attribute
*ea
= (struct extended_attribute
*)ex
;
22 hpfs_error(s
, "EAs don't end correctly, %s %08x, len %08x",
23 ano
? "anode" : "sectors", a
, len
);
26 if (hpfs_ea_read(s
, a
, ano
, pos
, 4, ex
)) return;
28 if (ea
->valuelen
!= 8) {
29 hpfs_error(s
, "ea->indirect set while ea->valuelen!=8, %s %08x, pos %08x",
30 ano
? "anode" : "sectors", a
, pos
);
33 if (hpfs_ea_read(s
, a
, ano
, pos
+ 4, ea
->namelen
+ 9, ex
+4))
35 hpfs_ea_remove(s
, ea_sec(ea
), ea
->anode
, ea_len(ea
));
37 pos
+= ea
->namelen
+ ea
->valuelen
+ 5;
39 if (!ano
) hpfs_free_sectors(s
, a
, (len
+511) >> 9);
41 struct buffer_head
*bh
;
43 if ((anode
= hpfs_map_anode(s
, a
, &bh
))) {
44 hpfs_remove_btree(s
, &anode
->btree
);
46 hpfs_free_sectors(s
, a
, 1);
51 static char *get_indirect_ea(struct super_block
*s
, int ano
, secno a
, int size
)
54 if (!(ret
= kmalloc(size
+ 1, GFP_KERNEL
))) {
55 printk("HPFS: out of memory for EA\n");
58 if (hpfs_ea_read(s
, a
, ano
, 0, size
, ret
)) {
66 static void set_indirect_ea(struct super_block
*s
, int ano
, secno a
, char *data
,
69 hpfs_ea_write(s
, a
, ano
, 0, size
, data
);
72 /* Read an extended attribute named 'key' into the provided buffer */
74 int hpfs_read_ea(struct super_block
*s
, struct fnode
*fnode
, char *key
,
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
>= size
)
88 memcpy(buf
, ea_data(ea
), ea
->valuelen
);
89 buf
[ea
->valuelen
] = 0;
93 len
= fnode
->ea_size_l
;
94 ano
= fnode
->ea_anode
;
97 char ex
[4 + 255 + 1 + 8];
98 ea
= (struct extended_attribute
*)ex
;
100 hpfs_error(s
, "EAs don't end correctly, %s %08x, len %08x",
101 ano
? "anode" : "sectors", a
, len
);
104 if (hpfs_ea_read(s
, a
, ano
, pos
, 4, ex
)) return -EIO
;
105 if (hpfs_ea_read(s
, a
, ano
, pos
+ 4, ea
->namelen
+ 1 + (ea
->indirect
? 8 : 0), ex
+ 4))
107 if (!strcmp(ea
->name
, key
)) {
110 if (ea
->valuelen
>= size
)
112 if (hpfs_ea_read(s
, a
, ano
, pos
+ 4 + ea
->namelen
+ 1, ea
->valuelen
, buf
))
114 buf
[ea
->valuelen
] = 0;
117 pos
+= ea
->namelen
+ ea
->valuelen
+ 5;
121 if (ea_len(ea
) >= size
)
123 if (hpfs_ea_read(s
, ea_sec(ea
), ea
->anode
, 0, ea_len(ea
), buf
))
129 /* Read an extended attribute named 'key' */
130 char *hpfs_get_ea(struct super_block
*s
, struct fnode
*fnode
, char *key
, int *size
)
136 struct extended_attribute
*ea
;
137 struct extended_attribute
*ea_end
= fnode_end_ea(fnode
);
138 for (ea
= fnode_ea(fnode
); ea
< ea_end
; ea
= next_ea(ea
))
139 if (!strcmp(ea
->name
, key
)) {
141 return get_indirect_ea(s
, ea
->anode
, ea_sec(ea
), *size
= ea_len(ea
));
142 if (!(ret
= kmalloc((*size
= ea
->valuelen
) + 1, GFP_KERNEL
))) {
143 printk("HPFS: out of memory for EA\n");
146 memcpy(ret
, ea_data(ea
), ea
->valuelen
);
147 ret
[ea
->valuelen
] = 0;
151 len
= fnode
->ea_size_l
;
152 ano
= fnode
->ea_anode
;
155 char ex
[4 + 255 + 1 + 8];
156 ea
= (struct extended_attribute
*)ex
;
158 hpfs_error(s
, "EAs don't end correctly, %s %08x, len %08x",
159 ano
? "anode" : "sectors", a
, len
);
162 if (hpfs_ea_read(s
, a
, ano
, pos
, 4, ex
)) return NULL
;
163 if (hpfs_ea_read(s
, a
, ano
, pos
+ 4, ea
->namelen
+ 1 + (ea
->indirect
? 8 : 0), ex
+ 4))
165 if (!strcmp(ea
->name
, key
)) {
167 return get_indirect_ea(s
, ea
->anode
, ea_sec(ea
), *size
= ea_len(ea
));
168 if (!(ret
= kmalloc((*size
= ea
->valuelen
) + 1, GFP_KERNEL
))) {
169 printk("HPFS: out of memory for EA\n");
172 if (hpfs_ea_read(s
, a
, ano
, pos
+ 4 + ea
->namelen
+ 1, ea
->valuelen
, ret
)) {
176 ret
[ea
->valuelen
] = 0;
179 pos
+= ea
->namelen
+ ea
->valuelen
+ 5;
185 * Update or create extended attribute 'key' with value 'data'. Note that
186 * when this ea exists, it MUST have the same size as size of data.
187 * This driver can't change sizes of eas ('cause I just don't need it).
190 void hpfs_set_ea(struct inode
*inode
, struct fnode
*fnode
, char *key
, 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
)) {
203 if (ea_len(ea
) == size
)
204 set_indirect_ea(s
, ea
->anode
, ea_sec(ea
), data
, size
);
205 } else if (ea
->valuelen
== size
) {
206 memcpy(ea_data(ea
), data
, size
);
211 len
= fnode
->ea_size_l
;
212 ano
= fnode
->ea_anode
;
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
? 8 : 0), ex
+ 4))
225 if (!strcmp(ea
->name
, key
)) {
227 if (ea_len(ea
) == size
)
228 set_indirect_ea(s
, ea
->anode
, ea_sec(ea
), data
, size
);
231 if (ea
->valuelen
== size
)
232 hpfs_ea_write(s
, a
, ano
, pos
+ 4 + ea
->namelen
+ 1, size
, data
);
236 pos
+= ea
->namelen
+ ea
->valuelen
+ 5;
238 if (!fnode
->ea_size_s
) {
239 /*if (fnode->ea_size_s) {
240 hpfs_error(s, "fnode %08x: ea_size_s == %03x, ea_offs == 0",
241 inode->i_ino, fnode->ea_size_s);
244 fnode
->ea_offs
= 0xc4;
246 if (fnode
->ea_offs
< 0xc4 || fnode
->ea_offs
+ fnode
->ea_size_s
> 0x200) {
247 hpfs_error(s
, "fnode %08x: ea_offs == %03x, ea_size_s == %03x",
248 inode
->i_ino
, fnode
->ea_offs
, fnode
->ea_size_s
);
251 if ((fnode
->ea_size_s
|| !fnode
->ea_size_l
) &&
252 fnode
->ea_offs
+ fnode
->ea_size_s
+ strlen(key
) + size
+ 5 <= 0x200) {
253 /* I'm not sure ... maybe we overwrite ACL here. I have no info
254 on it right now :-( */
255 ea
= fnode_end_ea(fnode
);
257 ea
->namelen
= strlen(key
);
259 strcpy(ea
->name
, key
);
260 memcpy(ea_data(ea
), data
, size
);
261 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 (fnode
->ea_size_s
&& !fnode
->ea_size_l
) {
268 struct buffer_head
*bh
;
270 if (!(n
= hpfs_alloc_sector(s
, fno
, 1, 0, 1))) return;
271 if (!(data
= hpfs_get_sector(s
, n
, &bh
))) {
272 hpfs_free_sectors(s
, n
, 1);
275 memcpy(data
, fnode_ea(fnode
), fnode
->ea_size_s
);
276 fnode
->ea_size_l
= fnode
->ea_size_s
;
277 fnode
->ea_size_s
= 0;
280 mark_buffer_dirty(bh
);
283 pos
= fnode
->ea_size_l
+ 5 + strlen(key
) + size
;
284 len
= (fnode
->ea_size_l
+ 511) >> 9;
285 if (pos
>= 30000) goto bail
;
286 while (((pos
+ 511) >> 9) > len
) {
288 if (!(fnode
->ea_secno
= hpfs_alloc_sector(s
, fno
, 1, 0, 1)))
292 } else if (!fnode
->ea_anode
) {
293 if (hpfs_alloc_if_possible(s
, fnode
->ea_secno
+ len
)) {
296 /* Aargh... don't know how to create ea anodes :-( */
297 /*struct buffer_head *bh;
300 if (!(anode = hpfs_alloc_anode(s, fno, &a_s, &bh)))
303 anode->btree.fnode_parent = 1;
304 anode->btree.n_free_nodes--;
305 anode->btree.n_used_nodes++;
306 anode->btree.first_free += 12;
307 anode->u.external[0].disk_secno = fnode->ea_secno;
308 anode->u.external[0].file_secno = 0;
309 anode->u.external[0].length = len;
310 mark_buffer_dirty(bh);
313 fnode->ea_secno = a_s;*/
316 if (!(new_sec
= hpfs_alloc_sector(s
, fno
, 1, 1 - ((pos
+ 511) >> 9), 1)))
318 for (i
= 0; i
< len
; i
++) {
319 struct buffer_head
*bh1
, *bh2
;
321 if (!(b1
= hpfs_map_sector(s
, fnode
->ea_secno
+ i
, &bh1
, len
- i
- 1))) {
322 hpfs_free_sectors(s
, new_sec
, (pos
+ 511) >> 9);
325 if (!(b2
= hpfs_get_sector(s
, new_sec
+ i
, &bh2
))) {
327 hpfs_free_sectors(s
, new_sec
, (pos
+ 511) >> 9);
332 mark_buffer_dirty(bh2
);
335 hpfs_free_sectors(s
, fnode
->ea_secno
, len
);
336 fnode
->ea_secno
= new_sec
;
337 len
= (pos
+ 511) >> 9;
340 if (fnode
->ea_anode
) {
341 if (hpfs_add_sector_to_btree(s
, fnode
->ea_secno
,
353 if (hpfs_ea_write(s
, fnode
->ea_secno
, fnode
->ea_anode
, fnode
->ea_size_l
, 4, h
)) goto bail
;
354 if (hpfs_ea_write(s
, fnode
->ea_secno
, fnode
->ea_anode
, fnode
->ea_size_l
+ 4, h
[1] + 1, key
)) goto bail
;
355 if (hpfs_ea_write(s
, fnode
->ea_secno
, fnode
->ea_anode
, fnode
->ea_size_l
+ 5 + h
[1], size
, data
)) goto bail
;
356 fnode
->ea_size_l
= pos
;
358 inode
->i_hpfs_ea_size
+= 5 + strlen(key
) + size
;
362 if (fnode
->ea_anode
) hpfs_truncate_btree(s
, fnode
->ea_secno
, 1, (fnode
->ea_size_l
+ 511) >> 9);
363 else hpfs_free_sectors(s
, fnode
->ea_secno
+ ((fnode
->ea_size_l
+ 511) >> 9), len
- ((fnode
->ea_size_l
+ 511) >> 9));
364 else fnode
->ea_secno
= fnode
->ea_size_l
= 0;