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