Merge tag 'microblaze-v6.6' of git://git.monstr.eu/linux-2.6-microblaze
[platform/kernel/linux-rpi.git] / fs / hpfs / ea.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  *  linux/fs/hpfs/ea.c
4  *
5  *  Mikulas Patocka (mikulas@artax.karlin.mff.cuni.cz), 1998-1999
6  *
7  *  handling extended attributes
8  */
9
10 #include "hpfs_fn.h"
11
12 /* Remove external extended attributes. ano specifies whether a is a 
13    direct sector where eas starts or an anode */
14
15 void hpfs_ea_ext_remove(struct super_block *s, secno a, int ano, unsigned len)
16 {
17         unsigned pos = 0;
18         while (pos < len) {
19                 char ex[4 + 255 + 1 + 8];
20                 struct extended_attribute *ea = (struct extended_attribute *)ex;
21                 if (pos + 4 > len) {
22                         hpfs_error(s, "EAs don't end correctly, %s %08x, len %08x",
23                                 ano ? "anode" : "sectors", a, len);
24                         return;
25                 }
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);
31                                 return;
32                         }
33                         if (hpfs_ea_read(s, a, ano, pos + 4, ea->namelen + 9, ex+4))
34                                 return;
35                         hpfs_ea_remove(s, ea_sec(ea), ea_in_anode(ea), ea_len(ea));
36                 }
37                 pos += ea->namelen + ea_valuelen(ea) + 5;
38         }
39         if (!ano) hpfs_free_sectors(s, a, (len+511) >> 9);
40         else {
41                 struct buffer_head *bh;
42                 struct anode *anode;
43                 if ((anode = hpfs_map_anode(s, a, &bh))) {
44                         hpfs_remove_btree(s, &anode->btree);
45                         brelse(bh);
46                         hpfs_free_sectors(s, a, 1);
47                 }
48         }
49 }
50
51 static char *get_indirect_ea(struct super_block *s, int ano, secno a, int size)
52 {
53         char *ret;
54         if (!(ret = kmalloc(size + 1, GFP_NOFS))) {
55                 pr_err("out of memory for EA\n");
56                 return NULL;
57         }
58         if (hpfs_ea_read(s, a, ano, 0, size, ret)) {
59                 kfree(ret);
60                 return NULL;
61         }
62         ret[size] = 0;
63         return ret;
64 }
65
66 static void set_indirect_ea(struct super_block *s, int ano, secno a,
67                             const char *data, int size)
68 {
69         hpfs_ea_write(s, a, ano, 0, size, data);
70 }
71
72 /* Read an extended attribute named 'key' into the provided buffer */
73
74 int hpfs_read_ea(struct super_block *s, struct fnode *fnode, char *key,
75                 char *buf, int size)
76 {
77         unsigned pos;
78         int ano, len;
79         secno a;
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)) {
85                         if (ea_indirect(ea))
86                                 goto indirect;
87                         if (ea_valuelen(ea) >= size)
88                                 return -EINVAL;
89                         memcpy(buf, ea_data(ea), ea_valuelen(ea));
90                         buf[ea_valuelen(ea)] = 0;
91                         return 0;
92                 }
93         a = le32_to_cpu(fnode->ea_secno);
94         len = le32_to_cpu(fnode->ea_size_l);
95         ano = fnode_in_anode(fnode);
96         pos = 0;
97         while (pos < len) {
98                 ea = (struct extended_attribute *)ex;
99                 if (pos + 4 > len) {
100                         hpfs_error(s, "EAs don't end correctly, %s %08x, len %08x",
101                                 ano ? "anode" : "sectors", a, len);
102                         return -EIO;
103                 }
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))
106                         return -EIO;
107                 if (!strcmp(ea->name, key)) {
108                         if (ea_indirect(ea))
109                                 goto indirect;
110                         if (ea_valuelen(ea) >= size)
111                                 return -EINVAL;
112                         if (hpfs_ea_read(s, a, ano, pos + 4 + ea->namelen + 1, ea_valuelen(ea), buf))
113                                 return -EIO;
114                         buf[ea_valuelen(ea)] = 0;
115                         return 0;
116                 }
117                 pos += ea->namelen + ea_valuelen(ea) + 5;
118         }
119         return -ENOENT;
120 indirect:
121         if (ea_len(ea) >= size)
122                 return -EINVAL;
123         if (hpfs_ea_read(s, ea_sec(ea), ea_in_anode(ea), 0, ea_len(ea), buf))
124                 return -EIO;
125         buf[ea_len(ea)] = 0;
126         return 0;
127 }
128
129 /* Read an extended attribute named 'key' */
130 char *hpfs_get_ea(struct super_block *s, struct fnode *fnode, char *key, int *size)
131 {
132         char *ret;
133         unsigned pos;
134         int ano, len;
135         secno a;
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)) {
140                         if (ea_indirect(ea))
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");
144                                 return NULL;
145                         }
146                         memcpy(ret, ea_data(ea), ea_valuelen(ea));
147                         ret[ea_valuelen(ea)] = 0;
148                         return ret;
149                 }
150         a = le32_to_cpu(fnode->ea_secno);
151         len = le32_to_cpu(fnode->ea_size_l);
152         ano = fnode_in_anode(fnode);
153         pos = 0;
154         while (pos < len) {
155                 char ex[4 + 255 + 1 + 8];
156                 ea = (struct extended_attribute *)ex;
157                 if (pos + 4 > len) {
158                         hpfs_error(s, "EAs don't end correctly, %s %08x, len %08x",
159                                 ano ? "anode" : "sectors", a, len);
160                         return NULL;
161                 }
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))
164                         return NULL;
165                 if (!strcmp(ea->name, key)) {
166                         if (ea_indirect(ea))
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");
170                                 return NULL;
171                         }
172                         if (hpfs_ea_read(s, a, ano, pos + 4 + ea->namelen + 1, ea_valuelen(ea), ret)) {
173                                 kfree(ret);
174                                 return NULL;
175                         }
176                         ret[ea_valuelen(ea)] = 0;
177                         return ret;
178                 }
179                 pos += ea->namelen + ea_valuelen(ea) + 5;
180         }
181         return NULL;
182 }
183
184 /* 
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).
188  */
189
190 void hpfs_set_ea(struct inode *inode, struct fnode *fnode, const char *key,
191                  const char *data, int size)
192 {
193         fnode_secno fno = inode->i_ino;
194         struct super_block *s = inode->i_sb;
195         unsigned pos;
196         int ano, len;
197         secno a;
198         unsigned char h[4];
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);
208                         }
209                         return;
210                 }
211         a = le32_to_cpu(fnode->ea_secno);
212         len = le32_to_cpu(fnode->ea_size_l);
213         ano = fnode_in_anode(fnode);
214         pos = 0;
215         while (pos < len) {
216                 char ex[4 + 255 + 1 + 8];
217                 ea = (struct extended_attribute *)ex;
218                 if (pos + 4 > len) {
219                         hpfs_error(s, "EAs don't end correctly, %s %08x, len %08x",
220                                 ano ? "anode" : "sectors", a, len);
221                         return;
222                 }
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))
225                         return;
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);
230                         }
231                         else {
232                                 if (ea_valuelen(ea) == size)
233                                         hpfs_ea_write(s, a, ano, pos + 4 + ea->namelen + 1, size, data);
234                         }
235                         return;
236                 }
237                 pos += ea->namelen + ea_valuelen(ea) + 5;
238         }
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));
243                         return;
244                 }*/
245                 fnode->ea_offs = cpu_to_le16(0xc4);
246         }
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));
251                 return;
252         }
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);
256                 *(char *)ea = 0;
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);
263                 goto ret;
264         }
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)) {
268                 secno n;
269                 struct buffer_head *bh;
270                 char *data;
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);
274                         return;
275                 }
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);
282                 brelse(bh);
283         }
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) {
288                 if (!len) {
289                         secno q = hpfs_alloc_sector(s, fno, 1, 0);
290                         if (!q) goto bail;
291                         fnode->ea_secno = cpu_to_le32(q);
292                         fnode->flags &= ~FNODE_anode;
293                         len++;
294                 } else if (!fnode_in_anode(fnode)) {
295                         if (hpfs_alloc_if_possible(s, le32_to_cpu(fnode->ea_secno) + len)) {
296                                 len++;
297                         } else {
298                                 /* Aargh... don't know how to create ea anodes :-( */
299                                 /*struct buffer_head *bh;
300                                 struct anode *anode;
301                                 anode_secno a_s;
302                                 if (!(anode = hpfs_alloc_anode(s, fno, &a_s, &bh)))
303                                         goto bail;
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);
313                                 brelse(bh);
314                                 fnode->flags |= FNODE_anode;
315                                 fnode->ea_secno = cpu_to_le32(a_s);*/
316                                 secno new_sec;
317                                 int i;
318                                 if (!(new_sec = hpfs_alloc_sector(s, fno, 1, 1 - ((pos + 511) >> 9))))
319                                         goto bail;
320                                 for (i = 0; i < len; i++) {
321                                         struct buffer_head *bh1, *bh2;
322                                         void *b1, *b2;
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);
325                                                 goto bail;
326                                         }
327                                         if (!(b2 = hpfs_get_sector(s, new_sec + i, &bh2))) {
328                                                 brelse(bh1);
329                                                 hpfs_free_sectors(s, new_sec, (pos + 511) >> 9);
330                                                 goto bail;
331                                         }
332                                         memcpy(b2, b1, 512);
333                                         brelse(bh1);
334                                         mark_buffer_dirty(bh2);
335                                         brelse(bh2);
336                                 }
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;
340                         }
341                 }
342                 if (fnode_in_anode(fnode)) {
343                         if (hpfs_add_sector_to_btree(s, le32_to_cpu(fnode->ea_secno),
344                                                      0, len) != -1) {
345                                 len++;
346                         } else {
347                                 goto bail;
348                         }
349                 }
350         }
351         h[0] = 0;
352         h[1] = strlen(key);
353         h[2] = size & 0xff;
354         h[3] = size >> 8;
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);
359         ret:
360         hpfs_i(inode)->i_ea_size += 5 + strlen(key) + size;
361         return;
362         bail:
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);
367 }
368