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, char *data, 66 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, char *key, char *data, int size) 190 { 191 fnode_secno fno = inode->i_ino; 192 struct super_block *s = inode->i_sb; 193 unsigned pos; 194 int ano, len; 195 secno a; 196 unsigned char h[4]; 197 struct extended_attribute *ea; 198 struct extended_attribute *ea_end = fnode_end_ea(fnode); 199 for (ea = fnode_ea(fnode); ea < ea_end; ea = next_ea(ea)) 200 if (!strcmp(ea->name, key)) { 201 if (ea->indirect) { 202 if (ea_len(ea) == size) 203 set_indirect_ea(s, ea->anode, ea_sec(ea), data, size); 204 } else if (ea->valuelen == size) { 205 memcpy(ea_data(ea), data, size); 206 } 207 return; 208 } 209 a = fnode->ea_secno; 210 len = fnode->ea_size_l; 211 ano = fnode->ea_anode; 212 pos = 0; 213 while (pos < len) { 214 char ex[4 + 255 + 1 + 8]; 215 ea = (struct extended_attribute *)ex; 216 if (pos + 4 > len) { 217 hpfs_error(s, "EAs don't end correctly, %s %08x, len %08x", 218 ano ? "anode" : "sectors", a, len); 219 return; 220 } 221 if (hpfs_ea_read(s, a, ano, pos, 4, ex)) return; 222 if (hpfs_ea_read(s, a, ano, pos + 4, ea->namelen + 1 + (ea->indirect ? 8 : 0), ex + 4)) 223 return; 224 if (!strcmp(ea->name, key)) { 225 if (ea->indirect) { 226 if (ea_len(ea) == size) 227 set_indirect_ea(s, ea->anode, ea_sec(ea), data, size); 228 } 229 else { 230 if (ea->valuelen == size) 231 hpfs_ea_write(s, a, ano, pos + 4 + ea->namelen + 1, size, data); 232 } 233 return; 234 } 235 pos += ea->namelen + ea->valuelen + 5; 236 } 237 if (!fnode->ea_offs) { 238 /*if (fnode->ea_size_s) { 239 hpfs_error(s, "fnode %08x: ea_size_s == %03x, ea_offs == 0", 240 inode->i_ino, fnode->ea_size_s); 241 return; 242 }*/ 243 fnode->ea_offs = 0xc4; 244 } 245 if (fnode->ea_offs < 0xc4 || fnode->ea_offs + fnode->acl_size_s + fnode->ea_size_s > 0x200) { 246 hpfs_error(s, "fnode %08lx: ea_offs == %03x, ea_size_s == %03x", 247 (unsigned long)inode->i_ino, 248 fnode->ea_offs, fnode->ea_size_s); 249 return; 250 } 251 if ((fnode->ea_size_s || !fnode->ea_size_l) && 252 fnode->ea_offs + fnode->acl_size_s + fnode->ea_size_s + strlen(key) + size + 5 <= 0x200) { 253 ea = fnode_end_ea(fnode); 254 *(char *)ea = 0; 255 ea->namelen = strlen(key); 256 ea->valuelen = size; 257 strcpy(ea->name, key); 258 memcpy(ea_data(ea), data, size); 259 fnode->ea_size_s += strlen(key) + size + 5; 260 goto ret; 261 } 262 /* Most the code here is 99.9993422% unused. I hope there are no bugs. 263 But what .. HPFS.IFS has also bugs in ea management. */ 264 if (fnode->ea_size_s && !fnode->ea_size_l) { 265 secno n; 266 struct buffer_head *bh; 267 char *data; 268 if (!(n = hpfs_alloc_sector(s, fno, 1, 0, 1))) return; 269 if (!(data = hpfs_get_sector(s, n, &bh))) { 270 hpfs_free_sectors(s, n, 1); 271 return; 272 } 273 memcpy(data, fnode_ea(fnode), fnode->ea_size_s); 274 fnode->ea_size_l = fnode->ea_size_s; 275 fnode->ea_size_s = 0; 276 fnode->ea_secno = n; 277 fnode->ea_anode = 0; 278 mark_buffer_dirty(bh); 279 brelse(bh); 280 } 281 pos = fnode->ea_size_l + 5 + strlen(key) + size; 282 len = (fnode->ea_size_l + 511) >> 9; 283 if (pos >= 30000) goto bail; 284 while (((pos + 511) >> 9) > len) { 285 if (!len) { 286 if (!(fnode->ea_secno = hpfs_alloc_sector(s, fno, 1, 0, 1))) 287 goto bail; 288 fnode->ea_anode = 0; 289 len++; 290 } else if (!fnode->ea_anode) { 291 if (hpfs_alloc_if_possible(s, fnode->ea_secno + len)) { 292 len++; 293 } else { 294 /* Aargh... don't know how to create ea anodes :-( */ 295 /*struct buffer_head *bh; 296 struct anode *anode; 297 anode_secno a_s; 298 if (!(anode = hpfs_alloc_anode(s, fno, &a_s, &bh))) 299 goto bail; 300 anode->up = fno; 301 anode->btree.fnode_parent = 1; 302 anode->btree.n_free_nodes--; 303 anode->btree.n_used_nodes++; 304 anode->btree.first_free += 12; 305 anode->u.external[0].disk_secno = fnode->ea_secno; 306 anode->u.external[0].file_secno = 0; 307 anode->u.external[0].length = len; 308 mark_buffer_dirty(bh); 309 brelse(bh); 310 fnode->ea_anode = 1; 311 fnode->ea_secno = a_s;*/ 312 secno new_sec; 313 int i; 314 if (!(new_sec = hpfs_alloc_sector(s, fno, 1, 1 - ((pos + 511) >> 9), 1))) 315 goto bail; 316 for (i = 0; i < len; i++) { 317 struct buffer_head *bh1, *bh2; 318 void *b1, *b2; 319 if (!(b1 = hpfs_map_sector(s, fnode->ea_secno + i, &bh1, len - i - 1))) { 320 hpfs_free_sectors(s, new_sec, (pos + 511) >> 9); 321 goto bail; 322 } 323 if (!(b2 = hpfs_get_sector(s, new_sec + i, &bh2))) { 324 brelse(bh1); 325 hpfs_free_sectors(s, new_sec, (pos + 511) >> 9); 326 goto bail; 327 } 328 memcpy(b2, b1, 512); 329 brelse(bh1); 330 mark_buffer_dirty(bh2); 331 brelse(bh2); 332 } 333 hpfs_free_sectors(s, fnode->ea_secno, len); 334 fnode->ea_secno = new_sec; 335 len = (pos + 511) >> 9; 336 } 337 } 338 if (fnode->ea_anode) { 339 if (hpfs_add_sector_to_btree(s, fnode->ea_secno, 340 0, len) != -1) { 341 len++; 342 } else { 343 goto bail; 344 } 345 } 346 } 347 h[0] = 0; 348 h[1] = strlen(key); 349 h[2] = size & 0xff; 350 h[3] = size >> 8; 351 if (hpfs_ea_write(s, fnode->ea_secno, fnode->ea_anode, fnode->ea_size_l, 4, h)) goto bail; 352 if (hpfs_ea_write(s, fnode->ea_secno, fnode->ea_anode, fnode->ea_size_l + 4, h[1] + 1, key)) goto bail; 353 if (hpfs_ea_write(s, fnode->ea_secno, fnode->ea_anode, fnode->ea_size_l + 5 + h[1], size, data)) goto bail; 354 fnode->ea_size_l = pos; 355 ret: 356 hpfs_i(inode)->i_ea_size += 5 + strlen(key) + size; 357 return; 358 bail: 359 if (fnode->ea_secno) 360 if (fnode->ea_anode) hpfs_truncate_btree(s, fnode->ea_secno, 1, (fnode->ea_size_l + 511) >> 9); 361 else hpfs_free_sectors(s, fnode->ea_secno + ((fnode->ea_size_l + 511) >> 9), len - ((fnode->ea_size_l + 511) >> 9)); 362 else fnode->ea_secno = fnode->ea_size_l = 0; 363 } 364 365