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 14 void 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) { 27 if (ea->valuelen != 8) { 28 hpfs_error(s, "ea->indirect 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->anode, ea_len(ea)); 35 } 36 pos += ea->namelen + ea->valuelen + 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 50 static 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 printk("HPFS: 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 65 static 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 73 int 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 struct extended_attribute *ea; 80 struct extended_attribute *ea_end = fnode_end_ea(fnode); 81 for (ea = fnode_ea(fnode); ea < ea_end; ea = next_ea(ea)) 82 if (!strcmp(ea->name, key)) { 83 if (ea->indirect) 84 goto indirect; 85 if (ea->valuelen >= size) 86 return -EINVAL; 87 memcpy(buf, ea_data(ea), ea->valuelen); 88 buf[ea->valuelen] = 0; 89 return 0; 90 } 91 a = fnode->ea_secno; 92 len = fnode->ea_size_l; 93 ano = fnode->ea_anode; 94 pos = 0; 95 while (pos < len) { 96 char ex[4 + 255 + 1 + 8]; 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 ? 8 : 0), ex + 4)) 105 return -EIO; 106 if (!strcmp(ea->name, key)) { 107 if (ea->indirect) 108 goto indirect; 109 if (ea->valuelen >= size) 110 return -EINVAL; 111 if (hpfs_ea_read(s, a, ano, pos + 4 + ea->namelen + 1, ea->valuelen, buf)) 112 return -EIO; 113 buf[ea->valuelen] = 0; 114 return 0; 115 } 116 pos += ea->namelen + ea->valuelen + 5; 117 } 118 return -ENOENT; 119 indirect: 120 if (ea_len(ea) >= size) 121 return -EINVAL; 122 if (hpfs_ea_read(s, ea_sec(ea), ea->anode, 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' */ 129 char *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) 140 return get_indirect_ea(s, ea->anode, ea_sec(ea), *size = ea_len(ea)); 141 if (!(ret = kmalloc((*size = ea->valuelen) + 1, GFP_NOFS))) { 142 printk("HPFS: out of memory for EA\n"); 143 return NULL; 144 } 145 memcpy(ret, ea_data(ea), ea->valuelen); 146 ret[ea->valuelen] = 0; 147 return ret; 148 } 149 a = fnode->ea_secno; 150 len = fnode->ea_size_l; 151 ano = fnode->ea_anode; 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 ? 8 : 0), ex + 4)) 163 return NULL; 164 if (!strcmp(ea->name, key)) { 165 if (ea->indirect) 166 return get_indirect_ea(s, ea->anode, ea_sec(ea), *size = ea_len(ea)); 167 if (!(ret = kmalloc((*size = ea->valuelen) + 1, GFP_NOFS))) { 168 printk("HPFS: 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, ret)) { 172 kfree(ret); 173 return NULL; 174 } 175 ret[ea->valuelen] = 0; 176 return ret; 177 } 178 pos += ea->namelen + ea->valuelen + 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 189 void 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) { 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); 207 } 208 return; 209 } 210 a = fnode->ea_secno; 211 len = fnode->ea_size_l; 212 ano = fnode->ea_anode; 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 ? 8 : 0), ex + 4)) 224 return; 225 if (!strcmp(ea->name, key)) { 226 if (ea->indirect) { 227 if (ea_len(ea) == size) 228 set_indirect_ea(s, ea->anode, ea_sec(ea), data, size); 229 } 230 else { 231 if (ea->valuelen == 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 + 5; 237 } 238 if (!fnode->ea_offs) { 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); 242 return; 243 }*/ 244 fnode->ea_offs = 0xc4; 245 } 246 if (fnode->ea_offs < 0xc4 || fnode->ea_offs + fnode->acl_size_s + 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 fnode->ea_offs, fnode->ea_size_s); 250 return; 251 } 252 if ((fnode->ea_size_s || !fnode->ea_size_l) && 253 fnode->ea_offs + fnode->acl_size_s + 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 = size; 258 strcpy(ea->name, key); 259 memcpy(ea_data(ea), data, size); 260 fnode->ea_size_s += strlen(key) + size + 5; 261 goto ret; 262 } 263 /* Most the code here is 99.9993422% unused. I hope there are no bugs. 264 But what .. HPFS.IFS has also bugs in ea management. */ 265 if (fnode->ea_size_s && !fnode->ea_size_l) { 266 secno n; 267 struct buffer_head *bh; 268 char *data; 269 if (!(n = hpfs_alloc_sector(s, fno, 1, 0, 1))) return; 270 if (!(data = hpfs_get_sector(s, n, &bh))) { 271 hpfs_free_sectors(s, n, 1); 272 return; 273 } 274 memcpy(data, fnode_ea(fnode), fnode->ea_size_s); 275 fnode->ea_size_l = fnode->ea_size_s; 276 fnode->ea_size_s = 0; 277 fnode->ea_secno = n; 278 fnode->ea_anode = 0; 279 mark_buffer_dirty(bh); 280 brelse(bh); 281 } 282 pos = fnode->ea_size_l + 5 + strlen(key) + size; 283 len = (fnode->ea_size_l + 511) >> 9; 284 if (pos >= 30000) goto bail; 285 while (((pos + 511) >> 9) > len) { 286 if (!len) { 287 if (!(fnode->ea_secno = hpfs_alloc_sector(s, fno, 1, 0, 1))) 288 goto bail; 289 fnode->ea_anode = 0; 290 len++; 291 } else if (!fnode->ea_anode) { 292 if (hpfs_alloc_if_possible(s, fnode->ea_secno + len)) { 293 len++; 294 } else { 295 /* Aargh... don't know how to create ea anodes :-( */ 296 /*struct buffer_head *bh; 297 struct anode *anode; 298 anode_secno a_s; 299 if (!(anode = hpfs_alloc_anode(s, fno, &a_s, &bh))) 300 goto bail; 301 anode->up = fno; 302 anode->btree.fnode_parent = 1; 303 anode->btree.n_free_nodes--; 304 anode->btree.n_used_nodes++; 305 anode->btree.first_free += 12; 306 anode->u.external[0].disk_secno = fnode->ea_secno; 307 anode->u.external[0].file_secno = 0; 308 anode->u.external[0].length = len; 309 mark_buffer_dirty(bh); 310 brelse(bh); 311 fnode->ea_anode = 1; 312 fnode->ea_secno = a_s;*/ 313 secno new_sec; 314 int i; 315 if (!(new_sec = hpfs_alloc_sector(s, fno, 1, 1 - ((pos + 511) >> 9), 1))) 316 goto bail; 317 for (i = 0; i < len; i++) { 318 struct buffer_head *bh1, *bh2; 319 void *b1, *b2; 320 if (!(b1 = hpfs_map_sector(s, fnode->ea_secno + i, &bh1, len - i - 1))) { 321 hpfs_free_sectors(s, new_sec, (pos + 511) >> 9); 322 goto bail; 323 } 324 if (!(b2 = hpfs_get_sector(s, new_sec + i, &bh2))) { 325 brelse(bh1); 326 hpfs_free_sectors(s, new_sec, (pos + 511) >> 9); 327 goto bail; 328 } 329 memcpy(b2, b1, 512); 330 brelse(bh1); 331 mark_buffer_dirty(bh2); 332 brelse(bh2); 333 } 334 hpfs_free_sectors(s, fnode->ea_secno, len); 335 fnode->ea_secno = new_sec; 336 len = (pos + 511) >> 9; 337 } 338 } 339 if (fnode->ea_anode) { 340 if (hpfs_add_sector_to_btree(s, fnode->ea_secno, 341 0, len) != -1) { 342 len++; 343 } else { 344 goto bail; 345 } 346 } 347 } 348 h[0] = 0; 349 h[1] = strlen(key); 350 h[2] = size & 0xff; 351 h[3] = size >> 8; 352 if (hpfs_ea_write(s, fnode->ea_secno, fnode->ea_anode, fnode->ea_size_l, 4, h)) goto bail; 353 if (hpfs_ea_write(s, fnode->ea_secno, fnode->ea_anode, fnode->ea_size_l + 4, h[1] + 1, key)) goto bail; 354 if (hpfs_ea_write(s, fnode->ea_secno, fnode->ea_anode, fnode->ea_size_l + 5 + h[1], size, data)) goto bail; 355 fnode->ea_size_l = pos; 356 ret: 357 hpfs_i(inode)->i_ea_size += 5 + strlen(key) + size; 358 return; 359 bail: 360 if (fnode->ea_secno) 361 if (fnode->ea_anode) hpfs_truncate_btree(s, fnode->ea_secno, 1, (fnode->ea_size_l + 511) >> 9); 362 else hpfs_free_sectors(s, fnode->ea_secno + ((fnode->ea_size_l + 511) >> 9), len - ((fnode->ea_size_l + 511) >> 9)); 363 else fnode->ea_secno = fnode->ea_size_l = 0; 364 } 365 366