1 /* 2 * inode.c --- utility routines to read and write inodes 3 * 4 * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o. 5 * 6 * %Begin-Header% 7 * This file may be redistributed under the terms of the GNU Library 8 * General Public License, version 2. 9 * %End-Header% 10 */ 11 12 #include "config.h" 13 #include <stdio.h> 14 #include <string.h> 15 #if HAVE_UNISTD_H 16 #include <unistd.h> 17 #endif 18 #if HAVE_ERRNO_H 19 #include <errno.h> 20 #endif 21 #include <time.h> 22 #if HAVE_SYS_STAT_H 23 #include <sys/stat.h> 24 #endif 25 #if HAVE_SYS_TYPES_H 26 #include <sys/types.h> 27 #endif 28 29 #include "ext2_fs.h" 30 #include "ext2fsP.h" 31 #include "e2image.h" 32 33 #define IBLOCK_STATUS_CSUMS_OK 1 34 #define IBLOCK_STATUS_INSANE 2 35 #define SCAN_BLOCK_STATUS(scan) ((scan)->temp_buffer + (scan)->inode_size) 36 37 struct ext2_struct_inode_scan { 38 errcode_t magic; 39 ext2_filsys fs; 40 ext2_ino_t current_inode; 41 blk64_t current_block; 42 dgrp_t current_group; 43 ext2_ino_t inodes_left; 44 blk_t blocks_left; 45 dgrp_t groups_left; 46 blk_t inode_buffer_blocks; 47 char * inode_buffer; 48 int inode_size; 49 char * ptr; 50 int bytes_left; 51 char *temp_buffer; 52 errcode_t (*done_group)(ext2_filsys fs, 53 ext2_inode_scan scan, 54 dgrp_t group, 55 void * priv_data); 56 void * done_group_data; 57 int bad_block_ptr; 58 int scan_flags; 59 int reserved[6]; 60 }; 61 62 /* 63 * This routine flushes the icache, if it exists. 64 */ 65 errcode_t ext2fs_flush_icache(ext2_filsys fs) 66 { 67 unsigned i; 68 69 if (!fs->icache) 70 return 0; 71 72 for (i=0; i < fs->icache->cache_size; i++) 73 fs->icache->cache[i].ino = 0; 74 75 fs->icache->buffer_blk = 0; 76 return 0; 77 } 78 79 /* 80 * Free the inode cache structure 81 */ 82 void ext2fs_free_inode_cache(struct ext2_inode_cache *icache) 83 { 84 unsigned i; 85 86 if (--icache->refcount) 87 return; 88 if (icache->buffer) 89 ext2fs_free_mem(&icache->buffer); 90 for (i = 0; i < icache->cache_size; i++) 91 ext2fs_free_mem(&icache->cache[i].inode); 92 if (icache->cache) 93 ext2fs_free_mem(&icache->cache); 94 icache->buffer_blk = 0; 95 ext2fs_free_mem(&icache); 96 } 97 98 errcode_t ext2fs_create_inode_cache(ext2_filsys fs, unsigned int cache_size) 99 { 100 unsigned i; 101 errcode_t retval; 102 103 if (fs->icache) 104 return 0; 105 retval = ext2fs_get_mem(sizeof(struct ext2_inode_cache), &fs->icache); 106 if (retval) 107 return retval; 108 109 memset(fs->icache, 0, sizeof(struct ext2_inode_cache)); 110 retval = ext2fs_get_mem(fs->blocksize, &fs->icache->buffer); 111 if (retval) 112 goto errout; 113 114 fs->icache->buffer_blk = 0; 115 fs->icache->cache_last = -1; 116 fs->icache->cache_size = cache_size; 117 fs->icache->refcount = 1; 118 retval = ext2fs_get_array(fs->icache->cache_size, 119 sizeof(struct ext2_inode_cache_ent), 120 &fs->icache->cache); 121 if (retval) 122 goto errout; 123 124 for (i = 0; i < fs->icache->cache_size; i++) { 125 retval = ext2fs_get_mem(EXT2_INODE_SIZE(fs->super), 126 &fs->icache->cache[i].inode); 127 if (retval) 128 goto errout; 129 } 130 131 ext2fs_flush_icache(fs); 132 return 0; 133 errout: 134 ext2fs_free_inode_cache(fs->icache); 135 fs->icache = 0; 136 return retval; 137 } 138 139 errcode_t ext2fs_open_inode_scan(ext2_filsys fs, int buffer_blocks, 140 ext2_inode_scan *ret_scan) 141 { 142 ext2_inode_scan scan; 143 errcode_t retval; 144 errcode_t (*save_get_blocks)(ext2_filsys f, ext2_ino_t ino, blk_t *blocks); 145 146 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); 147 if (fs->blocksize < 1024) 148 return EXT2_FILSYS_CORRUPTED; /* Should never happen */ 149 150 /* 151 * If fs->badblocks isn't set, then set it --- since the inode 152 * scanning functions require it. 153 */ 154 if (fs->badblocks == 0) { 155 /* 156 * Temporarily save fs->get_blocks and set it to zero, 157 * for compatibility with old e2fsck's. 158 */ 159 save_get_blocks = fs->get_blocks; 160 fs->get_blocks = 0; 161 retval = ext2fs_read_bb_inode(fs, &fs->badblocks); 162 if (retval && fs->badblocks) { 163 ext2fs_badblocks_list_free(fs->badblocks); 164 fs->badblocks = 0; 165 } 166 fs->get_blocks = save_get_blocks; 167 } 168 169 retval = ext2fs_get_mem(sizeof(struct ext2_struct_inode_scan), &scan); 170 if (retval) 171 return retval; 172 memset(scan, 0, sizeof(struct ext2_struct_inode_scan)); 173 174 scan->magic = EXT2_ET_MAGIC_INODE_SCAN; 175 scan->fs = fs; 176 scan->inode_size = EXT2_INODE_SIZE(fs->super); 177 scan->bytes_left = 0; 178 scan->current_group = 0; 179 scan->groups_left = fs->group_desc_count - 1; 180 scan->inode_buffer_blocks = buffer_blocks ? buffer_blocks : 181 EXT2_INODE_SCAN_DEFAULT_BUFFER_BLOCKS; 182 scan->current_block = ext2fs_inode_table_loc(scan->fs, 183 scan->current_group); 184 if (scan->current_block && 185 ((scan->current_block < fs->super->s_first_data_block) || 186 (scan->current_block + fs->inode_blocks_per_group - 1 >= 187 ext2fs_blocks_count(fs->super)))) { 188 ext2fs_free_mem(&scan); 189 return EXT2_ET_GDESC_BAD_INODE_TABLE; 190 } 191 192 scan->inodes_left = EXT2_INODES_PER_GROUP(scan->fs->super); 193 scan->blocks_left = scan->fs->inode_blocks_per_group; 194 if (ext2fs_has_group_desc_csum(fs)) { 195 __u32 unused = ext2fs_bg_itable_unused(fs, scan->current_group); 196 if (scan->inodes_left > unused) 197 scan->inodes_left -= unused; 198 else 199 scan->inodes_left = 0; 200 scan->blocks_left = 201 (scan->inodes_left + 202 (fs->blocksize / scan->inode_size - 1)) * 203 scan->inode_size / fs->blocksize; 204 } 205 retval = io_channel_alloc_buf(fs->io, scan->inode_buffer_blocks, 206 &scan->inode_buffer); 207 scan->done_group = 0; 208 scan->done_group_data = 0; 209 scan->bad_block_ptr = 0; 210 if (retval) { 211 ext2fs_free_mem(&scan); 212 return retval; 213 } 214 retval = ext2fs_get_mem(scan->inode_size + scan->inode_buffer_blocks, 215 &scan->temp_buffer); 216 if (retval) { 217 ext2fs_free_mem(&scan->inode_buffer); 218 ext2fs_free_mem(&scan); 219 return retval; 220 } 221 memset(SCAN_BLOCK_STATUS(scan), 0, scan->inode_buffer_blocks); 222 if (scan->fs->badblocks && scan->fs->badblocks->num) 223 scan->scan_flags |= EXT2_SF_CHK_BADBLOCKS; 224 if (ext2fs_has_group_desc_csum(fs)) 225 scan->scan_flags |= EXT2_SF_DO_LAZY; 226 *ret_scan = scan; 227 return 0; 228 } 229 230 void ext2fs_close_inode_scan(ext2_inode_scan scan) 231 { 232 if (!scan || (scan->magic != EXT2_ET_MAGIC_INODE_SCAN)) 233 return; 234 235 ext2fs_free_mem(&scan->inode_buffer); 236 scan->inode_buffer = NULL; 237 ext2fs_free_mem(&scan->temp_buffer); 238 scan->temp_buffer = NULL; 239 ext2fs_free_mem(&scan); 240 return; 241 } 242 243 void ext2fs_set_inode_callback(ext2_inode_scan scan, 244 errcode_t (*done_group)(ext2_filsys fs, 245 ext2_inode_scan scan, 246 dgrp_t group, 247 void * priv_data), 248 void *done_group_data) 249 { 250 if (!scan || (scan->magic != EXT2_ET_MAGIC_INODE_SCAN)) 251 return; 252 253 scan->done_group = done_group; 254 scan->done_group_data = done_group_data; 255 } 256 257 int ext2fs_inode_scan_flags(ext2_inode_scan scan, int set_flags, 258 int clear_flags) 259 { 260 int old_flags; 261 262 if (!scan || (scan->magic != EXT2_ET_MAGIC_INODE_SCAN)) 263 return 0; 264 265 old_flags = scan->scan_flags; 266 scan->scan_flags &= ~clear_flags; 267 scan->scan_flags |= set_flags; 268 return old_flags; 269 } 270 271 /* 272 * This function is called by ext2fs_get_next_inode when it needs to 273 * get ready to read in a new blockgroup. 274 */ 275 static errcode_t get_next_blockgroup(ext2_inode_scan scan) 276 { 277 ext2_filsys fs = scan->fs; 278 279 scan->current_group++; 280 scan->groups_left--; 281 282 scan->current_block = ext2fs_inode_table_loc(scan->fs, 283 scan->current_group); 284 scan->current_inode = scan->current_group * 285 EXT2_INODES_PER_GROUP(fs->super); 286 287 scan->bytes_left = 0; 288 scan->inodes_left = EXT2_INODES_PER_GROUP(fs->super); 289 scan->blocks_left = fs->inode_blocks_per_group; 290 if (ext2fs_has_group_desc_csum(fs)) { 291 __u32 unused = ext2fs_bg_itable_unused(fs, scan->current_group); 292 if (scan->inodes_left > unused) 293 scan->inodes_left -= unused; 294 else 295 scan->inodes_left = 0; 296 scan->blocks_left = 297 (scan->inodes_left + 298 (fs->blocksize / scan->inode_size - 1)) * 299 scan->inode_size / fs->blocksize; 300 } 301 if (scan->current_block && 302 ((scan->current_block < fs->super->s_first_data_block) || 303 (scan->current_block + fs->inode_blocks_per_group - 1 >= 304 ext2fs_blocks_count(fs->super)))) 305 return EXT2_ET_GDESC_BAD_INODE_TABLE; 306 return 0; 307 } 308 309 errcode_t ext2fs_inode_scan_goto_blockgroup(ext2_inode_scan scan, 310 int group) 311 { 312 scan->current_group = group - 1; 313 scan->groups_left = scan->fs->group_desc_count - group; 314 scan->bad_block_ptr = 0; 315 return get_next_blockgroup(scan); 316 } 317 318 /* 319 * This function is called by get_next_blocks() to check for bad 320 * blocks in the inode table. 321 * 322 * This function assumes that badblocks_list->list is sorted in 323 * increasing order. 324 */ 325 static errcode_t check_for_inode_bad_blocks(ext2_inode_scan scan, 326 blk64_t *num_blocks) 327 { 328 blk64_t blk = scan->current_block; 329 badblocks_list bb = scan->fs->badblocks; 330 331 /* 332 * If the inode table is missing, then obviously there are no 333 * bad blocks. :-) 334 */ 335 if (blk == 0) 336 return 0; 337 338 /* Make sure bad_block_ptr is still valid */ 339 if (scan->bad_block_ptr >= bb->num) { 340 scan->scan_flags &= ~EXT2_SF_CHK_BADBLOCKS; 341 return 0; 342 } 343 344 /* 345 * If the current block is greater than the bad block listed 346 * in the bad block list, then advance the pointer until this 347 * is no longer the case. If we run out of bad blocks, then 348 * we don't need to do any more checking! 349 */ 350 while (blk > bb->list[scan->bad_block_ptr]) { 351 if (++scan->bad_block_ptr >= bb->num) { 352 scan->scan_flags &= ~EXT2_SF_CHK_BADBLOCKS; 353 return 0; 354 } 355 } 356 357 /* 358 * If the current block is equal to the bad block listed in 359 * the bad block list, then handle that one block specially. 360 * (We could try to handle runs of bad blocks, but that 361 * only increases CPU efficiency by a small amount, at the 362 * expense of a huge expense of code complexity, and for an 363 * uncommon case at that.) 364 */ 365 if (blk == bb->list[scan->bad_block_ptr]) { 366 scan->scan_flags |= EXT2_SF_BAD_INODE_BLK; 367 *num_blocks = 1; 368 if (++scan->bad_block_ptr >= bb->num) 369 scan->scan_flags &= ~EXT2_SF_CHK_BADBLOCKS; 370 return 0; 371 } 372 373 /* 374 * If there is a bad block in the range that we're about to 375 * read in, adjust the number of blocks to read so that we we 376 * don't read in the bad block. (Then the next block to read 377 * will be the bad block, which is handled in the above case.) 378 */ 379 if ((blk + *num_blocks) > bb->list[scan->bad_block_ptr]) 380 *num_blocks = (int) (bb->list[scan->bad_block_ptr] - blk); 381 382 return 0; 383 } 384 385 static int block_map_looks_insane(ext2_filsys fs, 386 struct ext2_inode_large *inode) 387 { 388 unsigned int i, bad; 389 390 /* We're only interested in block mapped files, dirs, and symlinks */ 391 if ((inode->i_flags & EXT4_INLINE_DATA_FL) || 392 (inode->i_flags & EXT4_EXTENTS_FL)) 393 return 0; 394 if (!LINUX_S_ISREG(inode->i_mode) && 395 !LINUX_S_ISLNK(inode->i_mode) && 396 !LINUX_S_ISDIR(inode->i_mode)) 397 return 0; 398 if (LINUX_S_ISLNK(inode->i_mode) && 399 EXT2_I_SIZE(inode) <= sizeof(inode->i_block)) 400 return 0; 401 402 /* Unused inodes probably aren't insane */ 403 if (inode->i_links_count == 0) 404 return 0; 405 406 /* See if more than half the block maps are insane */ 407 for (i = 0, bad = 0; i < EXT2_N_BLOCKS; i++) 408 if (inode->i_block[i] != 0 && 409 (inode->i_block[i] < fs->super->s_first_data_block || 410 inode->i_block[i] >= ext2fs_blocks_count(fs->super))) 411 bad++; 412 return bad > EXT2_N_BLOCKS / 2; 413 } 414 415 static int extent_head_looks_insane(struct ext2_inode_large *inode) 416 { 417 if (!(inode->i_flags & EXT4_EXTENTS_FL) || 418 ext2fs_extent_header_verify(inode->i_block, 419 sizeof(inode->i_block)) == 0) 420 return 0; 421 return 1; 422 } 423 424 /* 425 * Check all the inodes that we just read into the buffer. Record what we 426 * find here -- currently, we can observe that all checksums are ok; more 427 * than half the inodes are insane; or no conclusions at all. 428 */ 429 static void check_inode_block_sanity(ext2_inode_scan scan, blk64_t num_blocks) 430 { 431 ext2_ino_t ino, inodes_to_scan; 432 unsigned int badness, checksum_failures; 433 unsigned int inodes_in_buf, inodes_per_block; 434 char *p; 435 struct ext2_inode_large *inode; 436 char *block_status; 437 unsigned int blk, bad_csum; 438 439 if (!(scan->scan_flags & EXT2_SF_WARN_GARBAGE_INODES)) 440 return; 441 442 inodes_to_scan = scan->inodes_left; 443 inodes_in_buf = num_blocks * scan->fs->blocksize / scan->inode_size; 444 if (inodes_to_scan > inodes_in_buf) 445 inodes_to_scan = inodes_in_buf; 446 447 p = (char *) scan->inode_buffer; 448 ino = scan->current_inode + 1; 449 checksum_failures = badness = 0; 450 block_status = SCAN_BLOCK_STATUS(scan); 451 memset(block_status, 0, scan->inode_buffer_blocks); 452 inodes_per_block = EXT2_INODES_PER_BLOCK(scan->fs->super); 453 454 if (inodes_per_block < 2) 455 return; 456 457 #ifdef WORDS_BIGENDIAN 458 if (ext2fs_get_mem(EXT2_INODE_SIZE(scan->fs->super), &inode)) 459 return; 460 #endif 461 462 while (inodes_to_scan > 0) { 463 blk = (p - (char *)scan->inode_buffer) / scan->fs->blocksize; 464 bad_csum = ext2fs_inode_csum_verify(scan->fs, ino, 465 (struct ext2_inode_large *) p) == 0; 466 467 #ifdef WORDS_BIGENDIAN 468 ext2fs_swap_inode_full(scan->fs, 469 (struct ext2_inode_large *) inode, 470 (struct ext2_inode_large *) p, 471 0, EXT2_INODE_SIZE(scan->fs->super)); 472 #else 473 inode = (struct ext2_inode_large *) p; 474 #endif 475 476 /* Is this inode insane? */ 477 if (bad_csum) { 478 checksum_failures++; 479 badness++; 480 } else if (extent_head_looks_insane(inode) || 481 block_map_looks_insane(scan->fs, inode)) 482 badness++; 483 484 /* If more than half are insane, declare the whole block bad */ 485 if (badness > inodes_per_block / 2) { 486 unsigned int ino_adj; 487 488 block_status[blk] |= IBLOCK_STATUS_INSANE; 489 ino_adj = inodes_per_block - 490 ((ino - 1) % inodes_per_block); 491 if (ino_adj > inodes_to_scan) 492 ino_adj = inodes_to_scan; 493 inodes_to_scan -= ino_adj; 494 p += scan->inode_size * ino_adj; 495 ino += ino_adj; 496 checksum_failures = badness = 0; 497 continue; 498 } 499 500 if ((ino % inodes_per_block) == 0) { 501 if (checksum_failures == 0) 502 block_status[blk] |= IBLOCK_STATUS_CSUMS_OK; 503 checksum_failures = badness = 0; 504 } 505 inodes_to_scan--; 506 p += scan->inode_size; 507 ino++; 508 }; 509 510 #ifdef WORDS_BIGENDIAN 511 ext2fs_free_mem(&inode); 512 #endif 513 } 514 515 /* 516 * This function is called by ext2fs_get_next_inode when it needs to 517 * read in more blocks from the current blockgroup's inode table. 518 */ 519 static errcode_t get_next_blocks(ext2_inode_scan scan) 520 { 521 blk64_t num_blocks; 522 errcode_t retval; 523 524 /* 525 * Figure out how many blocks to read; we read at most 526 * inode_buffer_blocks, and perhaps less if there aren't that 527 * many blocks left to read. 528 */ 529 num_blocks = scan->inode_buffer_blocks; 530 if (num_blocks > scan->blocks_left) 531 num_blocks = scan->blocks_left; 532 533 /* 534 * If the past block "read" was a bad block, then mark the 535 * left-over extra bytes as also being bad. 536 */ 537 if (scan->scan_flags & EXT2_SF_BAD_INODE_BLK) { 538 if (scan->bytes_left) 539 scan->scan_flags |= EXT2_SF_BAD_EXTRA_BYTES; 540 scan->scan_flags &= ~EXT2_SF_BAD_INODE_BLK; 541 } 542 543 /* 544 * Do inode bad block processing, if necessary. 545 */ 546 if (scan->scan_flags & EXT2_SF_CHK_BADBLOCKS) { 547 retval = check_for_inode_bad_blocks(scan, &num_blocks); 548 if (retval) 549 return retval; 550 } 551 552 if ((scan->scan_flags & EXT2_SF_BAD_INODE_BLK) || 553 (scan->current_block == 0)) { 554 memset(scan->inode_buffer, 0, 555 (size_t) num_blocks * scan->fs->blocksize); 556 } else { 557 retval = io_channel_read_blk64(scan->fs->io, 558 scan->current_block, 559 (int) num_blocks, 560 scan->inode_buffer); 561 if (retval) 562 return EXT2_ET_NEXT_INODE_READ; 563 } 564 check_inode_block_sanity(scan, num_blocks); 565 566 scan->ptr = scan->inode_buffer; 567 scan->bytes_left = num_blocks * scan->fs->blocksize; 568 569 scan->blocks_left -= num_blocks; 570 if (scan->current_block) 571 scan->current_block += num_blocks; 572 573 return 0; 574 } 575 576 #if 0 577 /* 578 * Returns 1 if the entire inode_buffer has a non-zero size and 579 * contains all zeros. (Not just deleted inodes, since that means 580 * that part of the inode table was used at one point; we want all 581 * zeros, which means that the inode table is pristine.) 582 */ 583 static inline int is_empty_scan(ext2_inode_scan scan) 584 { 585 int i; 586 587 if (scan->bytes_left == 0) 588 return 0; 589 590 for (i=0; i < scan->bytes_left; i++) 591 if (scan->ptr[i]) 592 return 0; 593 return 1; 594 } 595 #endif 596 597 errcode_t ext2fs_get_next_inode_full(ext2_inode_scan scan, ext2_ino_t *ino, 598 struct ext2_inode *inode, int bufsize) 599 { 600 errcode_t retval; 601 int extra_bytes = 0; 602 int length; 603 struct ext2_inode_large *iptr = (struct ext2_inode_large *)inode; 604 char *iblock_status; 605 unsigned int iblk; 606 607 EXT2_CHECK_MAGIC(scan, EXT2_ET_MAGIC_INODE_SCAN); 608 length = EXT2_INODE_SIZE(scan->fs->super); 609 iblock_status = SCAN_BLOCK_STATUS(scan); 610 611 /* 612 * Do we need to start reading a new block group? 613 */ 614 if (scan->inodes_left <= 0) { 615 force_new_group: 616 if (scan->done_group) { 617 retval = (scan->done_group) 618 (scan->fs, scan, scan->current_group, 619 scan->done_group_data); 620 if (retval) 621 return retval; 622 } 623 if (scan->groups_left <= 0) { 624 *ino = 0; 625 return 0; 626 } 627 retval = get_next_blockgroup(scan); 628 if (retval) 629 return retval; 630 } 631 /* 632 * These checks are done outside the above if statement so 633 * they can be done for block group #0. 634 */ 635 if ((scan->scan_flags & EXT2_SF_DO_LAZY) && 636 (ext2fs_bg_flags_test(scan->fs, scan->current_group, EXT2_BG_INODE_UNINIT) 637 )) 638 goto force_new_group; 639 if (scan->inodes_left == 0) 640 goto force_new_group; 641 if (scan->current_block == 0) { 642 if (scan->scan_flags & EXT2_SF_SKIP_MISSING_ITABLE) { 643 goto force_new_group; 644 } else 645 return EXT2_ET_MISSING_INODE_TABLE; 646 } 647 648 649 /* 650 * Have we run out of space in the inode buffer? If so, we 651 * need to read in more blocks. 652 */ 653 if (scan->bytes_left < scan->inode_size) { 654 if (scan->bytes_left) 655 memcpy(scan->temp_buffer, scan->ptr, scan->bytes_left); 656 extra_bytes = scan->bytes_left; 657 658 retval = get_next_blocks(scan); 659 if (retval) 660 return retval; 661 #if 0 662 /* 663 * XXX test Need check for used inode somehow. 664 * (Note: this is hard.) 665 */ 666 if (is_empty_scan(scan)) 667 goto force_new_group; 668 #endif 669 } 670 671 if (bufsize < length) { 672 retval = ext2fs_get_mem(length, &iptr); 673 if (retval) 674 return retval; 675 } 676 677 retval = 0; 678 iblk = scan->current_inode % EXT2_INODES_PER_GROUP(scan->fs->super) / 679 EXT2_INODES_PER_BLOCK(scan->fs->super) % 680 scan->inode_buffer_blocks; 681 if (extra_bytes) { 682 memcpy(scan->temp_buffer+extra_bytes, scan->ptr, 683 scan->inode_size - extra_bytes); 684 scan->ptr += scan->inode_size - extra_bytes; 685 scan->bytes_left -= scan->inode_size - extra_bytes; 686 687 /* Verify the inode checksum. */ 688 if (!(iblock_status[iblk] & IBLOCK_STATUS_CSUMS_OK) && 689 !(scan->fs->flags & EXT2_FLAG_IGNORE_CSUM_ERRORS) && 690 !ext2fs_inode_csum_verify(scan->fs, scan->current_inode + 1, 691 (struct ext2_inode_large *)scan->temp_buffer)) 692 retval = EXT2_ET_INODE_CSUM_INVALID; 693 694 #ifdef WORDS_BIGENDIAN 695 memset(iptr, 0, length); 696 ext2fs_swap_inode_full(scan->fs, 697 (struct ext2_inode_large *) iptr, 698 (struct ext2_inode_large *) scan->temp_buffer, 699 0, length); 700 #else 701 memcpy(iptr, scan->temp_buffer, length); 702 #endif 703 if (scan->scan_flags & EXT2_SF_BAD_EXTRA_BYTES) 704 retval = EXT2_ET_BAD_BLOCK_IN_INODE_TABLE; 705 scan->scan_flags &= ~EXT2_SF_BAD_EXTRA_BYTES; 706 } else { 707 /* Verify the inode checksum. */ 708 if (!(iblock_status[iblk] & IBLOCK_STATUS_CSUMS_OK) && 709 !(scan->fs->flags & EXT2_FLAG_IGNORE_CSUM_ERRORS) && 710 !ext2fs_inode_csum_verify(scan->fs, scan->current_inode + 1, 711 (struct ext2_inode_large *)scan->ptr)) 712 retval = EXT2_ET_INODE_CSUM_INVALID; 713 714 #ifdef WORDS_BIGENDIAN 715 memset(iptr, 0, length); 716 ext2fs_swap_inode_full(scan->fs, 717 (struct ext2_inode_large *) iptr, 718 (struct ext2_inode_large *) scan->ptr, 719 0, length); 720 #else 721 memcpy(iptr, scan->ptr, length); 722 #endif 723 scan->ptr += scan->inode_size; 724 scan->bytes_left -= scan->inode_size; 725 if (scan->scan_flags & EXT2_SF_BAD_INODE_BLK) 726 retval = EXT2_ET_BAD_BLOCK_IN_INODE_TABLE; 727 } 728 if ((iblock_status[iblk] & IBLOCK_STATUS_INSANE) && 729 (retval == 0 || retval == EXT2_ET_INODE_CSUM_INVALID)) 730 retval = EXT2_ET_INODE_IS_GARBAGE; 731 732 scan->inodes_left--; 733 scan->current_inode++; 734 *ino = scan->current_inode; 735 if (iptr != (struct ext2_inode_large *)inode) { 736 memcpy(inode, iptr, bufsize); 737 ext2fs_free_mem(&iptr); 738 } 739 return retval; 740 } 741 742 errcode_t ext2fs_get_next_inode(ext2_inode_scan scan, ext2_ino_t *ino, 743 struct ext2_inode *inode) 744 { 745 return ext2fs_get_next_inode_full(scan, ino, inode, 746 sizeof(struct ext2_inode)); 747 } 748 749 /* 750 * Functions to read and write a single inode. 751 */ 752 errcode_t ext2fs_read_inode2(ext2_filsys fs, ext2_ino_t ino, 753 struct ext2_inode * inode, int bufsize, 754 int flags) 755 { 756 blk64_t block_nr; 757 dgrp_t group; 758 unsigned long block, offset; 759 char *ptr; 760 errcode_t retval; 761 unsigned i; 762 int clen, inodes_per_block; 763 io_channel io; 764 int length = EXT2_INODE_SIZE(fs->super); 765 struct ext2_inode_large *iptr; 766 int cache_slot, fail_csum; 767 768 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); 769 if (fs->blocksize < 1024) 770 return EXT2_FILSYS_CORRUPTED; /* Should never happen */ 771 772 /* Check to see if user has an override function */ 773 if (fs->read_inode && 774 ((bufsize == sizeof(struct ext2_inode)) || 775 (EXT2_INODE_SIZE(fs->super) == sizeof(struct ext2_inode)))) { 776 retval = (fs->read_inode)(fs, ino, inode); 777 if (retval != EXT2_ET_CALLBACK_NOTHANDLED) 778 return retval; 779 } 780 if ((ino == 0) || (ino > fs->super->s_inodes_count)) 781 return EXT2_ET_BAD_INODE_NUM; 782 /* Create inode cache if not present */ 783 if (!fs->icache) { 784 retval = ext2fs_create_inode_cache(fs, 4); 785 if (retval) 786 return retval; 787 } 788 /* Check to see if it's in the inode cache */ 789 for (i = 0; i < fs->icache->cache_size; i++) { 790 if (fs->icache->cache[i].ino == ino) { 791 memcpy(inode, fs->icache->cache[i].inode, 792 (bufsize > length) ? length : bufsize); 793 return 0; 794 } 795 } 796 if (fs->flags & EXT2_FLAG_IMAGE_FILE) { 797 inodes_per_block = fs->blocksize / EXT2_INODE_SIZE(fs->super); 798 block_nr = ext2fs_le32_to_cpu(fs->image_header->offset_inode) / fs->blocksize; 799 block_nr += (ino - 1) / inodes_per_block; 800 offset = ((ino - 1) % inodes_per_block) * 801 EXT2_INODE_SIZE(fs->super); 802 io = fs->image_io; 803 } else { 804 group = (ino - 1) / EXT2_INODES_PER_GROUP(fs->super); 805 if (group > fs->group_desc_count) 806 return EXT2_ET_BAD_INODE_NUM; 807 offset = ((ino - 1) % EXT2_INODES_PER_GROUP(fs->super)) * 808 EXT2_INODE_SIZE(fs->super); 809 block = offset >> EXT2_BLOCK_SIZE_BITS(fs->super); 810 block_nr = ext2fs_inode_table_loc(fs, group); 811 if (!block_nr) 812 return EXT2_ET_MISSING_INODE_TABLE; 813 if ((block_nr < fs->super->s_first_data_block) || 814 (block_nr + fs->inode_blocks_per_group - 1 >= 815 ext2fs_blocks_count(fs->super))) 816 return EXT2_ET_GDESC_BAD_INODE_TABLE; 817 block_nr += block; 818 io = fs->io; 819 } 820 offset &= (EXT2_BLOCK_SIZE(fs->super) - 1); 821 822 cache_slot = (fs->icache->cache_last + 1) % fs->icache->cache_size; 823 iptr = (struct ext2_inode_large *)fs->icache->cache[cache_slot].inode; 824 825 ptr = (char *) iptr; 826 while (length) { 827 clen = length; 828 if ((offset + length) > fs->blocksize) 829 clen = fs->blocksize - offset; 830 831 if (block_nr != fs->icache->buffer_blk) { 832 retval = io_channel_read_blk64(io, block_nr, 1, 833 fs->icache->buffer); 834 if (retval) 835 return retval; 836 fs->icache->buffer_blk = block_nr; 837 } 838 839 memcpy(ptr, ((char *) fs->icache->buffer) + (unsigned) offset, 840 clen); 841 842 offset = 0; 843 length -= clen; 844 ptr += clen; 845 block_nr++; 846 } 847 length = EXT2_INODE_SIZE(fs->super); 848 849 /* Verify the inode checksum. */ 850 fail_csum = !ext2fs_inode_csum_verify(fs, ino, iptr); 851 852 #ifdef WORDS_BIGENDIAN 853 ext2fs_swap_inode_full(fs, (struct ext2_inode_large *) iptr, 854 (struct ext2_inode_large *) iptr, 855 0, length); 856 #endif 857 858 /* Update the inode cache bookkeeping */ 859 if (!fail_csum) { 860 fs->icache->cache_last = cache_slot; 861 fs->icache->cache[cache_slot].ino = ino; 862 } 863 memcpy(inode, iptr, (bufsize > length) ? length : bufsize); 864 865 if (!(fs->flags & EXT2_FLAG_IGNORE_CSUM_ERRORS) && 866 !(flags & READ_INODE_NOCSUM) && fail_csum) 867 return EXT2_ET_INODE_CSUM_INVALID; 868 869 return 0; 870 } 871 872 errcode_t ext2fs_read_inode_full(ext2_filsys fs, ext2_ino_t ino, 873 struct ext2_inode * inode, int bufsize) 874 { 875 return ext2fs_read_inode2(fs, ino, inode, bufsize, 0); 876 } 877 878 errcode_t ext2fs_read_inode(ext2_filsys fs, ext2_ino_t ino, 879 struct ext2_inode * inode) 880 { 881 return ext2fs_read_inode2(fs, ino, inode, 882 sizeof(struct ext2_inode), 0); 883 } 884 885 errcode_t ext2fs_write_inode2(ext2_filsys fs, ext2_ino_t ino, 886 struct ext2_inode * inode, int bufsize, 887 int flags) 888 { 889 blk64_t block_nr; 890 dgrp_t group; 891 unsigned long block, offset; 892 errcode_t retval = 0; 893 struct ext2_inode_large *w_inode; 894 char *ptr; 895 unsigned i; 896 int clen; 897 int length = EXT2_INODE_SIZE(fs->super); 898 899 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); 900 901 /* Check to see if user provided an override function */ 902 if (fs->write_inode) { 903 retval = (fs->write_inode)(fs, ino, inode); 904 if (retval != EXT2_ET_CALLBACK_NOTHANDLED) 905 return retval; 906 } 907 908 if ((ino == 0) || (ino > fs->super->s_inodes_count)) 909 return EXT2_ET_BAD_INODE_NUM; 910 911 /* Prepare our shadow buffer for read/modify/byteswap/write */ 912 retval = ext2fs_get_mem(length, &w_inode); 913 if (retval) 914 return retval; 915 916 if (bufsize < length) { 917 retval = ext2fs_read_inode2(fs, ino, 918 (struct ext2_inode *)w_inode, 919 length, READ_INODE_NOCSUM); 920 if (retval) 921 goto errout; 922 } 923 924 /* Check to see if the inode cache needs to be updated */ 925 if (fs->icache) { 926 for (i=0; i < fs->icache->cache_size; i++) { 927 if (fs->icache->cache[i].ino == ino) { 928 memcpy(fs->icache->cache[i].inode, inode, 929 (bufsize > length) ? length : bufsize); 930 break; 931 } 932 } 933 } else { 934 retval = ext2fs_create_inode_cache(fs, 4); 935 if (retval) 936 goto errout; 937 } 938 memcpy(w_inode, inode, (bufsize > length) ? length : bufsize); 939 940 if (!(fs->flags & EXT2_FLAG_RW)) { 941 retval = EXT2_ET_RO_FILSYS; 942 goto errout; 943 } 944 945 #ifdef WORDS_BIGENDIAN 946 ext2fs_swap_inode_full(fs, w_inode, w_inode, 1, length); 947 #endif 948 949 if ((flags & WRITE_INODE_NOCSUM) == 0) { 950 retval = ext2fs_inode_csum_set(fs, ino, w_inode); 951 if (retval) 952 goto errout; 953 } 954 955 group = (ino - 1) / EXT2_INODES_PER_GROUP(fs->super); 956 offset = ((ino - 1) % EXT2_INODES_PER_GROUP(fs->super)) * 957 EXT2_INODE_SIZE(fs->super); 958 block = offset >> EXT2_BLOCK_SIZE_BITS(fs->super); 959 block_nr = ext2fs_inode_table_loc(fs, (unsigned) group); 960 if (!block_nr) { 961 retval = EXT2_ET_MISSING_INODE_TABLE; 962 goto errout; 963 } 964 if ((block_nr < fs->super->s_first_data_block) || 965 (block_nr + fs->inode_blocks_per_group - 1 >= 966 ext2fs_blocks_count(fs->super))) { 967 retval = EXT2_ET_GDESC_BAD_INODE_TABLE; 968 goto errout; 969 } 970 block_nr += block; 971 972 offset &= (EXT2_BLOCK_SIZE(fs->super) - 1); 973 974 ptr = (char *) w_inode; 975 976 while (length) { 977 clen = length; 978 if ((offset + length) > fs->blocksize) 979 clen = fs->blocksize - offset; 980 981 if (fs->icache->buffer_blk != block_nr) { 982 retval = io_channel_read_blk64(fs->io, block_nr, 1, 983 fs->icache->buffer); 984 if (retval) 985 goto errout; 986 fs->icache->buffer_blk = block_nr; 987 } 988 989 990 memcpy((char *) fs->icache->buffer + (unsigned) offset, 991 ptr, clen); 992 993 retval = io_channel_write_blk64(fs->io, block_nr, 1, 994 fs->icache->buffer); 995 if (retval) 996 goto errout; 997 998 offset = 0; 999 ptr += clen; 1000 length -= clen; 1001 block_nr++; 1002 } 1003 1004 fs->flags |= EXT2_FLAG_CHANGED; 1005 errout: 1006 ext2fs_free_mem(&w_inode); 1007 return retval; 1008 } 1009 1010 errcode_t ext2fs_write_inode_full(ext2_filsys fs, ext2_ino_t ino, 1011 struct ext2_inode * inode, int bufsize) 1012 { 1013 return ext2fs_write_inode2(fs, ino, inode, bufsize, 0); 1014 } 1015 1016 errcode_t ext2fs_write_inode(ext2_filsys fs, ext2_ino_t ino, 1017 struct ext2_inode *inode) 1018 { 1019 return ext2fs_write_inode2(fs, ino, inode, 1020 sizeof(struct ext2_inode), 0); 1021 } 1022 1023 /* 1024 * This function should be called when writing a new inode. It makes 1025 * sure that extra part of large inodes is initialized properly. 1026 */ 1027 errcode_t ext2fs_write_new_inode(ext2_filsys fs, ext2_ino_t ino, 1028 struct ext2_inode *inode) 1029 { 1030 struct ext2_inode *buf; 1031 int size = EXT2_INODE_SIZE(fs->super); 1032 struct ext2_inode_large *large_inode; 1033 errcode_t retval; 1034 __u32 t = fs->now ? fs->now : time(NULL); 1035 1036 if (!inode->i_ctime) 1037 inode->i_ctime = t; 1038 if (!inode->i_mtime) 1039 inode->i_mtime = t; 1040 if (!inode->i_atime) 1041 inode->i_atime = t; 1042 1043 if (size == sizeof(struct ext2_inode)) 1044 return ext2fs_write_inode_full(fs, ino, inode, 1045 sizeof(struct ext2_inode)); 1046 1047 buf = malloc(size); 1048 if (!buf) 1049 return ENOMEM; 1050 1051 memset(buf, 0, size); 1052 *buf = *inode; 1053 1054 large_inode = (struct ext2_inode_large *) buf; 1055 large_inode->i_extra_isize = sizeof(struct ext2_inode_large) - 1056 EXT2_GOOD_OLD_INODE_SIZE; 1057 if (!large_inode->i_crtime) 1058 large_inode->i_crtime = t; 1059 1060 retval = ext2fs_write_inode_full(fs, ino, buf, size); 1061 free(buf); 1062 return retval; 1063 } 1064 1065 1066 errcode_t ext2fs_get_blocks(ext2_filsys fs, ext2_ino_t ino, blk_t *blocks) 1067 { 1068 struct ext2_inode inode; 1069 int i; 1070 errcode_t retval; 1071 1072 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); 1073 1074 if (ino > fs->super->s_inodes_count) 1075 return EXT2_ET_BAD_INODE_NUM; 1076 1077 if (fs->get_blocks) { 1078 if (!(*fs->get_blocks)(fs, ino, blocks)) 1079 return 0; 1080 } 1081 retval = ext2fs_read_inode(fs, ino, &inode); 1082 if (retval) 1083 return retval; 1084 for (i=0; i < EXT2_N_BLOCKS; i++) 1085 blocks[i] = inode.i_block[i]; 1086 return 0; 1087 } 1088 1089 errcode_t ext2fs_check_directory(ext2_filsys fs, ext2_ino_t ino) 1090 { 1091 struct ext2_inode inode; 1092 errcode_t retval; 1093 1094 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); 1095 1096 if (ino > fs->super->s_inodes_count) 1097 return EXT2_ET_BAD_INODE_NUM; 1098 1099 if (fs->check_directory) { 1100 retval = (fs->check_directory)(fs, ino); 1101 if (retval != EXT2_ET_CALLBACK_NOTHANDLED) 1102 return retval; 1103 } 1104 retval = ext2fs_read_inode(fs, ino, &inode); 1105 if (retval) 1106 return retval; 1107 if (!LINUX_S_ISDIR(inode.i_mode)) 1108 return EXT2_ET_NO_DIRECTORY; 1109 return 0; 1110 } 1111