1 /* 2 * Copyright 2000-2002 by Hans Reiser, licensing governed by reiserfs/README 3 * 4 * GRUB -- GRand Unified Bootloader 5 * Copyright (C) 2000, 2001 Free Software Foundation, Inc. 6 * 7 * (C) Copyright 2003 - 2004 8 * Sysgo AG, <www.elinos.com>, Pavel Bartusek <pba@sysgo.com> 9 * 10 * 11 * SPDX-License-Identifier: GPL-2.0+ 12 */ 13 14 /* An implementation for the ReiserFS filesystem ported from GRUB. 15 * Some parts of this code (mainly the structures and defines) are 16 * from the original reiser fs code, as found in the linux kernel. 17 */ 18 19 #include <common.h> 20 #include <malloc.h> 21 #include <linux/ctype.h> 22 #include <linux/time.h> 23 #include <asm/byteorder.h> 24 #include <reiserfs.h> 25 26 #include "reiserfs_private.h" 27 28 #undef REISERDEBUG 29 30 /* Some parts of this code (mainly the structures and defines) are 31 * from the original reiser fs code, as found in the linux kernel. 32 */ 33 34 static char fsys_buf[FSYS_BUFLEN]; 35 static reiserfs_error_t errnum = ERR_NONE; 36 static int print_possibilities; 37 static unsigned int filepos, filemax; 38 39 static int 40 substring (const char *s1, const char *s2) 41 { 42 while (*s1 == *s2) 43 { 44 /* The strings match exactly. */ 45 if (! *(s1++)) 46 return 0; 47 s2 ++; 48 } 49 50 /* S1 is a substring of S2. */ 51 if (*s1 == 0) 52 return -1; 53 54 /* S1 isn't a substring. */ 55 return 1; 56 } 57 58 static void sd_print_item (struct item_head * ih, char * item) 59 { 60 char filetime[30]; 61 time_t ttime; 62 63 if (stat_data_v1 (ih)) { 64 struct stat_data_v1 * sd = (struct stat_data_v1 *)item; 65 ttime = sd_v1_mtime(sd); 66 ctime_r(&ttime, filetime); 67 printf ("%-10s %4hd %6d %6d %9d %24.24s", 68 bb_mode_string(sd_v1_mode(sd)), sd_v1_nlink(sd),sd_v1_uid(sd), sd_v1_gid(sd), 69 sd_v1_size(sd), filetime); 70 } else { 71 struct stat_data * sd = (struct stat_data *)item; 72 ttime = sd_v2_mtime(sd); 73 ctime_r(&ttime, filetime); 74 printf ("%-10s %4d %6d %6d %9d %24.24s", 75 bb_mode_string(sd_v2_mode(sd)), sd_v2_nlink(sd),sd_v2_uid(sd),sd_v2_gid(sd), 76 (__u32) sd_v2_size(sd), filetime); 77 } 78 } 79 80 static int 81 journal_read (int block, int len, char *buffer) 82 { 83 return reiserfs_devread ((INFO->journal_block + block) << INFO->blocksize_shift, 84 0, len, buffer); 85 } 86 87 /* Read a block from ReiserFS file system, taking the journal into 88 * account. If the block nr is in the journal, the block from the 89 * journal taken. 90 */ 91 static int 92 block_read (unsigned int blockNr, int start, int len, char *buffer) 93 { 94 int transactions = INFO->journal_transactions; 95 int desc_block = INFO->journal_first_desc; 96 int journal_mask = INFO->journal_block_count - 1; 97 int translatedNr = blockNr; 98 __u32 *journal_table = JOURNAL_START; 99 while (transactions-- > 0) 100 { 101 int i = 0; 102 int j_len; 103 if (__le32_to_cpu(*journal_table) != 0xffffffff) 104 { 105 /* Search for the blockNr in cached journal */ 106 j_len = __le32_to_cpu(*journal_table++); 107 while (i++ < j_len) 108 { 109 if (__le32_to_cpu(*journal_table++) == blockNr) 110 { 111 journal_table += j_len - i; 112 goto found; 113 } 114 } 115 } 116 else 117 { 118 /* This is the end of cached journal marker. The remaining 119 * transactions are still on disk. 120 */ 121 struct reiserfs_journal_desc desc; 122 struct reiserfs_journal_commit commit; 123 124 if (! journal_read (desc_block, sizeof (desc), (char *) &desc)) 125 return 0; 126 127 j_len = __le32_to_cpu(desc.j_len); 128 while (i < j_len && i < JOURNAL_TRANS_HALF) 129 if (__le32_to_cpu(desc.j_realblock[i++]) == blockNr) 130 goto found; 131 132 if (j_len >= JOURNAL_TRANS_HALF) 133 { 134 int commit_block = (desc_block + 1 + j_len) & journal_mask; 135 if (! journal_read (commit_block, 136 sizeof (commit), (char *) &commit)) 137 return 0; 138 while (i < j_len) 139 if (__le32_to_cpu(commit.j_realblock[i++ - JOURNAL_TRANS_HALF]) == blockNr) 140 goto found; 141 } 142 } 143 goto not_found; 144 145 found: 146 translatedNr = INFO->journal_block + ((desc_block + i) & journal_mask); 147 #ifdef REISERDEBUG 148 printf ("block_read: block %d is mapped to journal block %d.\n", 149 blockNr, translatedNr - INFO->journal_block); 150 #endif 151 /* We must continue the search, as this block may be overwritten 152 * in later transactions. 153 */ 154 not_found: 155 desc_block = (desc_block + 2 + j_len) & journal_mask; 156 } 157 return reiserfs_devread (translatedNr << INFO->blocksize_shift, start, len, buffer); 158 } 159 160 /* Init the journal data structure. We try to cache as much as 161 * possible in the JOURNAL_START-JOURNAL_END space, but if it is full 162 * we can still read the rest from the disk on demand. 163 * 164 * The first number of valid transactions and the descriptor block of the 165 * first valid transaction are held in INFO. The transactions are all 166 * adjacent, but we must take care of the journal wrap around. 167 */ 168 static int 169 journal_init (void) 170 { 171 unsigned int block_count = INFO->journal_block_count; 172 unsigned int desc_block; 173 unsigned int commit_block; 174 unsigned int next_trans_id; 175 struct reiserfs_journal_header header; 176 struct reiserfs_journal_desc desc; 177 struct reiserfs_journal_commit commit; 178 __u32 *journal_table = JOURNAL_START; 179 180 journal_read (block_count, sizeof (header), (char *) &header); 181 desc_block = __le32_to_cpu(header.j_first_unflushed_offset); 182 if (desc_block >= block_count) 183 return 0; 184 185 INFO->journal_first_desc = desc_block; 186 next_trans_id = __le32_to_cpu(header.j_last_flush_trans_id) + 1; 187 188 #ifdef REISERDEBUG 189 printf ("journal_init: last flushed %d\n", 190 __le32_to_cpu(header.j_last_flush_trans_id)); 191 #endif 192 193 while (1) 194 { 195 journal_read (desc_block, sizeof (desc), (char *) &desc); 196 if (substring (JOURNAL_DESC_MAGIC, desc.j_magic) > 0 197 || __le32_to_cpu(desc.j_trans_id) != next_trans_id 198 || __le32_to_cpu(desc.j_mount_id) != __le32_to_cpu(header.j_mount_id)) 199 /* no more valid transactions */ 200 break; 201 202 commit_block = (desc_block + __le32_to_cpu(desc.j_len) + 1) & (block_count - 1); 203 journal_read (commit_block, sizeof (commit), (char *) &commit); 204 if (__le32_to_cpu(desc.j_trans_id) != commit.j_trans_id 205 || __le32_to_cpu(desc.j_len) != __le32_to_cpu(commit.j_len)) 206 /* no more valid transactions */ 207 break; 208 209 #ifdef REISERDEBUG 210 printf ("Found valid transaction %d/%d at %d.\n", 211 __le32_to_cpu(desc.j_trans_id), __le32_to_cpu(desc.j_mount_id), desc_block); 212 #endif 213 214 next_trans_id++; 215 if (journal_table < JOURNAL_END) 216 { 217 if ((journal_table + 1 + __le32_to_cpu(desc.j_len)) >= JOURNAL_END) 218 { 219 /* The table is almost full; mark the end of the cached 220 * journal.*/ 221 *journal_table = __cpu_to_le32(0xffffffff); 222 journal_table = JOURNAL_END; 223 } 224 else 225 { 226 unsigned int i; 227 /* Cache the length and the realblock numbers in the table. 228 * The block number of descriptor can easily be computed. 229 * and need not to be stored here. 230 */ 231 232 /* both are in the little endian format */ 233 *journal_table++ = desc.j_len; 234 for (i = 0; i < __le32_to_cpu(desc.j_len) && i < JOURNAL_TRANS_HALF; i++) 235 { 236 /* both are in the little endian format */ 237 *journal_table++ = desc.j_realblock[i]; 238 #ifdef REISERDEBUG 239 printf ("block %d is in journal %d.\n", 240 __le32_to_cpu(desc.j_realblock[i]), desc_block); 241 #endif 242 } 243 for ( ; i < __le32_to_cpu(desc.j_len); i++) 244 { 245 /* both are in the little endian format */ 246 *journal_table++ = commit.j_realblock[i-JOURNAL_TRANS_HALF]; 247 #ifdef REISERDEBUG 248 printf ("block %d is in journal %d.\n", 249 __le32_to_cpu(commit.j_realblock[i-JOURNAL_TRANS_HALF]), 250 desc_block); 251 #endif 252 } 253 } 254 } 255 desc_block = (commit_block + 1) & (block_count - 1); 256 } 257 #ifdef REISERDEBUG 258 printf ("Transaction %d/%d at %d isn't valid.\n", 259 __le32_to_cpu(desc.j_trans_id), __le32_to_cpu(desc.j_mount_id), desc_block); 260 #endif 261 262 INFO->journal_transactions 263 = next_trans_id - __le32_to_cpu(header.j_last_flush_trans_id) - 1; 264 return errnum == 0; 265 } 266 267 /* check filesystem types and read superblock into memory buffer */ 268 int 269 reiserfs_mount (unsigned part_length) 270 { 271 struct reiserfs_super_block super; 272 int superblock = REISERFS_DISK_OFFSET_IN_BYTES >> SECTOR_BITS; 273 char *cache; 274 275 if (part_length < superblock + (sizeof (super) >> SECTOR_BITS) 276 || ! reiserfs_devread (superblock, 0, sizeof (struct reiserfs_super_block), 277 (char *) &super) 278 || (substring (REISER3FS_SUPER_MAGIC_STRING, super.s_magic) > 0 279 && substring (REISER2FS_SUPER_MAGIC_STRING, super.s_magic) > 0 280 && substring (REISERFS_SUPER_MAGIC_STRING, super.s_magic) > 0) 281 || (/* check that this is not a copy inside the journal log */ 282 sb_journal_block(&super) * sb_blocksize(&super) 283 <= REISERFS_DISK_OFFSET_IN_BYTES)) 284 { 285 /* Try old super block position */ 286 superblock = REISERFS_OLD_DISK_OFFSET_IN_BYTES >> SECTOR_BITS; 287 if (part_length < superblock + (sizeof (super) >> SECTOR_BITS) 288 || ! reiserfs_devread (superblock, 0, sizeof (struct reiserfs_super_block), 289 (char *) &super)) 290 return 0; 291 292 if (substring (REISER2FS_SUPER_MAGIC_STRING, super.s_magic) > 0 293 && substring (REISERFS_SUPER_MAGIC_STRING, super.s_magic) > 0) 294 { 295 /* pre journaling super block ? */ 296 if (substring (REISERFS_SUPER_MAGIC_STRING, 297 (char*) ((int) &super + 20)) > 0) 298 return 0; 299 300 set_sb_blocksize(&super, REISERFS_OLD_BLOCKSIZE); 301 set_sb_journal_block(&super, 0); 302 set_sb_version(&super, 0); 303 } 304 } 305 306 /* check the version number. */ 307 if (sb_version(&super) > REISERFS_MAX_SUPPORTED_VERSION) 308 return 0; 309 310 INFO->version = sb_version(&super); 311 INFO->blocksize = sb_blocksize(&super); 312 INFO->fullblocksize_shift = log2 (sb_blocksize(&super)); 313 INFO->blocksize_shift = INFO->fullblocksize_shift - SECTOR_BITS; 314 INFO->cached_slots = 315 (FSYSREISER_CACHE_SIZE >> INFO->fullblocksize_shift) - 1; 316 317 #ifdef REISERDEBUG 318 printf ("reiserfs_mount: version=%d, blocksize=%d\n", 319 INFO->version, INFO->blocksize); 320 #endif /* REISERDEBUG */ 321 322 /* Clear node cache. */ 323 memset (INFO->blocks, 0, sizeof (INFO->blocks)); 324 325 if (sb_blocksize(&super) < FSYSREISER_MIN_BLOCKSIZE 326 || sb_blocksize(&super) > FSYSREISER_MAX_BLOCKSIZE 327 || (SECTOR_SIZE << INFO->blocksize_shift) != sb_blocksize(&super)) 328 return 0; 329 330 /* Initialize journal code. If something fails we end with zero 331 * journal_transactions, so we don't access the journal at all. 332 */ 333 INFO->journal_transactions = 0; 334 if (sb_journal_block(&super) != 0 && super.s_journal_dev == 0) 335 { 336 INFO->journal_block = sb_journal_block(&super); 337 INFO->journal_block_count = sb_journal_size(&super); 338 if (is_power_of_two (INFO->journal_block_count)) 339 journal_init (); 340 341 /* Read in super block again, maybe it is in the journal */ 342 block_read (superblock >> INFO->blocksize_shift, 343 0, sizeof (struct reiserfs_super_block), (char *) &super); 344 } 345 346 if (! block_read (sb_root_block(&super), 0, INFO->blocksize, (char*) ROOT)) 347 return 0; 348 349 cache = ROOT; 350 INFO->tree_depth = __le16_to_cpu(BLOCKHEAD (cache)->blk_level); 351 352 #ifdef REISERDEBUG 353 printf ("root read_in: block=%d, depth=%d\n", 354 sb_root_block(&super), INFO->tree_depth); 355 #endif /* REISERDEBUG */ 356 357 if (INFO->tree_depth >= MAX_HEIGHT) 358 return 0; 359 if (INFO->tree_depth == DISK_LEAF_NODE_LEVEL) 360 { 361 /* There is only one node in the whole filesystem, 362 * which is simultanously leaf and root */ 363 memcpy (LEAF, ROOT, INFO->blocksize); 364 } 365 return 1; 366 } 367 368 /***************** TREE ACCESSING METHODS *****************************/ 369 370 /* I assume you are familiar with the ReiserFS tree, if not go to 371 * http://www.namesys.com/content_table.html 372 * 373 * My tree node cache is organized as following 374 * 0 ROOT node 375 * 1 LEAF node (if the ROOT is also a LEAF it is copied here 376 * 2-n other nodes on current path from bottom to top. 377 * if there is not enough space in the cache, the top most are 378 * omitted. 379 * 380 * I have only two methods to find a key in the tree: 381 * search_stat(dir_id, objectid) searches for the stat entry (always 382 * the first entry) of an object. 383 * next_key() gets the next key in tree order. 384 * 385 * This means, that I can only sequential reads of files are 386 * efficient, but this really doesn't hurt for grub. 387 */ 388 389 /* Read in the node at the current path and depth into the node cache. 390 * You must set INFO->blocks[depth] before. 391 */ 392 static char * 393 read_tree_node (unsigned int blockNr, int depth) 394 { 395 char* cache = CACHE(depth); 396 int num_cached = INFO->cached_slots; 397 if (depth < num_cached) 398 { 399 /* This is the cached part of the path. Check if same block is 400 * needed. 401 */ 402 if (blockNr == INFO->blocks[depth]) 403 return cache; 404 } 405 else 406 cache = CACHE(num_cached); 407 408 #ifdef REISERDEBUG 409 printf (" next read_in: block=%d (depth=%d)\n", 410 blockNr, depth); 411 #endif /* REISERDEBUG */ 412 if (! block_read (blockNr, 0, INFO->blocksize, cache)) 413 return 0; 414 /* Make sure it has the right node level */ 415 if (__le16_to_cpu(BLOCKHEAD (cache)->blk_level) != depth) 416 { 417 errnum = ERR_FSYS_CORRUPT; 418 return 0; 419 } 420 421 INFO->blocks[depth] = blockNr; 422 return cache; 423 } 424 425 /* Get the next key, i.e. the key following the last retrieved key in 426 * tree order. INFO->current_ih and 427 * INFO->current_info are adapted accordingly. */ 428 static int 429 next_key (void) 430 { 431 int depth; 432 struct item_head *ih = INFO->current_ih + 1; 433 char *cache; 434 435 #ifdef REISERDEBUG 436 printf ("next_key:\n old ih: key %d:%d:%d:%d version:%d\n", 437 __le32_to_cpu(INFO->current_ih->ih_key.k_dir_id), 438 __le32_to_cpu(INFO->current_ih->ih_key.k_objectid), 439 __le32_to_cpu(INFO->current_ih->ih_key.u.v1.k_offset), 440 __le32_to_cpu(INFO->current_ih->ih_key.u.v1.k_uniqueness), 441 __le16_to_cpu(INFO->current_ih->ih_version)); 442 #endif /* REISERDEBUG */ 443 444 if (ih == &ITEMHEAD[__le16_to_cpu(BLOCKHEAD (LEAF)->blk_nr_item)]) 445 { 446 depth = DISK_LEAF_NODE_LEVEL; 447 /* The last item, was the last in the leaf node. 448 * Read in the next block 449 */ 450 do 451 { 452 if (depth == INFO->tree_depth) 453 { 454 /* There are no more keys at all. 455 * Return a dummy item with MAX_KEY */ 456 ih = (struct item_head *) &BLOCKHEAD (LEAF)->blk_right_delim_key; 457 goto found; 458 } 459 depth++; 460 #ifdef REISERDEBUG 461 printf (" depth=%d, i=%d\n", depth, INFO->next_key_nr[depth]); 462 #endif /* REISERDEBUG */ 463 } 464 while (INFO->next_key_nr[depth] == 0); 465 466 if (depth == INFO->tree_depth) 467 cache = ROOT; 468 else if (depth <= INFO->cached_slots) 469 cache = CACHE (depth); 470 else 471 { 472 cache = read_tree_node (INFO->blocks[depth], depth); 473 if (! cache) 474 return 0; 475 } 476 477 do 478 { 479 int nr_item = __le16_to_cpu(BLOCKHEAD (cache)->blk_nr_item); 480 int key_nr = INFO->next_key_nr[depth]++; 481 #ifdef REISERDEBUG 482 printf (" depth=%d, i=%d/%d\n", depth, key_nr, nr_item); 483 #endif /* REISERDEBUG */ 484 if (key_nr == nr_item) 485 /* This is the last item in this block, set the next_key_nr to 0 */ 486 INFO->next_key_nr[depth] = 0; 487 488 cache = read_tree_node (dc_block_number(&(DC (cache)[key_nr])), --depth); 489 if (! cache) 490 return 0; 491 } 492 while (depth > DISK_LEAF_NODE_LEVEL); 493 494 ih = ITEMHEAD; 495 } 496 found: 497 INFO->current_ih = ih; 498 INFO->current_item = &LEAF[__le16_to_cpu(ih->ih_item_location)]; 499 #ifdef REISERDEBUG 500 printf (" new ih: key %d:%d:%d:%d version:%d\n", 501 __le32_to_cpu(INFO->current_ih->ih_key.k_dir_id), 502 __le32_to_cpu(INFO->current_ih->ih_key.k_objectid), 503 __le32_to_cpu(INFO->current_ih->ih_key.u.v1.k_offset), 504 __le32_to_cpu(INFO->current_ih->ih_key.u.v1.k_uniqueness), 505 __le16_to_cpu(INFO->current_ih->ih_version)); 506 #endif /* REISERDEBUG */ 507 return 1; 508 } 509 510 /* preconditions: reiserfs_mount already executed, therefore 511 * INFO block is valid 512 * returns: 0 if error (errnum is set), 513 * nonzero iff we were able to find the key successfully. 514 * postconditions: on a nonzero return, the current_ih and 515 * current_item fields describe the key that equals the 516 * searched key. INFO->next_key contains the next key after 517 * the searched key. 518 * side effects: messes around with the cache. 519 */ 520 static int 521 search_stat (__u32 dir_id, __u32 objectid) 522 { 523 char *cache; 524 int depth; 525 int nr_item; 526 int i; 527 struct item_head *ih; 528 #ifdef REISERDEBUG 529 printf ("search_stat:\n key %d:%d:0:0\n", dir_id, objectid); 530 #endif /* REISERDEBUG */ 531 532 depth = INFO->tree_depth; 533 cache = ROOT; 534 535 while (depth > DISK_LEAF_NODE_LEVEL) 536 { 537 struct key *key; 538 nr_item = __le16_to_cpu(BLOCKHEAD (cache)->blk_nr_item); 539 540 key = KEY (cache); 541 542 for (i = 0; i < nr_item; i++) 543 { 544 if (__le32_to_cpu(key->k_dir_id) > dir_id 545 || (__le32_to_cpu(key->k_dir_id) == dir_id 546 && (__le32_to_cpu(key->k_objectid) > objectid 547 || (__le32_to_cpu(key->k_objectid) == objectid 548 && (__le32_to_cpu(key->u.v1.k_offset) 549 | __le32_to_cpu(key->u.v1.k_uniqueness)) > 0)))) 550 break; 551 key++; 552 } 553 554 #ifdef REISERDEBUG 555 printf (" depth=%d, i=%d/%d\n", depth, i, nr_item); 556 #endif /* REISERDEBUG */ 557 INFO->next_key_nr[depth] = (i == nr_item) ? 0 : i+1; 558 cache = read_tree_node (dc_block_number(&(DC (cache)[i])), --depth); 559 if (! cache) 560 return 0; 561 } 562 563 /* cache == LEAF */ 564 nr_item = __le16_to_cpu(BLOCKHEAD (LEAF)->blk_nr_item); 565 ih = ITEMHEAD; 566 for (i = 0; i < nr_item; i++) 567 { 568 if (__le32_to_cpu(ih->ih_key.k_dir_id) == dir_id 569 && __le32_to_cpu(ih->ih_key.k_objectid) == objectid 570 && __le32_to_cpu(ih->ih_key.u.v1.k_offset) == 0 571 && __le32_to_cpu(ih->ih_key.u.v1.k_uniqueness) == 0) 572 { 573 #ifdef REISERDEBUG 574 printf (" depth=%d, i=%d/%d\n", depth, i, nr_item); 575 #endif /* REISERDEBUG */ 576 INFO->current_ih = ih; 577 INFO->current_item = &LEAF[__le16_to_cpu(ih->ih_item_location)]; 578 return 1; 579 } 580 ih++; 581 } 582 errnum = ERR_FSYS_CORRUPT; 583 return 0; 584 } 585 586 int 587 reiserfs_read (char *buf, unsigned len) 588 { 589 unsigned int blocksize; 590 unsigned int offset; 591 unsigned int to_read; 592 char *prev_buf = buf; 593 594 #ifdef REISERDEBUG 595 printf ("reiserfs_read: filepos=%d len=%d, offset=%Lx\n", 596 filepos, len, (__u64) IH_KEY_OFFSET (INFO->current_ih) - 1); 597 #endif /* REISERDEBUG */ 598 599 if (__le32_to_cpu(INFO->current_ih->ih_key.k_objectid) != INFO->fileinfo.k_objectid 600 || IH_KEY_OFFSET (INFO->current_ih) > filepos + 1) 601 { 602 search_stat (INFO->fileinfo.k_dir_id, INFO->fileinfo.k_objectid); 603 goto get_next_key; 604 } 605 606 while (! errnum) 607 { 608 if (__le32_to_cpu(INFO->current_ih->ih_key.k_objectid) != INFO->fileinfo.k_objectid) { 609 break; 610 } 611 612 offset = filepos - IH_KEY_OFFSET (INFO->current_ih) + 1; 613 blocksize = __le16_to_cpu(INFO->current_ih->ih_item_len); 614 615 #ifdef REISERDEBUG 616 printf (" loop: filepos=%d len=%d, offset=%d blocksize=%d\n", 617 filepos, len, offset, blocksize); 618 #endif /* REISERDEBUG */ 619 620 if (IH_KEY_ISTYPE(INFO->current_ih, TYPE_DIRECT) 621 && offset < blocksize) 622 { 623 #ifdef REISERDEBUG 624 printf ("direct_read: offset=%d, blocksize=%d\n", 625 offset, blocksize); 626 #endif /* REISERDEBUG */ 627 to_read = blocksize - offset; 628 if (to_read > len) 629 to_read = len; 630 631 memcpy (buf, INFO->current_item + offset, to_read); 632 goto update_buf_len; 633 } 634 else if (IH_KEY_ISTYPE(INFO->current_ih, TYPE_INDIRECT)) 635 { 636 blocksize = (blocksize >> 2) << INFO->fullblocksize_shift; 637 #ifdef REISERDEBUG 638 printf ("indirect_read: offset=%d, blocksize=%d\n", 639 offset, blocksize); 640 #endif /* REISERDEBUG */ 641 642 while (offset < blocksize) 643 { 644 __u32 blocknr = __le32_to_cpu(((__u32 *) INFO->current_item) 645 [offset >> INFO->fullblocksize_shift]); 646 int blk_offset = offset & (INFO->blocksize-1); 647 to_read = INFO->blocksize - blk_offset; 648 if (to_read > len) 649 to_read = len; 650 651 /* Journal is only for meta data. Data blocks can be read 652 * directly without using block_read 653 */ 654 reiserfs_devread (blocknr << INFO->blocksize_shift, 655 blk_offset, to_read, buf); 656 update_buf_len: 657 len -= to_read; 658 buf += to_read; 659 offset += to_read; 660 filepos += to_read; 661 if (len == 0) 662 goto done; 663 } 664 } 665 get_next_key: 666 next_key (); 667 } 668 done: 669 return errnum ? 0 : buf - prev_buf; 670 } 671 672 673 /* preconditions: reiserfs_mount already executed, therefore 674 * INFO block is valid 675 * returns: 0 if error, nonzero iff we were able to find the file successfully 676 * postconditions: on a nonzero return, INFO->fileinfo contains the info 677 * of the file we were trying to look up, filepos is 0 and filemax is 678 * the size of the file. 679 */ 680 static int 681 reiserfs_dir (char *dirname) 682 { 683 struct reiserfs_de_head *de_head; 684 char *rest, ch; 685 __u32 dir_id, objectid, parent_dir_id = 0, parent_objectid = 0; 686 #ifndef STAGE1_5 687 int do_possibilities = 0; 688 #endif /* ! STAGE1_5 */ 689 char linkbuf[PATH_MAX]; /* buffer for following symbolic links */ 690 int link_count = 0; 691 int mode; 692 693 dir_id = REISERFS_ROOT_PARENT_OBJECTID; 694 objectid = REISERFS_ROOT_OBJECTID; 695 696 while (1) 697 { 698 #ifdef REISERDEBUG 699 printf ("dirname=%s\n", dirname); 700 #endif /* REISERDEBUG */ 701 702 /* Search for the stat info first. */ 703 if (! search_stat (dir_id, objectid)) 704 return 0; 705 706 #ifdef REISERDEBUG 707 printf ("sd_mode=%x sd_size=%d\n", 708 stat_data_v1(INFO->current_ih) ? sd_v1_mode((struct stat_data_v1 *) INFO->current_item) : 709 sd_v2_mode((struct stat_data *) (INFO->current_item)), 710 stat_data_v1(INFO->current_ih) ? sd_v1_size((struct stat_data_v1 *) INFO->current_item) : 711 sd_v2_size((struct stat_data *) INFO->current_item) 712 ); 713 714 #endif /* REISERDEBUG */ 715 mode = stat_data_v1(INFO->current_ih) ? 716 sd_v1_mode((struct stat_data_v1 *) INFO->current_item) : 717 sd_v2_mode((struct stat_data *) INFO->current_item); 718 719 /* If we've got a symbolic link, then chase it. */ 720 if (S_ISLNK (mode)) 721 { 722 unsigned int len; 723 if (++link_count > MAX_LINK_COUNT) 724 { 725 errnum = ERR_SYMLINK_LOOP; 726 return 0; 727 } 728 729 /* Get the symlink size. */ 730 filemax = stat_data_v1(INFO->current_ih) ? 731 sd_v1_size((struct stat_data_v1 *) INFO->current_item) : 732 sd_v2_size((struct stat_data *) INFO->current_item); 733 734 /* Find out how long our remaining name is. */ 735 len = 0; 736 while (dirname[len] && !isspace (dirname[len])) 737 len++; 738 739 if (filemax + len > sizeof (linkbuf) - 1) 740 { 741 errnum = ERR_FILELENGTH; 742 return 0; 743 } 744 745 /* Copy the remaining name to the end of the symlink data. 746 Note that DIRNAME and LINKBUF may overlap! */ 747 memmove (linkbuf + filemax, dirname, len+1); 748 749 INFO->fileinfo.k_dir_id = dir_id; 750 INFO->fileinfo.k_objectid = objectid; 751 filepos = 0; 752 if (! next_key () 753 || reiserfs_read (linkbuf, filemax) != filemax) 754 { 755 if (! errnum) 756 errnum = ERR_FSYS_CORRUPT; 757 return 0; 758 } 759 760 #ifdef REISERDEBUG 761 printf ("symlink=%s\n", linkbuf); 762 #endif /* REISERDEBUG */ 763 764 dirname = linkbuf; 765 if (*dirname == '/') 766 { 767 /* It's an absolute link, so look it up in root. */ 768 dir_id = REISERFS_ROOT_PARENT_OBJECTID; 769 objectid = REISERFS_ROOT_OBJECTID; 770 } 771 else 772 { 773 /* Relative, so look it up in our parent directory. */ 774 dir_id = parent_dir_id; 775 objectid = parent_objectid; 776 } 777 778 /* Now lookup the new name. */ 779 continue; 780 } 781 782 /* if we have a real file (and we're not just printing possibilities), 783 then this is where we want to exit */ 784 785 if (! *dirname || isspace (*dirname)) 786 { 787 if (! S_ISREG (mode)) 788 { 789 errnum = ERR_BAD_FILETYPE; 790 return 0; 791 } 792 793 filepos = 0; 794 filemax = stat_data_v1(INFO->current_ih) ? 795 sd_v1_size((struct stat_data_v1 *) INFO->current_item) : 796 sd_v2_size((struct stat_data *) INFO->current_item); 797 #if 0 798 /* If this is a new stat data and size is > 4GB set filemax to 799 * maximum 800 */ 801 if (__le16_to_cpu(INFO->current_ih->ih_version) == ITEM_VERSION_2 802 && sd_size_hi((struct stat_data *) INFO->current_item) > 0) 803 filemax = 0xffffffff; 804 #endif 805 INFO->fileinfo.k_dir_id = dir_id; 806 INFO->fileinfo.k_objectid = objectid; 807 return next_key (); 808 } 809 810 /* continue with the file/directory name interpretation */ 811 while (*dirname == '/') 812 dirname++; 813 if (! S_ISDIR (mode)) 814 { 815 errnum = ERR_BAD_FILETYPE; 816 return 0; 817 } 818 for (rest = dirname; (ch = *rest) && ! isspace (ch) && ch != '/'; rest++); 819 *rest = 0; 820 821 # ifndef STAGE1_5 822 if (print_possibilities && ch != '/') 823 do_possibilities = 1; 824 # endif /* ! STAGE1_5 */ 825 826 while (1) 827 { 828 char *name_end; 829 int num_entries; 830 831 if (! next_key ()) 832 return 0; 833 #ifdef REISERDEBUG 834 printf ("ih: key %d:%d:%d:%d version:%d\n", 835 __le32_to_cpu(INFO->current_ih->ih_key.k_dir_id), 836 __le32_to_cpu(INFO->current_ih->ih_key.k_objectid), 837 __le32_to_cpu(INFO->current_ih->ih_key.u.v1.k_offset), 838 __le32_to_cpu(INFO->current_ih->ih_key.u.v1.k_uniqueness), 839 __le16_to_cpu(INFO->current_ih->ih_version)); 840 #endif /* REISERDEBUG */ 841 842 if (__le32_to_cpu(INFO->current_ih->ih_key.k_objectid) != objectid) 843 break; 844 845 name_end = INFO->current_item + __le16_to_cpu(INFO->current_ih->ih_item_len); 846 de_head = (struct reiserfs_de_head *) INFO->current_item; 847 num_entries = __le16_to_cpu(INFO->current_ih->u.ih_entry_count); 848 while (num_entries > 0) 849 { 850 char *filename = INFO->current_item + deh_location(de_head); 851 char tmp = *name_end; 852 if ((deh_state(de_head) & DEH_Visible)) 853 { 854 int cmp; 855 /* Directory names in ReiserFS are not null 856 * terminated. We write a temporary 0 behind it. 857 * NOTE: that this may overwrite the first block in 858 * the tree cache. That doesn't hurt as long as we 859 * don't call next_key () in between. 860 */ 861 *name_end = 0; 862 cmp = substring (dirname, filename); 863 *name_end = tmp; 864 # ifndef STAGE1_5 865 if (do_possibilities) 866 { 867 if (cmp <= 0) 868 { 869 char fn[PATH_MAX]; 870 struct fsys_reiser_info info_save; 871 872 if (print_possibilities > 0) 873 print_possibilities = -print_possibilities; 874 *name_end = 0; 875 strcpy(fn, filename); 876 *name_end = tmp; 877 878 /* If NAME is "." or "..", do not count it. */ 879 if (strcmp (fn, ".") != 0 && strcmp (fn, "..") != 0) { 880 memcpy(&info_save, INFO, sizeof(struct fsys_reiser_info)); 881 search_stat (deh_dir_id(de_head), deh_objectid(de_head)); 882 sd_print_item(INFO->current_ih, INFO->current_item); 883 printf(" %s\n", fn); 884 search_stat (dir_id, objectid); 885 memcpy(INFO, &info_save, sizeof(struct fsys_reiser_info)); 886 } 887 } 888 } 889 else 890 # endif /* ! STAGE1_5 */ 891 if (cmp == 0) 892 goto found; 893 } 894 /* The beginning of this name marks the end of the next name. 895 */ 896 name_end = filename; 897 de_head++; 898 num_entries--; 899 } 900 } 901 902 # ifndef STAGE1_5 903 if (print_possibilities < 0) 904 return 1; 905 # endif /* ! STAGE1_5 */ 906 907 errnum = ERR_FILE_NOT_FOUND; 908 *rest = ch; 909 return 0; 910 911 found: 912 *rest = ch; 913 dirname = rest; 914 915 parent_dir_id = dir_id; 916 parent_objectid = objectid; 917 dir_id = deh_dir_id(de_head); 918 objectid = deh_objectid(de_head); 919 } 920 } 921 922 /* 923 * U-Boot interface functions 924 */ 925 926 /* 927 * List given directory 928 * 929 * RETURN: 0 - OK, else grub_error_t errnum 930 */ 931 int 932 reiserfs_ls (char *dirname) 933 { 934 char *dir_slash; 935 int res; 936 937 errnum = 0; 938 dir_slash = malloc(strlen(dirname) + 1); 939 if (dir_slash == NULL) { 940 return ERR_NUMBER_OVERFLOW; 941 } 942 strcpy(dir_slash, dirname); 943 /* add "/" to the directory name */ 944 strcat(dir_slash, "/"); 945 946 print_possibilities = 1; 947 res = reiserfs_dir (dir_slash); 948 free(dir_slash); 949 if (!res || errnum) { 950 return errnum; 951 } 952 953 return 0; 954 } 955 956 /* 957 * Open file for reading 958 * 959 * RETURN: >0 - OK, size of opened file 960 * <0 - ERROR -grub_error_t errnum 961 */ 962 int 963 reiserfs_open (char *filename) 964 { 965 /* open the file */ 966 errnum = 0; 967 print_possibilities = 0; 968 if (!reiserfs_dir (filename) || errnum) { 969 return -errnum; 970 } 971 return filemax; 972 } 973