blob: fc6e6a8c1e52053fb5adac89149eba9276d960b3 [file] [log] [blame]
Nicholas Flintham9fafe902014-03-31 13:51:31 +01001
2#include "hpfs_fn.h"
3
4
5void hpfs_ea_ext_remove(struct super_block *s, secno a, int ano, unsigned len)
6{
7 unsigned pos = 0;
8 while (pos < len) {
9 char ex[4 + 255 + 1 + 8];
10 struct extended_attribute *ea = (struct extended_attribute *)ex;
11 if (pos + 4 > len) {
12 hpfs_error(s, "EAs don't end correctly, %s %08x, len %08x",
13 ano ? "anode" : "sectors", a, len);
14 return;
15 }
16 if (hpfs_ea_read(s, a, ano, pos, 4, ex)) return;
17 if (ea->indirect) {
18 if (ea_valuelen(ea) != 8) {
19 hpfs_error(s, "ea->indirect set while ea->valuelen!=8, %s %08x, pos %08x",
20 ano ? "anode" : "sectors", a, pos);
21 return;
22 }
23 if (hpfs_ea_read(s, a, ano, pos + 4, ea->namelen + 9, ex+4))
24 return;
25 hpfs_ea_remove(s, ea_sec(ea), ea->anode, ea_len(ea));
26 }
27 pos += ea->namelen + ea_valuelen(ea) + 5;
28 }
29 if (!ano) hpfs_free_sectors(s, a, (len+511) >> 9);
30 else {
31 struct buffer_head *bh;
32 struct anode *anode;
33 if ((anode = hpfs_map_anode(s, a, &bh))) {
34 hpfs_remove_btree(s, &anode->btree);
35 brelse(bh);
36 hpfs_free_sectors(s, a, 1);
37 }
38 }
39}
40
41static char *get_indirect_ea(struct super_block *s, int ano, secno a, int size)
42{
43 char *ret;
44 if (!(ret = kmalloc(size + 1, GFP_NOFS))) {
45 printk("HPFS: out of memory for EA\n");
46 return NULL;
47 }
48 if (hpfs_ea_read(s, a, ano, 0, size, ret)) {
49 kfree(ret);
50 return NULL;
51 }
52 ret[size] = 0;
53 return ret;
54}
55
56static void set_indirect_ea(struct super_block *s, int ano, secno a,
57 const char *data, int size)
58{
59 hpfs_ea_write(s, a, ano, 0, size, data);
60}
61
62
63int hpfs_read_ea(struct super_block *s, struct fnode *fnode, char *key,
64 char *buf, int size)
65{
66 unsigned pos;
67 int ano, len;
68 secno a;
69 char ex[4 + 255 + 1 + 8];
70 struct extended_attribute *ea;
71 struct extended_attribute *ea_end = fnode_end_ea(fnode);
72 for (ea = fnode_ea(fnode); ea < ea_end; ea = next_ea(ea))
73 if (!strcmp(ea->name, key)) {
74 if (ea->indirect)
75 goto indirect;
76 if (ea_valuelen(ea) >= size)
77 return -EINVAL;
78 memcpy(buf, ea_data(ea), ea_valuelen(ea));
79 buf[ea_valuelen(ea)] = 0;
80 return 0;
81 }
82 a = le32_to_cpu(fnode->ea_secno);
83 len = le32_to_cpu(fnode->ea_size_l);
84 ano = fnode->ea_anode;
85 pos = 0;
86 while (pos < len) {
87 ea = (struct extended_attribute *)ex;
88 if (pos + 4 > len) {
89 hpfs_error(s, "EAs don't end correctly, %s %08x, len %08x",
90 ano ? "anode" : "sectors", a, len);
91 return -EIO;
92 }
93 if (hpfs_ea_read(s, a, ano, pos, 4, ex)) return -EIO;
94 if (hpfs_ea_read(s, a, ano, pos + 4, ea->namelen + 1 + (ea->indirect ? 8 : 0), ex + 4))
95 return -EIO;
96 if (!strcmp(ea->name, key)) {
97 if (ea->indirect)
98 goto indirect;
99 if (ea_valuelen(ea) >= size)
100 return -EINVAL;
101 if (hpfs_ea_read(s, a, ano, pos + 4 + ea->namelen + 1, ea_valuelen(ea), buf))
102 return -EIO;
103 buf[ea_valuelen(ea)] = 0;
104 return 0;
105 }
106 pos += ea->namelen + ea_valuelen(ea) + 5;
107 }
108 return -ENOENT;
109indirect:
110 if (ea_len(ea) >= size)
111 return -EINVAL;
112 if (hpfs_ea_read(s, ea_sec(ea), ea->anode, 0, ea_len(ea), buf))
113 return -EIO;
114 buf[ea_len(ea)] = 0;
115 return 0;
116}
117
118char *hpfs_get_ea(struct super_block *s, struct fnode *fnode, char *key, int *size)
119{
120 char *ret;
121 unsigned pos;
122 int ano, len;
123 secno a;
124 struct extended_attribute *ea;
125 struct extended_attribute *ea_end = fnode_end_ea(fnode);
126 for (ea = fnode_ea(fnode); ea < ea_end; ea = next_ea(ea))
127 if (!strcmp(ea->name, key)) {
128 if (ea->indirect)
129 return get_indirect_ea(s, ea->anode, ea_sec(ea), *size = ea_len(ea));
130 if (!(ret = kmalloc((*size = ea_valuelen(ea)) + 1, GFP_NOFS))) {
131 printk("HPFS: out of memory for EA\n");
132 return NULL;
133 }
134 memcpy(ret, ea_data(ea), ea_valuelen(ea));
135 ret[ea_valuelen(ea)] = 0;
136 return ret;
137 }
138 a = le32_to_cpu(fnode->ea_secno);
139 len = le32_to_cpu(fnode->ea_size_l);
140 ano = fnode->ea_anode;
141 pos = 0;
142 while (pos < len) {
143 char ex[4 + 255 + 1 + 8];
144 ea = (struct extended_attribute *)ex;
145 if (pos + 4 > len) {
146 hpfs_error(s, "EAs don't end correctly, %s %08x, len %08x",
147 ano ? "anode" : "sectors", a, len);
148 return NULL;
149 }
150 if (hpfs_ea_read(s, a, ano, pos, 4, ex)) return NULL;
151 if (hpfs_ea_read(s, a, ano, pos + 4, ea->namelen + 1 + (ea->indirect ? 8 : 0), ex + 4))
152 return NULL;
153 if (!strcmp(ea->name, key)) {
154 if (ea->indirect)
155 return get_indirect_ea(s, ea->anode, ea_sec(ea), *size = ea_len(ea));
156 if (!(ret = kmalloc((*size = ea_valuelen(ea)) + 1, GFP_NOFS))) {
157 printk("HPFS: out of memory for EA\n");
158 return NULL;
159 }
160 if (hpfs_ea_read(s, a, ano, pos + 4 + ea->namelen + 1, ea_valuelen(ea), ret)) {
161 kfree(ret);
162 return NULL;
163 }
164 ret[ea_valuelen(ea)] = 0;
165 return ret;
166 }
167 pos += ea->namelen + ea_valuelen(ea) + 5;
168 }
169 return NULL;
170}
171
172
173void hpfs_set_ea(struct inode *inode, struct fnode *fnode, const char *key,
174 const char *data, int size)
175{
176 fnode_secno fno = inode->i_ino;
177 struct super_block *s = inode->i_sb;
178 unsigned pos;
179 int ano, len;
180 secno a;
181 unsigned char h[4];
182 struct extended_attribute *ea;
183 struct extended_attribute *ea_end = fnode_end_ea(fnode);
184 for (ea = fnode_ea(fnode); ea < ea_end; ea = next_ea(ea))
185 if (!strcmp(ea->name, key)) {
186 if (ea->indirect) {
187 if (ea_len(ea) == size)
188 set_indirect_ea(s, ea->anode, ea_sec(ea), data, size);
189 } else if (ea_valuelen(ea) == size) {
190 memcpy(ea_data(ea), data, size);
191 }
192 return;
193 }
194 a = le32_to_cpu(fnode->ea_secno);
195 len = le32_to_cpu(fnode->ea_size_l);
196 ano = fnode->ea_anode;
197 pos = 0;
198 while (pos < len) {
199 char ex[4 + 255 + 1 + 8];
200 ea = (struct extended_attribute *)ex;
201 if (pos + 4 > len) {
202 hpfs_error(s, "EAs don't end correctly, %s %08x, len %08x",
203 ano ? "anode" : "sectors", a, len);
204 return;
205 }
206 if (hpfs_ea_read(s, a, ano, pos, 4, ex)) return;
207 if (hpfs_ea_read(s, a, ano, pos + 4, ea->namelen + 1 + (ea->indirect ? 8 : 0), ex + 4))
208 return;
209 if (!strcmp(ea->name, key)) {
210 if (ea->indirect) {
211 if (ea_len(ea) == size)
212 set_indirect_ea(s, ea->anode, ea_sec(ea), data, size);
213 }
214 else {
215 if (ea_valuelen(ea) == size)
216 hpfs_ea_write(s, a, ano, pos + 4 + ea->namelen + 1, size, data);
217 }
218 return;
219 }
220 pos += ea->namelen + ea_valuelen(ea) + 5;
221 }
222 if (!le16_to_cpu(fnode->ea_offs)) {
223 fnode->ea_offs = cpu_to_le16(0xc4);
224 }
225 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) {
226 hpfs_error(s, "fnode %08lx: ea_offs == %03x, ea_size_s == %03x",
227 (unsigned long)inode->i_ino,
228 le32_to_cpu(fnode->ea_offs), le16_to_cpu(fnode->ea_size_s));
229 return;
230 }
231 if ((le16_to_cpu(fnode->ea_size_s) || !le32_to_cpu(fnode->ea_size_l)) &&
232 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) {
233 ea = fnode_end_ea(fnode);
234 *(char *)ea = 0;
235 ea->namelen = strlen(key);
236 ea->valuelen_lo = size;
237 ea->valuelen_hi = size >> 8;
238 strcpy(ea->name, key);
239 memcpy(ea_data(ea), data, size);
240 fnode->ea_size_s = cpu_to_le16(le16_to_cpu(fnode->ea_size_s) + strlen(key) + size + 5);
241 goto ret;
242 }
243 if (le16_to_cpu(fnode->ea_size_s) && !le32_to_cpu(fnode->ea_size_l)) {
244 secno n;
245 struct buffer_head *bh;
246 char *data;
247 if (!(n = hpfs_alloc_sector(s, fno, 1, 0))) return;
248 if (!(data = hpfs_get_sector(s, n, &bh))) {
249 hpfs_free_sectors(s, n, 1);
250 return;
251 }
252 memcpy(data, fnode_ea(fnode), le16_to_cpu(fnode->ea_size_s));
253 fnode->ea_size_l = cpu_to_le32(le16_to_cpu(fnode->ea_size_s));
254 fnode->ea_size_s = cpu_to_le16(0);
255 fnode->ea_secno = cpu_to_le32(n);
256 fnode->ea_anode = cpu_to_le32(0);
257 mark_buffer_dirty(bh);
258 brelse(bh);
259 }
260 pos = le32_to_cpu(fnode->ea_size_l) + 5 + strlen(key) + size;
261 len = (le32_to_cpu(fnode->ea_size_l) + 511) >> 9;
262 if (pos >= 30000) goto bail;
263 while (((pos + 511) >> 9) > len) {
264 if (!len) {
265 secno q = hpfs_alloc_sector(s, fno, 1, 0);
266 if (!q) goto bail;
267 fnode->ea_secno = cpu_to_le32(q);
268 fnode->ea_anode = 0;
269 len++;
270 } else if (!fnode->ea_anode) {
271 if (hpfs_alloc_if_possible(s, le32_to_cpu(fnode->ea_secno) + len)) {
272 len++;
273 } else {
274
275 secno new_sec;
276 int i;
277 if (!(new_sec = hpfs_alloc_sector(s, fno, 1, 1 - ((pos + 511) >> 9))))
278 goto bail;
279 for (i = 0; i < len; i++) {
280 struct buffer_head *bh1, *bh2;
281 void *b1, *b2;
282 if (!(b1 = hpfs_map_sector(s, le32_to_cpu(fnode->ea_secno) + i, &bh1, len - i - 1))) {
283 hpfs_free_sectors(s, new_sec, (pos + 511) >> 9);
284 goto bail;
285 }
286 if (!(b2 = hpfs_get_sector(s, new_sec + i, &bh2))) {
287 brelse(bh1);
288 hpfs_free_sectors(s, new_sec, (pos + 511) >> 9);
289 goto bail;
290 }
291 memcpy(b2, b1, 512);
292 brelse(bh1);
293 mark_buffer_dirty(bh2);
294 brelse(bh2);
295 }
296 hpfs_free_sectors(s, le32_to_cpu(fnode->ea_secno), len);
297 fnode->ea_secno = cpu_to_le32(new_sec);
298 len = (pos + 511) >> 9;
299 }
300 }
301 if (fnode->ea_anode) {
302 if (hpfs_add_sector_to_btree(s, le32_to_cpu(fnode->ea_secno),
303 0, len) != -1) {
304 len++;
305 } else {
306 goto bail;
307 }
308 }
309 }
310 h[0] = 0;
311 h[1] = strlen(key);
312 h[2] = size & 0xff;
313 h[3] = size >> 8;
314 if (hpfs_ea_write(s, le32_to_cpu(fnode->ea_secno), fnode->ea_anode, le32_to_cpu(fnode->ea_size_l), 4, h)) goto bail;
315 if (hpfs_ea_write(s, le32_to_cpu(fnode->ea_secno), fnode->ea_anode, le32_to_cpu(fnode->ea_size_l) + 4, h[1] + 1, key)) goto bail;
316 if (hpfs_ea_write(s, le32_to_cpu(fnode->ea_secno), fnode->ea_anode, le32_to_cpu(fnode->ea_size_l) + 5 + h[1], size, data)) goto bail;
317 fnode->ea_size_l = cpu_to_le32(pos);
318 ret:
319 hpfs_i(inode)->i_ea_size += 5 + strlen(key) + size;
320 return;
321 bail:
322 if (le32_to_cpu(fnode->ea_secno))
323 if (fnode->ea_anode) hpfs_truncate_btree(s, le32_to_cpu(fnode->ea_secno), 1, (le32_to_cpu(fnode->ea_size_l) + 511) >> 9);
324 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));
325 else fnode->ea_secno = fnode->ea_size_l = cpu_to_le32(0);
326}
327