1 // SPDX-License-Identifier: GPL-2.0
5 * Mikulas Patocka (mikulas@artax.karlin.mff.cuni.cz), 1998-1999
7 * handling extended attributes
12 /* Remove external extended attributes. ano specifies whether a is a
13 direct sector where eas starts 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;
27 if (ea_indirect(ea
)) {
28 if (ea_valuelen(ea
) != 8) {
29 hpfs_error(s
, "ea_indirect(ea) 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_in_anode(ea
), ea_len(ea
));
37 pos
+= ea
->namelen
+ ea_valuelen(ea
) + 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_NOFS
))) {
55 pr_err("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
,
67 const char *data
, int size
)
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 char ex
[4 + 255 + 1 + 8];
81 struct extended_attribute
*ea
;
82 struct extended_attribute
*ea_end
= fnode_end_ea(fnode
);
83 for (ea
= fnode_ea(fnode
); ea
< ea_end
; ea
= next_ea(ea
))
84 if (!strcmp(ea
->name
, key
)) {
87 if (ea_valuelen(ea
) >= size
)
89 memcpy(buf
, ea_data(ea
), ea_valuelen(ea
));
90 buf
[ea_valuelen(ea
)] = 0;
93 a
= le32_to_cpu(fnode
->ea_secno
);
94 len
= le32_to_cpu(fnode
->ea_size_l
);
95 ano
= fnode_in_anode(fnode
);
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(ea
) ? 8 : 0), ex
+ 4))
107 if (!strcmp(ea
->name
, key
)) {
110 if (ea_valuelen(ea
) >= size
)
112 if (hpfs_ea_read(s
, a
, ano
, pos
+ 4 + ea
->namelen
+ 1, ea_valuelen(ea
), buf
))
114 buf
[ea_valuelen(ea
)] = 0;
117 pos
+= ea
->namelen
+ ea_valuelen(ea
) + 5;
121 if (ea_len(ea
) >= size
)
123 if (hpfs_ea_read(s
, ea_sec(ea
), ea_in_anode(ea
), 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_in_anode(ea
), ea_sec(ea
), *size
= ea_len(ea
));
142 if (!(ret
= kmalloc((*size
= ea_valuelen(ea
)) + 1, GFP_NOFS
))) {
143 pr_err("out of memory for EA\n");
146 memcpy(ret
, ea_data(ea
), ea_valuelen(ea
));
147 ret
[ea_valuelen(ea
)] = 0;
150 a
= le32_to_cpu(fnode
->ea_secno
);
151 len
= le32_to_cpu(fnode
->ea_size_l
);
152 ano
= fnode_in_anode(fnode
);
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(ea
) ? 8 : 0), ex
+ 4))
165 if (!strcmp(ea
->name
, key
)) {
167 return get_indirect_ea(s
, ea_in_anode(ea
), ea_sec(ea
), *size
= ea_len(ea
));
168 if (!(ret
= kmalloc((*size
= ea_valuelen(ea
)) + 1, GFP_NOFS
))) {
169 pr_err("out of memory for EA\n");
172 if (hpfs_ea_read(s
, a
, ano
, pos
+ 4 + ea
->namelen
+ 1, ea_valuelen(ea
), ret
)) {
176 ret
[ea_valuelen(ea
)] = 0;
179 pos
+= ea
->namelen
+ ea_valuelen(ea
) + 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
, const char *key
,
191 const char *data
, int size
)
193 fnode_secno fno
= inode
->i_ino
;
194 struct super_block
*s
= inode
->i_sb
;
199 struct extended_attribute
*ea
;
200 struct extended_attribute
*ea_end
= fnode_end_ea(fnode
);
201 for (ea
= fnode_ea(fnode
); ea
< ea_end
; ea
= next_ea(ea
))
202 if (!strcmp(ea
->name
, key
)) {
203 if (ea_indirect(ea
)) {
204 if (ea_len(ea
) == size
)
205 set_indirect_ea(s
, ea_in_anode(ea
), ea_sec(ea
), data
, size
);
206 } else if (ea_valuelen(ea
) == size
) {
207 memcpy(ea_data(ea
), data
, size
);
211 a
= le32_to_cpu(fnode
->ea_secno
);
212 len
= le32_to_cpu(fnode
->ea_size_l
);
213 ano
= fnode_in_anode(fnode
);
216 char ex
[4 + 255 + 1 + 8];
217 ea
= (struct extended_attribute
*)ex
;
219 hpfs_error(s
, "EAs don't end correctly, %s %08x, len %08x",
220 ano
? "anode" : "sectors", a
, len
);
223 if (hpfs_ea_read(s
, a
, ano
, pos
, 4, ex
)) return;
224 if (hpfs_ea_read(s
, a
, ano
, pos
+ 4, ea
->namelen
+ 1 + (ea_indirect(ea
) ? 8 : 0), ex
+ 4))
226 if (!strcmp(ea
->name
, key
)) {
227 if (ea_indirect(ea
)) {
228 if (ea_len(ea
) == size
)
229 set_indirect_ea(s
, ea_in_anode(ea
), ea_sec(ea
), data
, size
);
232 if (ea_valuelen(ea
) == size
)
233 hpfs_ea_write(s
, a
, ano
, pos
+ 4 + ea
->namelen
+ 1, size
, data
);
237 pos
+= ea
->namelen
+ ea_valuelen(ea
) + 5;
239 if (!le16_to_cpu(fnode
->ea_offs
)) {
240 /*if (le16_to_cpu(fnode->ea_size_s)) {
241 hpfs_error(s, "fnode %08x: ea_size_s == %03x, ea_offs == 0",
242 inode->i_ino, le16_to_cpu(fnode->ea_size_s));
245 fnode
->ea_offs
= cpu_to_le16(0xc4);
247 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) {
248 hpfs_error(s
, "fnode %08lx: ea_offs == %03x, ea_size_s == %03x",
249 (unsigned long)inode
->i_ino
,
250 le16_to_cpu(fnode
->ea_offs
), le16_to_cpu(fnode
->ea_size_s
));
253 if ((le16_to_cpu(fnode
->ea_size_s
) || !le32_to_cpu(fnode
->ea_size_l
)) &&
254 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) {
255 ea
= fnode_end_ea(fnode
);
257 ea
->namelen
= strlen(key
);
258 ea
->valuelen_lo
= size
;
259 ea
->valuelen_hi
= size
>> 8;
260 strcpy(ea
->name
, key
);
261 memcpy(ea_data(ea
), data
, size
);
262 fnode
->ea_size_s
= cpu_to_le16(le16_to_cpu(fnode
->ea_size_s
) + strlen(key
) + size
+ 5);
265 /* Most the code here is 99.9993422% unused. I hope there are no bugs.
266 But what .. HPFS.IFS has also bugs in ea management. */
267 if (le16_to_cpu(fnode
->ea_size_s
) && !le32_to_cpu(fnode
->ea_size_l
)) {
269 struct buffer_head
*bh
;
271 if (!(n
= hpfs_alloc_sector(s
, fno
, 1, 0))) return;
272 if (!(data
= hpfs_get_sector(s
, n
, &bh
))) {
273 hpfs_free_sectors(s
, n
, 1);
276 memcpy(data
, fnode_ea(fnode
), le16_to_cpu(fnode
->ea_size_s
));
277 fnode
->ea_size_l
= cpu_to_le32(le16_to_cpu(fnode
->ea_size_s
));
278 fnode
->ea_size_s
= cpu_to_le16(0);
279 fnode
->ea_secno
= cpu_to_le32(n
);
280 fnode
->flags
&= ~FNODE_anode
;
281 mark_buffer_dirty(bh
);
284 pos
= le32_to_cpu(fnode
->ea_size_l
) + 5 + strlen(key
) + size
;
285 len
= (le32_to_cpu(fnode
->ea_size_l
) + 511) >> 9;
286 if (pos
>= 30000) goto bail
;
287 while (((pos
+ 511) >> 9) > len
) {
289 secno q
= hpfs_alloc_sector(s
, fno
, 1, 0);
291 fnode
->ea_secno
= cpu_to_le32(q
);
292 fnode
->flags
&= ~FNODE_anode
;
294 } else if (!fnode_in_anode(fnode
)) {
295 if (hpfs_alloc_if_possible(s
, le32_to_cpu(fnode
->ea_secno
) + len
)) {
298 /* Aargh... don't know how to create ea anodes :-( */
299 /*struct buffer_head *bh;
302 if (!(anode = hpfs_alloc_anode(s, fno, &a_s, &bh)))
304 anode->up = cpu_to_le32(fno);
305 anode->btree.fnode_parent = 1;
306 anode->btree.n_free_nodes--;
307 anode->btree.n_used_nodes++;
308 anode->btree.first_free = cpu_to_le16(le16_to_cpu(anode->btree.first_free) + 12);
309 anode->u.external[0].disk_secno = cpu_to_le32(le32_to_cpu(fnode->ea_secno));
310 anode->u.external[0].file_secno = cpu_to_le32(0);
311 anode->u.external[0].length = cpu_to_le32(len);
312 mark_buffer_dirty(bh);
314 fnode->flags |= FNODE_anode;
315 fnode->ea_secno = cpu_to_le32(a_s);*/
318 if (!(new_sec
= hpfs_alloc_sector(s
, fno
, 1, 1 - ((pos
+ 511) >> 9))))
320 for (i
= 0; i
< len
; i
++) {
321 struct buffer_head
*bh1
, *bh2
;
323 if (!(b1
= hpfs_map_sector(s
, le32_to_cpu(fnode
->ea_secno
) + i
, &bh1
, len
- i
- 1))) {
324 hpfs_free_sectors(s
, new_sec
, (pos
+ 511) >> 9);
327 if (!(b2
= hpfs_get_sector(s
, new_sec
+ i
, &bh2
))) {
329 hpfs_free_sectors(s
, new_sec
, (pos
+ 511) >> 9);
334 mark_buffer_dirty(bh2
);
337 hpfs_free_sectors(s
, le32_to_cpu(fnode
->ea_secno
), len
);
338 fnode
->ea_secno
= cpu_to_le32(new_sec
);
339 len
= (pos
+ 511) >> 9;
342 if (fnode_in_anode(fnode
)) {
343 if (hpfs_add_sector_to_btree(s
, le32_to_cpu(fnode
->ea_secno
),
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
)) 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
) + 4, h
[1] + 1, key
)) goto bail
;
357 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
;
358 fnode
->ea_size_l
= cpu_to_le32(pos
);
360 hpfs_i(inode
)->i_ea_size
+= 5 + strlen(key
) + size
;
363 if (le32_to_cpu(fnode
->ea_secno
))
364 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);
365 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));
366 else fnode
->ea_secno
= fnode
->ea_size_l
= cpu_to_le32(0);