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