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