Changeset 7bc4508 in mainline for uspace/lib/ext4/libext4_directory.c
- Timestamp:
- 2011-10-18T19:58:36Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 7bd2c19
- Parents:
- 12f55220
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/ext4/libext4_directory.c
r12f55220 r7bc4508 66 66 } 67 67 68 uint8_t ext4_directory_dx_root_info_get_hash_version(ext4_directory_dx_root_info_t *root_info) 69 { 70 return root_info->hash_version; 71 } 72 73 uint8_t ext4_directory_dx_root_info_get_info_length(ext4_directory_dx_root_info_t *root_info) 74 { 75 return root_info->info_length; 76 } 77 78 uint8_t ext4_directory_dx_root_info_get_indirect_levels(ext4_directory_dx_root_info_t *root_info) 79 { 80 return root_info->indirect_levels; 81 } 82 83 uint16_t ext4_directory_dx_countlimit_get_limit(ext4_directory_dx_countlimit_t *countlimit) 84 { 85 return uint16_t_le2host(countlimit->limit); 86 } 87 uint16_t ext4_directory_dx_countlimit_get_count(ext4_directory_dx_countlimit_t *countlimit) 88 { 89 return uint16_t_le2host(countlimit->count); 90 } 91 92 uint32_t ext4_directory_dx_entry_get_hash(ext4_directory_dx_entry_t *entry) 93 { 94 return uint32_t_le2host(entry->hash); 95 } 96 97 uint32_t ext4_directory_dx_entry_get_block(ext4_directory_dx_entry_t *entry) 98 { 99 return uint32_t_le2host(entry->block); 100 } 101 102 103 68 104 int ext4_directory_iterator_init(ext4_directory_iterator_t *it, 69 105 ext4_filesystem_t *fs, ext4_inode_ref_t *inode_ref, aoff64_t pos) … … 209 245 } 210 246 247 int ext4_directory_dx_find_entry(ext4_directory_iterator_t *it, 248 ext4_filesystem_t *fs, ext4_inode_ref_t *inode_ref, const char *name) 249 { 250 int rc; 251 uint32_t fblock; 252 block_t *phys_block; 253 ext4_directory_dx_root_t *root; 254 uint32_t hash; 255 ext4_directory_dx_hash_info_t hinfo; 256 257 // get direct block 0 (index root) 258 rc = ext4_filesystem_get_inode_data_block_index(fs, inode_ref->inode, 0, &fblock); 259 if (rc != EOK) { 260 return rc; 261 } 262 263 rc = block_get(&phys_block, fs->device, fblock, BLOCK_FLAGS_NONE); 264 if (rc != EOK) { 265 it->current_block = NULL; 266 return rc; 267 } 268 269 // Now having index root 270 root = (ext4_directory_dx_root_t *)phys_block->data; 271 272 // Check hash version - only if supported 273 EXT4FS_DBG("hash_version = \%u", root->info.hash_version); 274 275 // Check unused flags 276 if (root->info.unused_flags != 0) { 277 EXT4FS_DBG("ERR: unused_flags = \%u", root->info.unused_flags); 278 block_put(phys_block); 279 return EXT4_ERR_BAD_DX_DIR; 280 } 281 282 // Check indirect levels 283 if (root->info.indirect_levels > 1) { 284 EXT4FS_DBG("ERR: indirect_levels = \%u", root->info.indirect_levels); 285 block_put(phys_block); 286 return EXT4_ERR_BAD_DX_DIR; 287 } 288 289 uint32_t bs = ext4_superblock_get_block_size(fs->superblock); 290 291 uint32_t entry_space = bs - 2* sizeof(ext4_directory_dx_dot_entry_t) - sizeof(ext4_directory_dx_root_info_t); 292 entry_space = entry_space / sizeof(ext4_directory_dx_entry_t); 293 294 295 uint32_t limit = ext4_directory_dx_countlimit_get_limit((ext4_directory_dx_countlimit_t *)&root->entries); 296 uint32_t count = ext4_directory_dx_countlimit_get_count((ext4_directory_dx_countlimit_t *)&root->entries); 297 298 if (limit != entry_space) { 299 block_put(phys_block); 300 return EXT4_ERR_BAD_DX_DIR; 301 } 302 303 if ((count == 0) || (count > limit)) { 304 block_put(phys_block); 305 return EXT4_ERR_BAD_DX_DIR; 306 } 307 308 /* DEBUG list 309 for (uint16_t i = 0; i < count; ++i) { 310 uint32_t hash = ext4_directory_dx_entry_get_hash(&root->entries[i]); 311 uint32_t block = ext4_directory_dx_entry_get_block(&root->entries[i]); 312 EXT4FS_DBG("hash = \%u, block = \%u", hash, block); 313 } 314 */ 315 316 hinfo.hash_version = ext4_directory_dx_root_info_get_hash_version(&root->info); 317 if ((hinfo.hash_version <= EXT4_DIRECTORY_DX_HASH_TEA) 318 && (ext4_superblock_has_flag(fs->superblock, EXT4_SUPERBLOCK_FLAGS_UNSIGNED_HASH))) { 319 // 3 is magic from ext4 linux implementation 320 hinfo.hash_version += 3; 321 } 322 323 hinfo.seed = ext4_superblock_get_hash_seed(fs->superblock); 324 hinfo.hash = 0; 325 if (name) { 326 ext4_directory_hash(&hinfo, name); 327 } 328 329 hash = hinfo.hash; 330 331 ext4_directory_dx_entry_t *p, *q, *m; 332 333 // TODO cycle 334 // while (true) 335 336 p = &root->entries[1]; 337 q = &root->entries[count - 1]; 338 339 while (p <= q) { 340 m = p + (q - p) / 2; 341 if (ext4_directory_dx_entry_get_hash(m) > hash) { 342 q = m - 1; 343 } else { 344 p = m + 1; 345 } 346 } 347 348 /* TODO move to leaf or next node 349 at = p - 1; 350 dxtrace(printk(" %x->%u\n", at == entries? 0: dx_get_hash(at), dx_get_block(at))); 351 frame->bh = bh; 352 frame->entries = entries; 353 frame->at = at; 354 355 if (indirect == 0) { 356 // TODO write return values !!! 357 return EOK; 358 } 359 360 indirect--; 361 362 // TODO read next block 363 if (!(bh = ext4_bread (NULL,dir, dx_get_block(at), 0, err))) 364 goto fail2; 365 at = entries = ((struct dx_node *) bh->b_data)->entries; 366 if (dx_get_limit(entries) != dx_node_limit (dir)) { 367 ext4_warning(dir->i_sb, "dx entry: limit != node limit"); 368 brelse(bh); 369 *err = ERR_BAD_DX_DIR; 370 goto fail2; 371 } 372 frame++; 373 frame->bh = NULL; 374 */ 375 376 // } END WHILE 377 378 379 // TODO delete it !!! 380 return EXT4_ERR_BAD_DX_DIR; 381 382 if ((it->current == NULL) || (it->current->inode == 0)) { 383 return ENOENT; 384 } 385 386 return EOK; 387 } 388 389 void ext4_directory_hash(ext4_directory_dx_hash_info_t *hinfo, const char* name) 390 { 391 // TODO 392 } 211 393 212 394 /**
Note:
See TracChangeset
for help on using the changeset viewer.