1/* vi: set sw=4 ts=4: */ 2/* 3 * e2fsck 4 * 5 * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o. 6 * Copyright (C) 2006 Garrett Kajmowicz 7 * 8 * Dictionary Abstract Data Type 9 * Copyright (C) 1997 Kaz Kylheku <kaz@ashi.footprints.net> 10 * Free Software License: 11 * All rights are reserved by the author, with the following exceptions: 12 * Permission is granted to freely reproduce and distribute this software, 13 * possibly in exchange for a fee, provided that this copyright notice appears 14 * intact. Permission is also granted to adapt this software to produce 15 * derivative works, as long as the modified versions carry this copyright 16 * notice and additional notices stating that the work has been modified. 17 * This source code may be translated into executable form and incorporated 18 * into proprietary software; there is no requirement for such software to 19 * contain a copyright notice related to this source. 20 * 21 * linux/fs/recovery and linux/fs/revoke 22 * Written by Stephen C. Tweedie <sct@redhat.com>, 1999 23 * 24 * Copyright 1999-2000 Red Hat Software --- All Rights Reserved 25 * 26 * Journal recovery routines for the generic filesystem journaling code; 27 * part of the ext2fs journaling system. 28 * 29 * Licensed under GPLv2 or later, see file License in this tarball for details. 30 */ 31 32#ifndef _GNU_SOURCE 33#define _GNU_SOURCE 1 /* get strnlen() */ 34#endif 35 36#include "e2fsck.h" /*Put all of our defines here to clean things up*/ 37 38#define _(x) x 39#define N_(x) x 40 41/* 42 * Procedure declarations 43 */ 44 45static void e2fsck_pass1_dupblocks(e2fsck_t ctx, char *block_buf); 46 47/* pass1.c */ 48static void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int bool); 49 50/* pass2.c */ 51static int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir, 52 ext2_ino_t ino, char *buf); 53 54/* pass3.c */ 55static int e2fsck_reconnect_file(e2fsck_t ctx, ext2_ino_t inode); 56static errcode_t e2fsck_expand_directory(e2fsck_t ctx, ext2_ino_t dir, 57 int num, int gauranteed_size); 58static ext2_ino_t e2fsck_get_lost_and_found(e2fsck_t ctx, int fix); 59static errcode_t e2fsck_adjust_inode_count(e2fsck_t ctx, ext2_ino_t ino, 60 int adj); 61 62/* rehash.c */ 63static void e2fsck_rehash_directories(e2fsck_t ctx); 64 65/* util.c */ 66static void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned int size, 67 const char *description); 68static int ask(e2fsck_t ctx, const char * string, int def); 69static void e2fsck_read_bitmaps(e2fsck_t ctx); 70static void preenhalt(e2fsck_t ctx); 71static void e2fsck_read_inode(e2fsck_t ctx, unsigned long ino, 72 struct ext2_inode * inode, const char * proc); 73static void e2fsck_write_inode(e2fsck_t ctx, unsigned long ino, 74 struct ext2_inode * inode, const char * proc); 75static blk_t get_backup_sb(e2fsck_t ctx, ext2_filsys fs, 76 const char *name, io_manager manager); 77 78/* unix.c */ 79static void e2fsck_clear_progbar(e2fsck_t ctx); 80static int e2fsck_simple_progress(e2fsck_t ctx, const char *label, 81 float percent, unsigned int dpynum); 82 83 84/* 85 * problem.h --- e2fsck problem error codes 86 */ 87 88typedef __u32 problem_t; 89 90struct problem_context { 91 errcode_t errcode; 92 ext2_ino_t ino, ino2, dir; 93 struct ext2_inode *inode; 94 struct ext2_dir_entry *dirent; 95 blk_t blk, blk2; 96 e2_blkcnt_t blkcount; 97 int group; 98 __u64 num; 99 const char *str; 100}; 101 102 103/* 104 * Function declarations 105 */ 106static int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx); 107static int end_problem_latch(e2fsck_t ctx, int mask); 108static int set_latch_flags(int mask, int setflags, int clearflags); 109static void clear_problem_context(struct problem_context *ctx); 110 111/* 112 * Dictionary Abstract Data Type 113 * Copyright (C) 1997 Kaz Kylheku <kaz@ashi.footprints.net> 114 * 115 * dict.h v 1.22.2.6 2000/11/13 01:36:44 kaz 116 * kazlib_1_20 117 */ 118 119#ifndef DICT_H 120#define DICT_H 121 122/* 123 * Blurb for inclusion into C++ translation units 124 */ 125 126typedef unsigned long dictcount_t; 127#define DICTCOUNT_T_MAX ULONG_MAX 128 129/* 130 * The dictionary is implemented as a red-black tree 131 */ 132 133typedef enum { dnode_red, dnode_black } dnode_color_t; 134 135typedef struct dnode_t { 136 struct dnode_t *dict_left; 137 struct dnode_t *dict_right; 138 struct dnode_t *dict_parent; 139 dnode_color_t dict_color; 140 const void *dict_key; 141 void *dict_data; 142} dnode_t; 143 144typedef int (*dict_comp_t)(const void *, const void *); 145typedef void (*dnode_free_t)(dnode_t *); 146 147typedef struct dict_t { 148 dnode_t dict_nilnode; 149 dictcount_t dict_nodecount; 150 dictcount_t dict_maxcount; 151 dict_comp_t dict_compare; 152 dnode_free_t dict_freenode; 153 int dict_dupes; 154} dict_t; 155 156typedef void (*dnode_process_t)(dict_t *, dnode_t *, void *); 157 158typedef struct dict_load_t { 159 dict_t *dict_dictptr; 160 dnode_t dict_nilnode; 161} dict_load_t; 162 163#define dict_count(D) ((D)->dict_nodecount) 164#define dnode_get(N) ((N)->dict_data) 165#define dnode_getkey(N) ((N)->dict_key) 166 167#endif 168 169/* 170 * Compatibility header file for e2fsck which should be included 171 * instead of linux/jfs.h 172 * 173 * Copyright (C) 2000 Stephen C. Tweedie 174 */ 175 176/* 177 * Pull in the definition of the e2fsck context structure 178 */ 179 180struct buffer_head { 181 char b_data[8192]; 182 e2fsck_t b_ctx; 183 io_channel b_io; 184 int b_size; 185 blk_t b_blocknr; 186 int b_dirty; 187 int b_uptodate; 188 int b_err; 189}; 190 191 192#define K_DEV_FS 1 193#define K_DEV_JOURNAL 2 194 195#define lock_buffer(bh) do {} while(0) 196#define unlock_buffer(bh) do {} while(0) 197#define buffer_req(bh) 1 198#define do_readahead(journal, start) do {} while(0) 199 200static e2fsck_t e2fsck_global_ctx; /* Try your very best not to use this! */ 201 202typedef struct { 203 int object_length; 204} kmem_cache_t; 205 206#define kmem_cache_alloc(cache,flags) malloc((cache)->object_length) 207 208/* 209 * We use the standard libext2fs portability tricks for inline 210 * functions. 211 */ 212 213static kmem_cache_t * do_cache_create(int len) 214{ 215 kmem_cache_t *new_cache; 216 217 new_cache = malloc(sizeof(*new_cache)); 218 if (new_cache) 219 new_cache->object_length = len; 220 return new_cache; 221} 222 223static void do_cache_destroy(kmem_cache_t *cache) 224{ 225 free(cache); 226} 227 228 229/* 230 * Dictionary Abstract Data Type 231 */ 232 233 234/* 235 * These macros provide short convenient names for structure members, 236 * which are embellished with dict_ prefixes so that they are 237 * properly confined to the documented namespace. It's legal for a 238 * program which uses dict to define, for instance, a macro called ``parent''. 239 * Such a macro would interfere with the dnode_t struct definition. 240 * In general, highly portable and reusable C modules which expose their 241 * structures need to confine structure member names to well-defined spaces. 242 * The resulting identifiers aren't necessarily convenient to use, nor 243 * readable, in the implementation, however! 244 */ 245 246#define left dict_left 247#define right dict_right 248#define parent dict_parent 249#define color dict_color 250#define key dict_key 251#define data dict_data 252 253#define nilnode dict_nilnode 254#define maxcount dict_maxcount 255#define compare dict_compare 256#define dupes dict_dupes 257 258#define dict_root(D) ((D)->nilnode.left) 259#define dict_nil(D) (&(D)->nilnode) 260 261static void dnode_free(dnode_t *node); 262 263/* 264 * Perform a ``left rotation'' adjustment on the tree. The given node P and 265 * its right child C are rearranged so that the P instead becomes the left 266 * child of C. The left subtree of C is inherited as the new right subtree 267 * for P. The ordering of the keys within the tree is thus preserved. 268 */ 269 270static void rotate_left(dnode_t *upper) 271{ 272 dnode_t *lower, *lowleft, *upparent; 273 274 lower = upper->right; 275 upper->right = lowleft = lower->left; 276 lowleft->parent = upper; 277 278 lower->parent = upparent = upper->parent; 279 280 /* don't need to check for root node here because root->parent is 281 the sentinel nil node, and root->parent->left points back to root */ 282 283 if (upper == upparent->left) { 284 upparent->left = lower; 285 } else { 286 assert (upper == upparent->right); 287 upparent->right = lower; 288 } 289 290 lower->left = upper; 291 upper->parent = lower; 292} 293 294/* 295 * This operation is the ``mirror'' image of rotate_left. It is 296 * the same procedure, but with left and right interchanged. 297 */ 298 299static void rotate_right(dnode_t *upper) 300{ 301 dnode_t *lower, *lowright, *upparent; 302 303 lower = upper->left; 304 upper->left = lowright = lower->right; 305 lowright->parent = upper; 306 307 lower->parent = upparent = upper->parent; 308 309 if (upper == upparent->right) { 310 upparent->right = lower; 311 } else { 312 assert (upper == upparent->left); 313 upparent->left = lower; 314 } 315 316 lower->right = upper; 317 upper->parent = lower; 318} 319 320/* 321 * Do a postorder traversal of the tree rooted at the specified 322 * node and free everything under it. Used by dict_free(). 323 */ 324 325static void free_nodes(dict_t *dict, dnode_t *node, dnode_t *nil) 326{ 327 if (node == nil) 328 return; 329 free_nodes(dict, node->left, nil); 330 free_nodes(dict, node->right, nil); 331 dict->dict_freenode(node); 332} 333 334/* 335 * Verify that the tree contains the given node. This is done by 336 * traversing all of the nodes and comparing their pointers to the 337 * given pointer. Returns 1 if the node is found, otherwise 338 * returns zero. It is intended for debugging purposes. 339 */ 340 341static int verify_dict_has_node(dnode_t *nil, dnode_t *root, dnode_t *node) 342{ 343 if (root != nil) { 344 return root == node 345 || verify_dict_has_node(nil, root->left, node) 346 || verify_dict_has_node(nil, root->right, node); 347 } 348 return 0; 349} 350 351 352/* 353 * Select a different set of node allocator routines. 354 */ 355 356static void dict_set_allocator(dict_t *dict, dnode_free_t fr) 357{ 358 assert (dict_count(dict) == 0); 359 dict->dict_freenode = fr; 360} 361 362/* 363 * Free all the nodes in the dictionary by using the dictionary's 364 * installed free routine. The dictionary is emptied. 365 */ 366 367static void dict_free_nodes(dict_t *dict) 368{ 369 dnode_t *nil = dict_nil(dict), *root = dict_root(dict); 370 free_nodes(dict, root, nil); 371 dict->dict_nodecount = 0; 372 dict->nilnode.left = &dict->nilnode; 373 dict->nilnode.right = &dict->nilnode; 374} 375 376/* 377 * Initialize a user-supplied dictionary object. 378 */ 379 380static dict_t *dict_init(dict_t *dict, dictcount_t maxcount, dict_comp_t comp) 381{ 382 dict->compare = comp; 383 dict->dict_freenode = dnode_free; 384 dict->dict_nodecount = 0; 385 dict->maxcount = maxcount; 386 dict->nilnode.left = &dict->nilnode; 387 dict->nilnode.right = &dict->nilnode; 388 dict->nilnode.parent = &dict->nilnode; 389 dict->nilnode.color = dnode_black; 390 dict->dupes = 0; 391 return dict; 392} 393 394/* 395 * Locate a node in the dictionary having the given key. 396 * If the node is not found, a null a pointer is returned (rather than 397 * a pointer that dictionary's nil sentinel node), otherwise a pointer to the 398 * located node is returned. 399 */ 400 401static dnode_t *dict_lookup(dict_t *dict, const void *key) 402{ 403 dnode_t *root = dict_root(dict); 404 dnode_t *nil = dict_nil(dict); 405 dnode_t *saved; 406 int result; 407 408 /* simple binary search adapted for trees that contain duplicate keys */ 409 410 while (root != nil) { 411 result = dict->compare(key, root->key); 412 if (result < 0) 413 root = root->left; 414 else if (result > 0) 415 root = root->right; 416 else { 417 if (!dict->dupes) { /* no duplicates, return match */ 418 return root; 419 } else { /* could be dupes, find leftmost one */ 420 do { 421 saved = root; 422 root = root->left; 423 while (root != nil && dict->compare(key, root->key)) 424 root = root->right; 425 } while (root != nil); 426 return saved; 427 } 428 } 429 } 430 431 return NULL; 432} 433 434/* 435 * Insert a node into the dictionary. The node should have been 436 * initialized with a data field. All other fields are ignored. 437 * The behavior is undefined if the user attempts to insert into 438 * a dictionary that is already full (for which the dict_isfull() 439 * function returns true). 440 */ 441 442static void dict_insert(dict_t *dict, dnode_t *node, const void *key) 443{ 444 dnode_t *where = dict_root(dict), *nil = dict_nil(dict); 445 dnode_t *parent = nil, *uncle, *grandpa; 446 int result = -1; 447 448 node->key = key; 449 450 /* basic binary tree insert */ 451 452 while (where != nil) { 453 parent = where; 454 result = dict->compare(key, where->key); 455 /* trap attempts at duplicate key insertion unless it's explicitly allowed */ 456 assert (dict->dupes || result != 0); 457 if (result < 0) 458 where = where->left; 459 else 460 where = where->right; 461 } 462 463 assert (where == nil); 464 465 if (result < 0) 466 parent->left = node; 467 else 468 parent->right = node; 469 470 node->parent = parent; 471 node->left = nil; 472 node->right = nil; 473 474 dict->dict_nodecount++; 475 476 /* red black adjustments */ 477 478 node->color = dnode_red; 479 480 while (parent->color == dnode_red) { 481 grandpa = parent->parent; 482 if (parent == grandpa->left) { 483 uncle = grandpa->right; 484 if (uncle->color == dnode_red) { /* red parent, red uncle */ 485 parent->color = dnode_black; 486 uncle->color = dnode_black; 487 grandpa->color = dnode_red; 488 node = grandpa; 489 parent = grandpa->parent; 490 } else { /* red parent, black uncle */ 491 if (node == parent->right) { 492 rotate_left(parent); 493 parent = node; 494 assert (grandpa == parent->parent); 495 /* rotation between parent and child preserves grandpa */ 496 } 497 parent->color = dnode_black; 498 grandpa->color = dnode_red; 499 rotate_right(grandpa); 500 break; 501 } 502 } else { /* symmetric cases: parent == parent->parent->right */ 503 uncle = grandpa->left; 504 if (uncle->color == dnode_red) { 505 parent->color = dnode_black; 506 uncle->color = dnode_black; 507 grandpa->color = dnode_red; 508 node = grandpa; 509 parent = grandpa->parent; 510 } else { 511 if (node == parent->left) { 512 rotate_right(parent); 513 parent = node; 514 assert (grandpa == parent->parent); 515 } 516 parent->color = dnode_black; 517 grandpa->color = dnode_red; 518 rotate_left(grandpa); 519 break; 520 } 521 } 522 } 523 524 dict_root(dict)->color = dnode_black; 525 526} 527 528/* 529 * Allocate a node using the dictionary's allocator routine, give it 530 * the data item. 531 */ 532 533static dnode_t *dnode_init(dnode_t *dnode, void *data) 534{ 535 dnode->data = data; 536 dnode->parent = NULL; 537 dnode->left = NULL; 538 dnode->right = NULL; 539 return dnode; 540} 541 542static int dict_alloc_insert(dict_t *dict, const void *key, void *data) 543{ 544 dnode_t *node = malloc(sizeof(dnode_t)); 545 546 if (node) { 547 dnode_init(node, data); 548 dict_insert(dict, node, key); 549 return 1; 550 } 551 return 0; 552} 553 554/* 555 * Return the node with the lowest (leftmost) key. If the dictionary is empty 556 * (that is, dict_isempty(dict) returns 1) a null pointer is returned. 557 */ 558 559static dnode_t *dict_first(dict_t *dict) 560{ 561 dnode_t *nil = dict_nil(dict), *root = dict_root(dict), *left; 562 563 if (root != nil) 564 while ((left = root->left) != nil) 565 root = left; 566 567 return (root == nil) ? NULL : root; 568} 569 570/* 571 * Return the given node's successor node---the node which has the 572 * next key in the the left to right ordering. If the node has 573 * no successor, a null pointer is returned rather than a pointer to 574 * the nil node. 575 */ 576 577static dnode_t *dict_next(dict_t *dict, dnode_t *curr) 578{ 579 dnode_t *nil = dict_nil(dict), *parent, *left; 580 581 if (curr->right != nil) { 582 curr = curr->right; 583 while ((left = curr->left) != nil) 584 curr = left; 585 return curr; 586 } 587 588 parent = curr->parent; 589 590 while (parent != nil && curr == parent->right) { 591 curr = parent; 592 parent = curr->parent; 593 } 594 595 return (parent == nil) ? NULL : parent; 596} 597 598 599static void dnode_free(dnode_t *node) 600{ 601 free(node); 602} 603 604 605#undef left 606#undef right 607#undef parent 608#undef color 609#undef key 610#undef data 611 612#undef nilnode 613#undef maxcount 614#undef compare 615#undef dupes 616 617 618/* 619 * dirinfo.c --- maintains the directory information table for e2fsck. 620 */ 621 622/* 623 * This subroutine is called during pass1 to create a directory info 624 * entry. During pass1, the passed-in parent is 0; it will get filled 625 * in during pass2. 626 */ 627static void e2fsck_add_dir_info(e2fsck_t ctx, ext2_ino_t ino, ext2_ino_t parent) 628{ 629 struct dir_info *dir; 630 int i, j; 631 ext2_ino_t num_dirs; 632 errcode_t retval; 633 unsigned long old_size; 634 635 if (!ctx->dir_info) { 636 ctx->dir_info_count = 0; 637 retval = ext2fs_get_num_dirs(ctx->fs, &num_dirs); 638 if (retval) 639 num_dirs = 1024; /* Guess */ 640 ctx->dir_info_size = num_dirs + 10; 641 ctx->dir_info = (struct dir_info *) 642 e2fsck_allocate_memory(ctx, ctx->dir_info_size 643 * sizeof (struct dir_info), 644 "directory map"); 645 } 646 647 if (ctx->dir_info_count >= ctx->dir_info_size) { 648 old_size = ctx->dir_info_size * sizeof(struct dir_info); 649 ctx->dir_info_size += 10; 650 retval = ext2fs_resize_mem(old_size, ctx->dir_info_size * 651 sizeof(struct dir_info), 652 &ctx->dir_info); 653 if (retval) { 654 ctx->dir_info_size -= 10; 655 return; 656 } 657 } 658 659 /* 660 * Normally, add_dir_info is called with each inode in 661 * sequential order; but once in a while (like when pass 3 662 * needs to recreate the root directory or lost+found 663 * directory) it is called out of order. In those cases, we 664 * need to move the dir_info entries down to make room, since 665 * the dir_info array needs to be sorted by inode number for 666 * get_dir_info()'s sake. 667 */ 668 if (ctx->dir_info_count && 669 ctx->dir_info[ctx->dir_info_count-1].ino >= ino) { 670 for (i = ctx->dir_info_count-1; i > 0; i--) 671 if (ctx->dir_info[i-1].ino < ino) 672 break; 673 dir = &ctx->dir_info[i]; 674 if (dir->ino != ino) 675 for (j = ctx->dir_info_count++; j > i; j--) 676 ctx->dir_info[j] = ctx->dir_info[j-1]; 677 } else 678 dir = &ctx->dir_info[ctx->dir_info_count++]; 679 680 dir->ino = ino; 681 dir->dotdot = parent; 682 dir->parent = parent; 683} 684 685/* 686 * get_dir_info() --- given an inode number, try to find the directory 687 * information entry for it. 688 */ 689static struct dir_info *e2fsck_get_dir_info(e2fsck_t ctx, ext2_ino_t ino) 690{ 691 int low, high, mid; 692 693 low = 0; 694 high = ctx->dir_info_count-1; 695 if (!ctx->dir_info) 696 return 0; 697 if (ino == ctx->dir_info[low].ino) 698 return &ctx->dir_info[low]; 699 if (ino == ctx->dir_info[high].ino) 700 return &ctx->dir_info[high]; 701 702 while (low < high) { 703 mid = (low+high)/2; 704 if (mid == low || mid == high) 705 break; 706 if (ino == ctx->dir_info[mid].ino) 707 return &ctx->dir_info[mid]; 708 if (ino < ctx->dir_info[mid].ino) 709 high = mid; 710 else 711 low = mid; 712 } 713 return 0; 714} 715 716/* 717 * Free the dir_info structure when it isn't needed any more. 718 */ 719static void e2fsck_free_dir_info(e2fsck_t ctx) 720{ 721 ext2fs_free_mem(&ctx->dir_info); 722 ctx->dir_info_size = 0; 723 ctx->dir_info_count = 0; 724} 725 726/* 727 * Return the count of number of directories in the dir_info structure 728 */ 729static int e2fsck_get_num_dirinfo(e2fsck_t ctx) 730{ 731 return ctx->dir_info_count; 732} 733 734/* 735 * A simple interator function 736 */ 737static struct dir_info *e2fsck_dir_info_iter(e2fsck_t ctx, int *control) 738{ 739 if (*control >= ctx->dir_info_count) 740 return 0; 741 742 return ctx->dir_info + (*control)++; 743} 744 745/* 746 * dirinfo.c --- maintains the directory information table for e2fsck. 747 * 748 */ 749 750#ifdef ENABLE_HTREE 751 752/* 753 * This subroutine is called during pass1 to create a directory info 754 * entry. During pass1, the passed-in parent is 0; it will get filled 755 * in during pass2. 756 */ 757static void e2fsck_add_dx_dir(e2fsck_t ctx, ext2_ino_t ino, int num_blocks) 758{ 759 struct dx_dir_info *dir; 760 int i, j; 761 errcode_t retval; 762 unsigned long old_size; 763 764 if (!ctx->dx_dir_info) { 765 ctx->dx_dir_info_count = 0; 766 ctx->dx_dir_info_size = 100; /* Guess */ 767 ctx->dx_dir_info = (struct dx_dir_info *) 768 e2fsck_allocate_memory(ctx, ctx->dx_dir_info_size 769 * sizeof (struct dx_dir_info), 770 "directory map"); 771 } 772 773 if (ctx->dx_dir_info_count >= ctx->dx_dir_info_size) { 774 old_size = ctx->dx_dir_info_size * sizeof(struct dx_dir_info); 775 ctx->dx_dir_info_size += 10; 776 retval = ext2fs_resize_mem(old_size, ctx->dx_dir_info_size * 777 sizeof(struct dx_dir_info), 778 &ctx->dx_dir_info); 779 if (retval) { 780 ctx->dx_dir_info_size -= 10; 781 return; 782 } 783 } 784 785 /* 786 * Normally, add_dx_dir_info is called with each inode in 787 * sequential order; but once in a while (like when pass 3 788 * needs to recreate the root directory or lost+found 789 * directory) it is called out of order. In those cases, we 790 * need to move the dx_dir_info entries down to make room, since 791 * the dx_dir_info array needs to be sorted by inode number for 792 * get_dx_dir_info()'s sake. 793 */ 794 if (ctx->dx_dir_info_count && 795 ctx->dx_dir_info[ctx->dx_dir_info_count-1].ino >= ino) { 796 for (i = ctx->dx_dir_info_count-1; i > 0; i--) 797 if (ctx->dx_dir_info[i-1].ino < ino) 798 break; 799 dir = &ctx->dx_dir_info[i]; 800 if (dir->ino != ino) 801 for (j = ctx->dx_dir_info_count++; j > i; j--) 802 ctx->dx_dir_info[j] = ctx->dx_dir_info[j-1]; 803 } else 804 dir = &ctx->dx_dir_info[ctx->dx_dir_info_count++]; 805 806 dir->ino = ino; 807 dir->numblocks = num_blocks; 808 dir->hashversion = 0; 809 dir->dx_block = e2fsck_allocate_memory(ctx, num_blocks 810 * sizeof (struct dx_dirblock_info), 811 "dx_block info array"); 812 813} 814 815/* 816 * get_dx_dir_info() --- given an inode number, try to find the directory 817 * information entry for it. 818 */ 819static struct dx_dir_info *e2fsck_get_dx_dir_info(e2fsck_t ctx, ext2_ino_t ino) 820{ 821 int low, high, mid; 822 823 low = 0; 824 high = ctx->dx_dir_info_count-1; 825 if (!ctx->dx_dir_info) 826 return 0; 827 if (ino == ctx->dx_dir_info[low].ino) 828 return &ctx->dx_dir_info[low]; 829 if (ino == ctx->dx_dir_info[high].ino) 830 return &ctx->dx_dir_info[high]; 831 832 while (low < high) { 833 mid = (low+high)/2; 834 if (mid == low || mid == high) 835 break; 836 if (ino == ctx->dx_dir_info[mid].ino) 837 return &ctx->dx_dir_info[mid]; 838 if (ino < ctx->dx_dir_info[mid].ino) 839 high = mid; 840 else 841 low = mid; 842 } 843 return 0; 844} 845 846/* 847 * Free the dx_dir_info structure when it isn't needed any more. 848 */ 849static void e2fsck_free_dx_dir_info(e2fsck_t ctx) 850{ 851 int i; 852 struct dx_dir_info *dir; 853 854 if (ctx->dx_dir_info) { 855 dir = ctx->dx_dir_info; 856 for (i=0; i < ctx->dx_dir_info_count; i++) { 857 ext2fs_free_mem(&dir->dx_block); 858 } 859 ext2fs_free_mem(&ctx->dx_dir_info); 860 } 861 ctx->dx_dir_info_size = 0; 862 ctx->dx_dir_info_count = 0; 863} 864 865/* 866 * A simple interator function 867 */ 868static struct dx_dir_info *e2fsck_dx_dir_info_iter(e2fsck_t ctx, int *control) 869{ 870 if (*control >= ctx->dx_dir_info_count) 871 return 0; 872 873 return ctx->dx_dir_info + (*control)++; 874} 875 876#endif /* ENABLE_HTREE */ 877/* 878 * e2fsck.c - a consistency checker for the new extended file system. 879 * 880 */ 881 882/* 883 * This function allocates an e2fsck context 884 */ 885static errcode_t e2fsck_allocate_context(e2fsck_t *ret) 886{ 887 e2fsck_t context; 888 errcode_t retval; 889 890 retval = ext2fs_get_mem(sizeof(struct e2fsck_struct), &context); 891 if (retval) 892 return retval; 893 894 memset(context, 0, sizeof(struct e2fsck_struct)); 895 896 context->process_inode_size = 256; 897 context->ext_attr_ver = 2; 898 899 *ret = context; 900 return 0; 901} 902 903struct ea_refcount_el { 904 blk_t ea_blk; 905 int ea_count; 906}; 907 908struct ea_refcount { 909 blk_t count; 910 blk_t size; 911 blk_t cursor; 912 struct ea_refcount_el *list; 913}; 914 915static void ea_refcount_free(ext2_refcount_t refcount) 916{ 917 if (!refcount) 918 return; 919 920 ext2fs_free_mem(&refcount->list); 921 ext2fs_free_mem(&refcount); 922} 923 924/* 925 * This function resets an e2fsck context; it is called when e2fsck 926 * needs to be restarted. 927 */ 928static errcode_t e2fsck_reset_context(e2fsck_t ctx) 929{ 930 ctx->flags = 0; 931 ctx->lost_and_found = 0; 932 ctx->bad_lost_and_found = 0; 933 ext2fs_free_inode_bitmap(ctx->inode_used_map); 934 ctx->inode_used_map = 0; 935 ext2fs_free_inode_bitmap(ctx->inode_dir_map); 936 ctx->inode_dir_map = 0; 937 ext2fs_free_inode_bitmap(ctx->inode_reg_map); 938 ctx->inode_reg_map = 0; 939 ext2fs_free_block_bitmap(ctx->block_found_map); 940 ctx->block_found_map = 0; 941 ext2fs_free_icount(ctx->inode_link_info); 942 ctx->inode_link_info = 0; 943 if (ctx->journal_io) { 944 if (ctx->fs && ctx->fs->io != ctx->journal_io) 945 io_channel_close(ctx->journal_io); 946 ctx->journal_io = 0; 947 } 948 if (ctx->fs) { 949 ext2fs_free_dblist(ctx->fs->dblist); 950 ctx->fs->dblist = 0; 951 } 952 e2fsck_free_dir_info(ctx); 953#ifdef ENABLE_HTREE 954 e2fsck_free_dx_dir_info(ctx); 955#endif 956 ea_refcount_free(ctx->refcount); 957 ctx->refcount = 0; 958 ea_refcount_free(ctx->refcount_extra); 959 ctx->refcount_extra = 0; 960 ext2fs_free_block_bitmap(ctx->block_dup_map); 961 ctx->block_dup_map = 0; 962 ext2fs_free_block_bitmap(ctx->block_ea_map); 963 ctx->block_ea_map = 0; 964 ext2fs_free_inode_bitmap(ctx->inode_bad_map); 965 ctx->inode_bad_map = 0; 966 ext2fs_free_inode_bitmap(ctx->inode_imagic_map); 967 ctx->inode_imagic_map = 0; 968 ext2fs_u32_list_free(ctx->dirs_to_hash); 969 ctx->dirs_to_hash = 0; 970 971 /* 972 * Clear the array of invalid meta-data flags 973 */ 974 ext2fs_free_mem(&ctx->invalid_inode_bitmap_flag); 975 ext2fs_free_mem(&ctx->invalid_block_bitmap_flag); 976 ext2fs_free_mem(&ctx->invalid_inode_table_flag); 977 978 /* Clear statistic counters */ 979 ctx->fs_directory_count = 0; 980 ctx->fs_regular_count = 0; 981 ctx->fs_blockdev_count = 0; 982 ctx->fs_chardev_count = 0; 983 ctx->fs_links_count = 0; 984 ctx->fs_symlinks_count = 0; 985 ctx->fs_fast_symlinks_count = 0; 986 ctx->fs_fifo_count = 0; 987 ctx->fs_total_count = 0; 988 ctx->fs_sockets_count = 0; 989 ctx->fs_ind_count = 0; 990 ctx->fs_dind_count = 0; 991 ctx->fs_tind_count = 0; 992 ctx->fs_fragmented = 0; 993 ctx->large_files = 0; 994 995 /* Reset the superblock to the user's requested value */ 996 ctx->superblock = ctx->use_superblock; 997 998 return 0; 999} 1000 1001static void e2fsck_free_context(e2fsck_t ctx) 1002{ 1003 if (!ctx) 1004 return; 1005 1006 e2fsck_reset_context(ctx); 1007 if (ctx->blkid) 1008 blkid_put_cache(ctx->blkid); 1009 1010 ext2fs_free_mem(&ctx); 1011} 1012 1013/* 1014 * ea_refcount.c 1015 */ 1016 1017/* 1018 * The strategy we use for keeping track of EA refcounts is as 1019 * follows. We keep a sorted array of first EA blocks and its 1020 * reference counts. Once the refcount has dropped to zero, it is 1021 * removed from the array to save memory space. Once the EA block is 1022 * checked, its bit is set in the block_ea_map bitmap. 1023 */ 1024 1025 1026static errcode_t ea_refcount_create(int size, ext2_refcount_t *ret) 1027{ 1028 ext2_refcount_t refcount; 1029 errcode_t retval; 1030 size_t bytes; 1031 1032 retval = ext2fs_get_mem(sizeof(struct ea_refcount), &refcount); 1033 if (retval) 1034 return retval; 1035 memset(refcount, 0, sizeof(struct ea_refcount)); 1036 1037 if (!size) 1038 size = 500; 1039 refcount->size = size; 1040 bytes = (size_t) (size * sizeof(struct ea_refcount_el)); 1041#ifdef DEBUG 1042 printf("Refcount allocated %d entries, %d bytes.\n", 1043 refcount->size, bytes); 1044#endif 1045 retval = ext2fs_get_mem(bytes, &refcount->list); 1046 if (retval) 1047 goto errout; 1048 memset(refcount->list, 0, bytes); 1049 1050 refcount->count = 0; 1051 refcount->cursor = 0; 1052 1053 *ret = refcount; 1054 return 0; 1055 1056errout: 1057 ea_refcount_free(refcount); 1058 return retval; 1059} 1060 1061/* 1062 * collapse_refcount() --- go through the refcount array, and get rid 1063 * of any count == zero entries 1064 */ 1065static void refcount_collapse(ext2_refcount_t refcount) 1066{ 1067 unsigned int i, j; 1068 struct ea_refcount_el *list; 1069 1070 list = refcount->list; 1071 for (i = 0, j = 0; i < refcount->count; i++) { 1072 if (list[i].ea_count) { 1073 if (i != j) 1074 list[j] = list[i]; 1075 j++; 1076 } 1077 } 1078#if defined(DEBUG) || defined(TEST_PROGRAM) 1079 printf("Refcount_collapse: size was %d, now %d\n", 1080 refcount->count, j); 1081#endif 1082 refcount->count = j; 1083} 1084 1085 1086/* 1087 * insert_refcount_el() --- Insert a new entry into the sorted list at a 1088 * specified position. 1089 */ 1090static struct ea_refcount_el *insert_refcount_el(ext2_refcount_t refcount, 1091 blk_t blk, int pos) 1092{ 1093 struct ea_refcount_el *el; 1094 errcode_t retval; 1095 blk_t new_size = 0; 1096 int num; 1097 1098 if (refcount->count >= refcount->size) { 1099 new_size = refcount->size + 100; 1100#ifdef DEBUG 1101 printf("Reallocating refcount %d entries...\n", new_size); 1102#endif 1103 retval = ext2fs_resize_mem((size_t) refcount->size * 1104 sizeof(struct ea_refcount_el), 1105 (size_t) new_size * 1106 sizeof(struct ea_refcount_el), 1107 &refcount->list); 1108 if (retval) 1109 return 0; 1110 refcount->size = new_size; 1111 } 1112 num = (int) refcount->count - pos; 1113 if (num < 0) 1114 return 0; /* should never happen */ 1115 if (num) { 1116 memmove(&refcount->list[pos+1], &refcount->list[pos], 1117 sizeof(struct ea_refcount_el) * num); 1118 } 1119 refcount->count++; 1120 el = &refcount->list[pos]; 1121 el->ea_count = 0; 1122 el->ea_blk = blk; 1123 return el; 1124} 1125 1126 1127/* 1128 * get_refcount_el() --- given an block number, try to find refcount 1129 * information in the sorted list. If the create flag is set, 1130 * and we can't find an entry, create one in the sorted list. 1131 */ 1132static struct ea_refcount_el *get_refcount_el(ext2_refcount_t refcount, 1133 blk_t blk, int create) 1134{ 1135 float range; 1136 int low, high, mid; 1137 blk_t lowval, highval; 1138 1139 if (!refcount || !refcount->list) 1140 return 0; 1141retry: 1142 low = 0; 1143 high = (int) refcount->count-1; 1144 if (create && ((refcount->count == 0) || 1145 (blk > refcount->list[high].ea_blk))) { 1146 if (refcount->count >= refcount->size) 1147 refcount_collapse(refcount); 1148 1149 return insert_refcount_el(refcount, blk, 1150 (unsigned) refcount->count); 1151 } 1152 if (refcount->count == 0) 1153 return 0; 1154 1155 if (refcount->cursor >= refcount->count) 1156 refcount->cursor = 0; 1157 if (blk == refcount->list[refcount->cursor].ea_blk) 1158 return &refcount->list[refcount->cursor++]; 1159#ifdef DEBUG 1160 printf("Non-cursor get_refcount_el: %u\n", blk); 1161#endif 1162 while (low <= high) { 1163 if (low == high) 1164 mid = low; 1165 else { 1166 /* Interpolate for efficiency */ 1167 lowval = refcount->list[low].ea_blk; 1168 highval = refcount->list[high].ea_blk; 1169 1170 if (blk < lowval) 1171 range = 0; 1172 else if (blk > highval) 1173 range = 1; 1174 else 1175 range = ((float) (blk - lowval)) / 1176 (highval - lowval); 1177 mid = low + ((int) (range * (high-low))); 1178 } 1179 1180 if (blk == refcount->list[mid].ea_blk) { 1181 refcount->cursor = mid+1; 1182 return &refcount->list[mid]; 1183 } 1184 if (blk < refcount->list[mid].ea_blk) 1185 high = mid-1; 1186 else 1187 low = mid+1; 1188 } 1189 /* 1190 * If we need to create a new entry, it should be right at 1191 * low (where high will be left at low-1). 1192 */ 1193 if (create) { 1194 if (refcount->count >= refcount->size) { 1195 refcount_collapse(refcount); 1196 if (refcount->count < refcount->size) 1197 goto retry; 1198 } 1199 return insert_refcount_el(refcount, blk, low); 1200 } 1201 return 0; 1202} 1203 1204static errcode_t 1205ea_refcount_increment(ext2_refcount_t refcount, blk_t blk, int *ret) 1206{ 1207 struct ea_refcount_el *el; 1208 1209 el = get_refcount_el(refcount, blk, 1); 1210 if (!el) 1211 return EXT2_ET_NO_MEMORY; 1212 el->ea_count++; 1213 1214 if (ret) 1215 *ret = el->ea_count; 1216 return 0; 1217} 1218 1219static errcode_t 1220ea_refcount_decrement(ext2_refcount_t refcount, blk_t blk, int *ret) 1221{ 1222 struct ea_refcount_el *el; 1223 1224 el = get_refcount_el(refcount, blk, 0); 1225 if (!el || el->ea_count == 0) 1226 return EXT2_ET_INVALID_ARGUMENT; 1227 1228 el->ea_count--; 1229 1230 if (ret) 1231 *ret = el->ea_count; 1232 return 0; 1233} 1234 1235static errcode_t 1236ea_refcount_store(ext2_refcount_t refcount, blk_t blk, int count) 1237{ 1238 struct ea_refcount_el *el; 1239 1240 /* 1241 * Get the refcount element 1242 */ 1243 el = get_refcount_el(refcount, blk, count ? 1 : 0); 1244 if (!el) 1245 return count ? EXT2_ET_NO_MEMORY : 0; 1246 el->ea_count = count; 1247 return 0; 1248} 1249 1250static inline void ea_refcount_intr_begin(ext2_refcount_t refcount) 1251{ 1252 refcount->cursor = 0; 1253} 1254 1255 1256static blk_t ea_refcount_intr_next(ext2_refcount_t refcount, int *ret) 1257{ 1258 struct ea_refcount_el *list; 1259 1260 while (1) { 1261 if (refcount->cursor >= refcount->count) 1262 return 0; 1263 list = refcount->list; 1264 if (list[refcount->cursor].ea_count) { 1265 if (ret) 1266 *ret = list[refcount->cursor].ea_count; 1267 return list[refcount->cursor++].ea_blk; 1268 } 1269 refcount->cursor++; 1270 } 1271} 1272 1273 1274/* 1275 * ehandler.c --- handle bad block errors which come up during the 1276 * course of an e2fsck session. 1277 */ 1278 1279 1280static const char *operation; 1281 1282static errcode_t 1283e2fsck_handle_read_error(io_channel channel, unsigned long block, int count, 1284 void *data, size_t size FSCK_ATTR((unused)), 1285 int actual FSCK_ATTR((unused)), errcode_t error) 1286{ 1287 int i; 1288 char *p; 1289 ext2_filsys fs = (ext2_filsys) channel->app_data; 1290 e2fsck_t ctx; 1291 1292 ctx = (e2fsck_t) fs->priv_data; 1293 1294 /* 1295 * If more than one block was read, try reading each block 1296 * separately. We could use the actual bytes read to figure 1297 * out where to start, but we don't bother. 1298 */ 1299 if (count > 1) { 1300 p = (char *) data; 1301 for (i=0; i < count; i++, p += channel->block_size, block++) { 1302 error = io_channel_read_blk(channel, block, 1303 1, p); 1304 if (error) 1305 return error; 1306 } 1307 return 0; 1308 } 1309 if (operation) 1310 printf(_("Error reading block %lu (%s) while %s. "), block, 1311 error_message(error), operation); 1312 else 1313 printf(_("Error reading block %lu (%s). "), block, 1314 error_message(error)); 1315 preenhalt(ctx); 1316 if (ask(ctx, _("Ignore error"), 1)) { 1317 if (ask(ctx, _("Force rewrite"), 1)) 1318 io_channel_write_blk(channel, block, 1, data); 1319 return 0; 1320 } 1321 1322 return error; 1323} 1324 1325static errcode_t 1326e2fsck_handle_write_error(io_channel channel, unsigned long block, int count, 1327 const void *data, size_t size FSCK_ATTR((unused)), 1328 int actual FSCK_ATTR((unused)), errcode_t error) 1329{ 1330 int i; 1331 const char *p; 1332 ext2_filsys fs = (ext2_filsys) channel->app_data; 1333 e2fsck_t ctx; 1334 1335 ctx = (e2fsck_t) fs->priv_data; 1336 1337 /* 1338 * If more than one block was written, try writing each block 1339 * separately. We could use the actual bytes read to figure 1340 * out where to start, but we don't bother. 1341 */ 1342 if (count > 1) { 1343 p = (const char *) data; 1344 for (i=0; i < count; i++, p += channel->block_size, block++) { 1345 error = io_channel_write_blk(channel, block, 1346 1, p); 1347 if (error) 1348 return error; 1349 } 1350 return 0; 1351 } 1352 1353 if (operation) 1354 printf(_("Error writing block %lu (%s) while %s. "), block, 1355 error_message(error), operation); 1356 else 1357 printf(_("Error writing block %lu (%s). "), block, 1358 error_message(error)); 1359 preenhalt(ctx); 1360 if (ask(ctx, _("Ignore error"), 1)) 1361 return 0; 1362 1363 return error; 1364} 1365 1366static const char *ehandler_operation(const char *op) 1367{ 1368 const char *ret = operation; 1369 1370 operation = op; 1371 return ret; 1372} 1373 1374static void ehandler_init(io_channel channel) 1375{ 1376 channel->read_error = e2fsck_handle_read_error; 1377 channel->write_error = e2fsck_handle_write_error; 1378} 1379 1380/* 1381 * journal.c --- code for handling the "ext3" journal 1382 * 1383 * Copyright (C) 2000 Andreas Dilger 1384 * Copyright (C) 2000 Theodore Ts'o 1385 * 1386 * Parts of the code are based on fs/jfs/journal.c by Stephen C. Tweedie 1387 * Copyright (C) 1999 Red Hat Software 1388 * 1389 * This file may be redistributed under the terms of the 1390 * GNU General Public License version 2 or at your discretion 1391 * any later version. 1392 */ 1393 1394/* 1395 * Define USE_INODE_IO to use the inode_io.c / fileio.c codepaths. 1396 * This creates a larger static binary, and a smaller binary using 1397 * shared libraries. It's also probably slightly less CPU-efficient, 1398 * which is why it's not on by default. But, it's a good way of 1399 * testing the functions in inode_io.c and fileio.c. 1400 */ 1401#undef USE_INODE_IO 1402 1403/* Kernel compatibility functions for handling the journal. These allow us 1404 * to use the recovery.c file virtually unchanged from the kernel, so we 1405 * don't have to do much to keep kernel and user recovery in sync. 1406 */ 1407static int journal_bmap(journal_t *journal, blk_t block, unsigned long *phys) 1408{ 1409#ifdef USE_INODE_IO 1410 *phys = block; 1411 return 0; 1412#else 1413 struct inode *inode = journal->j_inode; 1414 errcode_t retval; 1415 blk_t pblk; 1416 1417 if (!inode) { 1418 *phys = block; 1419 return 0; 1420 } 1421 1422 retval= ext2fs_bmap(inode->i_ctx->fs, inode->i_ino, 1423 &inode->i_ext2, NULL, 0, block, &pblk); 1424 *phys = pblk; 1425 return retval; 1426#endif 1427} 1428 1429static struct buffer_head *getblk(kdev_t kdev, blk_t blocknr, int blocksize) 1430{ 1431 struct buffer_head *bh; 1432 1433 bh = e2fsck_allocate_memory(kdev->k_ctx, sizeof(*bh), "block buffer"); 1434 if (!bh) 1435 return NULL; 1436 1437 bh->b_ctx = kdev->k_ctx; 1438 if (kdev->k_dev == K_DEV_FS) 1439 bh->b_io = kdev->k_ctx->fs->io; 1440 else 1441 bh->b_io = kdev->k_ctx->journal_io; 1442 bh->b_size = blocksize; 1443 bh->b_blocknr = blocknr; 1444 1445 return bh; 1446} 1447 1448static void sync_blockdev(kdev_t kdev) 1449{ 1450 io_channel io; 1451 1452 if (kdev->k_dev == K_DEV_FS) 1453 io = kdev->k_ctx->fs->io; 1454 else 1455 io = kdev->k_ctx->journal_io; 1456 1457 io_channel_flush(io); 1458} 1459 1460static void ll_rw_block(int rw, int nr, struct buffer_head *bhp[]) 1461{ 1462 int retval; 1463 struct buffer_head *bh; 1464 1465 for (; nr > 0; --nr) { 1466 bh = *bhp++; 1467 if (rw == READ && !bh->b_uptodate) { 1468 retval = io_channel_read_blk(bh->b_io, 1469 bh->b_blocknr, 1470 1, bh->b_data); 1471 if (retval) { 1472 bb_error_msg("while reading block %lu", 1473 (unsigned long) bh->b_blocknr); 1474 bh->b_err = retval; 1475 continue; 1476 } 1477 bh->b_uptodate = 1; 1478 } else if (rw == WRITE && bh->b_dirty) { 1479 retval = io_channel_write_blk(bh->b_io, 1480 bh->b_blocknr, 1481 1, bh->b_data); 1482 if (retval) { 1483 bb_error_msg("while writing block %lu", 1484 (unsigned long) bh->b_blocknr); 1485 bh->b_err = retval; 1486 continue; 1487 } 1488 bh->b_dirty = 0; 1489 bh->b_uptodate = 1; 1490 } 1491 } 1492} 1493 1494static void mark_buffer_dirty(struct buffer_head *bh) 1495{ 1496 bh->b_dirty = 1; 1497} 1498 1499static inline void mark_buffer_clean(struct buffer_head * bh) 1500{ 1501 bh->b_dirty = 0; 1502} 1503 1504static void brelse(struct buffer_head *bh) 1505{ 1506 if (bh->b_dirty) 1507 ll_rw_block(WRITE, 1, &bh); 1508 ext2fs_free_mem(&bh); 1509} 1510 1511static int buffer_uptodate(struct buffer_head *bh) 1512{ 1513 return bh->b_uptodate; 1514} 1515 1516static inline void mark_buffer_uptodate(struct buffer_head *bh, int val) 1517{ 1518 bh->b_uptodate = val; 1519} 1520 1521static void wait_on_buffer(struct buffer_head *bh) 1522{ 1523 if (!bh->b_uptodate) 1524 ll_rw_block(READ, 1, &bh); 1525} 1526 1527 1528static void e2fsck_clear_recover(e2fsck_t ctx, int error) 1529{ 1530 ctx->fs->super->s_feature_incompat &= ~EXT3_FEATURE_INCOMPAT_RECOVER; 1531 1532 /* if we had an error doing journal recovery, we need a full fsck */ 1533 if (error) 1534 ctx->fs->super->s_state &= ~EXT2_VALID_FS; 1535 ext2fs_mark_super_dirty(ctx->fs); 1536} 1537 1538static errcode_t e2fsck_get_journal(e2fsck_t ctx, journal_t **ret_journal) 1539{ 1540 struct ext2_super_block *sb = ctx->fs->super; 1541 struct ext2_super_block jsuper; 1542 struct problem_context pctx; 1543 struct buffer_head *bh; 1544 struct inode *j_inode = NULL; 1545 struct kdev_s *dev_fs = NULL, *dev_journal; 1546 const char *journal_name = 0; 1547 journal_t *journal = NULL; 1548 errcode_t retval = 0; 1549 io_manager io_ptr = 0; 1550 unsigned long start = 0; 1551 blk_t blk; 1552 int ext_journal = 0; 1553 int tried_backup_jnl = 0; 1554 int i; 1555 1556 clear_problem_context(&pctx); 1557 1558 journal = e2fsck_allocate_memory(ctx, sizeof(journal_t), "journal"); 1559 if (!journal) { 1560 return EXT2_ET_NO_MEMORY; 1561 } 1562 1563 dev_fs = e2fsck_allocate_memory(ctx, 2*sizeof(struct kdev_s), "kdev"); 1564 if (!dev_fs) { 1565 retval = EXT2_ET_NO_MEMORY; 1566 goto errout; 1567 } 1568 dev_journal = dev_fs+1; 1569 1570 dev_fs->k_ctx = dev_journal->k_ctx = ctx; 1571 dev_fs->k_dev = K_DEV_FS; 1572 dev_journal->k_dev = K_DEV_JOURNAL; 1573 1574 journal->j_dev = dev_journal; 1575 journal->j_fs_dev = dev_fs; 1576 journal->j_inode = NULL; 1577 journal->j_blocksize = ctx->fs->blocksize; 1578 1579 if (uuid_is_null(sb->s_journal_uuid)) { 1580 if (!sb->s_journal_inum) 1581 return EXT2_ET_BAD_INODE_NUM; 1582 j_inode = e2fsck_allocate_memory(ctx, sizeof(*j_inode), 1583 "journal inode"); 1584 if (!j_inode) { 1585 retval = EXT2_ET_NO_MEMORY; 1586 goto errout; 1587 } 1588 1589 j_inode->i_ctx = ctx; 1590 j_inode->i_ino = sb->s_journal_inum; 1591 1592 if ((retval = ext2fs_read_inode(ctx->fs, 1593 sb->s_journal_inum, 1594 &j_inode->i_ext2))) { 1595 try_backup_journal: 1596 if (sb->s_jnl_backup_type != EXT3_JNL_BACKUP_BLOCKS || 1597 tried_backup_jnl) 1598 goto errout; 1599 memset(&j_inode->i_ext2, 0, sizeof(struct ext2_inode)); 1600 memcpy(&j_inode->i_ext2.i_block[0], sb->s_jnl_blocks, 1601 EXT2_N_BLOCKS*4); 1602 j_inode->i_ext2.i_size = sb->s_jnl_blocks[16]; 1603 j_inode->i_ext2.i_links_count = 1; 1604 j_inode->i_ext2.i_mode = LINUX_S_IFREG | 0600; 1605 tried_backup_jnl++; 1606 } 1607 if (!j_inode->i_ext2.i_links_count || 1608 !LINUX_S_ISREG(j_inode->i_ext2.i_mode)) { 1609 retval = EXT2_ET_NO_JOURNAL; 1610 goto try_backup_journal; 1611 } 1612 if (j_inode->i_ext2.i_size / journal->j_blocksize < 1613 JFS_MIN_JOURNAL_BLOCKS) { 1614 retval = EXT2_ET_JOURNAL_TOO_SMALL; 1615 goto try_backup_journal; 1616 } 1617 for (i=0; i < EXT2_N_BLOCKS; i++) { 1618 blk = j_inode->i_ext2.i_block[i]; 1619 if (!blk) { 1620 if (i < EXT2_NDIR_BLOCKS) { 1621 retval = EXT2_ET_JOURNAL_TOO_SMALL; 1622 goto try_backup_journal; 1623 } 1624 continue; 1625 } 1626 if (blk < sb->s_first_data_block || 1627 blk >= sb->s_blocks_count) { 1628 retval = EXT2_ET_BAD_BLOCK_NUM; 1629 goto try_backup_journal; 1630 } 1631 } 1632 journal->j_maxlen = j_inode->i_ext2.i_size / journal->j_blocksize; 1633 1634#ifdef USE_INODE_IO 1635 retval = ext2fs_inode_io_intern2(ctx->fs, sb->s_journal_inum, 1636 &j_inode->i_ext2, 1637 &journal_name); 1638 if (retval) 1639 goto errout; 1640 1641 io_ptr = inode_io_manager; 1642#else 1643 journal->j_inode = j_inode; 1644 ctx->journal_io = ctx->fs->io; 1645 if ((retval = journal_bmap(journal, 0, &start)) != 0) 1646 goto errout; 1647#endif 1648 } else { 1649 ext_journal = 1; 1650 if (!ctx->journal_name) { 1651 char uuid[37]; 1652 1653 uuid_unparse(sb->s_journal_uuid, uuid); 1654 ctx->journal_name = blkid_get_devname(ctx->blkid, 1655 "UUID", uuid); 1656 if (!ctx->journal_name) 1657 ctx->journal_name = blkid_devno_to_devname(sb->s_journal_dev); 1658 } 1659 journal_name = ctx->journal_name; 1660 1661 if (!journal_name) { 1662 fix_problem(ctx, PR_0_CANT_FIND_JOURNAL, &pctx); 1663 return EXT2_ET_LOAD_EXT_JOURNAL; 1664 } 1665 1666 io_ptr = unix_io_manager; 1667 } 1668 1669#ifndef USE_INODE_IO 1670 if (ext_journal) 1671#endif 1672 retval = io_ptr->open(journal_name, IO_FLAG_RW, 1673 &ctx->journal_io); 1674 if (retval) 1675 goto errout; 1676 1677 io_channel_set_blksize(ctx->journal_io, ctx->fs->blocksize); 1678 1679 if (ext_journal) { 1680 if (ctx->fs->blocksize == 1024) 1681 start = 1; 1682 bh = getblk(dev_journal, start, ctx->fs->blocksize); 1683 if (!bh) { 1684 retval = EXT2_ET_NO_MEMORY; 1685 goto errout; 1686 } 1687 ll_rw_block(READ, 1, &bh); 1688 if ((retval = bh->b_err) != 0) 1689 goto errout; 1690 memcpy(&jsuper, start ? bh->b_data : bh->b_data + 1024, 1691 sizeof(jsuper)); 1692 brelse(bh); 1693#if BB_BIG_ENDIAN 1694 if (jsuper.s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC)) 1695 ext2fs_swap_super(&jsuper); 1696#endif 1697 if (jsuper.s_magic != EXT2_SUPER_MAGIC || 1698 !(jsuper.s_feature_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)) { 1699 fix_problem(ctx, PR_0_EXT_JOURNAL_BAD_SUPER, &pctx); 1700 retval = EXT2_ET_LOAD_EXT_JOURNAL; 1701 goto errout; 1702 } 1703 /* Make sure the journal UUID is correct */ 1704 if (memcmp(jsuper.s_uuid, ctx->fs->super->s_journal_uuid, 1705 sizeof(jsuper.s_uuid))) { 1706 fix_problem(ctx, PR_0_JOURNAL_BAD_UUID, &pctx); 1707 retval = EXT2_ET_LOAD_EXT_JOURNAL; 1708 goto errout; 1709 } 1710 1711 journal->j_maxlen = jsuper.s_blocks_count; 1712 start++; 1713 } 1714 1715 if (!(bh = getblk(dev_journal, start, journal->j_blocksize))) { 1716 retval = EXT2_ET_NO_MEMORY; 1717 goto errout; 1718 } 1719 1720 journal->j_sb_buffer = bh; 1721 journal->j_superblock = (journal_superblock_t *)bh->b_data; 1722 1723#ifdef USE_INODE_IO 1724 ext2fs_free_mem(&j_inode); 1725#endif 1726 1727 *ret_journal = journal; 1728 return 0; 1729 1730errout: 1731 ext2fs_free_mem(&dev_fs); 1732 ext2fs_free_mem(&j_inode); 1733 ext2fs_free_mem(&journal); 1734 return retval; 1735 1736} 1737 1738static errcode_t e2fsck_journal_fix_bad_inode(e2fsck_t ctx, 1739 struct problem_context *pctx) 1740{ 1741 struct ext2_super_block *sb = ctx->fs->super; 1742 int recover = ctx->fs->super->s_feature_incompat & 1743 EXT3_FEATURE_INCOMPAT_RECOVER; 1744 int has_journal = ctx->fs->super->s_feature_compat & 1745 EXT3_FEATURE_COMPAT_HAS_JOURNAL; 1746 1747 if (has_journal || sb->s_journal_inum) { 1748 /* The journal inode is bogus, remove and force full fsck */ 1749 pctx->ino = sb->s_journal_inum; 1750 if (fix_problem(ctx, PR_0_JOURNAL_BAD_INODE, pctx)) { 1751 if (has_journal && sb->s_journal_inum) 1752 printf("*** ext3 journal has been deleted - " 1753 "filesystem is now ext2 only ***\n\n"); 1754 sb->s_feature_compat &= ~EXT3_FEATURE_COMPAT_HAS_JOURNAL; 1755 sb->s_journal_inum = 0; 1756 ctx->flags |= E2F_FLAG_JOURNAL_INODE; 1757 e2fsck_clear_recover(ctx, 1); 1758 return 0; 1759 } 1760 return EXT2_ET_BAD_INODE_NUM; 1761 } else if (recover) { 1762 if (fix_problem(ctx, PR_0_JOURNAL_RECOVER_SET, pctx)) { 1763 e2fsck_clear_recover(ctx, 1); 1764 return 0; 1765 } 1766 return EXT2_ET_UNSUPP_FEATURE; 1767 } 1768 return 0; 1769} 1770 1771#define V1_SB_SIZE 0x0024 1772static void clear_v2_journal_fields(journal_t *journal) 1773{ 1774 e2fsck_t ctx = journal->j_dev->k_ctx; 1775 struct problem_context pctx; 1776 1777 clear_problem_context(&pctx); 1778 1779 if (!fix_problem(ctx, PR_0_CLEAR_V2_JOURNAL, &pctx)) 1780 return; 1781 1782 memset(((char *) journal->j_superblock) + V1_SB_SIZE, 0, 1783 ctx->fs->blocksize-V1_SB_SIZE); 1784 mark_buffer_dirty(journal->j_sb_buffer); 1785} 1786 1787 1788static errcode_t e2fsck_journal_load(journal_t *journal) 1789{ 1790 e2fsck_t ctx = journal->j_dev->k_ctx; 1791 journal_superblock_t *jsb; 1792 struct buffer_head *jbh = journal->j_sb_buffer; 1793 struct problem_context pctx; 1794 1795 clear_problem_context(&pctx); 1796 1797 ll_rw_block(READ, 1, &jbh); 1798 if (jbh->b_err) { 1799 bb_error_msg(_("reading journal superblock")); 1800 return jbh->b_err; 1801 } 1802 1803 jsb = journal->j_superblock; 1804 /* If we don't even have JFS_MAGIC, we probably have a wrong inode */ 1805 if (jsb->s_header.h_magic != htonl(JFS_MAGIC_NUMBER)) 1806 return e2fsck_journal_fix_bad_inode(ctx, &pctx); 1807 1808 switch (ntohl(jsb->s_header.h_blocktype)) { 1809 case JFS_SUPERBLOCK_V1: 1810 journal->j_format_version = 1; 1811 if (jsb->s_feature_compat || 1812 jsb->s_feature_incompat || 1813 jsb->s_feature_ro_compat || 1814 jsb->s_nr_users) 1815 clear_v2_journal_fields(journal); 1816 break; 1817 1818 case JFS_SUPERBLOCK_V2: 1819 journal->j_format_version = 2; 1820 if (ntohl(jsb->s_nr_users) > 1 && 1821 uuid_is_null(ctx->fs->super->s_journal_uuid)) 1822 clear_v2_journal_fields(journal); 1823 if (ntohl(jsb->s_nr_users) > 1) { 1824 fix_problem(ctx, PR_0_JOURNAL_UNSUPP_MULTIFS, &pctx); 1825 return EXT2_ET_JOURNAL_UNSUPP_VERSION; 1826 } 1827 break; 1828 1829 /* 1830 * These should never appear in a journal super block, so if 1831 * they do, the journal is badly corrupted. 1832 */ 1833 case JFS_DESCRIPTOR_BLOCK: 1834 case JFS_COMMIT_BLOCK: 1835 case JFS_REVOKE_BLOCK: 1836 return EXT2_ET_CORRUPT_SUPERBLOCK; 1837 1838 /* If we don't understand the superblock major type, but there 1839 * is a magic number, then it is likely to be a new format we 1840 * just don't understand, so leave it alone. */ 1841 default: 1842 return EXT2_ET_JOURNAL_UNSUPP_VERSION; 1843 } 1844 1845 if (JFS_HAS_INCOMPAT_FEATURE(journal, ~JFS_KNOWN_INCOMPAT_FEATURES)) 1846 return EXT2_ET_UNSUPP_FEATURE; 1847 1848 if (JFS_HAS_RO_COMPAT_FEATURE(journal, ~JFS_KNOWN_ROCOMPAT_FEATURES)) 1849 return EXT2_ET_RO_UNSUPP_FEATURE; 1850 1851 /* We have now checked whether we know enough about the journal 1852 * format to be able to proceed safely, so any other checks that 1853 * fail we should attempt to recover from. */ 1854 if (jsb->s_blocksize != htonl(journal->j_blocksize)) { 1855 bb_error_msg(_("%s: no valid journal superblock found"), 1856 ctx->device_name); 1857 return EXT2_ET_CORRUPT_SUPERBLOCK; 1858 } 1859 1860 if (ntohl(jsb->s_maxlen) < journal->j_maxlen) 1861 journal->j_maxlen = ntohl(jsb->s_maxlen); 1862 else if (ntohl(jsb->s_maxlen) > journal->j_maxlen) { 1863 bb_error_msg(_("%s: journal too short"), 1864 ctx->device_name); 1865 return EXT2_ET_CORRUPT_SUPERBLOCK; 1866 } 1867 1868 journal->j_tail_sequence = ntohl(jsb->s_sequence); 1869 journal->j_transaction_sequence = journal->j_tail_sequence; 1870 journal->j_tail = ntohl(jsb->s_start); 1871 journal->j_first = ntohl(jsb->s_first); 1872 journal->j_last = ntohl(jsb->s_maxlen); 1873 1874 return 0; 1875} 1876 1877static void e2fsck_journal_reset_super(e2fsck_t ctx, journal_superblock_t *jsb, 1878 journal_t *journal) 1879{ 1880 char *p; 1881 union { 1882 uuid_t uuid; 1883 __u32 val[4]; 1884 } u; 1885 __u32 new_seq = 0; 1886 int i; 1887 1888 /* Leave a valid existing V1 superblock signature alone. 1889 * Anything unrecognisable we overwrite with a new V2 1890 * signature. */ 1891 1892 if (jsb->s_header.h_magic != htonl(JFS_MAGIC_NUMBER) || 1893 jsb->s_header.h_blocktype != htonl(JFS_SUPERBLOCK_V1)) { 1894 jsb->s_header.h_magic = htonl(JFS_MAGIC_NUMBER); 1895 jsb->s_header.h_blocktype = htonl(JFS_SUPERBLOCK_V2); 1896 } 1897 1898 /* Zero out everything else beyond the superblock header */ 1899 1900 p = ((char *) jsb) + sizeof(journal_header_t); 1901 memset (p, 0, ctx->fs->blocksize-sizeof(journal_header_t)); 1902 1903 jsb->s_blocksize = htonl(ctx->fs->blocksize); 1904 jsb->s_maxlen = htonl(journal->j_maxlen); 1905 jsb->s_first = htonl(1); 1906 1907 /* Initialize the journal sequence number so that there is "no" 1908 * chance we will find old "valid" transactions in the journal. 1909 * This avoids the need to zero the whole journal (slow to do, 1910 * and risky when we are just recovering the filesystem). 1911 */ 1912 uuid_generate(u.uuid); 1913 for (i = 0; i < 4; i ++) 1914 new_seq ^= u.val[i]; 1915 jsb->s_sequence = htonl(new_seq); 1916 1917 mark_buffer_dirty(journal->j_sb_buffer); 1918 ll_rw_block(WRITE, 1, &journal->j_sb_buffer); 1919} 1920 1921static errcode_t e2fsck_journal_fix_corrupt_super(e2fsck_t ctx, 1922 journal_t *journal, 1923 struct problem_context *pctx) 1924{ 1925 struct ext2_super_block *sb = ctx->fs->super; 1926 int recover = ctx->fs->super->s_feature_incompat & 1927 EXT3_FEATURE_INCOMPAT_RECOVER; 1928 1929 if (sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) { 1930 if (fix_problem(ctx, PR_0_JOURNAL_BAD_SUPER, pctx)) { 1931 e2fsck_journal_reset_super(ctx, journal->j_superblock, 1932 journal); 1933 journal->j_transaction_sequence = 1; 1934 e2fsck_clear_recover(ctx, recover); 1935 return 0; 1936 } 1937 return EXT2_ET_CORRUPT_SUPERBLOCK; 1938 } else if (e2fsck_journal_fix_bad_inode(ctx, pctx)) 1939 return EXT2_ET_CORRUPT_SUPERBLOCK; 1940 1941 return 0; 1942} 1943 1944static void e2fsck_journal_release(e2fsck_t ctx, journal_t *journal, 1945 int reset, int drop) 1946{ 1947 journal_superblock_t *jsb; 1948 1949 if (drop) 1950 mark_buffer_clean(journal->j_sb_buffer); 1951 else if (!(ctx->options & E2F_OPT_READONLY)) { 1952 jsb = journal->j_superblock; 1953 jsb->s_sequence = htonl(journal->j_transaction_sequence); 1954 if (reset) 1955 jsb->s_start = 0; /* this marks the journal as empty */ 1956 mark_buffer_dirty(journal->j_sb_buffer); 1957 } 1958 brelse(journal->j_sb_buffer); 1959 1960 if (ctx->journal_io) { 1961 if (ctx->fs && ctx->fs->io != ctx->journal_io) 1962 io_channel_close(ctx->journal_io); 1963 ctx->journal_io = 0; 1964 } 1965 1966#ifndef USE_INODE_IO 1967 ext2fs_free_mem(&journal->j_inode); 1968#endif 1969 ext2fs_free_mem(&journal->j_fs_dev); 1970 ext2fs_free_mem(&journal); 1971} 1972 1973/* 1974 * This function makes sure that the superblock fields regarding the 1975 * journal are consistent. 1976 */ 1977static int e2fsck_check_ext3_journal(e2fsck_t ctx) 1978{ 1979 struct ext2_super_block *sb = ctx->fs->super; 1980 journal_t *journal; 1981 int recover = ctx->fs->super->s_feature_incompat & 1982 EXT3_FEATURE_INCOMPAT_RECOVER; 1983 struct problem_context pctx; 1984 problem_t problem; 1985 int reset = 0, force_fsck = 0; 1986 int retval; 1987 1988 /* If we don't have any journal features, don't do anything more */ 1989 if (!(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) && 1990 !recover && sb->s_journal_inum == 0 && sb->s_journal_dev == 0 && 1991 uuid_is_null(sb->s_journal_uuid)) 1992 return 0; 1993 1994 clear_problem_context(&pctx); 1995 pctx.num = sb->s_journal_inum; 1996 1997 retval = e2fsck_get_journal(ctx, &journal); 1998 if (retval) { 1999 if ((retval == EXT2_ET_BAD_INODE_NUM) || 2000 (retval == EXT2_ET_BAD_BLOCK_NUM) || 2001 (retval == EXT2_ET_JOURNAL_TOO_SMALL) || 2002 (retval == EXT2_ET_NO_JOURNAL)) 2003 return e2fsck_journal_fix_bad_inode(ctx, &pctx); 2004 return retval; 2005 } 2006 2007 retval = e2fsck_journal_load(journal); 2008 if (retval) { 2009 if ((retval == EXT2_ET_CORRUPT_SUPERBLOCK) || 2010 ((retval == EXT2_ET_UNSUPP_FEATURE) && 2011 (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_INCOMPAT, 2012 &pctx))) || 2013 ((retval == EXT2_ET_RO_UNSUPP_FEATURE) && 2014 (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_ROCOMPAT, 2015 &pctx))) || 2016 ((retval == EXT2_ET_JOURNAL_UNSUPP_VERSION) && 2017 (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_VERSION, &pctx)))) 2018 retval = e2fsck_journal_fix_corrupt_super(ctx, journal, 2019 &pctx); 2020 e2fsck_journal_release(ctx, journal, 0, 1); 2021 return retval; 2022 } 2023 2024 /* 2025 * We want to make the flags consistent here. We will not leave with 2026 * needs_recovery set but has_journal clear. We can't get in a loop 2027 * with -y, -n, or -p, only if a user isn't making up their mind. 2028 */ 2029no_has_journal: 2030 if (!(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL)) { 2031 recover = sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER; 2032 pctx.str = "inode"; 2033 if (fix_problem(ctx, PR_0_JOURNAL_HAS_JOURNAL, &pctx)) { 2034 if (recover && 2035 !fix_problem(ctx, PR_0_JOURNAL_RECOVER_SET, &pctx)) 2036 goto no_has_journal; 2037 /* 2038 * Need a full fsck if we are releasing a 2039 * journal stored on a reserved inode. 2040 */ 2041 force_fsck = recover || 2042 (sb->s_journal_inum < EXT2_FIRST_INODE(sb)); 2043 /* Clear all of the journal fields */ 2044 sb->s_journal_inum = 0; 2045 sb->s_journal_dev = 0; 2046 memset(sb->s_journal_uuid, 0, 2047 sizeof(sb->s_journal_uuid)); 2048 e2fsck_clear_recover(ctx, force_fsck); 2049 } else if (!(ctx->options & E2F_OPT_READONLY)) { 2050 sb->s_feature_compat |= EXT3_FEATURE_COMPAT_HAS_JOURNAL; 2051 ext2fs_mark_super_dirty(ctx->fs); 2052 } 2053 } 2054 2055 if (sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL && 2056 !(sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) && 2057 journal->j_superblock->s_start != 0) { 2058 /* Print status information */ 2059 fix_problem(ctx, PR_0_JOURNAL_RECOVERY_CLEAR, &pctx); 2060 if (ctx->superblock) 2061 problem = PR_0_JOURNAL_RUN_DEFAULT; 2062 else 2063 problem = PR_0_JOURNAL_RUN; 2064 if (fix_problem(ctx, problem, &pctx)) { 2065 ctx->options |= E2F_OPT_FORCE; 2066 sb->s_feature_incompat |= 2067 EXT3_FEATURE_INCOMPAT_RECOVER; 2068 ext2fs_mark_super_dirty(ctx->fs); 2069 } else if (fix_problem(ctx, 2070 PR_0_JOURNAL_RESET_JOURNAL, &pctx)) { 2071 reset = 1; 2072 sb->s_state &= ~EXT2_VALID_FS; 2073 ext2fs_mark_super_dirty(ctx->fs); 2074 } 2075 } 2076 2077 e2fsck_journal_release(ctx, journal, reset, 0); 2078 return retval; 2079} 2080 2081static errcode_t recover_ext3_journal(e2fsck_t ctx) 2082{ 2083 journal_t *journal; 2084 int retval; 2085 2086 journal_init_revoke_caches(); 2087 retval = e2fsck_get_journal(ctx, &journal); 2088 if (retval) 2089 return retval; 2090 2091 retval = e2fsck_journal_load(journal); 2092 if (retval) 2093 goto errout; 2094 2095 retval = journal_init_revoke(journal, 1024); 2096 if (retval) 2097 goto errout; 2098 2099 retval = -journal_recover(journal); 2100 if (retval) 2101 goto errout; 2102 2103 if (journal->j_superblock->s_errno) { 2104 ctx->fs->super->s_state |= EXT2_ERROR_FS; 2105 ext2fs_mark_super_dirty(ctx->fs); 2106 journal->j_superblock->s_errno = 0; 2107 mark_buffer_dirty(journal->j_sb_buffer); 2108 } 2109 2110errout: 2111 journal_destroy_revoke(journal); 2112 journal_destroy_revoke_caches(); 2113 e2fsck_journal_release(ctx, journal, 1, 0); 2114 return retval; 2115} 2116 2117static int e2fsck_run_ext3_journal(e2fsck_t ctx) 2118{ 2119 io_manager io_ptr = ctx->fs->io->manager; 2120 int blocksize = ctx->fs->blocksize; 2121 errcode_t retval, recover_retval; 2122 2123 printf(_("%s: recovering journal\n"), ctx->device_name); 2124 if (ctx->options & E2F_OPT_READONLY) { 2125 printf(_("%s: won't do journal recovery while read-only\n"), 2126 ctx->device_name); 2127 return EXT2_ET_FILE_RO; 2128 } 2129 2130 if (ctx->fs->flags & EXT2_FLAG_DIRTY) 2131 ext2fs_flush(ctx->fs); /* Force out any modifications */ 2132 2133 recover_retval = recover_ext3_journal(ctx); 2134 2135 /* 2136 * Reload the filesystem context to get up-to-date data from disk 2137 * because journal recovery will change the filesystem under us. 2138 */ 2139 ext2fs_close(ctx->fs); 2140 retval = ext2fs_open(ctx->filesystem_name, EXT2_FLAG_RW, 2141 ctx->superblock, blocksize, io_ptr, 2142 &ctx->fs); 2143 2144 if (retval) { 2145 bb_error_msg(_("while trying to re-open %s"), 2146 ctx->device_name); 2147 bb_error_msg_and_die(0); 2148 } 2149 ctx->fs->priv_data = ctx; 2150 2151 /* Set the superblock flags */ 2152 e2fsck_clear_recover(ctx, recover_retval); 2153 return recover_retval; 2154} 2155 2156/* 2157 * This function will move the journal inode from a visible file in 2158 * the filesystem directory hierarchy to the reserved inode if necessary. 2159 */ 2160static const char *const journal_names[] = { 2161 ".journal", "journal", ".journal.dat", "journal.dat", 0 }; 2162 2163static void e2fsck_move_ext3_journal(e2fsck_t ctx) 2164{ 2165 struct ext2_super_block *sb = ctx->fs->super; 2166 struct problem_context pctx; 2167 struct ext2_inode inode; 2168 ext2_filsys fs = ctx->fs; 2169 ext2_ino_t ino; 2170 errcode_t retval; 2171 const char *const * cpp; 2172 int group, mount_flags; 2173 2174 clear_problem_context(&pctx); 2175 2176 /* 2177 * If the filesystem is opened read-only, or there is no 2178 * journal, then do nothing. 2179 */ 2180 if ((ctx->options & E2F_OPT_READONLY) || 2181 (sb->s_journal_inum == 0) || 2182 !(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL)) 2183 return; 2184 2185 /* 2186 * Read in the journal inode 2187 */ 2188 if (ext2fs_read_inode(fs, sb->s_journal_inum, &inode) != 0) 2189 return; 2190 2191 /* 2192 * If it's necessary to backup the journal inode, do so. 2193 */ 2194 if ((sb->s_jnl_backup_type == 0) || 2195 ((sb->s_jnl_backup_type == EXT3_JNL_BACKUP_BLOCKS) && 2196 memcmp(inode.i_block, sb->s_jnl_blocks, EXT2_N_BLOCKS*4))) { 2197 if (fix_problem(ctx, PR_0_BACKUP_JNL, &pctx)) { 2198 memcpy(sb->s_jnl_blocks, inode.i_block, 2199 EXT2_N_BLOCKS*4); 2200 sb->s_jnl_blocks[16] = inode.i_size; 2201 sb->s_jnl_backup_type = EXT3_JNL_BACKUP_BLOCKS; 2202 ext2fs_mark_super_dirty(fs); 2203 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY; 2204 } 2205 } 2206 2207 /* 2208 * If the journal is already the hidden inode, then do nothing 2209 */ 2210 if (sb->s_journal_inum == EXT2_JOURNAL_INO) 2211 return; 2212 2213 /* 2214 * The journal inode had better have only one link and not be readable. 2215 */ 2216 if (inode.i_links_count != 1) 2217 return; 2218 2219 /* 2220 * If the filesystem is mounted, or we can't tell whether 2221 * or not it's mounted, do nothing. 2222 */ 2223 retval = ext2fs_check_if_mounted(ctx->filesystem_name, &mount_flags); 2224 if (retval || (mount_flags & EXT2_MF_MOUNTED)) 2225 return; 2226 2227 /* 2228 * If we can't find the name of the journal inode, then do 2229 * nothing. 2230 */ 2231 for (cpp = journal_names; *cpp; cpp++) { 2232 retval = ext2fs_lookup(fs, EXT2_ROOT_INO, *cpp, 2233 strlen(*cpp), 0, &ino); 2234 if ((retval == 0) && (ino == sb->s_journal_inum)) 2235 break; 2236 } 2237 if (*cpp == 0) 2238 return; 2239 2240 /* We need the inode bitmap to be loaded */ 2241 retval = ext2fs_read_bitmaps(fs); 2242 if (retval) 2243 return; 2244 2245 pctx.str = *cpp; 2246 if (!fix_problem(ctx, PR_0_MOVE_JOURNAL, &pctx)) 2247 return; 2248 2249 /* 2250 * OK, we've done all the checks, let's actually move the 2251 * journal inode. Errors at this point mean we need to force 2252 * an ext2 filesystem check. 2253 */ 2254 if ((retval = ext2fs_unlink(fs, EXT2_ROOT_INO, *cpp, ino, 0)) != 0) 2255 goto err_out; 2256 if ((retval = ext2fs_write_inode(fs, EXT2_JOURNAL_INO, &inode)) != 0) 2257 goto err_out; 2258 sb->s_journal_inum = EXT2_JOURNAL_INO; 2259 ext2fs_mark_super_dirty(fs); 2260 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY; 2261 inode.i_links_count = 0; 2262 inode.i_dtime = time(0); 2263 if ((retval = ext2fs_write_inode(fs, ino, &inode)) != 0) 2264 goto err_out; 2265 2266 group = ext2fs_group_of_ino(fs, ino); 2267 ext2fs_unmark_inode_bitmap(fs->inode_map, ino); 2268 ext2fs_mark_ib_dirty(fs); 2269 fs->group_desc[group].bg_free_inodes_count++; 2270 fs->super->s_free_inodes_count++; 2271 return; 2272 2273err_out: 2274 pctx.errcode = retval; 2275 fix_problem(ctx, PR_0_ERR_MOVE_JOURNAL, &pctx); 2276 fs->super->s_state &= ~EXT2_VALID_FS; 2277 ext2fs_mark_super_dirty(fs); 2278} 2279 2280/* 2281 * message.c --- print e2fsck messages (with compression) 2282 * 2283 * print_e2fsck_message() prints a message to the user, using 2284 * compression techniques and expansions of abbreviations. 2285 * 2286 * The following % expansions are supported: 2287 * 2288 * %b <blk> block number 2289 * %B <blkcount> integer 2290 * %c <blk2> block number 2291 * %Di <dirent>->ino inode number 2292 * %Dn <dirent>->name string 2293 * %Dr <dirent>->rec_len 2294 * %Dl <dirent>->name_len 2295 * %Dt <dirent>->filetype 2296 * %d <dir> inode number 2297 * %g <group> integer 2298 * %i <ino> inode number 2299 * %Is <inode> -> i_size 2300 * %IS <inode> -> i_extra_isize 2301 * %Ib <inode> -> i_blocks 2302 * %Il <inode> -> i_links_count 2303 * %Im <inode> -> i_mode 2304 * %IM <inode> -> i_mtime 2305 * %IF <inode> -> i_faddr 2306 * %If <inode> -> i_file_acl 2307 * %Id <inode> -> i_dir_acl 2308 * %Iu <inode> -> i_uid 2309 * %Ig <inode> -> i_gid 2310 * %j <ino2> inode number 2311 * %m <com_err error message> 2312 * %N <num> 2313 * %p ext2fs_get_pathname of directory <ino> 2314 * %P ext2fs_get_pathname of <dirent>->ino with <ino2> as 2315 * the containing directory. (If dirent is NULL 2316 * then return the pathname of directory <ino2>) 2317 * %q ext2fs_get_pathname of directory <dir> 2318 * %Q ext2fs_get_pathname of directory <ino> with <dir> as 2319 * the containing directory. 2320 * %s <str> miscellaneous string 2321 * %S backup superblock 2322 * %X <num> hexadecimal format 2323 * 2324 * The following '@' expansions are supported: 2325 * 2326 * @a extended attribute 2327 * @A error allocating 2328 * @b block 2329 * @B bitmap 2330 * @c compress 2331 * @C conflicts with some other fs block 2332 * @D deleted 2333 * @d directory 2334 * @e entry 2335 * @E Entry '%Dn' in %p (%i) 2336 * @f filesystem 2337 * @F for @i %i (%Q) is 2338 * @g group 2339 * @h HTREE directory inode 2340 * @i inode 2341 * @I illegal 2342 * @j journal 2343 * @l lost+found 2344 * @L is a link 2345 * @m multiply-claimed 2346 * @n invalid 2347 * @o orphaned 2348 * @p problem in 2349 * @r root inode 2350 * @s should be 2351 * @S superblock 2352 * @u unattached 2353 * @v device 2354 * @z zero-length 2355 */ 2356 2357 2358/* 2359 * This structure defines the abbreviations used by the text strings 2360 * below. The first character in the string is the index letter. An 2361 * abbreviation of the form '@<i>' is expanded by looking up the index 2362 * letter <i> in the table below. 2363 */ 2364static const char *const abbrevs[] = { 2365 N_("aextended attribute"), 2366 N_("Aerror allocating"), 2367 N_("bblock"), 2368 N_("Bbitmap"), 2369 N_("ccompress"), 2370 N_("Cconflicts with some other fs @b"), 2371 N_("iinode"), 2372 N_("Iillegal"), 2373 N_("jjournal"), 2374 N_("Ddeleted"), 2375 N_("ddirectory"), 2376 N_("eentry"), 2377 N_("E@e '%Dn' in %p (%i)"), 2378 N_("ffilesystem"), 2379 N_("Ffor @i %i (%Q) is"), 2380 N_("ggroup"), 2381 N_("hHTREE @d @i"), 2382 N_("llost+found"), 2383 N_("Lis a link"), 2384 N_("mmultiply-claimed"), 2385 N_("ninvalid"), 2386 N_("oorphaned"), 2387 N_("pproblem in"), 2388 N_("rroot @i"), 2389 N_("sshould be"), 2390 N_("Ssuper@b"), 2391 N_("uunattached"), 2392 N_("vdevice"), 2393 N_("zzero-length"), 2394 "@@", 2395 0 2396 }; 2397 2398/* 2399 * Give more user friendly names to the "special" inodes. 2400 */ 2401#define num_special_inodes 11 2402static const char *const special_inode_name[] = 2403{ 2404 N_("<The NULL inode>"), /* 0 */ 2405 N_("<The bad blocks inode>"), /* 1 */ 2406 "/", /* 2 */ 2407 N_("<The ACL index inode>"), /* 3 */ 2408 N_("<The ACL data inode>"), /* 4 */ 2409 N_("<The boot loader inode>"), /* 5 */ 2410 N_("<The undelete directory inode>"), /* 6 */ 2411 N_("<The group descriptor inode>"), /* 7 */ 2412 N_("<The journal inode>"), /* 8 */ 2413 N_("<Reserved inode 9>"), /* 9 */ 2414 N_("<Reserved inode 10>"), /* 10 */ 2415}; 2416 2417/* 2418 * This function does "safe" printing. It will convert non-printable 2419 * ASCII characters using '^' and M- notation. 2420 */ 2421static void safe_print(const char *cp, int len) 2422{ 2423 unsigned char ch; 2424 2425 if (len < 0) 2426 len = strlen(cp); 2427 2428 while (len--) { 2429 ch = *cp++; 2430 if (ch > 128) { 2431 fputs("M-", stdout); 2432 ch -= 128; 2433 } 2434 if ((ch < 32) || (ch == 0x7f)) { 2435 fputc('^', stdout); 2436 ch ^= 0x40; /* ^@, ^A, ^B; ^? for DEL */ 2437 } 2438 fputc(ch, stdout); 2439 } 2440} 2441 2442 2443/* 2444 * This function prints a pathname, using the ext2fs_get_pathname 2445 * function 2446 */ 2447static void print_pathname(ext2_filsys fs, ext2_ino_t dir, ext2_ino_t ino) 2448{ 2449 errcode_t retval; 2450 char *path; 2451 2452 if (!dir && (ino < num_special_inodes)) { 2453 fputs(_(special_inode_name[ino]), stdout); 2454 return; 2455 } 2456 2457 retval = ext2fs_get_pathname(fs, dir, ino, &path); 2458 if (retval) 2459 fputs("???", stdout); 2460 else { 2461 safe_print(path, -1); 2462 ext2fs_free_mem(&path); 2463 } 2464} 2465 2466static void print_e2fsck_message(e2fsck_t ctx, const char *msg, 2467 struct problem_context *pctx, int first); 2468/* 2469 * This function handles the '@' expansion. We allow recursive 2470 * expansion; an @ expression can contain further '@' and '%' 2471 * expressions. 2472 */ 2473static void expand_at_expression(e2fsck_t ctx, char ch, 2474 struct problem_context *pctx, 2475 int *first) 2476{ 2477 const char *const *cpp; 2478 const char *str; 2479 2480 /* Search for the abbreviation */ 2481 for (cpp = abbrevs; *cpp; cpp++) { 2482 if (ch == *cpp[0]) 2483 break; 2484 } 2485 if (*cpp) { 2486 str = _(*cpp) + 1; 2487 if (*first && islower(*str)) { 2488 *first = 0; 2489 fputc(toupper(*str++), stdout); 2490 } 2491 print_e2fsck_message(ctx, str, pctx, *first); 2492 } else 2493 printf("@%c", ch); 2494} 2495 2496/* 2497 * This function expands '%IX' expressions 2498 */ 2499static void expand_inode_expression(char ch, 2500 struct problem_context *ctx) 2501{ 2502 struct ext2_inode *inode; 2503 struct ext2_inode_large *large_inode; 2504 char * time_str; 2505 time_t t; 2506 int do_gmt = -1; 2507 2508 if (!ctx || !ctx->inode) 2509 goto no_inode; 2510 2511 inode = ctx->inode; 2512 large_inode = (struct ext2_inode_large *) inode; 2513 2514 switch (ch) { 2515 case 's': 2516 if (LINUX_S_ISDIR(inode->i_mode)) 2517 printf("%u", inode->i_size); 2518 else { 2519 printf("%"PRIu64, (inode->i_size | 2520 ((uint64_t) inode->i_size_high << 32))); 2521 } 2522 break; 2523 case 'S': 2524 printf("%u", large_inode->i_extra_isize); 2525 break; 2526 case 'b': 2527 printf("%u", inode->i_blocks); 2528 break; 2529 case 'l': 2530 printf("%d", inode->i_links_count); 2531 break; 2532 case 'm': 2533 printf("0%o", inode->i_mode); 2534 break; 2535 case 'M': 2536 /* The diet libc doesn't respect the TZ environemnt variable */ 2537 if (do_gmt == -1) { 2538 time_str = getenv("TZ"); 2539 if (!time_str) 2540 time_str = ""; 2541 do_gmt = !strcmp(time_str, "GMT"); 2542 } 2543 t = inode->i_mtime; 2544 time_str = asctime(do_gmt ? gmtime(&t) : localtime(&t)); 2545 printf("%.24s", time_str); 2546 break; 2547 case 'F': 2548 printf("%u", inode->i_faddr); 2549 break; 2550 case 'f': 2551 printf("%u", inode->i_file_acl); 2552 break; 2553 case 'd': 2554 printf("%u", (LINUX_S_ISDIR(inode->i_mode) ? 2555 inode->i_dir_acl : 0)); 2556 break; 2557 case 'u': 2558 printf("%d", (inode->i_uid | 2559 (inode->osd2.linux2.l_i_uid_high << 16))); 2560 break; 2561 case 'g': 2562 printf("%d", (inode->i_gid | 2563 (inode->osd2.linux2.l_i_gid_high << 16))); 2564 break; 2565 default: 2566 no_inode: 2567 printf("%%I%c", ch); 2568 break; 2569 } 2570} 2571 2572/* 2573 * This function expands '%dX' expressions 2574 */ 2575static void expand_dirent_expression(char ch, 2576 struct problem_context *ctx) 2577{ 2578 struct ext2_dir_entry *dirent; 2579 int len; 2580 2581 if (!ctx || !ctx->dirent) 2582 goto no_dirent; 2583 2584 dirent = ctx->dirent; 2585 2586 switch (ch) { 2587 case 'i': 2588 printf("%u", dirent->inode); 2589 break; 2590 case 'n': 2591 len = dirent->name_len & 0xFF; 2592 if (len > EXT2_NAME_LEN) 2593 len = EXT2_NAME_LEN; 2594 if (len > dirent->rec_len) 2595 len = dirent->rec_len; 2596 safe_print(dirent->name, len); 2597 break; 2598 case 'r': 2599 printf("%u", dirent->rec_len); 2600 break; 2601 case 'l': 2602 printf("%u", dirent->name_len & 0xFF); 2603 break; 2604 case 't': 2605 printf("%u", dirent->name_len >> 8); 2606 break; 2607 default: 2608 no_dirent: 2609 printf("%%D%c", ch); 2610 break; 2611 } 2612} 2613 2614static void expand_percent_expression(ext2_filsys fs, char ch, 2615 struct problem_context *ctx) 2616{ 2617 if (!ctx) 2618 goto no_context; 2619 2620 switch (ch) { 2621 case '%': 2622 fputc('%', stdout); 2623 break; 2624 case 'b': 2625 printf("%u", ctx->blk); 2626 break; 2627 case 'B': 2628 printf("%"PRIi64, ctx->blkcount); 2629 break; 2630 case 'c': 2631 printf("%u", ctx->blk2); 2632 break; 2633 case 'd': 2634 printf("%u", ctx->dir); 2635 break; 2636 case 'g': 2637 printf("%d", ctx->group); 2638 break; 2639 case 'i': 2640 printf("%u", ctx->ino); 2641 break; 2642 case 'j': 2643 printf("%u", ctx->ino2); 2644 break; 2645 case 'm': 2646 printf("%s", error_message(ctx->errcode)); 2647 break; 2648 case 'N': 2649 printf("%"PRIi64, ctx->num); 2650 break; 2651 case 'p': 2652 print_pathname(fs, ctx->ino, 0); 2653 break; 2654 case 'P': 2655 print_pathname(fs, ctx->ino2, 2656 ctx->dirent ? ctx->dirent->inode : 0); 2657 break; 2658 case 'q': 2659 print_pathname(fs, ctx->dir, 0); 2660 break; 2661 case 'Q': 2662 print_pathname(fs, ctx->dir, ctx->ino); 2663 break; 2664 case 'S': 2665 printf("%d", get_backup_sb(NULL, fs, NULL, NULL)); 2666 break; 2667 case 's': 2668 printf("%s", ctx->str ? ctx->str : "NULL"); 2669 break; 2670 case 'X': 2671 printf("0x%"PRIi64, ctx->num); 2672 break; 2673 default: 2674 no_context: 2675 printf("%%%c", ch); 2676 break; 2677 } 2678} 2679 2680 2681static void print_e2fsck_message(e2fsck_t ctx, const char *msg, 2682 struct problem_context *pctx, int first) 2683{ 2684 ext2_filsys fs = ctx->fs; 2685 const char * cp; 2686 int i; 2687 2688 e2fsck_clear_progbar(ctx); 2689 for (cp = msg; *cp; cp++) { 2690 if (cp[0] == '@') { 2691 cp++; 2692 expand_at_expression(ctx, *cp, pctx, &first); 2693 } else if (cp[0] == '%' && cp[1] == 'I') { 2694 cp += 2; 2695 expand_inode_expression(*cp, pctx); 2696 } else if (cp[0] == '%' && cp[1] == 'D') { 2697 cp += 2; 2698 expand_dirent_expression(*cp, pctx); 2699 } else if ((cp[0] == '%')) { 2700 cp++; 2701 expand_percent_expression(fs, *cp, pctx); 2702 } else { 2703 for (i=0; cp[i]; i++) 2704 if ((cp[i] == '@') || cp[i] == '%') 2705 break; 2706 printf("%.*s", i, cp); 2707 cp += i-1; 2708 } 2709 first = 0; 2710 } 2711} 2712 2713 2714/* 2715 * region.c --- code which manages allocations within a region. 2716 */ 2717 2718struct region_el { 2719 region_addr_t start; 2720 region_addr_t end; 2721 struct region_el *next; 2722}; 2723 2724struct region_struct { 2725 region_addr_t min; 2726 region_addr_t max; 2727 struct region_el *allocated; 2728}; 2729 2730static region_t region_create(region_addr_t min, region_addr_t max) 2731{ 2732 region_t region; 2733 2734 region = malloc(sizeof(struct region_struct)); 2735 if (!region) 2736 return NULL; 2737 memset(region, 0, sizeof(struct region_struct)); 2738 region->min = min; 2739 region->max = max; 2740 return region; 2741} 2742 2743static void region_free(region_t region) 2744{ 2745 struct region_el *r, *next; 2746 2747 for (r = region->allocated; r; r = next) { 2748 next = r->next; 2749 free(r); 2750 } 2751 memset(region, 0, sizeof(struct region_struct)); 2752 free(region); 2753} 2754 2755static int region_allocate(region_t region, region_addr_t start, int n) 2756{ 2757 struct region_el *r, *new_region, *prev, *next; 2758 region_addr_t end; 2759 2760 end = start+n; 2761 if ((start < region->min) || (end > region->max)) 2762 return -1; 2763 if (n == 0) 2764 return 1; 2765 2766 /* 2767 * Search through the linked list. If we find that it 2768 * conflicts witih something that's already allocated, return 2769 * 1; if we can find an existing region which we can grow, do 2770 * so. Otherwise, stop when we find the appropriate place 2771 * insert a new region element into the linked list. 2772 */ 2773 for (r = region->allocated, prev=NULL; r; prev = r, r = r->next) { 2774 if (((start >= r->start) && (start < r->end)) || 2775 ((end > r->start) && (end <= r->end)) || 2776 ((start <= r->start) && (end >= r->end))) 2777 return 1; 2778 if (end == r->start) { 2779 r->start = start; 2780 return 0; 2781 } 2782 if (start == r->end) { 2783 if ((next = r->next)) { 2784 if (end > next->start) 2785 return 1; 2786 if (end == next->start) { 2787 r->end = next->end; 2788 r->next = next->next; 2789 free(next); 2790 return 0; 2791 } 2792 } 2793 r->end = end; 2794 return 0; 2795 } 2796 if (start < r->start) 2797 break; 2798 } 2799 /* 2800 * Insert a new region element structure into the linked list 2801 */ 2802 new_region = malloc(sizeof(struct region_el)); 2803 if (!new_region) 2804 return -1; 2805 new_region->start = start; 2806 new_region->end = start + n; 2807 new_region->next = r; 2808 if (prev) 2809 prev->next = new_region; 2810 else 2811 region->allocated = new_region; 2812 return 0; 2813} 2814 2815/* 2816 * pass1.c -- pass #1 of e2fsck: sequential scan of the inode table 2817 * 2818 * Pass 1 of e2fsck iterates over all the inodes in the filesystems, 2819 * and applies the following tests to each inode: 2820 * 2821 * - The mode field of the inode must be legal. 2822 * - The size and block count fields of the inode are correct. 2823 * - A data block must not be used by another inode 2824 * 2825 * Pass 1 also gathers the collects the following information: 2826 * 2827 * - A bitmap of which inodes are in use. (inode_used_map) 2828 * - A bitmap of which inodes are directories. (inode_dir_map) 2829 * - A bitmap of which inodes are regular files. (inode_reg_map) 2830 * - A bitmap of which inodes have bad fields. (inode_bad_map) 2831 * - A bitmap of which inodes are imagic inodes. (inode_imagic_map) 2832 * - A bitmap of which blocks are in use. (block_found_map) 2833 * - A bitmap of which blocks are in use by two inodes (block_dup_map) 2834 * - The data blocks of the directory inodes. (dir_map) 2835 * 2836 * Pass 1 is designed to stash away enough information so that the 2837 * other passes should not need to read in the inode information 2838 * during the normal course of a filesystem check. (Althogh if an 2839 * inconsistency is detected, other passes may need to read in an 2840 * inode to fix it.) 2841 * 2842 * Note that pass 1B will be invoked if there are any duplicate blocks 2843 * found. 2844 */ 2845 2846 2847static int process_block(ext2_filsys fs, blk_t *blocknr, 2848 e2_blkcnt_t blockcnt, blk_t ref_blk, 2849 int ref_offset, void *priv_data); 2850static int process_bad_block(ext2_filsys fs, blk_t *block_nr, 2851 e2_blkcnt_t blockcnt, blk_t ref_blk, 2852 int ref_offset, void *priv_data); 2853static void check_blocks(e2fsck_t ctx, struct problem_context *pctx, 2854 char *block_buf); 2855static void mark_table_blocks(e2fsck_t ctx); 2856static void alloc_imagic_map(e2fsck_t ctx); 2857static void mark_inode_bad(e2fsck_t ctx, ino_t ino); 2858static void handle_fs_bad_blocks(e2fsck_t ctx); 2859static void process_inodes(e2fsck_t ctx, char *block_buf); 2860static int process_inode_cmp(const void *a, const void *b); 2861static errcode_t scan_callback(ext2_filsys fs, 2862 dgrp_t group, void * priv_data); 2863static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount, 2864 char *block_buf, int adjust_sign); 2865/* static char *describe_illegal_block(ext2_filsys fs, blk_t block); */ 2866 2867static void e2fsck_write_inode_full(e2fsck_t ctx, unsigned long ino, 2868 struct ext2_inode * inode, int bufsize, 2869 const char *proc); 2870 2871struct process_block_struct_1 { 2872 ext2_ino_t ino; 2873 unsigned is_dir:1, is_reg:1, clear:1, suppress:1, 2874 fragmented:1, compressed:1, bbcheck:1; 2875 blk_t num_blocks; 2876 blk_t max_blocks; 2877 e2_blkcnt_t last_block; 2878 int num_illegal_blocks; 2879 blk_t previous_block; 2880 struct ext2_inode *inode; 2881 struct problem_context *pctx; 2882 ext2fs_block_bitmap fs_meta_blocks; 2883 e2fsck_t ctx; 2884}; 2885 2886struct process_inode_block { 2887 ext2_ino_t ino; 2888 struct ext2_inode inode; 2889}; 2890 2891struct scan_callback_struct { 2892 e2fsck_t ctx; 2893 char *block_buf; 2894}; 2895 2896/* 2897 * For the inodes to process list. 2898 */ 2899static struct process_inode_block *inodes_to_process; 2900static int process_inode_count; 2901 2902static __u64 ext2_max_sizes[EXT2_MAX_BLOCK_LOG_SIZE - 2903 EXT2_MIN_BLOCK_LOG_SIZE + 1]; 2904 2905/* 2906 * Free all memory allocated by pass1 in preparation for restarting 2907 * things. 2908 */ 2909static void unwind_pass1(void) 2910{ 2911 ext2fs_free_mem(&inodes_to_process); 2912} 2913 2914/* 2915 * Check to make sure a device inode is real. Returns 1 if the device 2916 * checks out, 0 if not. 2917 * 2918 * Note: this routine is now also used to check FIFO's and Sockets, 2919 * since they have the same requirement; the i_block fields should be 2920 * zero. 2921 */ 2922static int 2923e2fsck_pass1_check_device_inode(ext2_filsys fs, struct ext2_inode *inode) 2924{ 2925 int i; 2926 2927 /* 2928 * If i_blocks is non-zero, or the index flag is set, then 2929 * this is a bogus device/fifo/socket 2930 */ 2931 if ((ext2fs_inode_data_blocks(fs, inode) != 0) || 2932 (inode->i_flags & EXT2_INDEX_FL)) 2933 return 0; 2934 2935 /* 2936 * We should be able to do the test below all the time, but 2937 * because the kernel doesn't forcibly clear the device 2938 * inode's additional i_block fields, there are some rare 2939 * occasions when a legitimate device inode will have non-zero 2940 * additional i_block fields. So for now, we only complain 2941 * when the immutable flag is set, which should never happen 2942 * for devices. (And that's when the problem is caused, since 2943 * you can't set or clear immutable flags for devices.) Once 2944 * the kernel has been fixed we can change this... 2945 */ 2946 if (inode->i_flags & (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL)) { 2947 for (i=4; i < EXT2_N_BLOCKS; i++) 2948 if (inode->i_block[i]) 2949 return 0; 2950 } 2951 return 1; 2952} 2953 2954/* 2955 * Check to make sure a symlink inode is real. Returns 1 if the symlink 2956 * checks out, 0 if not. 2957 */ 2958static int 2959e2fsck_pass1_check_symlink(ext2_filsys fs, struct ext2_inode *inode, char *buf) 2960{ 2961 unsigned int len; 2962 int i; 2963 blk_t blocks; 2964 2965 if ((inode->i_size_high || inode->i_size == 0) || 2966 (inode->i_flags & EXT2_INDEX_FL)) 2967 return 0; 2968 2969 blocks = ext2fs_inode_data_blocks(fs, inode); 2970 if (blocks) { 2971 if ((inode->i_size >= fs->blocksize) || 2972 (blocks != fs->blocksize >> 9) || 2973 (inode->i_block[0] < fs->super->s_first_data_block) || 2974 (inode->i_block[0] >= fs->super->s_blocks_count)) 2975 return 0; 2976 2977 for (i = 1; i < EXT2_N_BLOCKS; i++) 2978 if (inode->i_block[i]) 2979 return 0; 2980 2981 if (io_channel_read_blk(fs->io, inode->i_block[0], 1, buf)) 2982 return 0; 2983 2984 len = strnlen(buf, fs->blocksize); 2985 if (len == fs->blocksize) 2986 return 0; 2987 } else { 2988 if (inode->i_size >= sizeof(inode->i_block)) 2989 return 0; 2990 2991 len = strnlen((char *)inode->i_block, sizeof(inode->i_block)); 2992 if (len == sizeof(inode->i_block)) 2993 return 0; 2994 } 2995 if (len != inode->i_size) 2996 return 0; 2997 return 1; 2998} 2999 3000/* 3001 * If the immutable (or append-only) flag is set on the inode, offer 3002 * to clear it. 3003 */ 3004#define BAD_SPECIAL_FLAGS (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL) 3005static void check_immutable(e2fsck_t ctx, struct problem_context *pctx) 3006{ 3007 if (!(pctx->inode->i_flags & BAD_SPECIAL_FLAGS)) 3008 return; 3009 3010 if (!fix_problem(ctx, PR_1_SET_IMMUTABLE, pctx)) 3011 return; 3012 3013 pctx->inode->i_flags &= ~BAD_SPECIAL_FLAGS; 3014 e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1"); 3015} 3016 3017/* 3018 * If device, fifo or socket, check size is zero -- if not offer to 3019 * clear it 3020 */ 3021static void check_size(e2fsck_t ctx, struct problem_context *pctx) 3022{ 3023 struct ext2_inode *inode = pctx->inode; 3024 3025 if ((inode->i_size == 0) && (inode->i_size_high == 0)) 3026 return; 3027 3028 if (!fix_problem(ctx, PR_1_SET_NONZSIZE, pctx)) 3029 return; 3030 3031 inode->i_size = 0; 3032 inode->i_size_high = 0; 3033 e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1"); 3034} 3035 3036static void check_ea_in_inode(e2fsck_t ctx, struct problem_context *pctx) 3037{ 3038 struct ext2_super_block *sb = ctx->fs->super; 3039 struct ext2_inode_large *inode; 3040 struct ext2_ext_attr_entry *entry; 3041 char *start, *end; 3042 int storage_size, remain, offs; 3043 int problem = 0; 3044 3045 inode = (struct ext2_inode_large *) pctx->inode; 3046 storage_size = EXT2_INODE_SIZE(ctx->fs->super) - EXT2_GOOD_OLD_INODE_SIZE - 3047 inode->i_extra_isize; 3048 start = ((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE + 3049 inode->i_extra_isize + sizeof(__u32); 3050 end = (char *) inode + EXT2_INODE_SIZE(ctx->fs->super); 3051 entry = (struct ext2_ext_attr_entry *) start; 3052 3053 /* scan all entry's headers first */ 3054 3055 /* take finish entry 0UL into account */ 3056 remain = storage_size - sizeof(__u32); 3057 offs = end - start; 3058 3059 while (!EXT2_EXT_IS_LAST_ENTRY(entry)) { 3060 3061 /* header eats this space */ 3062 remain -= sizeof(struct ext2_ext_attr_entry); 3063 3064 /* is attribute name valid? */ 3065 if (EXT2_EXT_ATTR_SIZE(entry->e_name_len) > remain) { 3066 pctx->num = entry->e_name_len; 3067 problem = PR_1_ATTR_NAME_LEN; 3068 goto fix; 3069 } 3070 3071 /* attribute len eats this space */ 3072 remain -= EXT2_EXT_ATTR_SIZE(entry->e_name_len); 3073 3074 /* check value size */ 3075 if (entry->e_value_size == 0 || entry->e_value_size > remain) { 3076 pctx->num = entry->e_value_size; 3077 problem = PR_1_ATTR_VALUE_SIZE; 3078 goto fix; 3079 } 3080 3081 /* check value placement */ 3082 if (entry->e_value_offs + 3083 EXT2_XATTR_SIZE(entry->e_value_size) != offs) { 3084 printf("(entry->e_value_offs + entry->e_value_size: %d, offs: %d)\n", entry->e_value_offs + entry->e_value_size, offs); 3085 pctx->num = entry->e_value_offs; 3086 problem = PR_1_ATTR_VALUE_OFFSET; 3087 goto fix; 3088 } 3089 3090 /* e_value_block must be 0 in inode's ea */ 3091 if (entry->e_value_block != 0) { 3092 pctx->num = entry->e_value_block; 3093 problem = PR_1_ATTR_VALUE_BLOCK; 3094 goto fix; 3095 } 3096 3097 /* e_hash must be 0 in inode's ea */ 3098 if (entry->e_hash != 0) { 3099 pctx->num = entry->e_hash; 3100 problem = PR_1_ATTR_HASH; 3101 goto fix; 3102 } 3103 3104 remain -= entry->e_value_size; 3105 offs -= EXT2_XATTR_SIZE(entry->e_value_size); 3106 3107 entry = EXT2_EXT_ATTR_NEXT(entry); 3108 } 3109fix: 3110 /* 3111 * it seems like a corruption. it's very unlikely we could repair 3112 * EA(s) in automatic fashion -bzzz 3113 */ 3114 if (problem == 0 || !fix_problem(ctx, problem, pctx)) 3115 return; 3116 3117 /* simple remove all possible EA(s) */ 3118 *((__u32 *)start) = 0UL; 3119 e2fsck_write_inode_full(ctx, pctx->ino, (struct ext2_inode *)inode, 3120 EXT2_INODE_SIZE(sb), "pass1"); 3121} 3122 3123static void check_inode_extra_space(e2fsck_t ctx, struct problem_context *pctx) 3124{ 3125 struct ext2_super_block *sb = ctx->fs->super; 3126 struct ext2_inode_large *inode; 3127 __u32 *eamagic; 3128 int min, max; 3129 3130 inode = (struct ext2_inode_large *) pctx->inode; 3131 if (EXT2_INODE_SIZE(sb) == EXT2_GOOD_OLD_INODE_SIZE) { 3132 /* this isn't large inode. so, nothing to check */ 3133 return; 3134 } 3135 3136 /* i_extra_isize must cover i_extra_isize + i_pad1 at least */ 3137 min = sizeof(inode->i_extra_isize) + sizeof(inode->i_pad1); 3138 max = EXT2_INODE_SIZE(sb) - EXT2_GOOD_OLD_INODE_SIZE; 3139 /* 3140 * For now we will allow i_extra_isize to be 0, but really 3141 * implementations should never allow i_extra_isize to be 0 3142 */ 3143 if (inode->i_extra_isize && 3144 (inode->i_extra_isize < min || inode->i_extra_isize > max)) { 3145 if (!fix_problem(ctx, PR_1_EXTRA_ISIZE, pctx)) 3146 return; 3147 inode->i_extra_isize = min; 3148 e2fsck_write_inode_full(ctx, pctx->ino, pctx->inode, 3149 EXT2_INODE_SIZE(sb), "pass1"); 3150 return; 3151 } 3152 3153 eamagic = (__u32 *) (((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE + 3154 inode->i_extra_isize); 3155 if (*eamagic == EXT2_EXT_ATTR_MAGIC) { 3156 /* it seems inode has an extended attribute(s) in body */ 3157 check_ea_in_inode(ctx, pctx); 3158 } 3159} 3160 3161static void e2fsck_pass1(e2fsck_t ctx) 3162{ 3163 int i; 3164 __u64 max_sizes; 3165 ext2_filsys fs = ctx->fs; 3166 ext2_ino_t ino; 3167 struct ext2_inode *inode; 3168 ext2_inode_scan scan; 3169 char *block_buf; 3170 unsigned char frag, fsize; 3171 struct problem_context pctx; 3172 struct scan_callback_struct scan_struct; 3173 struct ext2_super_block *sb = ctx->fs->super; 3174 int imagic_fs; 3175 int busted_fs_time = 0; 3176 int inode_size; 3177 3178 clear_problem_context(&pctx); 3179 3180 if (!(ctx->options & E2F_OPT_PREEN)) 3181 fix_problem(ctx, PR_1_PASS_HEADER, &pctx); 3182 3183 if ((fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) && 3184 !(ctx->options & E2F_OPT_NO)) { 3185 if (ext2fs_u32_list_create(&ctx->dirs_to_hash, 50)) 3186 ctx->dirs_to_hash = 0; 3187 } 3188 3189 /* Pass 1 */ 3190 3191#define EXT2_BPP(bits) (1ULL << ((bits) - 2)) 3192 3193 for (i = EXT2_MIN_BLOCK_LOG_SIZE; i <= EXT2_MAX_BLOCK_LOG_SIZE; i++) { 3194 max_sizes = EXT2_NDIR_BLOCKS + EXT2_BPP(i); 3195 max_sizes = max_sizes + EXT2_BPP(i) * EXT2_BPP(i); 3196 max_sizes = max_sizes + EXT2_BPP(i) * EXT2_BPP(i) * EXT2_BPP(i); 3197 max_sizes = (max_sizes * (1UL << i)) - 1; 3198 ext2_max_sizes[i - EXT2_MIN_BLOCK_LOG_SIZE] = max_sizes; 3199 } 3200#undef EXT2_BPP 3201 3202 imagic_fs = (sb->s_feature_compat & EXT2_FEATURE_COMPAT_IMAGIC_INODES); 3203 3204 /* 3205 * Allocate bitmaps structures 3206 */ 3207 pctx.errcode = ext2fs_allocate_inode_bitmap(fs, _("in-use inode map"), 3208 &ctx->inode_used_map); 3209 if (pctx.errcode) { 3210 pctx.num = 1; 3211 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx); 3212 ctx->flags |= E2F_FLAG_ABORT; 3213 return; 3214 } 3215 pctx.errcode = ext2fs_allocate_inode_bitmap(fs, 3216 _("directory inode map"), &ctx->inode_dir_map); 3217 if (pctx.errcode) { 3218 pctx.num = 2; 3219 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx); 3220 ctx->flags |= E2F_FLAG_ABORT; 3221 return; 3222 } 3223 pctx.errcode = ext2fs_allocate_inode_bitmap(fs, 3224 _("regular file inode map"), &ctx->inode_reg_map); 3225 if (pctx.errcode) { 3226 pctx.num = 6; 3227 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx); 3228 ctx->flags |= E2F_FLAG_ABORT; 3229 return; 3230 } 3231 pctx.errcode = ext2fs_allocate_block_bitmap(fs, _("in-use block map"), 3232 &ctx->block_found_map); 3233 if (pctx.errcode) { 3234 pctx.num = 1; 3235 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx); 3236 ctx->flags |= E2F_FLAG_ABORT; 3237 return; 3238 } 3239 pctx.errcode = ext2fs_create_icount2(fs, 0, 0, 0, 3240 &ctx->inode_link_info); 3241 if (pctx.errcode) { 3242 fix_problem(ctx, PR_1_ALLOCATE_ICOUNT, &pctx); 3243 ctx->flags |= E2F_FLAG_ABORT; 3244 return; 3245 } 3246 inode_size = EXT2_INODE_SIZE(fs->super); 3247 inode = (struct ext2_inode *) 3248 e2fsck_allocate_memory(ctx, inode_size, "scratch inode"); 3249 3250 inodes_to_process = (struct process_inode_block *) 3251 e2fsck_allocate_memory(ctx, 3252 (ctx->process_inode_size * 3253 sizeof(struct process_inode_block)), 3254 "array of inodes to process"); 3255 process_inode_count = 0; 3256 3257 pctx.errcode = ext2fs_init_dblist(fs, 0); 3258 if (pctx.errcode) { 3259 fix_problem(ctx, PR_1_ALLOCATE_DBCOUNT, &pctx); 3260 ctx->flags |= E2F_FLAG_ABORT; 3261 return; 3262 } 3263 3264 /* 3265 * If the last orphan field is set, clear it, since the pass1 3266 * processing will automatically find and clear the orphans. 3267 * In the future, we may want to try using the last_orphan 3268 * linked list ourselves, but for now, we clear it so that the 3269 * ext3 mount code won't get confused. 3270 */ 3271 if (!(ctx->options & E2F_OPT_READONLY)) { 3272 if (fs->super->s_last_orphan) { 3273 fs->super->s_last_orphan = 0; 3274 ext2fs_mark_super_dirty(fs); 3275 } 3276 } 3277 3278 mark_table_blocks(ctx); 3279 block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 3, 3280 "block interate buffer"); 3281 e2fsck_use_inode_shortcuts(ctx, 1); 3282 ehandler_operation(_("doing inode scan")); 3283 pctx.errcode = ext2fs_open_inode_scan(fs, ctx->inode_buffer_blocks, 3284 &scan); 3285 if (pctx.errcode) { 3286 fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx); 3287 ctx->flags |= E2F_FLAG_ABORT; 3288 return; 3289 } 3290 ext2fs_inode_scan_flags(scan, EXT2_SF_SKIP_MISSING_ITABLE, 0); 3291 ctx->stashed_inode = inode; 3292 scan_struct.ctx = ctx; 3293 scan_struct.block_buf = block_buf; 3294 ext2fs_set_inode_callback(scan, scan_callback, &scan_struct); 3295 if (ctx->progress) 3296 if ((ctx->progress)(ctx, 1, 0, ctx->fs->group_desc_count)) 3297 return; 3298 if ((fs->super->s_wtime < fs->super->s_inodes_count) || 3299 (fs->super->s_mtime < fs->super->s_inodes_count)) 3300 busted_fs_time = 1; 3301 3302 while (1) { 3303 pctx.errcode = ext2fs_get_next_inode_full(scan, &ino, 3304 inode, inode_size); 3305 if (ctx->flags & E2F_FLAG_SIGNAL_MASK) 3306 return; 3307 if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE) { 3308 continue; 3309 } 3310 if (pctx.errcode) { 3311 fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx); 3312 ctx->flags |= E2F_FLAG_ABORT; 3313 return; 3314 } 3315 if (!ino) 3316 break; 3317 pctx.ino = ino; 3318 pctx.inode = inode; 3319 ctx->stashed_ino = ino; 3320 if (inode->i_links_count) { 3321 pctx.errcode = ext2fs_icount_store(ctx->inode_link_info, 3322 ino, inode->i_links_count); 3323 if (pctx.errcode) { 3324 pctx.num = inode->i_links_count; 3325 fix_problem(ctx, PR_1_ICOUNT_STORE, &pctx); 3326 ctx->flags |= E2F_FLAG_ABORT; 3327 return; 3328 } 3329 } 3330 if (ino == EXT2_BAD_INO) { 3331 struct process_block_struct_1 pb; 3332 3333 pctx.errcode = ext2fs_copy_bitmap(ctx->block_found_map, 3334 &pb.fs_meta_blocks); 3335 if (pctx.errcode) { 3336 pctx.num = 4; 3337 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx); 3338 ctx->flags |= E2F_FLAG_ABORT; 3339 return; 3340 } 3341 pb.ino = EXT2_BAD_INO; 3342 pb.num_blocks = pb.last_block = 0; 3343 pb.num_illegal_blocks = 0; 3344 pb.suppress = 0; pb.clear = 0; pb.is_dir = 0; 3345 pb.is_reg = 0; pb.fragmented = 0; pb.bbcheck = 0; 3346 pb.inode = inode; 3347 pb.pctx = &pctx; 3348 pb.ctx = ctx; 3349 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, 3350 block_buf, process_bad_block, &pb); 3351 ext2fs_free_block_bitmap(pb.fs_meta_blocks); 3352 if (pctx.errcode) { 3353 fix_problem(ctx, PR_1_BLOCK_ITERATE, &pctx); 3354 ctx->flags |= E2F_FLAG_ABORT; 3355 return; 3356 } 3357 if (pb.bbcheck) 3358 if (!fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK_PROMPT, &pctx)) { 3359 ctx->flags |= E2F_FLAG_ABORT; 3360 return; 3361 } 3362 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino); 3363 clear_problem_context(&pctx); 3364 continue; 3365 } else if (ino == EXT2_ROOT_INO) { 3366 /* 3367 * Make sure the root inode is a directory; if 3368 * not, offer to clear it. It will be 3369 * regnerated in pass #3. 3370 */ 3371 if (!LINUX_S_ISDIR(inode->i_mode)) { 3372 if (fix_problem(ctx, PR_1_ROOT_NO_DIR, &pctx)) { 3373 inode->i_dtime = time(0); 3374 inode->i_links_count = 0; 3375 ext2fs_icount_store(ctx->inode_link_info, 3376 ino, 0); 3377 e2fsck_write_inode(ctx, ino, inode, 3378 "pass1"); 3379 } 3380 3381 } 3382 /* 3383 * If dtime is set, offer to clear it. mke2fs 3384 * version 0.2b created filesystems with the 3385 * dtime field set for the root and lost+found 3386 * directories. We won't worry about 3387 * /lost+found, since that can be regenerated 3388 * easily. But we will fix the root directory 3389 * as a special case. 3390 */ 3391 if (inode->i_dtime && inode->i_links_count) { 3392 if (fix_problem(ctx, PR_1_ROOT_DTIME, &pctx)) { 3393 inode->i_dtime = 0; 3394 e2fsck_write_inode(ctx, ino, inode, 3395 "pass1"); 3396 } 3397 } 3398 } else if (ino == EXT2_JOURNAL_INO) { 3399 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino); 3400 if (fs->super->s_journal_inum == EXT2_JOURNAL_INO) { 3401 if (!LINUX_S_ISREG(inode->i_mode) && 3402 fix_problem(ctx, PR_1_JOURNAL_BAD_MODE, 3403 &pctx)) { 3404 inode->i_mode = LINUX_S_IFREG; 3405 e2fsck_write_inode(ctx, ino, inode, 3406 "pass1"); 3407 } 3408 check_blocks(ctx, &pctx, block_buf); 3409 continue; 3410 } 3411 if ((inode->i_links_count || inode->i_blocks || 3412 inode->i_blocks || inode->i_block[0]) && 3413 fix_problem(ctx, PR_1_JOURNAL_INODE_NOT_CLEAR, 3414 &pctx)) { 3415 memset(inode, 0, inode_size); 3416 ext2fs_icount_store(ctx->inode_link_info, 3417 ino, 0); 3418 e2fsck_write_inode_full(ctx, ino, inode, 3419 inode_size, "pass1"); 3420 } 3421 } else if (ino < EXT2_FIRST_INODE(fs->super)) { 3422 int problem = 0; 3423 3424 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino); 3425 if (ino == EXT2_BOOT_LOADER_INO) { 3426 if (LINUX_S_ISDIR(inode->i_mode)) 3427 problem = PR_1_RESERVED_BAD_MODE; 3428 } else if (ino == EXT2_RESIZE_INO) { 3429 if (inode->i_mode && 3430 !LINUX_S_ISREG(inode->i_mode)) 3431 problem = PR_1_RESERVED_BAD_MODE; 3432 } else { 3433 if (inode->i_mode != 0) 3434 problem = PR_1_RESERVED_BAD_MODE; 3435 } 3436 if (problem) { 3437 if (fix_problem(ctx, problem, &pctx)) { 3438 inode->i_mode = 0; 3439 e2fsck_write_inode(ctx, ino, inode, 3440 "pass1"); 3441 } 3442 } 3443 check_blocks(ctx, &pctx, block_buf); 3444 continue; 3445 } 3446 if (inode->i_dtime && !busted_fs_time && 3447 inode->i_dtime < ctx->fs->super->s_inodes_count) { 3448 if (fix_problem(ctx, PR_1_LOW_DTIME, &pctx)) { 3449 inode->i_dtime = inode->i_links_count ? 3450 0 : time(0); 3451 e2fsck_write_inode(ctx, ino, inode, 3452 "pass1"); 3453 } 3454 } 3455 3456 /* 3457 * This code assumes that deleted inodes have 3458 * i_links_count set to 0. 3459 */ 3460 if (!inode->i_links_count) { 3461 if (!inode->i_dtime && inode->i_mode) { 3462 if (fix_problem(ctx, 3463 PR_1_ZERO_DTIME, &pctx)) { 3464 inode->i_dtime = time(0); 3465 e2fsck_write_inode(ctx, ino, inode, 3466 "pass1"); 3467 } 3468 } 3469 continue; 3470 } 3471 /* 3472 * n.b. 0.3c ext2fs code didn't clear i_links_count for 3473 * deleted files. Oops. 3474 * 3475 * Since all new ext2 implementations get this right, 3476 * we now assume that the case of non-zero 3477 * i_links_count and non-zero dtime means that we 3478 * should keep the file, not delete it. 3479 * 3480 */ 3481 if (inode->i_dtime) { 3482 if (fix_problem(ctx, PR_1_SET_DTIME, &pctx)) { 3483 inode->i_dtime = 0; 3484 e2fsck_write_inode(ctx, ino, inode, "pass1"); 3485 } 3486 } 3487 3488 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino); 3489 switch (fs->super->s_creator_os) { 3490 case EXT2_OS_LINUX: 3491 frag = inode->osd2.linux2.l_i_frag; 3492 fsize = inode->osd2.linux2.l_i_fsize; 3493 break; 3494 case EXT2_OS_HURD: 3495 frag = inode->osd2.hurd2.h_i_frag; 3496 fsize = inode->osd2.hurd2.h_i_fsize; 3497 break; 3498 case EXT2_OS_MASIX: 3499 frag = inode->osd2.masix2.m_i_frag; 3500 fsize = inode->osd2.masix2.m_i_fsize; 3501 break; 3502 default: 3503 frag = fsize = 0; 3504 } 3505 3506 if (inode->i_faddr || frag || fsize || 3507 (LINUX_S_ISDIR(inode->i_mode) && inode->i_dir_acl)) 3508 mark_inode_bad(ctx, ino); 3509 if (inode->i_flags & EXT2_IMAGIC_FL) { 3510 if (imagic_fs) { 3511 if (!ctx->inode_imagic_map) 3512 alloc_imagic_map(ctx); 3513 ext2fs_mark_inode_bitmap(ctx->inode_imagic_map, 3514 ino); 3515 } else { 3516 if (fix_problem(ctx, PR_1_SET_IMAGIC, &pctx)) { 3517 inode->i_flags &= ~EXT2_IMAGIC_FL; 3518 e2fsck_write_inode(ctx, ino, 3519 inode, "pass1"); 3520 } 3521 } 3522 } 3523 3524 check_inode_extra_space(ctx, &pctx); 3525 3526 if (LINUX_S_ISDIR(inode->i_mode)) { 3527 ext2fs_mark_inode_bitmap(ctx->inode_dir_map, ino); 3528 e2fsck_add_dir_info(ctx, ino, 0); 3529 ctx->fs_directory_count++; 3530 } else if (LINUX_S_ISREG (inode->i_mode)) { 3531 ext2fs_mark_inode_bitmap(ctx->inode_reg_map, ino); 3532 ctx->fs_regular_count++; 3533 } else if (LINUX_S_ISCHR (inode->i_mode) && 3534 e2fsck_pass1_check_device_inode(fs, inode)) { 3535 check_immutable(ctx, &pctx); 3536 check_size(ctx, &pctx); 3537 ctx->fs_chardev_count++; 3538 } else if (LINUX_S_ISBLK (inode->i_mode) && 3539 e2fsck_pass1_check_device_inode(fs, inode)) { 3540 check_immutable(ctx, &pctx); 3541 check_size(ctx, &pctx); 3542 ctx->fs_blockdev_count++; 3543 } else if (LINUX_S_ISLNK (inode->i_mode) && 3544 e2fsck_pass1_check_symlink(fs, inode, block_buf)) { 3545 check_immutable(ctx, &pctx); 3546 ctx->fs_symlinks_count++; 3547 if (ext2fs_inode_data_blocks(fs, inode) == 0) { 3548 ctx->fs_fast_symlinks_count++; 3549 check_blocks(ctx, &pctx, block_buf); 3550 continue; 3551 } 3552 } 3553 else if (LINUX_S_ISFIFO (inode->i_mode) && 3554 e2fsck_pass1_check_device_inode(fs, inode)) { 3555 check_immutable(ctx, &pctx); 3556 check_size(ctx, &pctx); 3557 ctx->fs_fifo_count++; 3558 } else if ((LINUX_S_ISSOCK (inode->i_mode)) && 3559 e2fsck_pass1_check_device_inode(fs, inode)) { 3560 check_immutable(ctx, &pctx); 3561 check_size(ctx, &pctx); 3562 ctx->fs_sockets_count++; 3563 } else 3564 mark_inode_bad(ctx, ino); 3565 if (inode->i_block[EXT2_IND_BLOCK]) 3566 ctx->fs_ind_count++; 3567 if (inode->i_block[EXT2_DIND_BLOCK]) 3568 ctx->fs_dind_count++; 3569 if (inode->i_block[EXT2_TIND_BLOCK]) 3570 ctx->fs_tind_count++; 3571 if (inode->i_block[EXT2_IND_BLOCK] || 3572 inode->i_block[EXT2_DIND_BLOCK] || 3573 inode->i_block[EXT2_TIND_BLOCK] || 3574 inode->i_file_acl) { 3575 inodes_to_process[process_inode_count].ino = ino; 3576 inodes_to_process[process_inode_count].inode = *inode; 3577 process_inode_count++; 3578 } else 3579 check_blocks(ctx, &pctx, block_buf); 3580 3581 if (ctx->flags & E2F_FLAG_SIGNAL_MASK) 3582 return; 3583 3584 if (process_inode_count >= ctx->process_inode_size) { 3585 process_inodes(ctx, block_buf); 3586 3587 if (ctx->flags & E2F_FLAG_SIGNAL_MASK) 3588 return; 3589 } 3590 } 3591 process_inodes(ctx, block_buf); 3592 ext2fs_close_inode_scan(scan); 3593 ehandler_operation(0); 3594 3595 /* 3596 * If any extended attribute blocks' reference counts need to 3597 * be adjusted, either up (ctx->refcount_extra), or down 3598 * (ctx->refcount), then fix them. 3599 */ 3600 if (ctx->refcount) { 3601 adjust_extattr_refcount(ctx, ctx->refcount, block_buf, -1); 3602 ea_refcount_free(ctx->refcount); 3603 ctx->refcount = 0; 3604 } 3605 if (ctx->refcount_extra) { 3606 adjust_extattr_refcount(ctx, ctx->refcount_extra, 3607 block_buf, +1); 3608 ea_refcount_free(ctx->refcount_extra); 3609 ctx->refcount_extra = 0; 3610 } 3611 3612 if (ctx->invalid_bitmaps) 3613 handle_fs_bad_blocks(ctx); 3614 3615 /* We don't need the block_ea_map any more */ 3616 ext2fs_free_block_bitmap(ctx->block_ea_map); 3617 ctx->block_ea_map = 0; 3618 3619 if (ctx->flags & E2F_FLAG_RESIZE_INODE) { 3620 ext2fs_block_bitmap save_bmap; 3621 3622 save_bmap = fs->block_map; 3623 fs->block_map = ctx->block_found_map; 3624 clear_problem_context(&pctx); 3625 pctx.errcode = ext2fs_create_resize_inode(fs); 3626 if (pctx.errcode) { 3627 fix_problem(ctx, PR_1_RESIZE_INODE_CREATE, &pctx); 3628 /* Should never get here */ 3629 ctx->flags |= E2F_FLAG_ABORT; 3630 return; 3631 } 3632 e2fsck_read_inode(ctx, EXT2_RESIZE_INO, inode, 3633 "recreate inode"); 3634 inode->i_mtime = time(0); 3635 e2fsck_write_inode(ctx, EXT2_RESIZE_INO, inode, 3636 "recreate inode"); 3637 fs->block_map = save_bmap; 3638 ctx->flags &= ~E2F_FLAG_RESIZE_INODE; 3639 } 3640 3641 if (ctx->flags & E2F_FLAG_RESTART) { 3642 /* 3643 * Only the master copy of the superblock and block 3644 * group descriptors are going to be written during a 3645 * restart, so set the superblock to be used to be the 3646 * master superblock. 3647 */ 3648 ctx->use_superblock = 0; 3649 unwind_pass1(); 3650 goto endit; 3651 } 3652 3653 if (ctx->block_dup_map) { 3654 if (ctx->options & E2F_OPT_PREEN) { 3655 clear_problem_context(&pctx); 3656 fix_problem(ctx, PR_1_DUP_BLOCKS_PREENSTOP, &pctx); 3657 } 3658 e2fsck_pass1_dupblocks(ctx, block_buf); 3659 } 3660 ext2fs_free_mem(&inodes_to_process); 3661endit: 3662 e2fsck_use_inode_shortcuts(ctx, 0); 3663 3664 ext2fs_free_mem(&block_buf); 3665 ext2fs_free_mem(&inode); 3666 3667} 3668 3669/* 3670 * When the inode_scan routines call this callback at the end of the 3671 * glock group, call process_inodes. 3672 */ 3673static errcode_t scan_callback(ext2_filsys fs, 3674 dgrp_t group, void * priv_data) 3675{ 3676 struct scan_callback_struct *scan_struct; 3677 e2fsck_t ctx; 3678 3679 scan_struct = (struct scan_callback_struct *) priv_data; 3680 ctx = scan_struct->ctx; 3681 3682 process_inodes((e2fsck_t) fs->priv_data, scan_struct->block_buf); 3683 3684 if (ctx->progress) 3685 if ((ctx->progress)(ctx, 1, group+1, 3686 ctx->fs->group_desc_count)) 3687 return EXT2_ET_CANCEL_REQUESTED; 3688 3689 return 0; 3690} 3691 3692/* 3693 * Process the inodes in the "inodes to process" list. 3694 */ 3695static void process_inodes(e2fsck_t ctx, char *block_buf) 3696{ 3697 int i; 3698 struct ext2_inode *old_stashed_inode; 3699 ext2_ino_t old_stashed_ino; 3700 const char *old_operation; 3701 char buf[80]; 3702 struct problem_context pctx; 3703 3704 /* begin process_inodes */ 3705 if (process_inode_count == 0) 3706 return; 3707 old_operation = ehandler_operation(0); 3708 old_stashed_inode = ctx->stashed_inode; 3709 old_stashed_ino = ctx->stashed_ino; 3710 qsort(inodes_to_process, process_inode_count, 3711 sizeof(struct process_inode_block), process_inode_cmp); 3712 clear_problem_context(&pctx); 3713 for (i=0; i < process_inode_count; i++) { 3714 pctx.inode = ctx->stashed_inode = &inodes_to_process[i].inode; 3715 pctx.ino = ctx->stashed_ino = inodes_to_process[i].ino; 3716 sprintf(buf, _("reading indirect blocks of inode %u"), 3717 pctx.ino); 3718 ehandler_operation(buf); 3719 check_blocks(ctx, &pctx, block_buf); 3720 if (ctx->flags & E2F_FLAG_SIGNAL_MASK) 3721 break; 3722 } 3723 ctx->stashed_inode = old_stashed_inode; 3724 ctx->stashed_ino = old_stashed_ino; 3725 process_inode_count = 0; 3726 /* end process inodes */ 3727 3728 ehandler_operation(old_operation); 3729} 3730 3731static int process_inode_cmp(const void *a, const void *b) 3732{ 3733 const struct process_inode_block *ib_a = 3734 (const struct process_inode_block *) a; 3735 const struct process_inode_block *ib_b = 3736 (const struct process_inode_block *) b; 3737 int ret; 3738 3739 ret = (ib_a->inode.i_block[EXT2_IND_BLOCK] - 3740 ib_b->inode.i_block[EXT2_IND_BLOCK]); 3741 if (ret == 0) 3742 ret = ib_a->inode.i_file_acl - ib_b->inode.i_file_acl; 3743 return ret; 3744} 3745 3746/* 3747 * Mark an inode as being bad in some what 3748 */ 3749static void mark_inode_bad(e2fsck_t ctx, ino_t ino) 3750{ 3751 struct problem_context pctx; 3752 3753 if (!ctx->inode_bad_map) { 3754 clear_problem_context(&pctx); 3755 3756 pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs, 3757 _("bad inode map"), &ctx->inode_bad_map); 3758 if (pctx.errcode) { 3759 pctx.num = 3; 3760 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx); 3761 /* Should never get here */ 3762 ctx->flags |= E2F_FLAG_ABORT; 3763 return; 3764 } 3765 } 3766 ext2fs_mark_inode_bitmap(ctx->inode_bad_map, ino); 3767} 3768 3769 3770/* 3771 * This procedure will allocate the inode imagic table 3772 */ 3773static void alloc_imagic_map(e2fsck_t ctx) 3774{ 3775 struct problem_context pctx; 3776 3777 clear_problem_context(&pctx); 3778 pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs, 3779 _("imagic inode map"), 3780 &ctx->inode_imagic_map); 3781 if (pctx.errcode) { 3782 pctx.num = 5; 3783 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx); 3784 /* Should never get here */ 3785 ctx->flags |= E2F_FLAG_ABORT; 3786 return; 3787 } 3788} 3789 3790/* 3791 * Marks a block as in use, setting the dup_map if it's been set 3792 * already. Called by process_block and process_bad_block. 3793 * 3794 * WARNING: Assumes checks have already been done to make sure block 3795 * is valid. This is true in both process_block and process_bad_block. 3796 */ 3797static void mark_block_used(e2fsck_t ctx, blk_t block) 3798{ 3799 struct problem_context pctx; 3800 3801 clear_problem_context(&pctx); 3802 3803 if (ext2fs_fast_test_block_bitmap(ctx->block_found_map, block)) { 3804 if (!ctx->block_dup_map) { 3805 pctx.errcode = ext2fs_allocate_block_bitmap(ctx->fs, 3806 _("multiply claimed block map"), 3807 &ctx->block_dup_map); 3808 if (pctx.errcode) { 3809 pctx.num = 3; 3810 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, 3811 &pctx); 3812 /* Should never get here */ 3813 ctx->flags |= E2F_FLAG_ABORT; 3814 return; 3815 } 3816 } 3817 ext2fs_fast_mark_block_bitmap(ctx->block_dup_map, block); 3818 } else { 3819 ext2fs_fast_mark_block_bitmap(ctx->block_found_map, block); 3820 } 3821} 3822 3823/* 3824 * Adjust the extended attribute block's reference counts at the end 3825 * of pass 1, either by subtracting out references for EA blocks that 3826 * are still referenced in ctx->refcount, or by adding references for 3827 * EA blocks that had extra references as accounted for in 3828 * ctx->refcount_extra. 3829 */ 3830static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount, 3831 char *block_buf, int adjust_sign) 3832{ 3833 struct ext2_ext_attr_header *header; 3834 struct problem_context pctx; 3835 ext2_filsys fs = ctx->fs; 3836 blk_t blk; 3837 __u32 should_be; 3838 int count; 3839 3840 clear_problem_context(&pctx); 3841 3842 ea_refcount_intr_begin(refcount); 3843 while (1) { 3844 if ((blk = ea_refcount_intr_next(refcount, &count)) == 0) 3845 break; 3846 pctx.blk = blk; 3847 pctx.errcode = ext2fs_read_ext_attr(fs, blk, block_buf); 3848 if (pctx.errcode) { 3849 fix_problem(ctx, PR_1_EXTATTR_READ_ABORT, &pctx); 3850 return; 3851 } 3852 header = (struct ext2_ext_attr_header *) block_buf; 3853 pctx.blkcount = header->h_refcount; 3854 should_be = header->h_refcount + adjust_sign * count; 3855 pctx.num = should_be; 3856 if (fix_problem(ctx, PR_1_EXTATTR_REFCOUNT, &pctx)) { 3857 header->h_refcount = should_be; 3858 pctx.errcode = ext2fs_write_ext_attr(fs, blk, 3859 block_buf); 3860 if (pctx.errcode) { 3861 fix_problem(ctx, PR_1_EXTATTR_WRITE, &pctx); 3862 continue; 3863 } 3864 } 3865 } 3866} 3867 3868/* 3869 * Handle processing the extended attribute blocks 3870 */ 3871static int check_ext_attr(e2fsck_t ctx, struct problem_context *pctx, 3872 char *block_buf) 3873{ 3874 ext2_filsys fs = ctx->fs; 3875 ext2_ino_t ino = pctx->ino; 3876 struct ext2_inode *inode = pctx->inode; 3877 blk_t blk; 3878 char * end; 3879 struct ext2_ext_attr_header *header; 3880 struct ext2_ext_attr_entry *entry; 3881 int count; 3882 region_t region; 3883 3884 blk = inode->i_file_acl; 3885 if (blk == 0) 3886 return 0; 3887 3888 /* 3889 * If the Extended attribute flag isn't set, then a non-zero 3890 * file acl means that the inode is corrupted. 3891 * 3892 * Or if the extended attribute block is an invalid block, 3893 * then the inode is also corrupted. 3894 */ 3895 if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) || 3896 (blk < fs->super->s_first_data_block) || 3897 (blk >= fs->super->s_blocks_count)) { 3898 mark_inode_bad(ctx, ino); 3899 return 0; 3900 } 3901 3902 /* If ea bitmap hasn't been allocated, create it */ 3903 if (!ctx->block_ea_map) { 3904 pctx->errcode = ext2fs_allocate_block_bitmap(fs, 3905 _("ext attr block map"), 3906 &ctx->block_ea_map); 3907 if (pctx->errcode) { 3908 pctx->num = 2; 3909 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, pctx); 3910 ctx->flags |= E2F_FLAG_ABORT; 3911 return 0; 3912 } 3913 } 3914 3915 /* Create the EA refcount structure if necessary */ 3916 if (!ctx->refcount) { 3917 pctx->errcode = ea_refcount_create(0, &ctx->refcount); 3918 if (pctx->errcode) { 3919 pctx->num = 1; 3920 fix_problem(ctx, PR_1_ALLOCATE_REFCOUNT, pctx); 3921 ctx->flags |= E2F_FLAG_ABORT; 3922 return 0; 3923 } 3924 } 3925 3926 /* Have we seen this EA block before? */ 3927 if (ext2fs_fast_test_block_bitmap(ctx->block_ea_map, blk)) { 3928 if (ea_refcount_decrement(ctx->refcount, blk, 0) == 0) 3929 return 1; 3930 /* Ooops, this EA was referenced more than it stated */ 3931 if (!ctx->refcount_extra) { 3932 pctx->errcode = ea_refcount_create(0, 3933 &ctx->refcount_extra); 3934 if (pctx->errcode) { 3935 pctx->num = 2; 3936 fix_problem(ctx, PR_1_ALLOCATE_REFCOUNT, pctx); 3937 ctx->flags |= E2F_FLAG_ABORT; 3938 return 0; 3939 } 3940 } 3941 ea_refcount_increment(ctx->refcount_extra, blk, 0); 3942 return 1; 3943 } 3944 3945 /* 3946 * OK, we haven't seen this EA block yet. So we need to 3947 * validate it 3948 */ 3949 pctx->blk = blk; 3950 pctx->errcode = ext2fs_read_ext_attr(fs, blk, block_buf); 3951 if (pctx->errcode && fix_problem(ctx, PR_1_READ_EA_BLOCK, pctx)) 3952 goto clear_extattr; 3953 header = (struct ext2_ext_attr_header *) block_buf; 3954 pctx->blk = inode->i_file_acl; 3955 if (((ctx->ext_attr_ver == 1) && 3956 (header->h_magic != EXT2_EXT_ATTR_MAGIC_v1)) || 3957 ((ctx->ext_attr_ver == 2) && 3958 (header->h_magic != EXT2_EXT_ATTR_MAGIC))) { 3959 if (fix_problem(ctx, PR_1_BAD_EA_BLOCK, pctx)) 3960 goto clear_extattr; 3961 } 3962 3963 if (header->h_blocks != 1) { 3964 if (fix_problem(ctx, PR_1_EA_MULTI_BLOCK, pctx)) 3965 goto clear_extattr; 3966 } 3967 3968 region = region_create(0, fs->blocksize); 3969 if (!region) { 3970 fix_problem(ctx, PR_1_EA_ALLOC_REGION, pctx); 3971 ctx->flags |= E2F_FLAG_ABORT; 3972 return 0; 3973 } 3974 if (region_allocate(region, 0, sizeof(struct ext2_ext_attr_header))) { 3975 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx)) 3976 goto clear_extattr; 3977 } 3978 3979 entry = (struct ext2_ext_attr_entry *)(header+1); 3980 end = block_buf + fs->blocksize; 3981 while ((char *)entry < end && *(__u32 *)entry) { 3982 if (region_allocate(region, (char *)entry - (char *)header, 3983 EXT2_EXT_ATTR_LEN(entry->e_name_len))) { 3984 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx)) 3985 goto clear_extattr; 3986 } 3987 if ((ctx->ext_attr_ver == 1 && 3988 (entry->e_name_len == 0 || entry->e_name_index != 0)) || 3989 (ctx->ext_attr_ver == 2 && 3990 entry->e_name_index == 0)) { 3991 if (fix_problem(ctx, PR_1_EA_BAD_NAME, pctx)) 3992 goto clear_extattr; 3993 } 3994 if (entry->e_value_block != 0) { 3995 if (fix_problem(ctx, PR_1_EA_BAD_VALUE, pctx)) 3996 goto clear_extattr; 3997 } 3998 if (entry->e_value_size && 3999 region_allocate(region, entry->e_value_offs, 4000 EXT2_EXT_ATTR_SIZE(entry->e_value_size))) { 4001 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx)) 4002 goto clear_extattr; 4003 } 4004 entry = EXT2_EXT_ATTR_NEXT(entry); 4005 } 4006 if (region_allocate(region, (char *)entry - (char *)header, 4)) { 4007 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx)) 4008 goto clear_extattr; 4009 } 4010 region_free(region); 4011 4012 count = header->h_refcount - 1; 4013 if (count) 4014 ea_refcount_store(ctx->refcount, blk, count); 4015 mark_block_used(ctx, blk); 4016 ext2fs_fast_mark_block_bitmap(ctx->block_ea_map, blk); 4017 4018 return 1; 4019 4020clear_extattr: 4021 inode->i_file_acl = 0; 4022 e2fsck_write_inode(ctx, ino, inode, "check_ext_attr"); 4023 return 0; 4024} 4025 4026/* Returns 1 if bad htree, 0 if OK */ 4027static int handle_htree(e2fsck_t ctx, struct problem_context *pctx, 4028 ext2_ino_t ino FSCK_ATTR((unused)), 4029 struct ext2_inode *inode, 4030 char *block_buf) 4031{ 4032 struct ext2_dx_root_info *root; 4033 ext2_filsys fs = ctx->fs; 4034 errcode_t retval; 4035 blk_t blk; 4036 4037 if ((!LINUX_S_ISDIR(inode->i_mode) && 4038 fix_problem(ctx, PR_1_HTREE_NODIR, pctx)) || 4039 (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) && 4040 fix_problem(ctx, PR_1_HTREE_SET, pctx))) 4041 return 1; 4042 4043 blk = inode->i_block[0]; 4044 if (((blk == 0) || 4045 (blk < fs->super->s_first_data_block) || 4046 (blk >= fs->super->s_blocks_count)) && 4047 fix_problem(ctx, PR_1_HTREE_BADROOT, pctx)) 4048 return 1; 4049 4050 retval = io_channel_read_blk(fs->io, blk, 1, block_buf); 4051 if (retval && fix_problem(ctx, PR_1_HTREE_BADROOT, pctx)) 4052 return 1; 4053 4054 root = (struct ext2_dx_root_info *) (block_buf + 24); 4055 4056 if ((root->reserved_zero || root->info_length < 8) && 4057 fix_problem(ctx, PR_1_HTREE_BADROOT, pctx)) 4058 return 1; 4059 4060 pctx->num = root->hash_version; 4061 if ((root->hash_version != EXT2_HASH_LEGACY) && 4062 (root->hash_version != EXT2_HASH_HALF_MD4) && 4063 (root->hash_version != EXT2_HASH_TEA) && 4064 fix_problem(ctx, PR_1_HTREE_HASHV, pctx)) 4065 return 1; 4066 4067 if ((root->unused_flags & EXT2_HASH_FLAG_INCOMPAT) && 4068 fix_problem(ctx, PR_1_HTREE_INCOMPAT, pctx)) 4069 return 1; 4070 4071 pctx->num = root->indirect_levels; 4072 if ((root->indirect_levels > 1) && 4073 fix_problem(ctx, PR_1_HTREE_DEPTH, pctx)) 4074 return 1; 4075 4076 return 0; 4077} 4078 4079/* 4080 * This subroutine is called on each inode to account for all of the 4081 * blocks used by that inode. 4082 */ 4083static void check_blocks(e2fsck_t ctx, struct problem_context *pctx, 4084 char *block_buf) 4085{ 4086 ext2_filsys fs = ctx->fs; 4087 struct process_block_struct_1 pb; 4088 ext2_ino_t ino = pctx->ino; 4089 struct ext2_inode *inode = pctx->inode; 4090 int bad_size = 0; 4091 int dirty_inode = 0; 4092 __u64 size; 4093 4094 pb.ino = ino; 4095 pb.num_blocks = 0; 4096 pb.last_block = -1; 4097 pb.num_illegal_blocks = 0; 4098 pb.suppress = 0; pb.clear = 0; 4099 pb.fragmented = 0; 4100 pb.compressed = 0; 4101 pb.previous_block = 0; 4102 pb.is_dir = LINUX_S_ISDIR(inode->i_mode); 4103 pb.is_reg = LINUX_S_ISREG(inode->i_mode); 4104 pb.max_blocks = 1 << (31 - fs->super->s_log_block_size); 4105 pb.inode = inode; 4106 pb.pctx = pctx; 4107 pb.ctx = ctx; 4108 pctx->ino = ino; 4109 pctx->errcode = 0; 4110 4111 if (inode->i_flags & EXT2_COMPRBLK_FL) { 4112 if (fs->super->s_feature_incompat & 4113 EXT2_FEATURE_INCOMPAT_COMPRESSION) 4114 pb.compressed = 1; 4115 else { 4116 if (fix_problem(ctx, PR_1_COMPR_SET, pctx)) { 4117 inode->i_flags &= ~EXT2_COMPRBLK_FL; 4118 dirty_inode++; 4119 } 4120 } 4121 } 4122 4123 if (inode->i_file_acl && check_ext_attr(ctx, pctx, block_buf)) 4124 pb.num_blocks++; 4125 4126 if (ext2fs_inode_has_valid_blocks(inode)) 4127 pctx->errcode = ext2fs_block_iterate2(fs, ino, 4128 pb.is_dir ? BLOCK_FLAG_HOLE : 0, 4129 block_buf, process_block, &pb); 4130 end_problem_latch(ctx, PR_LATCH_BLOCK); 4131 end_problem_latch(ctx, PR_LATCH_TOOBIG); 4132 if (ctx->flags & E2F_FLAG_SIGNAL_MASK) 4133 goto out; 4134 if (pctx->errcode) 4135 fix_problem(ctx, PR_1_BLOCK_ITERATE, pctx); 4136 4137 if (pb.fragmented && pb.num_blocks < fs->super->s_blocks_per_group) 4138 ctx->fs_fragmented++; 4139 4140 if (pb.clear) { 4141 inode->i_links_count = 0; 4142 ext2fs_icount_store(ctx->inode_link_info, ino, 0); 4143 inode->i_dtime = time(0); 4144 dirty_inode++; 4145 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino); 4146 ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino); 4147 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino); 4148 /* 4149 * The inode was probably partially accounted for 4150 * before processing was aborted, so we need to 4151 * restart the pass 1 scan. 4152 */ 4153 ctx->flags |= E2F_FLAG_RESTART; 4154 goto out; 4155 } 4156 4157 if (inode->i_flags & EXT2_INDEX_FL) { 4158 if (handle_htree(ctx, pctx, ino, inode, block_buf)) { 4159 inode->i_flags &= ~EXT2_INDEX_FL; 4160 dirty_inode++; 4161 } else { 4162#ifdef ENABLE_HTREE 4163 e2fsck_add_dx_dir(ctx, ino, pb.last_block+1); 4164#endif 4165 } 4166 } 4167 if (ctx->dirs_to_hash && pb.is_dir && 4168 !(inode->i_flags & EXT2_INDEX_FL) && 4169 ((inode->i_size / fs->blocksize) >= 3)) 4170 ext2fs_u32_list_add(ctx->dirs_to_hash, ino); 4171 4172 if (!pb.num_blocks && pb.is_dir) { 4173 if (fix_problem(ctx, PR_1_ZERO_LENGTH_DIR, pctx)) { 4174 inode->i_links_count = 0; 4175 ext2fs_icount_store(ctx->inode_link_info, ino, 0); 4176 inode->i_dtime = time(0); 4177 dirty_inode++; 4178 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino); 4179 ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino); 4180 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino); 4181 ctx->fs_directory_count--; 4182 goto out; 4183 } 4184 } 4185 4186 pb.num_blocks *= (fs->blocksize / 512); 4187 4188 if (pb.is_dir) { 4189 int nblock = inode->i_size >> EXT2_BLOCK_SIZE_BITS(fs->super); 4190 if (nblock > (pb.last_block + 1)) 4191 bad_size = 1; 4192 else if (nblock < (pb.last_block + 1)) { 4193 if (((pb.last_block + 1) - nblock) > 4194 fs->super->s_prealloc_dir_blocks) 4195 bad_size = 2; 4196 } 4197 } else { 4198 size = EXT2_I_SIZE(inode); 4199 if ((pb.last_block >= 0) && 4200 (size < (__u64) pb.last_block * fs->blocksize)) 4201 bad_size = 3; 4202 else if (size > ext2_max_sizes[fs->super->s_log_block_size]) 4203 bad_size = 4; 4204 } 4205 /* i_size for symlinks is checked elsewhere */ 4206 if (bad_size && !LINUX_S_ISLNK(inode->i_mode)) { 4207 pctx->num = (pb.last_block+1) * fs->blocksize; 4208 if (fix_problem(ctx, PR_1_BAD_I_SIZE, pctx)) { 4209 inode->i_size = pctx->num; 4210 if (!LINUX_S_ISDIR(inode->i_mode)) 4211 inode->i_size_high = pctx->num >> 32; 4212 dirty_inode++; 4213 } 4214 pctx->num = 0; 4215 } 4216 if (LINUX_S_ISREG(inode->i_mode) && 4217 (inode->i_size_high || inode->i_size & 0x80000000UL)) 4218 ctx->large_files++; 4219 if (pb.num_blocks != inode->i_blocks) { 4220 pctx->num = pb.num_blocks; 4221 if (fix_problem(ctx, PR_1_BAD_I_BLOCKS, pctx)) { 4222 inode->i_blocks = pb.num_blocks; 4223 dirty_inode++; 4224 } 4225 pctx->num = 0; 4226 } 4227out: 4228 if (dirty_inode) 4229 e2fsck_write_inode(ctx, ino, inode, "check_blocks"); 4230} 4231 4232 4233/* 4234 * This is a helper function for check_blocks(). 4235 */ 4236static int process_block(ext2_filsys fs, 4237 blk_t *block_nr, 4238 e2_blkcnt_t blockcnt, 4239 blk_t ref_block FSCK_ATTR((unused)), 4240 int ref_offset FSCK_ATTR((unused)), 4241 void *priv_data) 4242{ 4243 struct process_block_struct_1 *p; 4244 struct problem_context *pctx; 4245 blk_t blk = *block_nr; 4246 int ret_code = 0; 4247 int problem = 0; 4248 e2fsck_t ctx; 4249 4250 p = (struct process_block_struct_1 *) priv_data; 4251 pctx = p->pctx; 4252 ctx = p->ctx; 4253 4254 if (p->compressed && (blk == EXT2FS_COMPRESSED_BLKADDR)) { 4255 /* todo: Check that the comprblk_fl is high, that the 4256 blkaddr pattern looks right (all non-holes up to 4257 first EXT2FS_COMPRESSED_BLKADDR, then all 4258 EXT2FS_COMPRESSED_BLKADDR up to end of cluster), 4259 that the feature_incompat bit is high, and that the 4260 inode is a regular file. If we're doing a "full 4261 check" (a concept introduced to e2fsck by e2compr, 4262 meaning that we look at data blocks as well as 4263 metadata) then call some library routine that 4264 checks the compressed data. I'll have to think 4265 about this, because one particularly important 4266 problem to be able to fix is to recalculate the 4267 cluster size if necessary. I think that perhaps 4268 we'd better do most/all e2compr-specific checks 4269 separately, after the non-e2compr checks. If not 4270 doing a full check, it may be useful to test that 4271 the personality is linux; e.g. if it isn't then 4272 perhaps this really is just an illegal block. */ 4273 return 0; 4274 } 4275 4276 if (blk == 0) { 4277 if (p->is_dir == 0) { 4278 /* 4279 * Should never happen, since only directories 4280 * get called with BLOCK_FLAG_HOLE 4281 */ 4282#ifdef DEBUG_E2FSCK 4283 printf("process_block() called with blk == 0, " 4284 "blockcnt=%d, inode %lu???\n", 4285 blockcnt, p->ino); 4286#endif 4287 return 0; 4288 } 4289 if (blockcnt < 0) 4290 return 0; 4291 if (blockcnt * fs->blocksize < p->inode->i_size) { 4292 goto mark_dir; 4293 } 4294 return 0; 4295 } 4296 4297 /* 4298 * Simplistic fragmentation check. We merely require that the 4299 * file be contiguous. (Which can never be true for really 4300 * big files that are greater than a block group.) 4301 */ 4302 if (!HOLE_BLKADDR(p->previous_block)) { 4303 if (p->previous_block+1 != blk) 4304 p->fragmented = 1; 4305 } 4306 p->previous_block = blk; 4307 4308 if (p->is_dir && blockcnt > (1 << (21 - fs->super->s_log_block_size))) 4309 problem = PR_1_TOOBIG_DIR; 4310 if (p->is_reg && p->num_blocks+1 >= p->max_blocks) 4311 problem = PR_1_TOOBIG_REG; 4312 if (!p->is_dir && !p->is_reg && blockcnt > 0) 4313 problem = PR_1_TOOBIG_SYMLINK; 4314 4315 if (blk < fs->super->s_first_data_block || 4316 blk >= fs->super->s_blocks_count) 4317 problem = PR_1_ILLEGAL_BLOCK_NUM; 4318 4319 if (problem) { 4320 p->num_illegal_blocks++; 4321 if (!p->suppress && (p->num_illegal_blocks % 12) == 0) { 4322 if (fix_problem(ctx, PR_1_TOO_MANY_BAD_BLOCKS, pctx)) { 4323 p->clear = 1; 4324 return BLOCK_ABORT; 4325 } 4326 if (fix_problem(ctx, PR_1_SUPPRESS_MESSAGES, pctx)) { 4327 p->suppress = 1; 4328 set_latch_flags(PR_LATCH_BLOCK, 4329 PRL_SUPPRESS, 0); 4330 } 4331 } 4332 pctx->blk = blk; 4333 pctx->blkcount = blockcnt; 4334 if (fix_problem(ctx, problem, pctx)) { 4335 blk = *block_nr = 0; 4336 ret_code = BLOCK_CHANGED; 4337 goto mark_dir; 4338 } else 4339 return 0; 4340 } 4341 4342 if (p->ino == EXT2_RESIZE_INO) { 4343 /* 4344 * The resize inode has already be sanity checked 4345 * during pass #0 (the superblock checks). All we 4346 * have to do is mark the double indirect block as 4347 * being in use; all of the other blocks are handled 4348 * by mark_table_blocks()). 4349 */ 4350 if (blockcnt == BLOCK_COUNT_DIND) 4351 mark_block_used(ctx, blk); 4352 } else 4353 mark_block_used(ctx, blk); 4354 p->num_blocks++; 4355 if (blockcnt >= 0) 4356 p->last_block = blockcnt; 4357mark_dir: 4358 if (p->is_dir && (blockcnt >= 0)) { 4359 pctx->errcode = ext2fs_add_dir_block(fs->dblist, p->ino, 4360 blk, blockcnt); 4361 if (pctx->errcode) { 4362 pctx->blk = blk; 4363 pctx->num = blockcnt; 4364 fix_problem(ctx, PR_1_ADD_DBLOCK, pctx); 4365 /* Should never get here */ 4366 ctx->flags |= E2F_FLAG_ABORT; 4367 return BLOCK_ABORT; 4368 } 4369 } 4370 return ret_code; 4371} 4372 4373static int process_bad_block(ext2_filsys fs FSCK_ATTR((unused)), 4374 blk_t *block_nr, 4375 e2_blkcnt_t blockcnt, 4376 blk_t ref_block FSCK_ATTR((unused)), 4377 int ref_offset FSCK_ATTR((unused)), 4378 void *priv_data EXT2FS_ATTR((unused))) 4379{ 4380 /* 4381 * Note: This function processes blocks for the bad blocks 4382 * inode, which is never compressed. So we don't use HOLE_BLKADDR(). 4383 */ 4384 4385 printf("Unrecoverable Error: Found %"PRIi64" bad blocks starting at block number: %u\n", blockcnt, *block_nr); 4386 return BLOCK_ERROR; 4387} 4388 4389/* 4390 * This routine gets called at the end of pass 1 if bad blocks are 4391 * detected in the superblock, group descriptors, inode_bitmaps, or 4392 * block bitmaps. At this point, all of the blocks have been mapped 4393 * out, so we can try to allocate new block(s) to replace the bad 4394 * blocks. 4395 */ 4396static void handle_fs_bad_blocks(e2fsck_t ctx) 4397{ 4398 printf("Bad blocks detected on your filesystem\n" 4399 "You should get your data off as the device will soon die\n"); 4400} 4401 4402/* 4403 * This routine marks all blocks which are used by the superblock, 4404 * group descriptors, inode bitmaps, and block bitmaps. 4405 */ 4406static void mark_table_blocks(e2fsck_t ctx) 4407{ 4408 ext2_filsys fs = ctx->fs; 4409 blk_t block, b; 4410 dgrp_t i; 4411 int j; 4412 struct problem_context pctx; 4413 4414 clear_problem_context(&pctx); 4415 4416 block = fs->super->s_first_data_block; 4417 for (i = 0; i < fs->group_desc_count; i++) { 4418 pctx.group = i; 4419 4420 ext2fs_reserve_super_and_bgd(fs, i, ctx->block_found_map); 4421 4422 /* 4423 * Mark the blocks used for the inode table 4424 */ 4425 if (fs->group_desc[i].bg_inode_table) { 4426 for (j = 0, b = fs->group_desc[i].bg_inode_table; 4427 j < fs->inode_blocks_per_group; 4428 j++, b++) { 4429 if (ext2fs_test_block_bitmap(ctx->block_found_map, 4430 b)) { 4431 pctx.blk = b; 4432 if (fix_problem(ctx, 4433 PR_1_ITABLE_CONFLICT, &pctx)) { 4434 ctx->invalid_inode_table_flag[i]++; 4435 ctx->invalid_bitmaps++; 4436 } 4437 } else { 4438 ext2fs_mark_block_bitmap(ctx->block_found_map, 4439 b); 4440 } 4441 } 4442 } 4443 4444 /* 4445 * Mark block used for the block bitmap 4446 */ 4447 if (fs->group_desc[i].bg_block_bitmap) { 4448 if (ext2fs_test_block_bitmap(ctx->block_found_map, 4449 fs->group_desc[i].bg_block_bitmap)) { 4450 pctx.blk = fs->group_desc[i].bg_block_bitmap; 4451 if (fix_problem(ctx, PR_1_BB_CONFLICT, &pctx)) { 4452 ctx->invalid_block_bitmap_flag[i]++; 4453 ctx->invalid_bitmaps++; 4454 } 4455 } else { 4456 ext2fs_mark_block_bitmap(ctx->block_found_map, 4457 fs->group_desc[i].bg_block_bitmap); 4458 } 4459 4460 } 4461 /* 4462 * Mark block used for the inode bitmap 4463 */ 4464 if (fs->group_desc[i].bg_inode_bitmap) { 4465 if (ext2fs_test_block_bitmap(ctx->block_found_map, 4466 fs->group_desc[i].bg_inode_bitmap)) { 4467 pctx.blk = fs->group_desc[i].bg_inode_bitmap; 4468 if (fix_problem(ctx, PR_1_IB_CONFLICT, &pctx)) { 4469 ctx->invalid_inode_bitmap_flag[i]++; 4470 ctx->invalid_bitmaps++; 4471 } 4472 } else { 4473 ext2fs_mark_block_bitmap(ctx->block_found_map, 4474 fs->group_desc[i].bg_inode_bitmap); 4475 } 4476 } 4477 block += fs->super->s_blocks_per_group; 4478 } 4479} 4480 4481/* 4482 * Thes subroutines short circuits ext2fs_get_blocks and 4483 * ext2fs_check_directory; we use them since we already have the inode 4484 * structure, so there's no point in letting the ext2fs library read 4485 * the inode again. 4486 */ 4487static errcode_t pass1_get_blocks(ext2_filsys fs, ext2_ino_t ino, 4488 blk_t *blocks) 4489{ 4490 e2fsck_t ctx = (e2fsck_t) fs->priv_data; 4491 int i; 4492 4493 if ((ino != ctx->stashed_ino) || !ctx->stashed_inode) 4494 return EXT2_ET_CALLBACK_NOTHANDLED; 4495 4496 for (i=0; i < EXT2_N_BLOCKS; i++) 4497 blocks[i] = ctx->stashed_inode->i_block[i]; 4498 return 0; 4499} 4500 4501static errcode_t pass1_read_inode(ext2_filsys fs, ext2_ino_t ino, 4502 struct ext2_inode *inode) 4503{ 4504 e2fsck_t ctx = (e2fsck_t) fs->priv_data; 4505 4506 if ((ino != ctx->stashed_ino) || !ctx->stashed_inode) 4507 return EXT2_ET_CALLBACK_NOTHANDLED; 4508 *inode = *ctx->stashed_inode; 4509 return 0; 4510} 4511 4512static errcode_t pass1_write_inode(ext2_filsys fs, ext2_ino_t ino, 4513 struct ext2_inode *inode) 4514{ 4515 e2fsck_t ctx = (e2fsck_t) fs->priv_data; 4516 4517 if ((ino == ctx->stashed_ino) && ctx->stashed_inode) 4518 *ctx->stashed_inode = *inode; 4519 return EXT2_ET_CALLBACK_NOTHANDLED; 4520} 4521 4522static errcode_t pass1_check_directory(ext2_filsys fs, ext2_ino_t ino) 4523{ 4524 e2fsck_t ctx = (e2fsck_t) fs->priv_data; 4525 4526 if ((ino != ctx->stashed_ino) || !ctx->stashed_inode) 4527 return EXT2_ET_CALLBACK_NOTHANDLED; 4528 4529 if (!LINUX_S_ISDIR(ctx->stashed_inode->i_mode)) 4530 return EXT2_ET_NO_DIRECTORY; 4531 return 0; 4532} 4533 4534void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int bool) 4535{ 4536 ext2_filsys fs = ctx->fs; 4537 4538 if (bool) { 4539 fs->get_blocks = pass1_get_blocks; 4540 fs->check_directory = pass1_check_directory; 4541 fs->read_inode = pass1_read_inode; 4542 fs->write_inode = pass1_write_inode; 4543 ctx->stashed_ino = 0; 4544 } else { 4545 fs->get_blocks = 0; 4546 fs->check_directory = 0; 4547 fs->read_inode = 0; 4548 fs->write_inode = 0; 4549 } 4550} 4551 4552/* 4553 * pass1b.c --- Pass #1b of e2fsck 4554 * 4555 * This file contains pass1B, pass1C, and pass1D of e2fsck. They are 4556 * only invoked if pass 1 discovered blocks which are in use by more 4557 * than one inode. 4558 * 4559 * Pass1B scans the data blocks of all the inodes again, generating a 4560 * complete list of duplicate blocks and which inodes have claimed 4561 * them. 4562 * 4563 * Pass1C does a tree-traversal of the filesystem, to determine the 4564 * parent directories of these inodes. This step is necessary so that 4565 * e2fsck can print out the pathnames of affected inodes. 4566 * 4567 * Pass1D is a reconciliation pass. For each inode with duplicate 4568 * blocks, the user is prompted if s/he would like to clone the file 4569 * (so that the file gets a fresh copy of the duplicated blocks) or 4570 * simply to delete the file. 4571 * 4572 */ 4573 4574 4575/* Needed for architectures where sizeof(int) != sizeof(void *) */ 4576#define INT_TO_VOIDPTR(val) ((void *)(intptr_t)(val)) 4577#define VOIDPTR_TO_INT(ptr) ((int)(intptr_t)(ptr)) 4578 4579/* Define an extension to the ext2 library's block count information */ 4580#define BLOCK_COUNT_EXTATTR (-5) 4581 4582struct block_el { 4583 blk_t block; 4584 struct block_el *next; 4585}; 4586 4587struct inode_el { 4588 ext2_ino_t inode; 4589 struct inode_el *next; 4590}; 4591 4592struct dup_block { 4593 int num_bad; 4594 struct inode_el *inode_list; 4595}; 4596 4597/* 4598 * This structure stores information about a particular inode which 4599 * is sharing blocks with other inodes. This information is collected 4600 * to display to the user, so that the user knows what files he or she 4601 * is dealing with, when trying to decide how to resolve the conflict 4602 * of multiply-claimed blocks. 4603 */ 4604struct dup_inode { 4605 ext2_ino_t dir; 4606 int num_dupblocks; 4607 struct ext2_inode inode; 4608 struct block_el *block_list; 4609}; 4610 4611static int process_pass1b_block(ext2_filsys fs, blk_t *blocknr, 4612 e2_blkcnt_t blockcnt, blk_t ref_blk, 4613 int ref_offset, void *priv_data); 4614static void delete_file(e2fsck_t ctx, ext2_ino_t ino, 4615 struct dup_inode *dp, char *block_buf); 4616static int clone_file(e2fsck_t ctx, ext2_ino_t ino, 4617 struct dup_inode *dp, char* block_buf); 4618static int check_if_fs_block(e2fsck_t ctx, blk_t test_blk); 4619 4620static void pass1b(e2fsck_t ctx, char *block_buf); 4621static void pass1c(e2fsck_t ctx, char *block_buf); 4622static void pass1d(e2fsck_t ctx, char *block_buf); 4623 4624static int dup_inode_count = 0; 4625 4626static dict_t blk_dict, ino_dict; 4627 4628static ext2fs_inode_bitmap inode_dup_map; 4629 4630static int dict_int_cmp(const void *a, const void *b) 4631{ 4632 intptr_t ia, ib; 4633 4634 ia = (intptr_t)a; 4635 ib = (intptr_t)b; 4636 4637 return (ia-ib); 4638} 4639 4640/* 4641 * Add a duplicate block record 4642 */ 4643static void add_dupe(e2fsck_t ctx, ext2_ino_t ino, blk_t blk, 4644 struct ext2_inode *inode) 4645{ 4646 dnode_t *n; 4647 struct dup_block *db; 4648 struct dup_inode *di; 4649 struct block_el *blk_el; 4650 struct inode_el *ino_el; 4651 4652 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(blk)); 4653 if (n) 4654 db = (struct dup_block *) dnode_get(n); 4655 else { 4656 db = (struct dup_block *) e2fsck_allocate_memory(ctx, 4657 sizeof(struct dup_block), "duplicate block header"); 4658 db->num_bad = 0; 4659 db->inode_list = 0; 4660 dict_alloc_insert(&blk_dict, INT_TO_VOIDPTR(blk), db); 4661 } 4662 ino_el = (struct inode_el *) e2fsck_allocate_memory(ctx, 4663 sizeof(struct inode_el), "inode element"); 4664 ino_el->inode = ino; 4665 ino_el->next = db->inode_list; 4666 db->inode_list = ino_el; 4667 db->num_bad++; 4668 4669 n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(ino)); 4670 if (n) 4671 di = (struct dup_inode *) dnode_get(n); 4672 else { 4673 di = (struct dup_inode *) e2fsck_allocate_memory(ctx, 4674 sizeof(struct dup_inode), "duplicate inode header"); 4675 di->dir = (ino == EXT2_ROOT_INO) ? EXT2_ROOT_INO : 0; 4676 di->num_dupblocks = 0; 4677 di->block_list = 0; 4678 di->inode = *inode; 4679 dict_alloc_insert(&ino_dict, INT_TO_VOIDPTR(ino), di); 4680 } 4681 blk_el = (struct block_el *) e2fsck_allocate_memory(ctx, 4682 sizeof(struct block_el), "block element"); 4683 blk_el->block = blk; 4684 blk_el->next = di->block_list; 4685 di->block_list = blk_el; 4686 di->num_dupblocks++; 4687} 4688 4689/* 4690 * Free a duplicate inode record 4691 */ 4692static void inode_dnode_free(dnode_t *node) 4693{ 4694 struct dup_inode *di; 4695 struct block_el *p, *next; 4696 4697 di = (struct dup_inode *) dnode_get(node); 4698 for (p = di->block_list; p; p = next) { 4699 next = p->next; 4700 free(p); 4701 } 4702 free(node); 4703} 4704 4705/* 4706 * Free a duplicate block record 4707 */ 4708static void block_dnode_free(dnode_t *node) 4709{ 4710 struct dup_block *db; 4711 struct inode_el *p, *next; 4712 4713 db = (struct dup_block *) dnode_get(node); 4714 for (p = db->inode_list; p; p = next) { 4715 next = p->next; 4716 free(p); 4717 } 4718 free(node); 4719} 4720 4721 4722/* 4723 * Main procedure for handling duplicate blocks 4724 */ 4725void e2fsck_pass1_dupblocks(e2fsck_t ctx, char *block_buf) 4726{ 4727 ext2_filsys fs = ctx->fs; 4728 struct problem_context pctx; 4729 4730 clear_problem_context(&pctx); 4731 4732 pctx.errcode = ext2fs_allocate_inode_bitmap(fs, 4733 _("multiply claimed inode map"), &inode_dup_map); 4734 if (pctx.errcode) { 4735 fix_problem(ctx, PR_1B_ALLOCATE_IBITMAP_ERROR, &pctx); 4736 ctx->flags |= E2F_FLAG_ABORT; 4737 return; 4738 } 4739 4740 dict_init(&ino_dict, DICTCOUNT_T_MAX, dict_int_cmp); 4741 dict_init(&blk_dict, DICTCOUNT_T_MAX, dict_int_cmp); 4742 dict_set_allocator(&ino_dict, inode_dnode_free); 4743 dict_set_allocator(&blk_dict, block_dnode_free); 4744 4745 pass1b(ctx, block_buf); 4746 pass1c(ctx, block_buf); 4747 pass1d(ctx, block_buf); 4748 4749 /* 4750 * Time to free all of the accumulated data structures that we 4751 * don't need anymore. 4752 */ 4753 dict_free_nodes(&ino_dict); 4754 dict_free_nodes(&blk_dict); 4755} 4756 4757/* 4758 * Scan the inodes looking for inodes that contain duplicate blocks. 4759 */ 4760struct process_block_struct_1b { 4761 e2fsck_t ctx; 4762 ext2_ino_t ino; 4763 int dup_blocks; 4764 struct ext2_inode *inode; 4765 struct problem_context *pctx; 4766}; 4767 4768static void pass1b(e2fsck_t ctx, char *block_buf) 4769{ 4770 ext2_filsys fs = ctx->fs; 4771 ext2_ino_t ino; 4772 struct ext2_inode inode; 4773 ext2_inode_scan scan; 4774 struct process_block_struct_1b pb; 4775 struct problem_context pctx; 4776 4777 clear_problem_context(&pctx); 4778 4779 if (!(ctx->options & E2F_OPT_PREEN)) 4780 fix_problem(ctx, PR_1B_PASS_HEADER, &pctx); 4781 pctx.errcode = ext2fs_open_inode_scan(fs, ctx->inode_buffer_blocks, 4782 &scan); 4783 if (pctx.errcode) { 4784 fix_problem(ctx, PR_1B_ISCAN_ERROR, &pctx); 4785 ctx->flags |= E2F_FLAG_ABORT; 4786 return; 4787 } 4788 ctx->stashed_inode = &inode; 4789 pb.ctx = ctx; 4790 pb.pctx = &pctx; 4791 pctx.str = "pass1b"; 4792 while (1) { 4793 pctx.errcode = ext2fs_get_next_inode(scan, &ino, &inode); 4794 if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE) 4795 continue; 4796 if (pctx.errcode) { 4797 fix_problem(ctx, PR_1B_ISCAN_ERROR, &pctx); 4798 ctx->flags |= E2F_FLAG_ABORT; 4799 return; 4800 } 4801 if (!ino) 4802 break; 4803 pctx.ino = ctx->stashed_ino = ino; 4804 if ((ino != EXT2_BAD_INO) && 4805 !ext2fs_test_inode_bitmap(ctx->inode_used_map, ino)) 4806 continue; 4807 4808 pb.ino = ino; 4809 pb.dup_blocks = 0; 4810 pb.inode = &inode; 4811 4812 if (ext2fs_inode_has_valid_blocks(&inode) || 4813 (ino == EXT2_BAD_INO)) 4814 pctx.errcode = ext2fs_block_iterate2(fs, ino, 4815 0, block_buf, process_pass1b_block, &pb); 4816 if (inode.i_file_acl) 4817 process_pass1b_block(fs, &inode.i_file_acl, 4818 BLOCK_COUNT_EXTATTR, 0, 0, &pb); 4819 if (pb.dup_blocks) { 4820 end_problem_latch(ctx, PR_LATCH_DBLOCK); 4821 if (ino >= EXT2_FIRST_INODE(fs->super) || 4822 ino == EXT2_ROOT_INO) 4823 dup_inode_count++; 4824 } 4825 if (pctx.errcode) 4826 fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx); 4827 } 4828 ext2fs_close_inode_scan(scan); 4829 e2fsck_use_inode_shortcuts(ctx, 0); 4830} 4831 4832static int process_pass1b_block(ext2_filsys fs FSCK_ATTR((unused)), 4833 blk_t *block_nr, 4834 e2_blkcnt_t blockcnt FSCK_ATTR((unused)), 4835 blk_t ref_blk FSCK_ATTR((unused)), 4836 int ref_offset FSCK_ATTR((unused)), 4837 void *priv_data) 4838{ 4839 struct process_block_struct_1b *p; 4840 e2fsck_t ctx; 4841 4842 if (HOLE_BLKADDR(*block_nr)) 4843 return 0; 4844 p = (struct process_block_struct_1b *) priv_data; 4845 ctx = p->ctx; 4846 4847 if (!ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr)) 4848 return 0; 4849 4850 /* OK, this is a duplicate block */ 4851 if (p->ino != EXT2_BAD_INO) { 4852 p->pctx->blk = *block_nr; 4853 fix_problem(ctx, PR_1B_DUP_BLOCK, p->pctx); 4854 } 4855 p->dup_blocks++; 4856 ext2fs_mark_inode_bitmap(inode_dup_map, p->ino); 4857 4858 add_dupe(ctx, p->ino, *block_nr, p->inode); 4859 4860 return 0; 4861} 4862 4863/* 4864 * Pass 1c: Scan directories for inodes with duplicate blocks. This 4865 * is used so that we can print pathnames when prompting the user for 4866 * what to do. 4867 */ 4868struct search_dir_struct { 4869 int count; 4870 ext2_ino_t first_inode; 4871 ext2_ino_t max_inode; 4872}; 4873 4874static int search_dirent_proc(ext2_ino_t dir, int entry, 4875 struct ext2_dir_entry *dirent, 4876 int offset FSCK_ATTR((unused)), 4877 int blocksize FSCK_ATTR((unused)), 4878 char *buf FSCK_ATTR((unused)), 4879 void *priv_data) 4880{ 4881 struct search_dir_struct *sd; 4882 struct dup_inode *p; 4883 dnode_t *n; 4884 4885 sd = (struct search_dir_struct *) priv_data; 4886 4887 if (dirent->inode > sd->max_inode) 4888 /* Should abort this inode, but not everything */ 4889 return 0; 4890 4891 if ((dirent->inode < sd->first_inode) || (entry < DIRENT_OTHER_FILE) || 4892 !ext2fs_test_inode_bitmap(inode_dup_map, dirent->inode)) 4893 return 0; 4894 4895 n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(dirent->inode)); 4896 if (!n) 4897 return 0; 4898 p = (struct dup_inode *) dnode_get(n); 4899 p->dir = dir; 4900 sd->count--; 4901 4902 return sd->count ? 0 : DIRENT_ABORT; 4903} 4904 4905 4906static void pass1c(e2fsck_t ctx, char *block_buf) 4907{ 4908 ext2_filsys fs = ctx->fs; 4909 struct search_dir_struct sd; 4910 struct problem_context pctx; 4911 4912 clear_problem_context(&pctx); 4913 4914 if (!(ctx->options & E2F_OPT_PREEN)) 4915 fix_problem(ctx, PR_1C_PASS_HEADER, &pctx); 4916 4917 /* 4918 * Search through all directories to translate inodes to names 4919 * (by searching for the containing directory for that inode.) 4920 */ 4921 sd.count = dup_inode_count; 4922 sd.first_inode = EXT2_FIRST_INODE(fs->super); 4923 sd.max_inode = fs->super->s_inodes_count; 4924 ext2fs_dblist_dir_iterate(fs->dblist, 0, block_buf, 4925 search_dirent_proc, &sd); 4926} 4927 4928static void pass1d(e2fsck_t ctx, char *block_buf) 4929{ 4930 ext2_filsys fs = ctx->fs; 4931 struct dup_inode *p, *t; 4932 struct dup_block *q; 4933 ext2_ino_t *shared, ino; 4934 int shared_len; 4935 int i; 4936 int file_ok; 4937 int meta_data = 0; 4938 struct problem_context pctx; 4939 dnode_t *n, *m; 4940 struct block_el *s; 4941 struct inode_el *r; 4942 4943 clear_problem_context(&pctx); 4944 4945 if (!(ctx->options & E2F_OPT_PREEN)) 4946 fix_problem(ctx, PR_1D_PASS_HEADER, &pctx); 4947 e2fsck_read_bitmaps(ctx); 4948 4949 pctx.num = dup_inode_count; /* dict_count(&ino_dict); */ 4950 fix_problem(ctx, PR_1D_NUM_DUP_INODES, &pctx); 4951 shared = (ext2_ino_t *) e2fsck_allocate_memory(ctx, 4952 sizeof(ext2_ino_t) * dict_count(&ino_dict), 4953 "Shared inode list"); 4954 for (n = dict_first(&ino_dict); n; n = dict_next(&ino_dict, n)) { 4955 p = (struct dup_inode *) dnode_get(n); 4956 shared_len = 0; 4957 file_ok = 1; 4958 ino = (ext2_ino_t)VOIDPTR_TO_INT(dnode_getkey(n)); 4959 if (ino == EXT2_BAD_INO || ino == EXT2_RESIZE_INO) 4960 continue; 4961 4962 /* 4963 * Find all of the inodes which share blocks with this 4964 * one. First we find all of the duplicate blocks 4965 * belonging to this inode, and then search each block 4966 * get the list of inodes, and merge them together. 4967 */ 4968 for (s = p->block_list; s; s = s->next) { 4969 m = dict_lookup(&blk_dict, INT_TO_VOIDPTR(s->block)); 4970 if (!m) 4971 continue; /* Should never happen... */ 4972 q = (struct dup_block *) dnode_get(m); 4973 if (q->num_bad > 1) 4974 file_ok = 0; 4975 if (check_if_fs_block(ctx, s->block)) { 4976 file_ok = 0; 4977 meta_data = 1; 4978 } 4979 4980 /* 4981 * Add all inodes used by this block to the 4982 * shared[] --- which is a unique list, so 4983 * if an inode is already in shared[], don't 4984 * add it again. 4985 */ 4986 for (r = q->inode_list; r; r = r->next) { 4987 if (r->inode == ino) 4988 continue; 4989 for (i = 0; i < shared_len; i++) 4990 if (shared[i] == r->inode) 4991 break; 4992 if (i == shared_len) { 4993 shared[shared_len++] = r->inode; 4994 } 4995 } 4996 } 4997 4998 /* 4999 * Report the inode that we are working on 5000 */ 5001 pctx.inode = &p->inode; 5002 pctx.ino = ino; 5003 pctx.dir = p->dir; 5004 pctx.blkcount = p->num_dupblocks; 5005 pctx.num = meta_data ? shared_len+1 : shared_len; 5006 fix_problem(ctx, PR_1D_DUP_FILE, &pctx); 5007 pctx.blkcount = 0; 5008 pctx.num = 0; 5009 5010 if (meta_data) 5011 fix_problem(ctx, PR_1D_SHARE_METADATA, &pctx); 5012 5013 for (i = 0; i < shared_len; i++) { 5014 m = dict_lookup(&ino_dict, INT_TO_VOIDPTR(shared[i])); 5015 if (!m) 5016 continue; /* should never happen */ 5017 t = (struct dup_inode *) dnode_get(m); 5018 /* 5019 * Report the inode that we are sharing with 5020 */ 5021 pctx.inode = &t->inode; 5022 pctx.ino = shared[i]; 5023 pctx.dir = t->dir; 5024 fix_problem(ctx, PR_1D_DUP_FILE_LIST, &pctx); 5025 } 5026 if (file_ok) { 5027 fix_problem(ctx, PR_1D_DUP_BLOCKS_DEALT, &pctx); 5028 continue; 5029 } 5030 if (fix_problem(ctx, PR_1D_CLONE_QUESTION, &pctx)) { 5031 pctx.errcode = clone_file(ctx, ino, p, block_buf); 5032 if (pctx.errcode) 5033 fix_problem(ctx, PR_1D_CLONE_ERROR, &pctx); 5034 else 5035 continue; 5036 } 5037 if (fix_problem(ctx, PR_1D_DELETE_QUESTION, &pctx)) 5038 delete_file(ctx, ino, p, block_buf); 5039 else 5040 ext2fs_unmark_valid(fs); 5041 } 5042 ext2fs_free_mem(&shared); 5043} 5044 5045/* 5046 * Drop the refcount on the dup_block structure, and clear the entry 5047 * in the block_dup_map if appropriate. 5048 */ 5049static void decrement_badcount(e2fsck_t ctx, blk_t block, struct dup_block *p) 5050{ 5051 p->num_bad--; 5052 if (p->num_bad <= 0 || 5053 (p->num_bad == 1 && !check_if_fs_block(ctx, block))) 5054 ext2fs_unmark_block_bitmap(ctx->block_dup_map, block); 5055} 5056 5057static int delete_file_block(ext2_filsys fs, 5058 blk_t *block_nr, 5059 e2_blkcnt_t blockcnt FSCK_ATTR((unused)), 5060 blk_t ref_block FSCK_ATTR((unused)), 5061 int ref_offset FSCK_ATTR((unused)), 5062 void *priv_data) 5063{ 5064 struct process_block_struct_1b *pb; 5065 struct dup_block *p; 5066 dnode_t *n; 5067 e2fsck_t ctx; 5068 5069 pb = (struct process_block_struct_1b *) priv_data; 5070 ctx = pb->ctx; 5071 5072 if (HOLE_BLKADDR(*block_nr)) 5073 return 0; 5074 5075 if (ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr)) { 5076 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(*block_nr)); 5077 if (n) { 5078 p = (struct dup_block *) dnode_get(n); 5079 decrement_badcount(ctx, *block_nr, p); 5080 } else 5081 bb_error_msg(_("internal error; can't find dup_blk for %d"), 5082 *block_nr); 5083 } else { 5084 ext2fs_unmark_block_bitmap(ctx->block_found_map, *block_nr); 5085 ext2fs_block_alloc_stats(fs, *block_nr, -1); 5086 } 5087 5088 return 0; 5089} 5090 5091static void delete_file(e2fsck_t ctx, ext2_ino_t ino, 5092 struct dup_inode *dp, char* block_buf) 5093{ 5094 ext2_filsys fs = ctx->fs; 5095 struct process_block_struct_1b pb; 5096 struct ext2_inode inode; 5097 struct problem_context pctx; 5098 unsigned int count; 5099 5100 clear_problem_context(&pctx); 5101 pctx.ino = pb.ino = ino; 5102 pb.dup_blocks = dp->num_dupblocks; 5103 pb.ctx = ctx; 5104 pctx.str = "delete_file"; 5105 5106 e2fsck_read_inode(ctx, ino, &inode, "delete_file"); 5107 if (ext2fs_inode_has_valid_blocks(&inode)) 5108 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf, 5109 delete_file_block, &pb); 5110 if (pctx.errcode) 5111 fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx); 5112 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino); 5113 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino); 5114 if (ctx->inode_bad_map) 5115 ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino); 5116 ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(inode.i_mode)); 5117 5118 /* Inode may have changed by block_iterate, so reread it */ 5119 e2fsck_read_inode(ctx, ino, &inode, "delete_file"); 5120 inode.i_links_count = 0; 5121 inode.i_dtime = time(0); 5122 if (inode.i_file_acl && 5123 (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR)) { 5124 count = 1; 5125 pctx.errcode = ext2fs_adjust_ea_refcount(fs, inode.i_file_acl, 5126 block_buf, -1, &count); 5127 if (pctx.errcode == EXT2_ET_BAD_EA_BLOCK_NUM) { 5128 pctx.errcode = 0; 5129 count = 1; 5130 } 5131 if (pctx.errcode) { 5132 pctx.blk = inode.i_file_acl; 5133 fix_problem(ctx, PR_1B_ADJ_EA_REFCOUNT, &pctx); 5134 } 5135 /* 5136 * If the count is zero, then arrange to have the 5137 * block deleted. If the block is in the block_dup_map, 5138 * also call delete_file_block since it will take care 5139 * of keeping the accounting straight. 5140 */ 5141 if ((count == 0) || 5142 ext2fs_test_block_bitmap(ctx->block_dup_map, 5143 inode.i_file_acl)) 5144 delete_file_block(fs, &inode.i_file_acl, 5145 BLOCK_COUNT_EXTATTR, 0, 0, &pb); 5146 } 5147 e2fsck_write_inode(ctx, ino, &inode, "delete_file"); 5148} 5149 5150struct clone_struct { 5151 errcode_t errcode; 5152 ext2_ino_t dir; 5153 char *buf; 5154 e2fsck_t ctx; 5155}; 5156 5157static int clone_file_block(ext2_filsys fs, 5158 blk_t *block_nr, 5159 e2_blkcnt_t blockcnt, 5160 blk_t ref_block FSCK_ATTR((unused)), 5161 int ref_offset FSCK_ATTR((unused)), 5162 void *priv_data) 5163{ 5164 struct dup_block *p; 5165 blk_t new_block; 5166 errcode_t retval; 5167 struct clone_struct *cs = (struct clone_struct *) priv_data; 5168 dnode_t *n; 5169 e2fsck_t ctx; 5170 5171 ctx = cs->ctx; 5172 5173 if (HOLE_BLKADDR(*block_nr)) 5174 return 0; 5175 5176 if (ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr)) { 5177 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(*block_nr)); 5178 if (n) { 5179 p = (struct dup_block *) dnode_get(n); 5180 retval = ext2fs_new_block(fs, 0, ctx->block_found_map, 5181 &new_block); 5182 if (retval) { 5183 cs->errcode = retval; 5184 return BLOCK_ABORT; 5185 } 5186 if (cs->dir && (blockcnt >= 0)) { 5187 retval = ext2fs_set_dir_block(fs->dblist, 5188 cs->dir, new_block, blockcnt); 5189 if (retval) { 5190 cs->errcode = retval; 5191 return BLOCK_ABORT; 5192 } 5193 } 5194 5195 retval = io_channel_read_blk(fs->io, *block_nr, 1, 5196 cs->buf); 5197 if (retval) { 5198 cs->errcode = retval; 5199 return BLOCK_ABORT; 5200 } 5201 retval = io_channel_write_blk(fs->io, new_block, 1, 5202 cs->buf); 5203 if (retval) { 5204 cs->errcode = retval; 5205 return BLOCK_ABORT; 5206 } 5207 decrement_badcount(ctx, *block_nr, p); 5208 *block_nr = new_block; 5209 ext2fs_mark_block_bitmap(ctx->block_found_map, 5210 new_block); 5211 ext2fs_mark_block_bitmap(fs->block_map, new_block); 5212 return BLOCK_CHANGED; 5213 } else 5214 bb_error_msg(_("internal error; can't find dup_blk for %d"), 5215 *block_nr); 5216 } 5217 return 0; 5218} 5219 5220static int clone_file(e2fsck_t ctx, ext2_ino_t ino, 5221 struct dup_inode *dp, char* block_buf) 5222{ 5223 ext2_filsys fs = ctx->fs; 5224 errcode_t retval; 5225 struct clone_struct cs; 5226 struct problem_context pctx; 5227 blk_t blk; 5228 dnode_t *n; 5229 struct inode_el *ino_el; 5230 struct dup_block *db; 5231 struct dup_inode *di; 5232 5233 clear_problem_context(&pctx); 5234 cs.errcode = 0; 5235 cs.dir = 0; 5236 cs.ctx = ctx; 5237 retval = ext2fs_get_mem(fs->blocksize, &cs.buf); 5238 if (retval) 5239 return retval; 5240 5241 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, ino)) 5242 cs.dir = ino; 5243 5244 pctx.ino = ino; 5245 pctx.str = "clone_file"; 5246 if (ext2fs_inode_has_valid_blocks(&dp->inode)) 5247 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf, 5248 clone_file_block, &cs); 5249 ext2fs_mark_bb_dirty(fs); 5250 if (pctx.errcode) { 5251 fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx); 5252 retval = pctx.errcode; 5253 goto errout; 5254 } 5255 if (cs.errcode) { 5256 bb_error_msg(_("returned from clone_file_block")); 5257 retval = cs.errcode; 5258 goto errout; 5259 } 5260 /* The inode may have changed on disk, so we have to re-read it */ 5261 e2fsck_read_inode(ctx, ino, &dp->inode, "clone file EA"); 5262 blk = dp->inode.i_file_acl; 5263 if (blk && (clone_file_block(fs, &dp->inode.i_file_acl, 5264 BLOCK_COUNT_EXTATTR, 0, 0, &cs) == 5265 BLOCK_CHANGED)) { 5266 e2fsck_write_inode(ctx, ino, &dp->inode, "clone file EA"); 5267 /* 5268 * If we cloned the EA block, find all other inodes 5269 * which refered to that EA block, and modify 5270 * them to point to the new EA block. 5271 */ 5272 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(blk)); 5273 db = (struct dup_block *) dnode_get(n); 5274 for (ino_el = db->inode_list; ino_el; ino_el = ino_el->next) { 5275 if (ino_el->inode == ino) 5276 continue; 5277 n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(ino_el->inode)); 5278 di = (struct dup_inode *) dnode_get(n); 5279 if (di->inode.i_file_acl == blk) { 5280 di->inode.i_file_acl = dp->inode.i_file_acl; 5281 e2fsck_write_inode(ctx, ino_el->inode, 5282 &di->inode, "clone file EA"); 5283 decrement_badcount(ctx, blk, db); 5284 } 5285 } 5286 } 5287 retval = 0; 5288errout: 5289 ext2fs_free_mem(&cs.buf); 5290 return retval; 5291} 5292 5293/* 5294 * This routine returns 1 if a block overlaps with one of the superblocks, 5295 * group descriptors, inode bitmaps, or block bitmaps. 5296 */ 5297static int check_if_fs_block(e2fsck_t ctx, blk_t test_block) 5298{ 5299 ext2_filsys fs = ctx->fs; 5300 blk_t block; 5301 dgrp_t i; 5302 5303 block = fs->super->s_first_data_block; 5304 for (i = 0; i < fs->group_desc_count; i++) { 5305 5306 /* Check superblocks/block group descriptros */ 5307 if (ext2fs_bg_has_super(fs, i)) { 5308 if (test_block >= block && 5309 (test_block <= block + fs->desc_blocks)) 5310 return 1; 5311 } 5312 5313 /* Check the inode table */ 5314 if ((fs->group_desc[i].bg_inode_table) && 5315 (test_block >= fs->group_desc[i].bg_inode_table) && 5316 (test_block < (fs->group_desc[i].bg_inode_table + 5317 fs->inode_blocks_per_group))) 5318 return 1; 5319 5320 /* Check the bitmap blocks */ 5321 if ((test_block == fs->group_desc[i].bg_block_bitmap) || 5322 (test_block == fs->group_desc[i].bg_inode_bitmap)) 5323 return 1; 5324 5325 block += fs->super->s_blocks_per_group; 5326 } 5327 return 0; 5328} 5329/* 5330 * pass2.c --- check directory structure 5331 * 5332 * Pass 2 of e2fsck iterates through all active directory inodes, and 5333 * applies to following tests to each directory entry in the directory 5334 * blocks in the inodes: 5335 * 5336 * - The length of the directory entry (rec_len) should be at 5337 * least 8 bytes, and no more than the remaining space 5338 * left in the directory block. 5339 * - The length of the name in the directory entry (name_len) 5340 * should be less than (rec_len - 8). 5341 * - The inode number in the directory entry should be within 5342 * legal bounds. 5343 * - The inode number should refer to a in-use inode. 5344 * - The first entry should be '.', and its inode should be 5345 * the inode of the directory. 5346 * - The second entry should be '..'. 5347 * 5348 * To minimize disk seek time, the directory blocks are processed in 5349 * sorted order of block numbers. 5350 * 5351 * Pass 2 also collects the following information: 5352 * - The inode numbers of the subdirectories for each directory. 5353 * 5354 * Pass 2 relies on the following information from previous passes: 5355 * - The directory information collected in pass 1. 5356 * - The inode_used_map bitmap 5357 * - The inode_bad_map bitmap 5358 * - The inode_dir_map bitmap 5359 * 5360 * Pass 2 frees the following data structures 5361 * - The inode_bad_map bitmap 5362 * - The inode_reg_map bitmap 5363 */ 5364 5365/* 5366 * Keeps track of how many times an inode is referenced. 5367 */ 5368static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf); 5369static int check_dir_block(ext2_filsys fs, 5370 struct ext2_db_entry *dir_blocks_info, 5371 void *priv_data); 5372static int allocate_dir_block(e2fsck_t ctx, struct ext2_db_entry *dir_blocks_info, 5373 struct problem_context *pctx); 5374static int update_dir_block(ext2_filsys fs, 5375 blk_t *block_nr, 5376 e2_blkcnt_t blockcnt, 5377 blk_t ref_block, 5378 int ref_offset, 5379 void *priv_data); 5380static void clear_htree(e2fsck_t ctx, ext2_ino_t ino); 5381static int htree_depth(struct dx_dir_info *dx_dir, 5382 struct dx_dirblock_info *dx_db); 5383static int special_dir_block_cmp(const void *a, const void *b); 5384 5385struct check_dir_struct { 5386 char *buf; 5387 struct problem_context pctx; 5388 int count, max; 5389 e2fsck_t ctx; 5390}; 5391 5392static void e2fsck_pass2(e2fsck_t ctx) 5393{ 5394 struct ext2_super_block *sb = ctx->fs->super; 5395 struct problem_context pctx; 5396 ext2_filsys fs = ctx->fs; 5397 char *buf; 5398 struct dir_info *dir; 5399 struct check_dir_struct cd; 5400 struct dx_dir_info *dx_dir; 5401 struct dx_dirblock_info *dx_db, *dx_parent; 5402 int b; 5403 int i, depth; 5404 problem_t code; 5405 int bad_dir; 5406 5407 clear_problem_context(&cd.pctx); 5408 5409 /* Pass 2 */ 5410 5411 if (!(ctx->options & E2F_OPT_PREEN)) 5412 fix_problem(ctx, PR_2_PASS_HEADER, &cd.pctx); 5413 5414 cd.pctx.errcode = ext2fs_create_icount2(fs, EXT2_ICOUNT_OPT_INCREMENT, 5415 0, ctx->inode_link_info, 5416 &ctx->inode_count); 5417 if (cd.pctx.errcode) { 5418 fix_problem(ctx, PR_2_ALLOCATE_ICOUNT, &cd.pctx); 5419 ctx->flags |= E2F_FLAG_ABORT; 5420 return; 5421 } 5422 buf = (char *) e2fsck_allocate_memory(ctx, 2*fs->blocksize, 5423 "directory scan buffer"); 5424 5425 /* 5426 * Set up the parent pointer for the root directory, if 5427 * present. (If the root directory is not present, we will 5428 * create it in pass 3.) 5429 */ 5430 dir = e2fsck_get_dir_info(ctx, EXT2_ROOT_INO); 5431 if (dir) 5432 dir->parent = EXT2_ROOT_INO; 5433 5434 cd.buf = buf; 5435 cd.ctx = ctx; 5436 cd.count = 1; 5437 cd.max = ext2fs_dblist_count(fs->dblist); 5438 5439 if (ctx->progress) 5440 (void) (ctx->progress)(ctx, 2, 0, cd.max); 5441 5442 if (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) 5443 ext2fs_dblist_sort(fs->dblist, special_dir_block_cmp); 5444 5445 cd.pctx.errcode = ext2fs_dblist_iterate(fs->dblist, check_dir_block, 5446 &cd); 5447 if (ctx->flags & E2F_FLAG_SIGNAL_MASK) 5448 return; 5449 if (cd.pctx.errcode) { 5450 fix_problem(ctx, PR_2_DBLIST_ITERATE, &cd.pctx); 5451 ctx->flags |= E2F_FLAG_ABORT; 5452 return; 5453 } 5454 5455#ifdef ENABLE_HTREE 5456 for (i=0; (dx_dir = e2fsck_dx_dir_info_iter(ctx, &i)) != 0;) { 5457 if (ctx->flags & E2F_FLAG_SIGNAL_MASK) 5458 return; 5459 if (dx_dir->numblocks == 0) 5460 continue; 5461 clear_problem_context(&pctx); 5462 bad_dir = 0; 5463 pctx.dir = dx_dir->ino; 5464 dx_db = dx_dir->dx_block; 5465 if (dx_db->flags & DX_FLAG_REFERENCED) 5466 dx_db->flags |= DX_FLAG_DUP_REF; 5467 else 5468 dx_db->flags |= DX_FLAG_REFERENCED; 5469 /* 5470 * Find all of the first and last leaf blocks, and 5471 * update their parent's min and max hash values 5472 */ 5473 for (b=0, dx_db = dx_dir->dx_block; 5474 b < dx_dir->numblocks; 5475 b++, dx_db++) { 5476 if ((dx_db->type != DX_DIRBLOCK_LEAF) || 5477 !(dx_db->flags & (DX_FLAG_FIRST | DX_FLAG_LAST))) 5478 continue; 5479 dx_parent = &dx_dir->dx_block[dx_db->parent]; 5480 if (dx_db->flags & DX_FLAG_FIRST) 5481 dx_parent->min_hash = dx_db->min_hash; 5482 if (dx_db->flags & DX_FLAG_LAST) 5483 dx_parent->max_hash = dx_db->max_hash; 5484 } 5485 5486 for (b=0, dx_db = dx_dir->dx_block; 5487 b < dx_dir->numblocks; 5488 b++, dx_db++) { 5489 pctx.blkcount = b; 5490 pctx.group = dx_db->parent; 5491 code = 0; 5492 if (!(dx_db->flags & DX_FLAG_FIRST) && 5493 (dx_db->min_hash < dx_db->node_min_hash)) { 5494 pctx.blk = dx_db->min_hash; 5495 pctx.blk2 = dx_db->node_min_hash; 5496 code = PR_2_HTREE_MIN_HASH; 5497 fix_problem(ctx, code, &pctx); 5498 bad_dir++; 5499 } 5500 if (dx_db->type == DX_DIRBLOCK_LEAF) { 5501 depth = htree_depth(dx_dir, dx_db); 5502 if (depth != dx_dir->depth) { 5503 code = PR_2_HTREE_BAD_DEPTH; 5504 fix_problem(ctx, code, &pctx); 5505 bad_dir++; 5506 } 5507 } 5508 /* 5509 * This test doesn't apply for the root block 5510 * at block #0 5511 */ 5512 if (b && 5513 (dx_db->max_hash > dx_db->node_max_hash)) { 5514 pctx.blk = dx_db->max_hash; 5515 pctx.blk2 = dx_db->node_max_hash; 5516 code = PR_2_HTREE_MAX_HASH; 5517 fix_problem(ctx, code, &pctx); 5518 bad_dir++; 5519 } 5520 if (!(dx_db->flags & DX_FLAG_REFERENCED)) { 5521 code = PR_2_HTREE_NOTREF; 5522 fix_problem(ctx, code, &pctx); 5523 bad_dir++; 5524 } else if (dx_db->flags & DX_FLAG_DUP_REF) { 5525 code = PR_2_HTREE_DUPREF; 5526 fix_problem(ctx, code, &pctx); 5527 bad_dir++; 5528 } 5529 if (code == 0) 5530 continue; 5531 } 5532 if (bad_dir && fix_problem(ctx, PR_2_HTREE_CLEAR, &pctx)) { 5533 clear_htree(ctx, dx_dir->ino); 5534 dx_dir->numblocks = 0; 5535 } 5536 } 5537#endif 5538 ext2fs_free_mem(&buf); 5539 ext2fs_free_dblist(fs->dblist); 5540 5541 ext2fs_free_inode_bitmap(ctx->inode_bad_map); 5542 ctx->inode_bad_map = 0; 5543 ext2fs_free_inode_bitmap(ctx->inode_reg_map); 5544 ctx->inode_reg_map = 0; 5545 5546 clear_problem_context(&pctx); 5547 if (ctx->large_files) { 5548 if (!(sb->s_feature_ro_compat & 5549 EXT2_FEATURE_RO_COMPAT_LARGE_FILE) && 5550 fix_problem(ctx, PR_2_FEATURE_LARGE_FILES, &pctx)) { 5551 sb->s_feature_ro_compat |= 5552 EXT2_FEATURE_RO_COMPAT_LARGE_FILE; 5553 ext2fs_mark_super_dirty(fs); 5554 } 5555 if (sb->s_rev_level == EXT2_GOOD_OLD_REV && 5556 fix_problem(ctx, PR_1_FS_REV_LEVEL, &pctx)) { 5557 ext2fs_update_dynamic_rev(fs); 5558 ext2fs_mark_super_dirty(fs); 5559 } 5560 } else if (!ctx->large_files && 5561 (sb->s_feature_ro_compat & 5562 EXT2_FEATURE_RO_COMPAT_LARGE_FILE)) { 5563 if (fs->flags & EXT2_FLAG_RW) { 5564 sb->s_feature_ro_compat &= 5565 ~EXT2_FEATURE_RO_COMPAT_LARGE_FILE; 5566 ext2fs_mark_super_dirty(fs); 5567 } 5568 } 5569 5570} 5571 5572#define MAX_DEPTH 32000 5573static int htree_depth(struct dx_dir_info *dx_dir, 5574 struct dx_dirblock_info *dx_db) 5575{ 5576 int depth = 0; 5577 5578 while (dx_db->type != DX_DIRBLOCK_ROOT && depth < MAX_DEPTH) { 5579 dx_db = &dx_dir->dx_block[dx_db->parent]; 5580 depth++; 5581 } 5582 return depth; 5583} 5584 5585static int dict_de_cmp(const void *a, const void *b) 5586{ 5587 const struct ext2_dir_entry *de_a, *de_b; 5588 int a_len, b_len; 5589 5590 de_a = (const struct ext2_dir_entry *) a; 5591 a_len = de_a->name_len & 0xFF; 5592 de_b = (const struct ext2_dir_entry *) b; 5593 b_len = de_b->name_len & 0xFF; 5594 5595 if (a_len != b_len) 5596 return (a_len - b_len); 5597 5598 return strncmp(de_a->name, de_b->name, a_len); 5599} 5600 5601/* 5602 * This is special sort function that makes sure that directory blocks 5603 * with a dirblock of zero are sorted to the beginning of the list. 5604 * This guarantees that the root node of the htree directories are 5605 * processed first, so we know what hash version to use. 5606 */ 5607static int special_dir_block_cmp(const void *a, const void *b) 5608{ 5609 const struct ext2_db_entry *db_a = 5610 (const struct ext2_db_entry *) a; 5611 const struct ext2_db_entry *db_b = 5612 (const struct ext2_db_entry *) b; 5613 5614 if (db_a->blockcnt && !db_b->blockcnt) 5615 return 1; 5616 5617 if (!db_a->blockcnt && db_b->blockcnt) 5618 return -1; 5619 5620 if (db_a->blk != db_b->blk) 5621 return (int) (db_a->blk - db_b->blk); 5622 5623 if (db_a->ino != db_b->ino) 5624 return (int) (db_a->ino - db_b->ino); 5625 5626 return (int) (db_a->blockcnt - db_b->blockcnt); 5627} 5628 5629 5630/* 5631 * Make sure the first entry in the directory is '.', and that the 5632 * directory entry is sane. 5633 */ 5634static int check_dot(e2fsck_t ctx, 5635 struct ext2_dir_entry *dirent, 5636 ext2_ino_t ino, struct problem_context *pctx) 5637{ 5638 struct ext2_dir_entry *nextdir; 5639 int status = 0; 5640 int created = 0; 5641 int new_len; 5642 int problem = 0; 5643 5644 if (!dirent->inode) 5645 problem = PR_2_MISSING_DOT; 5646 else if (((dirent->name_len & 0xFF) != 1) || 5647 (dirent->name[0] != '.')) 5648 problem = PR_2_1ST_NOT_DOT; 5649 else if (dirent->name[1] != '\0') 5650 problem = PR_2_DOT_NULL_TERM; 5651 5652 if (problem) { 5653 if (fix_problem(ctx, problem, pctx)) { 5654 if (dirent->rec_len < 12) 5655 dirent->rec_len = 12; 5656 dirent->inode = ino; 5657 dirent->name_len = 1; 5658 dirent->name[0] = '.'; 5659 dirent->name[1] = '\0'; 5660 status = 1; 5661 created = 1; 5662 } 5663 } 5664 if (dirent->inode != ino) { 5665 if (fix_problem(ctx, PR_2_BAD_INODE_DOT, pctx)) { 5666 dirent->inode = ino; 5667 status = 1; 5668 } 5669 } 5670 if (dirent->rec_len > 12) { 5671 new_len = dirent->rec_len - 12; 5672 if (new_len > 12) { 5673 if (created || 5674 fix_problem(ctx, PR_2_SPLIT_DOT, pctx)) { 5675 nextdir = (struct ext2_dir_entry *) 5676 ((char *) dirent + 12); 5677 dirent->rec_len = 12; 5678 nextdir->rec_len = new_len; 5679 nextdir->inode = 0; 5680 nextdir->name_len = 0; 5681 status = 1; 5682 } 5683 } 5684 } 5685 return status; 5686} 5687 5688/* 5689 * Make sure the second entry in the directory is '..', and that the 5690 * directory entry is sane. We do not check the inode number of '..' 5691 * here; this gets done in pass 3. 5692 */ 5693static int check_dotdot(e2fsck_t ctx, 5694 struct ext2_dir_entry *dirent, 5695 struct dir_info *dir, struct problem_context *pctx) 5696{ 5697 int problem = 0; 5698 5699 if (!dirent->inode) 5700 problem = PR_2_MISSING_DOT_DOT; 5701 else if (((dirent->name_len & 0xFF) != 2) || 5702 (dirent->name[0] != '.') || 5703 (dirent->name[1] != '.')) 5704 problem = PR_2_2ND_NOT_DOT_DOT; 5705 else if (dirent->name[2] != '\0') 5706 problem = PR_2_DOT_DOT_NULL_TERM; 5707 5708 if (problem) { 5709 if (fix_problem(ctx, problem, pctx)) { 5710 if (dirent->rec_len < 12) 5711 dirent->rec_len = 12; 5712 /* 5713 * Note: we don't have the parent inode just 5714 * yet, so we will fill it in with the root 5715 * inode. This will get fixed in pass 3. 5716 */ 5717 dirent->inode = EXT2_ROOT_INO; 5718 dirent->name_len = 2; 5719 dirent->name[0] = '.'; 5720 dirent->name[1] = '.'; 5721 dirent->name[2] = '\0'; 5722 return 1; 5723 } 5724 return 0; 5725 } 5726 dir->dotdot = dirent->inode; 5727 return 0; 5728} 5729 5730/* 5731 * Check to make sure a directory entry doesn't contain any illegal 5732 * characters. 5733 */ 5734static int check_name(e2fsck_t ctx, 5735 struct ext2_dir_entry *dirent, 5736 struct problem_context *pctx) 5737{ 5738 int i; 5739 int fixup = -1; 5740 int ret = 0; 5741 5742 for ( i = 0; i < (dirent->name_len & 0xFF); i++) { 5743 if (dirent->name[i] == '/' || dirent->name[i] == '\0') { 5744 if (fixup < 0) { 5745 fixup = fix_problem(ctx, PR_2_BAD_NAME, pctx); 5746 } 5747 if (fixup) { 5748 dirent->name[i] = '.'; 5749 ret = 1; 5750 } 5751 } 5752 } 5753 return ret; 5754} 5755 5756/* 5757 * Check the directory filetype (if present) 5758 */ 5759 5760/* 5761 * Given a mode, return the ext2 file type 5762 */ 5763static int ext2_file_type(unsigned int mode) 5764{ 5765 if (LINUX_S_ISREG(mode)) 5766 return EXT2_FT_REG_FILE; 5767 5768 if (LINUX_S_ISDIR(mode)) 5769 return EXT2_FT_DIR; 5770 5771 if (LINUX_S_ISCHR(mode)) 5772 return EXT2_FT_CHRDEV; 5773 5774 if (LINUX_S_ISBLK(mode)) 5775 return EXT2_FT_BLKDEV; 5776 5777 if (LINUX_S_ISLNK(mode)) 5778 return EXT2_FT_SYMLINK; 5779 5780 if (LINUX_S_ISFIFO(mode)) 5781 return EXT2_FT_FIFO; 5782 5783 if (LINUX_S_ISSOCK(mode)) 5784 return EXT2_FT_SOCK; 5785 5786 return 0; 5787} 5788 5789static int check_filetype(e2fsck_t ctx, 5790 struct ext2_dir_entry *dirent, 5791 struct problem_context *pctx) 5792{ 5793 int filetype = dirent->name_len >> 8; 5794 int should_be = EXT2_FT_UNKNOWN; 5795 struct ext2_inode inode; 5796 5797 if (!(ctx->fs->super->s_feature_incompat & 5798 EXT2_FEATURE_INCOMPAT_FILETYPE)) { 5799 if (filetype == 0 || 5800 !fix_problem(ctx, PR_2_CLEAR_FILETYPE, pctx)) 5801 return 0; 5802 dirent->name_len = dirent->name_len & 0xFF; 5803 return 1; 5804 } 5805 5806 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, dirent->inode)) { 5807 should_be = EXT2_FT_DIR; 5808 } else if (ext2fs_test_inode_bitmap(ctx->inode_reg_map, 5809 dirent->inode)) { 5810 should_be = EXT2_FT_REG_FILE; 5811 } else if (ctx->inode_bad_map && 5812 ext2fs_test_inode_bitmap(ctx->inode_bad_map, 5813 dirent->inode)) 5814 should_be = 0; 5815 else { 5816 e2fsck_read_inode(ctx, dirent->inode, &inode, 5817 "check_filetype"); 5818 should_be = ext2_file_type(inode.i_mode); 5819 } 5820 if (filetype == should_be) 5821 return 0; 5822 pctx->num = should_be; 5823 5824 if (fix_problem(ctx, filetype ? PR_2_BAD_FILETYPE : PR_2_SET_FILETYPE, 5825 pctx) == 0) 5826 return 0; 5827 5828 dirent->name_len = (dirent->name_len & 0xFF) | should_be << 8; 5829 return 1; 5830} 5831 5832#ifdef ENABLE_HTREE 5833static void parse_int_node(ext2_filsys fs, 5834 struct ext2_db_entry *db, 5835 struct check_dir_struct *cd, 5836 struct dx_dir_info *dx_dir, 5837 char *block_buf) 5838{ 5839 struct ext2_dx_root_info *root; 5840 struct ext2_dx_entry *ent; 5841 struct ext2_dx_countlimit *limit; 5842 struct dx_dirblock_info *dx_db; 5843 int i, expect_limit, count; 5844 blk_t blk; 5845 ext2_dirhash_t min_hash = 0xffffffff; 5846 ext2_dirhash_t max_hash = 0; 5847 ext2_dirhash_t hash = 0, prev_hash; 5848 5849 if (db->blockcnt == 0) { 5850 root = (struct ext2_dx_root_info *) (block_buf + 24); 5851 ent = (struct ext2_dx_entry *) (block_buf + 24 + root->info_length); 5852 } else { 5853 ent = (struct ext2_dx_entry *) (block_buf+8); 5854 } 5855 limit = (struct ext2_dx_countlimit *) ent; 5856 5857 count = ext2fs_le16_to_cpu(limit->count); 5858 expect_limit = (fs->blocksize - ((char *) ent - block_buf)) / 5859 sizeof(struct ext2_dx_entry); 5860 if (ext2fs_le16_to_cpu(limit->limit) != expect_limit) { 5861 cd->pctx.num = ext2fs_le16_to_cpu(limit->limit); 5862 if (fix_problem(cd->ctx, PR_2_HTREE_BAD_LIMIT, &cd->pctx)) 5863 goto clear_and_exit; 5864 } 5865 if (count > expect_limit) { 5866 cd->pctx.num = count; 5867 if (fix_problem(cd->ctx, PR_2_HTREE_BAD_COUNT, &cd->pctx)) 5868 goto clear_and_exit; 5869 count = expect_limit; 5870 } 5871 5872 for (i=0; i < count; i++) { 5873 prev_hash = hash; 5874 hash = i ? (ext2fs_le32_to_cpu(ent[i].hash) & ~1) : 0; 5875 blk = ext2fs_le32_to_cpu(ent[i].block) & 0x0ffffff; 5876 /* Check to make sure the block is valid */ 5877 if (blk > (blk_t) dx_dir->numblocks) { 5878 cd->pctx.blk = blk; 5879 if (fix_problem(cd->ctx, PR_2_HTREE_BADBLK, 5880 &cd->pctx)) 5881 goto clear_and_exit; 5882 } 5883 if (hash < prev_hash && 5884 fix_problem(cd->ctx, PR_2_HTREE_HASH_ORDER, &cd->pctx)) 5885 goto clear_and_exit; 5886 dx_db = &dx_dir->dx_block[blk]; 5887 if (dx_db->flags & DX_FLAG_REFERENCED) { 5888 dx_db->flags |= DX_FLAG_DUP_REF; 5889 } else { 5890 dx_db->flags |= DX_FLAG_REFERENCED; 5891 dx_db->parent = db->blockcnt; 5892 } 5893 if (hash < min_hash) 5894 min_hash = hash; 5895 if (hash > max_hash) 5896 max_hash = hash; 5897 dx_db->node_min_hash = hash; 5898 if ((i+1) < count) 5899 dx_db->node_max_hash = 5900 ext2fs_le32_to_cpu(ent[i+1].hash) & ~1; 5901 else { 5902 dx_db->node_max_hash = 0xfffffffe; 5903 dx_db->flags |= DX_FLAG_LAST; 5904 } 5905 if (i == 0) 5906 dx_db->flags |= DX_FLAG_FIRST; 5907 } 5908 dx_db = &dx_dir->dx_block[db->blockcnt]; 5909 dx_db->min_hash = min_hash; 5910 dx_db->max_hash = max_hash; 5911 return; 5912 5913clear_and_exit: 5914 clear_htree(cd->ctx, cd->pctx.ino); 5915 dx_dir->numblocks = 0; 5916} 5917#endif /* ENABLE_HTREE */ 5918 5919/* 5920 * Given a busted directory, try to salvage it somehow. 5921 * 5922 */ 5923static void salvage_directory(ext2_filsys fs, 5924 struct ext2_dir_entry *dirent, 5925 struct ext2_dir_entry *prev, 5926 unsigned int *offset) 5927{ 5928 char *cp = (char *) dirent; 5929 int left = fs->blocksize - *offset - dirent->rec_len; 5930 int name_len = dirent->name_len & 0xFF; 5931 5932 /* 5933 * Special case of directory entry of size 8: copy what's left 5934 * of the directory block up to cover up the invalid hole. 5935 */ 5936 if ((left >= 12) && (dirent->rec_len == 8)) { 5937 memmove(cp, cp+8, left); 5938 memset(cp + left, 0, 8); 5939 return; 5940 } 5941 /* 5942 * If the directory entry overruns the end of the directory 5943 * block, and the name is small enough to fit, then adjust the 5944 * record length. 5945 */ 5946 if ((left < 0) && 5947 (name_len + 8 <= dirent->rec_len + left) && 5948 dirent->inode <= fs->super->s_inodes_count && 5949 strnlen(dirent->name, name_len) == name_len) { 5950 dirent->rec_len += left; 5951 return; 5952 } 5953 /* 5954 * If the directory entry is a multiple of four, so it is 5955 * valid, let the previous directory entry absorb the invalid 5956 * one. 5957 */ 5958 if (prev && dirent->rec_len && (dirent->rec_len % 4) == 0) { 5959 prev->rec_len += dirent->rec_len; 5960 *offset += dirent->rec_len; 5961 return; 5962 } 5963 /* 5964 * Default salvage method --- kill all of the directory 5965 * entries for the rest of the block. We will either try to 5966 * absorb it into the previous directory entry, or create a 5967 * new empty directory entry the rest of the directory block. 5968 */ 5969 if (prev) { 5970 prev->rec_len += fs->blocksize - *offset; 5971 *offset = fs->blocksize; 5972 } else { 5973 dirent->rec_len = fs->blocksize - *offset; 5974 dirent->name_len = 0; 5975 dirent->inode = 0; 5976 } 5977} 5978 5979static int check_dir_block(ext2_filsys fs, 5980 struct ext2_db_entry *db, 5981 void *priv_data) 5982{ 5983 struct dir_info *subdir, *dir; 5984 struct dx_dir_info *dx_dir; 5985#ifdef ENABLE_HTREE 5986 struct dx_dirblock_info *dx_db = 0; 5987#endif /* ENABLE_HTREE */ 5988 struct ext2_dir_entry *dirent, *prev; 5989 ext2_dirhash_t hash; 5990 unsigned int offset = 0; 5991 int dir_modified = 0; 5992 int dot_state; 5993 blk_t block_nr = db->blk; 5994 ext2_ino_t ino = db->ino; 5995 __u16 links; 5996 struct check_dir_struct *cd; 5997 char *buf; 5998 e2fsck_t ctx; 5999 int problem; 6000 struct ext2_dx_root_info *root; 6001 struct ext2_dx_countlimit *limit; 6002 static dict_t de_dict; 6003 struct problem_context pctx; 6004 int dups_found = 0; 6005 6006 cd = (struct check_dir_struct *) priv_data; 6007 buf = cd->buf; 6008 ctx = cd->ctx; 6009 6010 if (ctx->flags & E2F_FLAG_SIGNAL_MASK) 6011 return DIRENT_ABORT; 6012 6013 if (ctx->progress && (ctx->progress)(ctx, 2, cd->count++, cd->max)) 6014 return DIRENT_ABORT; 6015 6016 /* 6017 * Make sure the inode is still in use (could have been 6018 * deleted in the duplicate/bad blocks pass. 6019 */ 6020 if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map, ino))) 6021 return 0; 6022 6023 cd->pctx.ino = ino; 6024 cd->pctx.blk = block_nr; 6025 cd->pctx.blkcount = db->blockcnt; 6026 cd->pctx.ino2 = 0; 6027 cd->pctx.dirent = 0; 6028 cd->pctx.num = 0; 6029 6030 if (db->blk == 0) { 6031 if (allocate_dir_block(ctx, db, &cd->pctx)) 6032 return 0; 6033 block_nr = db->blk; 6034 } 6035 6036 if (db->blockcnt) 6037 dot_state = 2; 6038 else 6039 dot_state = 0; 6040 6041 if (ctx->dirs_to_hash && 6042 ext2fs_u32_list_test(ctx->dirs_to_hash, ino)) 6043 dups_found++; 6044 6045 cd->pctx.errcode = ext2fs_read_dir_block(fs, block_nr, buf); 6046 if (cd->pctx.errcode == EXT2_ET_DIR_CORRUPTED) 6047 cd->pctx.errcode = 0; /* We'll handle this ourselves */ 6048 if (cd->pctx.errcode) { 6049 if (!fix_problem(ctx, PR_2_READ_DIRBLOCK, &cd->pctx)) { 6050 ctx->flags |= E2F_FLAG_ABORT; 6051 return DIRENT_ABORT; 6052 } 6053 memset(buf, 0, fs->blocksize); 6054 } 6055#ifdef ENABLE_HTREE 6056 dx_dir = e2fsck_get_dx_dir_info(ctx, ino); 6057 if (dx_dir && dx_dir->numblocks) { 6058 if (db->blockcnt >= dx_dir->numblocks) { 6059 printf("XXX should never happen!!!\n"); 6060 abort(); 6061 } 6062 dx_db = &dx_dir->dx_block[db->blockcnt]; 6063 dx_db->type = DX_DIRBLOCK_LEAF; 6064 dx_db->phys = block_nr; 6065 dx_db->min_hash = ~0; 6066 dx_db->max_hash = 0; 6067 6068 dirent = (struct ext2_dir_entry *) buf; 6069 limit = (struct ext2_dx_countlimit *) (buf+8); 6070 if (db->blockcnt == 0) { 6071 root = (struct ext2_dx_root_info *) (buf + 24); 6072 dx_db->type = DX_DIRBLOCK_ROOT; 6073 dx_db->flags |= DX_FLAG_FIRST | DX_FLAG_LAST; 6074 if ((root->reserved_zero || 6075 root->info_length < 8 || 6076 root->indirect_levels > 1) && 6077 fix_problem(ctx, PR_2_HTREE_BAD_ROOT, &cd->pctx)) { 6078 clear_htree(ctx, ino); 6079 dx_dir->numblocks = 0; 6080 dx_db = 0; 6081 } 6082 dx_dir->hashversion = root->hash_version; 6083 dx_dir->depth = root->indirect_levels + 1; 6084 } else if ((dirent->inode == 0) && 6085 (dirent->rec_len == fs->blocksize) && 6086 (dirent->name_len == 0) && 6087 (ext2fs_le16_to_cpu(limit->limit) == 6088 ((fs->blocksize-8) / 6089 sizeof(struct ext2_dx_entry)))) 6090 dx_db->type = DX_DIRBLOCK_NODE; 6091 } 6092#endif /* ENABLE_HTREE */ 6093 6094 dict_init(&de_dict, DICTCOUNT_T_MAX, dict_de_cmp); 6095 prev = 0; 6096 do { 6097 problem = 0; 6098 dirent = (struct ext2_dir_entry *) (buf + offset); 6099 cd->pctx.dirent = dirent; 6100 cd->pctx.num = offset; 6101 if (((offset + dirent->rec_len) > fs->blocksize) || 6102 (dirent->rec_len < 12) || 6103 ((dirent->rec_len % 4) != 0) || 6104 (((dirent->name_len & 0xFF)+8) > dirent->rec_len)) { 6105 if (fix_problem(ctx, PR_2_DIR_CORRUPTED, &cd->pctx)) { 6106 salvage_directory(fs, dirent, prev, &offset); 6107 dir_modified++; 6108 continue; 6109 } else 6110 goto abort_free_dict; 6111 } 6112 if ((dirent->name_len & 0xFF) > EXT2_NAME_LEN) { 6113 if (fix_problem(ctx, PR_2_FILENAME_LONG, &cd->pctx)) { 6114 dirent->name_len = EXT2_NAME_LEN; 6115 dir_modified++; 6116 } 6117 } 6118 6119 if (dot_state == 0) { 6120 if (check_dot(ctx, dirent, ino, &cd->pctx)) 6121 dir_modified++; 6122 } else if (dot_state == 1) { 6123 dir = e2fsck_get_dir_info(ctx, ino); 6124 if (!dir) { 6125 fix_problem(ctx, PR_2_NO_DIRINFO, &cd->pctx); 6126 goto abort_free_dict; 6127 } 6128 if (check_dotdot(ctx, dirent, dir, &cd->pctx)) 6129 dir_modified++; 6130 } else if (dirent->inode == ino) { 6131 problem = PR_2_LINK_DOT; 6132 if (fix_problem(ctx, PR_2_LINK_DOT, &cd->pctx)) { 6133 dirent->inode = 0; 6134 dir_modified++; 6135 goto next; 6136 } 6137 } 6138 if (!dirent->inode) 6139 goto next; 6140 6141 /* 6142 * Make sure the inode listed is a legal one. 6143 */ 6144 if (((dirent->inode != EXT2_ROOT_INO) && 6145 (dirent->inode < EXT2_FIRST_INODE(fs->super))) || 6146 (dirent->inode > fs->super->s_inodes_count)) { 6147 problem = PR_2_BAD_INO; 6148 } else if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map, 6149 dirent->inode))) { 6150 /* 6151 * If the inode is unused, offer to clear it. 6152 */ 6153 problem = PR_2_UNUSED_INODE; 6154 } else if ((dot_state > 1) && 6155 ((dirent->name_len & 0xFF) == 1) && 6156 (dirent->name[0] == '.')) { 6157 /* 6158 * If there's a '.' entry in anything other 6159 * than the first directory entry, it's a 6160 * duplicate entry that should be removed. 6161 */ 6162 problem = PR_2_DUP_DOT; 6163 } else if ((dot_state > 1) && 6164 ((dirent->name_len & 0xFF) == 2) && 6165 (dirent->name[0] == '.') && 6166 (dirent->name[1] == '.')) { 6167 /* 6168 * If there's a '..' entry in anything other 6169 * than the second directory entry, it's a 6170 * duplicate entry that should be removed. 6171 */ 6172 problem = PR_2_DUP_DOT_DOT; 6173 } else if ((dot_state > 1) && 6174 (dirent->inode == EXT2_ROOT_INO)) { 6175 /* 6176 * Don't allow links to the root directory. 6177 * We check this specially to make sure we 6178 * catch this error case even if the root 6179 * directory hasn't been created yet. 6180 */ 6181 problem = PR_2_LINK_ROOT; 6182 } else if ((dot_state > 1) && 6183 (dirent->name_len & 0xFF) == 0) { 6184 /* 6185 * Don't allow zero-length directory names. 6186 */ 6187 problem = PR_2_NULL_NAME; 6188 } 6189 6190 if (problem) { 6191 if (fix_problem(ctx, problem, &cd->pctx)) { 6192 dirent->inode = 0; 6193 dir_modified++; 6194 goto next; 6195 } else { 6196 ext2fs_unmark_valid(fs); 6197 if (problem == PR_2_BAD_INO) 6198 goto next; 6199 } 6200 } 6201 6202 /* 6203 * If the inode was marked as having bad fields in 6204 * pass1, process it and offer to fix/clear it. 6205 * (We wait until now so that we can display the 6206 * pathname to the user.) 6207 */ 6208 if (ctx->inode_bad_map && 6209 ext2fs_test_inode_bitmap(ctx->inode_bad_map, 6210 dirent->inode)) { 6211 if (e2fsck_process_bad_inode(ctx, ino, 6212 dirent->inode, 6213 buf + fs->blocksize)) { 6214 dirent->inode = 0; 6215 dir_modified++; 6216 goto next; 6217 } 6218 if (ctx->flags & E2F_FLAG_SIGNAL_MASK) 6219 return DIRENT_ABORT; 6220 } 6221 6222 if (check_name(ctx, dirent, &cd->pctx)) 6223 dir_modified++; 6224 6225 if (check_filetype(ctx, dirent, &cd->pctx)) 6226 dir_modified++; 6227 6228#ifdef ENABLE_HTREE 6229 if (dx_db) { 6230 ext2fs_dirhash(dx_dir->hashversion, dirent->name, 6231 (dirent->name_len & 0xFF), 6232 fs->super->s_hash_seed, &hash, 0); 6233 if (hash < dx_db->min_hash) 6234 dx_db->min_hash = hash; 6235 if (hash > dx_db->max_hash) 6236 dx_db->max_hash = hash; 6237 } 6238#endif 6239 6240 /* 6241 * If this is a directory, then mark its parent in its 6242 * dir_info structure. If the parent field is already 6243 * filled in, then this directory has more than one 6244 * hard link. We assume the first link is correct, 6245 * and ask the user if he/she wants to clear this one. 6246 */ 6247 if ((dot_state > 1) && 6248 (ext2fs_test_inode_bitmap(ctx->inode_dir_map, 6249 dirent->inode))) { 6250 subdir = e2fsck_get_dir_info(ctx, dirent->inode); 6251 if (!subdir) { 6252 cd->pctx.ino = dirent->inode; 6253 fix_problem(ctx, PR_2_NO_DIRINFO, &cd->pctx); 6254 goto abort_free_dict; 6255 } 6256 if (subdir->parent) { 6257 cd->pctx.ino2 = subdir->parent; 6258 if (fix_problem(ctx, PR_2_LINK_DIR, 6259 &cd->pctx)) { 6260 dirent->inode = 0; 6261 dir_modified++; 6262 goto next; 6263 } 6264 cd->pctx.ino2 = 0; 6265 } else 6266 subdir->parent = ino; 6267 } 6268 6269 if (dups_found) { 6270 ; 6271 } else if (dict_lookup(&de_dict, dirent)) { 6272 clear_problem_context(&pctx); 6273 pctx.ino = ino; 6274 pctx.dirent = dirent; 6275 fix_problem(ctx, PR_2_REPORT_DUP_DIRENT, &pctx); 6276 if (!ctx->dirs_to_hash) 6277 ext2fs_u32_list_create(&ctx->dirs_to_hash, 50); 6278 if (ctx->dirs_to_hash) 6279 ext2fs_u32_list_add(ctx->dirs_to_hash, ino); 6280 dups_found++; 6281 } else 6282 dict_alloc_insert(&de_dict, dirent, dirent); 6283 6284 ext2fs_icount_increment(ctx->inode_count, dirent->inode, 6285 &links); 6286 if (links > 1) 6287 ctx->fs_links_count++; 6288 ctx->fs_total_count++; 6289 next: 6290 prev = dirent; 6291 offset += dirent->rec_len; 6292 dot_state++; 6293 } while (offset < fs->blocksize); 6294#ifdef ENABLE_HTREE 6295 if (dx_db) { 6296 cd->pctx.dir = cd->pctx.ino; 6297 if ((dx_db->type == DX_DIRBLOCK_ROOT) || 6298 (dx_db->type == DX_DIRBLOCK_NODE)) 6299 parse_int_node(fs, db, cd, dx_dir, buf); 6300 } 6301#endif /* ENABLE_HTREE */ 6302 if (offset != fs->blocksize) { 6303 cd->pctx.num = dirent->rec_len - fs->blocksize + offset; 6304 if (fix_problem(ctx, PR_2_FINAL_RECLEN, &cd->pctx)) { 6305 dirent->rec_len = cd->pctx.num; 6306 dir_modified++; 6307 } 6308 } 6309 if (dir_modified) { 6310 cd->pctx.errcode = ext2fs_write_dir_block(fs, block_nr, buf); 6311 if (cd->pctx.errcode) { 6312 if (!fix_problem(ctx, PR_2_WRITE_DIRBLOCK, 6313 &cd->pctx)) 6314 goto abort_free_dict; 6315 } 6316 ext2fs_mark_changed(fs); 6317 } 6318 dict_free_nodes(&de_dict); 6319 return 0; 6320abort_free_dict: 6321 dict_free_nodes(&de_dict); 6322 ctx->flags |= E2F_FLAG_ABORT; 6323 return DIRENT_ABORT; 6324} 6325 6326/* 6327 * This function is called to deallocate a block, and is an interator 6328 * functioned called by deallocate inode via ext2fs_iterate_block(). 6329 */ 6330static int deallocate_inode_block(ext2_filsys fs, blk_t *block_nr, 6331 e2_blkcnt_t blockcnt FSCK_ATTR((unused)), 6332 blk_t ref_block FSCK_ATTR((unused)), 6333 int ref_offset FSCK_ATTR((unused)), 6334 void *priv_data) 6335{ 6336 e2fsck_t ctx = (e2fsck_t) priv_data; 6337 6338 if (HOLE_BLKADDR(*block_nr)) 6339 return 0; 6340 if ((*block_nr < fs->super->s_first_data_block) || 6341 (*block_nr >= fs->super->s_blocks_count)) 6342 return 0; 6343 ext2fs_unmark_block_bitmap(ctx->block_found_map, *block_nr); 6344 ext2fs_block_alloc_stats(fs, *block_nr, -1); 6345 return 0; 6346} 6347 6348/* 6349 * This fuction deallocates an inode 6350 */ 6351static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf) 6352{ 6353 ext2_filsys fs = ctx->fs; 6354 struct ext2_inode inode; 6355 struct problem_context pctx; 6356 __u32 count; 6357 6358 ext2fs_icount_store(ctx->inode_link_info, ino, 0); 6359 e2fsck_read_inode(ctx, ino, &inode, "deallocate_inode"); 6360 inode.i_links_count = 0; 6361 inode.i_dtime = time(0); 6362 e2fsck_write_inode(ctx, ino, &inode, "deallocate_inode"); 6363 clear_problem_context(&pctx); 6364 pctx.ino = ino; 6365 6366 /* 6367 * Fix up the bitmaps... 6368 */ 6369 e2fsck_read_bitmaps(ctx); 6370 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino); 6371 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino); 6372 if (ctx->inode_bad_map) 6373 ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino); 6374 ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(inode.i_mode)); 6375 6376 if (inode.i_file_acl && 6377 (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR)) { 6378 pctx.errcode = ext2fs_adjust_ea_refcount(fs, inode.i_file_acl, 6379 block_buf, -1, &count); 6380 if (pctx.errcode == EXT2_ET_BAD_EA_BLOCK_NUM) { 6381 pctx.errcode = 0; 6382 count = 1; 6383 } 6384 if (pctx.errcode) { 6385 pctx.blk = inode.i_file_acl; 6386 fix_problem(ctx, PR_2_ADJ_EA_REFCOUNT, &pctx); 6387 ctx->flags |= E2F_FLAG_ABORT; 6388 return; 6389 } 6390 if (count == 0) { 6391 ext2fs_unmark_block_bitmap(ctx->block_found_map, 6392 inode.i_file_acl); 6393 ext2fs_block_alloc_stats(fs, inode.i_file_acl, -1); 6394 } 6395 inode.i_file_acl = 0; 6396 } 6397 6398 if (!ext2fs_inode_has_valid_blocks(&inode)) 6399 return; 6400 6401 if (LINUX_S_ISREG(inode.i_mode) && 6402 (inode.i_size_high || inode.i_size & 0x80000000UL)) 6403 ctx->large_files--; 6404 6405 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf, 6406 deallocate_inode_block, ctx); 6407 if (pctx.errcode) { 6408 fix_problem(ctx, PR_2_DEALLOC_INODE, &pctx); 6409 ctx->flags |= E2F_FLAG_ABORT; 6410 return; 6411 } 6412} 6413 6414/* 6415 * This fuction clears the htree flag on an inode 6416 */ 6417static void clear_htree(e2fsck_t ctx, ext2_ino_t ino) 6418{ 6419 struct ext2_inode inode; 6420 6421 e2fsck_read_inode(ctx, ino, &inode, "clear_htree"); 6422 inode.i_flags = inode.i_flags & ~EXT2_INDEX_FL; 6423 e2fsck_write_inode(ctx, ino, &inode, "clear_htree"); 6424 if (ctx->dirs_to_hash) 6425 ext2fs_u32_list_add(ctx->dirs_to_hash, ino); 6426} 6427 6428 6429static int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir, 6430 ext2_ino_t ino, char *buf) 6431{ 6432 ext2_filsys fs = ctx->fs; 6433 struct ext2_inode inode; 6434 int inode_modified = 0; 6435 int not_fixed = 0; 6436 unsigned char *frag, *fsize; 6437 struct problem_context pctx; 6438 int problem = 0; 6439 6440 e2fsck_read_inode(ctx, ino, &inode, "process_bad_inode"); 6441 6442 clear_problem_context(&pctx); 6443 pctx.ino = ino; 6444 pctx.dir = dir; 6445 pctx.inode = &inode; 6446 6447 if (inode.i_file_acl && 6448 !(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) && 6449 fix_problem(ctx, PR_2_FILE_ACL_ZERO, &pctx)) { 6450 inode.i_file_acl = 0; 6451#if BB_BIG_ENDIAN 6452 /* 6453 * This is a special kludge to deal with long symlinks 6454 * on big endian systems. i_blocks had already been 6455 * decremented earlier in pass 1, but since i_file_acl 6456 * hadn't yet been cleared, ext2fs_read_inode() 6457 * assumed that the file was short symlink and would 6458 * not have byte swapped i_block[0]. Hence, we have 6459 * to byte-swap it here. 6460 */ 6461 if (LINUX_S_ISLNK(inode.i_mode) && 6462 (fs->flags & EXT2_FLAG_SWAP_BYTES) && 6463 (inode.i_blocks == fs->blocksize >> 9)) 6464 inode.i_block[0] = ext2fs_swab32(inode.i_block[0]); 6465#endif 6466 inode_modified++; 6467 } else 6468 not_fixed++; 6469 6470 if (!LINUX_S_ISDIR(inode.i_mode) && !LINUX_S_ISREG(inode.i_mode) && 6471 !LINUX_S_ISCHR(inode.i_mode) && !LINUX_S_ISBLK(inode.i_mode) && 6472 !LINUX_S_ISLNK(inode.i_mode) && !LINUX_S_ISFIFO(inode.i_mode) && 6473 !(LINUX_S_ISSOCK(inode.i_mode))) 6474 problem = PR_2_BAD_MODE; 6475 else if (LINUX_S_ISCHR(inode.i_mode) 6476 && !e2fsck_pass1_check_device_inode(fs, &inode)) 6477 problem = PR_2_BAD_CHAR_DEV; 6478 else if (LINUX_S_ISBLK(inode.i_mode) 6479 && !e2fsck_pass1_check_device_inode(fs, &inode)) 6480 problem = PR_2_BAD_BLOCK_DEV; 6481 else if (LINUX_S_ISFIFO(inode.i_mode) 6482 && !e2fsck_pass1_check_device_inode(fs, &inode)) 6483 problem = PR_2_BAD_FIFO; 6484 else if (LINUX_S_ISSOCK(inode.i_mode) 6485 && !e2fsck_pass1_check_device_inode(fs, &inode)) 6486 problem = PR_2_BAD_SOCKET; 6487 else if (LINUX_S_ISLNK(inode.i_mode) 6488 && !e2fsck_pass1_check_symlink(fs, &inode, buf)) { 6489 problem = PR_2_INVALID_SYMLINK; 6490 } 6491 6492 if (problem) { 6493 if (fix_problem(ctx, problem, &pctx)) { 6494 deallocate_inode(ctx, ino, 0); 6495 if (ctx->flags & E2F_FLAG_SIGNAL_MASK) 6496 return 0; 6497 return 1; 6498 } else 6499 not_fixed++; 6500 problem = 0; 6501 } 6502 6503 if (inode.i_faddr) { 6504 if (fix_problem(ctx, PR_2_FADDR_ZERO, &pctx)) { 6505 inode.i_faddr = 0; 6506 inode_modified++; 6507 } else 6508 not_fixed++; 6509 } 6510 6511 switch (fs->super->s_creator_os) { 6512 case EXT2_OS_LINUX: 6513 frag = &inode.osd2.linux2.l_i_frag; 6514 fsize = &inode.osd2.linux2.l_i_fsize; 6515 break; 6516 case EXT2_OS_HURD: 6517 frag = &inode.osd2.hurd2.h_i_frag; 6518 fsize = &inode.osd2.hurd2.h_i_fsize; 6519 break; 6520 case EXT2_OS_MASIX: 6521 frag = &inode.osd2.masix2.m_i_frag; 6522 fsize = &inode.osd2.masix2.m_i_fsize; 6523 break; 6524 default: 6525 frag = fsize = 0; 6526 } 6527 if (frag && *frag) { 6528 pctx.num = *frag; 6529 if (fix_problem(ctx, PR_2_FRAG_ZERO, &pctx)) { 6530 *frag = 0; 6531 inode_modified++; 6532 } else 6533 not_fixed++; 6534 pctx.num = 0; 6535 } 6536 if (fsize && *fsize) { 6537 pctx.num = *fsize; 6538 if (fix_problem(ctx, PR_2_FSIZE_ZERO, &pctx)) { 6539 *fsize = 0; 6540 inode_modified++; 6541 } else 6542 not_fixed++; 6543 pctx.num = 0; 6544 } 6545 6546 if (inode.i_file_acl && 6547 ((inode.i_file_acl < fs->super->s_first_data_block) || 6548 (inode.i_file_acl >= fs->super->s_blocks_count))) { 6549 if (fix_problem(ctx, PR_2_FILE_ACL_BAD, &pctx)) { 6550 inode.i_file_acl = 0; 6551 inode_modified++; 6552 } else 6553 not_fixed++; 6554 } 6555 if (inode.i_dir_acl && 6556 LINUX_S_ISDIR(inode.i_mode)) { 6557 if (fix_problem(ctx, PR_2_DIR_ACL_ZERO, &pctx)) { 6558 inode.i_dir_acl = 0; 6559 inode_modified++; 6560 } else 6561 not_fixed++; 6562 } 6563 6564 if (inode_modified) 6565 e2fsck_write_inode(ctx, ino, &inode, "process_bad_inode"); 6566 if (!not_fixed) 6567 ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino); 6568 return 0; 6569} 6570 6571 6572/* 6573 * allocate_dir_block --- this function allocates a new directory 6574 * block for a particular inode; this is done if a directory has 6575 * a "hole" in it, or if a directory has a illegal block number 6576 * that was zeroed out and now needs to be replaced. 6577 */ 6578static int allocate_dir_block(e2fsck_t ctx, struct ext2_db_entry *db, 6579 struct problem_context *pctx) 6580{ 6581 ext2_filsys fs = ctx->fs; 6582 blk_t blk; 6583 char *block; 6584 struct ext2_inode inode; 6585 6586 if (fix_problem(ctx, PR_2_DIRECTORY_HOLE, pctx) == 0) 6587 return 1; 6588 6589 /* 6590 * Read the inode and block bitmaps in; we'll be messing with 6591 * them. 6592 */ 6593 e2fsck_read_bitmaps(ctx); 6594 6595 /* 6596 * First, find a free block 6597 */ 6598 pctx->errcode = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk); 6599 if (pctx->errcode) { 6600 pctx->str = "ext2fs_new_block"; 6601 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx); 6602 return 1; 6603 } 6604 ext2fs_mark_block_bitmap(ctx->block_found_map, blk); 6605 ext2fs_mark_block_bitmap(fs->block_map, blk); 6606 ext2fs_mark_bb_dirty(fs); 6607 6608 /* 6609 * Now let's create the actual data block for the inode 6610 */ 6611 if (db->blockcnt) 6612 pctx->errcode = ext2fs_new_dir_block(fs, 0, 0, &block); 6613 else 6614 pctx->errcode = ext2fs_new_dir_block(fs, db->ino, 6615 EXT2_ROOT_INO, &block); 6616 6617 if (pctx->errcode) { 6618 pctx->str = "ext2fs_new_dir_block"; 6619 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx); 6620 return 1; 6621 } 6622 6623 pctx->errcode = ext2fs_write_dir_block(fs, blk, block); 6624 ext2fs_free_mem(&block); 6625 if (pctx->errcode) { 6626 pctx->str = "ext2fs_write_dir_block"; 6627 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx); 6628 return 1; 6629 } 6630 6631 /* 6632 * Update the inode block count 6633 */ 6634 e2fsck_read_inode(ctx, db->ino, &inode, "allocate_dir_block"); 6635 inode.i_blocks += fs->blocksize / 512; 6636 if (inode.i_size < (db->blockcnt+1) * fs->blocksize) 6637 inode.i_size = (db->blockcnt+1) * fs->blocksize; 6638 e2fsck_write_inode(ctx, db->ino, &inode, "allocate_dir_block"); 6639 6640 /* 6641 * Finally, update the block pointers for the inode 6642 */ 6643 db->blk = blk; 6644 pctx->errcode = ext2fs_block_iterate2(fs, db->ino, BLOCK_FLAG_HOLE, 6645 0, update_dir_block, db); 6646 if (pctx->errcode) { 6647 pctx->str = "ext2fs_block_iterate"; 6648 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx); 6649 return 1; 6650 } 6651 6652 return 0; 6653} 6654 6655/* 6656 * This is a helper function for allocate_dir_block(). 6657 */ 6658static int update_dir_block(ext2_filsys fs FSCK_ATTR((unused)), 6659 blk_t *block_nr, 6660 e2_blkcnt_t blockcnt, 6661 blk_t ref_block FSCK_ATTR((unused)), 6662 int ref_offset FSCK_ATTR((unused)), 6663 void *priv_data) 6664{ 6665 struct ext2_db_entry *db; 6666 6667 db = (struct ext2_db_entry *) priv_data; 6668 if (db->blockcnt == (int) blockcnt) { 6669 *block_nr = db->blk; 6670 return BLOCK_CHANGED; 6671 } 6672 return 0; 6673} 6674 6675/* 6676 * pass3.c -- pass #3 of e2fsck: Check for directory connectivity 6677 * 6678 * Pass #3 assures that all directories are connected to the 6679 * filesystem tree, using the following algorithm: 6680 * 6681 * First, the root directory is checked to make sure it exists; if 6682 * not, e2fsck will offer to create a new one. It is then marked as 6683 * "done". 6684 * 6685 * Then, pass3 interates over all directory inodes; for each directory 6686 * it attempts to trace up the filesystem tree, using dirinfo.parent 6687 * until it reaches a directory which has been marked "done". If it 6688 * cannot do so, then the directory must be disconnected, and e2fsck 6689 * will offer to reconnect it to /lost+found. While it is chasing 6690 * parent pointers up the filesystem tree, if pass3 sees a directory 6691 * twice, then it has detected a filesystem loop, and it will again 6692 * offer to reconnect the directory to /lost+found in to break the 6693 * filesystem loop. 6694 * 6695 * Pass 3 also contains the subroutine, e2fsck_reconnect_file() to 6696 * reconnect inodes to /lost+found; this subroutine is also used by 6697 * pass 4. e2fsck_reconnect_file() calls get_lost_and_found(), which 6698 * is responsible for creating /lost+found if it does not exist. 6699 * 6700 * Pass 3 frees the following data structures: 6701 * - The dirinfo directory information cache. 6702 */ 6703 6704static void check_root(e2fsck_t ctx); 6705static int check_directory(e2fsck_t ctx, struct dir_info *dir, 6706 struct problem_context *pctx); 6707static void fix_dotdot(e2fsck_t ctx, struct dir_info *dir, ext2_ino_t parent); 6708 6709static ext2fs_inode_bitmap inode_loop_detect; 6710static ext2fs_inode_bitmap inode_done_map; 6711 6712static void e2fsck_pass3(e2fsck_t ctx) 6713{ 6714 ext2_filsys fs = ctx->fs; 6715 int i; 6716 struct problem_context pctx; 6717 struct dir_info *dir; 6718 unsigned long maxdirs, count; 6719 6720 clear_problem_context(&pctx); 6721 6722 /* Pass 3 */ 6723 6724 if (!(ctx->options & E2F_OPT_PREEN)) 6725 fix_problem(ctx, PR_3_PASS_HEADER, &pctx); 6726 6727 /* 6728 * Allocate some bitmaps to do loop detection. 6729 */ 6730 pctx.errcode = ext2fs_allocate_inode_bitmap(fs, _("inode done bitmap"), 6731 &inode_done_map); 6732 if (pctx.errcode) { 6733 pctx.num = 2; 6734 fix_problem(ctx, PR_3_ALLOCATE_IBITMAP_ERROR, &pctx); 6735 ctx->flags |= E2F_FLAG_ABORT; 6736 goto abort_exit; 6737 } 6738 check_root(ctx); 6739 if (ctx->flags & E2F_FLAG_SIGNAL_MASK) 6740 goto abort_exit; 6741 6742 ext2fs_mark_inode_bitmap(inode_done_map, EXT2_ROOT_INO); 6743 6744 maxdirs = e2fsck_get_num_dirinfo(ctx); 6745 count = 1; 6746 6747 if (ctx->progress) 6748 if ((ctx->progress)(ctx, 3, 0, maxdirs)) 6749 goto abort_exit; 6750 6751 for (i=0; (dir = e2fsck_dir_info_iter(ctx, &i)) != 0;) { 6752 if (ctx->flags & E2F_FLAG_SIGNAL_MASK) 6753 goto abort_exit; 6754 if (ctx->progress && (ctx->progress)(ctx, 3, count++, maxdirs)) 6755 goto abort_exit; 6756 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, dir->ino)) 6757 if (check_directory(ctx, dir, &pctx)) 6758 goto abort_exit; 6759 } 6760 6761 /* 6762 * Force the creation of /lost+found if not present 6763 */ 6764 if ((ctx->flags & E2F_OPT_READONLY) == 0) 6765 e2fsck_get_lost_and_found(ctx, 1); 6766 6767 /* 6768 * If there are any directories that need to be indexed or 6769 * optimized, do it here. 6770 */ 6771 e2fsck_rehash_directories(ctx); 6772 6773abort_exit: 6774 e2fsck_free_dir_info(ctx); 6775 ext2fs_free_inode_bitmap(inode_loop_detect); 6776 inode_loop_detect = 0; 6777 ext2fs_free_inode_bitmap(inode_done_map); 6778 inode_done_map = 0; 6779} 6780 6781/* 6782 * This makes sure the root inode is present; if not, we ask if the 6783 * user wants us to create it. Not creating it is a fatal error. 6784 */ 6785static void check_root(e2fsck_t ctx) 6786{ 6787 ext2_filsys fs = ctx->fs; 6788 blk_t blk; 6789 struct ext2_inode inode; 6790 char * block; 6791 struct problem_context pctx; 6792 6793 clear_problem_context(&pctx); 6794 6795 if (ext2fs_test_inode_bitmap(ctx->inode_used_map, EXT2_ROOT_INO)) { 6796 /* 6797 * If the root inode is not a directory, die here. The 6798 * user must have answered 'no' in pass1 when we 6799 * offered to clear it. 6800 */ 6801 if (!(ext2fs_test_inode_bitmap(ctx->inode_dir_map, 6802 EXT2_ROOT_INO))) { 6803 fix_problem(ctx, PR_3_ROOT_NOT_DIR_ABORT, &pctx); 6804 ctx->flags |= E2F_FLAG_ABORT; 6805 } 6806 return; 6807 } 6808 6809 if (!fix_problem(ctx, PR_3_NO_ROOT_INODE, &pctx)) { 6810 fix_problem(ctx, PR_3_NO_ROOT_INODE_ABORT, &pctx); 6811 ctx->flags |= E2F_FLAG_ABORT; 6812 return; 6813 } 6814 6815 e2fsck_read_bitmaps(ctx); 6816 6817 /* 6818 * First, find a free block 6819 */ 6820 pctx.errcode = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk); 6821 if (pctx.errcode) { 6822 pctx.str = "ext2fs_new_block"; 6823 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx); 6824 ctx->flags |= E2F_FLAG_ABORT; 6825 return; 6826 } 6827 ext2fs_mark_block_bitmap(ctx->block_found_map, blk); 6828 ext2fs_mark_block_bitmap(fs->block_map, blk); 6829 ext2fs_mark_bb_dirty(fs); 6830 6831 /* 6832 * Now let's create the actual data block for the inode 6833 */ 6834 pctx.errcode = ext2fs_new_dir_block(fs, EXT2_ROOT_INO, EXT2_ROOT_INO, 6835 &block); 6836 if (pctx.errcode) { 6837 pctx.str = "ext2fs_new_dir_block"; 6838 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx); 6839 ctx->flags |= E2F_FLAG_ABORT; 6840 return; 6841 } 6842 6843 pctx.errcode = ext2fs_write_dir_block(fs, blk, block); 6844 if (pctx.errcode) { 6845 pctx.str = "ext2fs_write_dir_block"; 6846 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx); 6847 ctx->flags |= E2F_FLAG_ABORT; 6848 return; 6849 } 6850 ext2fs_free_mem(&block); 6851 6852 /* 6853 * Set up the inode structure 6854 */ 6855 memset(&inode, 0, sizeof(inode)); 6856 inode.i_mode = 040755; 6857 inode.i_size = fs->blocksize; 6858 inode.i_atime = inode.i_ctime = inode.i_mtime = time(0); 6859 inode.i_links_count = 2; 6860 inode.i_blocks = fs->blocksize / 512; 6861 inode.i_block[0] = blk; 6862 6863 /* 6864 * Write out the inode. 6865 */ 6866 pctx.errcode = ext2fs_write_new_inode(fs, EXT2_ROOT_INO, &inode); 6867 if (pctx.errcode) { 6868 pctx.str = "ext2fs_write_inode"; 6869 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx); 6870 ctx->flags |= E2F_FLAG_ABORT; 6871 return; 6872 } 6873 6874 /* 6875 * Miscellaneous bookkeeping... 6876 */ 6877 e2fsck_add_dir_info(ctx, EXT2_ROOT_INO, EXT2_ROOT_INO); 6878 ext2fs_icount_store(ctx->inode_count, EXT2_ROOT_INO, 2); 6879 ext2fs_icount_store(ctx->inode_link_info, EXT2_ROOT_INO, 2); 6880 6881 ext2fs_mark_inode_bitmap(ctx->inode_used_map, EXT2_ROOT_INO); 6882 ext2fs_mark_inode_bitmap(ctx->inode_dir_map, EXT2_ROOT_INO); 6883 ext2fs_mark_inode_bitmap(fs->inode_map, EXT2_ROOT_INO); 6884 ext2fs_mark_ib_dirty(fs); 6885} 6886 6887/* 6888 * This subroutine is responsible for making sure that a particular 6889 * directory is connected to the root; if it isn't we trace it up as 6890 * far as we can go, and then offer to connect the resulting parent to 6891 * the lost+found. We have to do loop detection; if we ever discover 6892 * a loop, we treat that as a disconnected directory and offer to 6893 * reparent it to lost+found. 6894 * 6895 * However, loop detection is expensive, because for very large 6896 * filesystems, the inode_loop_detect bitmap is huge, and clearing it 6897 * is non-trivial. Loops in filesystems are also a rare error case, 6898 * and we shouldn't optimize for error cases. So we try two passes of 6899 * the algorithm. The first time, we ignore loop detection and merely 6900 * increment a counter; if the counter exceeds some extreme threshold, 6901 * then we try again with the loop detection bitmap enabled. 6902 */ 6903static int check_directory(e2fsck_t ctx, struct dir_info *dir, 6904 struct problem_context *pctx) 6905{ 6906 ext2_filsys fs = ctx->fs; 6907 struct dir_info *p = dir; 6908 int loop_pass = 0, parent_count = 0; 6909 6910 if (!p) 6911 return 0; 6912 6913 while (1) { 6914 /* 6915 * Mark this inode as being "done"; by the time we 6916 * return from this function, the inode we either be 6917 * verified as being connected to the directory tree, 6918 * or we will have offered to reconnect this to 6919 * lost+found. 6920 * 6921 * If it was marked done already, then we've reached a 6922 * parent we've already checked. 6923 */ 6924 if (ext2fs_mark_inode_bitmap(inode_done_map, p->ino)) 6925 break; 6926 6927 /* 6928 * If this directory doesn't have a parent, or we've 6929 * seen the parent once already, then offer to 6930 * reparent it to lost+found 6931 */ 6932 if (!p->parent || 6933 (loop_pass && 6934 (ext2fs_test_inode_bitmap(inode_loop_detect, 6935 p->parent)))) { 6936 pctx->ino = p->ino; 6937 if (fix_problem(ctx, PR_3_UNCONNECTED_DIR, pctx)) { 6938 if (e2fsck_reconnect_file(ctx, pctx->ino)) 6939 ext2fs_unmark_valid(fs); 6940 else { 6941 p = e2fsck_get_dir_info(ctx, pctx->ino); 6942 p->parent = ctx->lost_and_found; 6943 fix_dotdot(ctx, p, ctx->lost_and_found); 6944 } 6945 } 6946 break; 6947 } 6948 p = e2fsck_get_dir_info(ctx, p->parent); 6949 if (!p) { 6950 fix_problem(ctx, PR_3_NO_DIRINFO, pctx); 6951 return 0; 6952 } 6953 if (loop_pass) { 6954 ext2fs_mark_inode_bitmap(inode_loop_detect, 6955 p->ino); 6956 } else if (parent_count++ > 2048) { 6957 /* 6958 * If we've run into a path depth that's 6959 * greater than 2048, try again with the inode 6960 * loop bitmap turned on and start from the 6961 * top. 6962 */ 6963 loop_pass = 1; 6964 if (inode_loop_detect) 6965 ext2fs_clear_inode_bitmap(inode_loop_detect); 6966 else { 6967 pctx->errcode = ext2fs_allocate_inode_bitmap(fs, _("inode loop detection bitmap"), &inode_loop_detect); 6968 if (pctx->errcode) { 6969 pctx->num = 1; 6970 fix_problem(ctx, 6971 PR_3_ALLOCATE_IBITMAP_ERROR, pctx); 6972 ctx->flags |= E2F_FLAG_ABORT; 6973 return -1; 6974 } 6975 } 6976 p = dir; 6977 } 6978 } 6979 6980 /* 6981 * Make sure that .. and the parent directory are the same; 6982 * offer to fix it if not. 6983 */ 6984 if (dir->parent != dir->dotdot) { 6985 pctx->ino = dir->ino; 6986 pctx->ino2 = dir->dotdot; 6987 pctx->dir = dir->parent; 6988 if (fix_problem(ctx, PR_3_BAD_DOT_DOT, pctx)) 6989 fix_dotdot(ctx, dir, dir->parent); 6990 } 6991 return 0; 6992} 6993 6994/* 6995 * This routine gets the lost_and_found inode, making it a directory 6996 * if necessary 6997 */ 6998ext2_ino_t e2fsck_get_lost_and_found(e2fsck_t ctx, int fix) 6999{ 7000 ext2_filsys fs = ctx->fs; 7001 ext2_ino_t ino; 7002 blk_t blk; 7003 errcode_t retval; 7004 struct ext2_inode inode; 7005 char * block; 7006 static const char name[] = "lost+found"; 7007 struct problem_context pctx; 7008 struct dir_info *dirinfo; 7009 7010 if (ctx->lost_and_found) 7011 return ctx->lost_and_found; 7012 7013 clear_problem_context(&pctx); 7014 7015 retval = ext2fs_lookup(fs, EXT2_ROOT_INO, name, 7016 sizeof(name)-1, 0, &ino); 7017 if (retval && !fix) 7018 return 0; 7019 if (!retval) { 7020 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, ino)) { 7021 ctx->lost_and_found = ino; 7022 return ino; 7023 } 7024 7025 /* Lost+found isn't a directory! */ 7026 if (!fix) 7027 return 0; 7028 pctx.ino = ino; 7029 if (!fix_problem(ctx, PR_3_LPF_NOTDIR, &pctx)) 7030 return 0; 7031 7032 /* OK, unlink the old /lost+found file. */ 7033 pctx.errcode = ext2fs_unlink(fs, EXT2_ROOT_INO, name, ino, 0); 7034 if (pctx.errcode) { 7035 pctx.str = "ext2fs_unlink"; 7036 fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx); 7037 return 0; 7038 } 7039 dirinfo = e2fsck_get_dir_info(ctx, ino); 7040 if (dirinfo) 7041 dirinfo->parent = 0; 7042 e2fsck_adjust_inode_count(ctx, ino, -1); 7043 } else if (retval != EXT2_ET_FILE_NOT_FOUND) { 7044 pctx.errcode = retval; 7045 fix_problem(ctx, PR_3_ERR_FIND_LPF, &pctx); 7046 } 7047 if (!fix_problem(ctx, PR_3_NO_LF_DIR, 0)) 7048 return 0; 7049 7050 /* 7051 * Read the inode and block bitmaps in; we'll be messing with 7052 * them. 7053 */ 7054 e2fsck_read_bitmaps(ctx); 7055 7056 /* 7057 * First, find a free block 7058 */ 7059 retval = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk); 7060 if (retval) { 7061 pctx.errcode = retval; 7062 fix_problem(ctx, PR_3_ERR_LPF_NEW_BLOCK, &pctx); 7063 return 0; 7064 } 7065 ext2fs_mark_block_bitmap(ctx->block_found_map, blk); 7066 ext2fs_block_alloc_stats(fs, blk, +1); 7067 7068 /* 7069 * Next find a free inode. 7070 */ 7071 retval = ext2fs_new_inode(fs, EXT2_ROOT_INO, 040700, 7072 ctx->inode_used_map, &ino); 7073 if (retval) { 7074 pctx.errcode = retval; 7075 fix_problem(ctx, PR_3_ERR_LPF_NEW_INODE, &pctx); 7076 return 0; 7077 } 7078 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino); 7079 ext2fs_mark_inode_bitmap(ctx->inode_dir_map, ino); 7080 ext2fs_inode_alloc_stats2(fs, ino, +1, 1); 7081 7082 /* 7083 * Now let's create the actual data block for the inode 7084 */ 7085 retval = ext2fs_new_dir_block(fs, ino, EXT2_ROOT_INO, &block); 7086 if (retval) { 7087 pctx.errcode = retval; 7088 fix_problem(ctx, PR_3_ERR_LPF_NEW_DIR_BLOCK, &pctx); 7089 return 0; 7090 } 7091 7092 retval = ext2fs_write_dir_block(fs, blk, block); 7093 ext2fs_free_mem(&block); 7094 if (retval) { 7095 pctx.errcode = retval; 7096 fix_problem(ctx, PR_3_ERR_LPF_WRITE_BLOCK, &pctx); 7097 return 0; 7098 } 7099 7100 /* 7101 * Set up the inode structure 7102 */ 7103 memset(&inode, 0, sizeof(inode)); 7104 inode.i_mode = 040700; 7105 inode.i_size = fs->blocksize; 7106 inode.i_atime = inode.i_ctime = inode.i_mtime = time(0); 7107 inode.i_links_count = 2; 7108 inode.i_blocks = fs->blocksize / 512; 7109 inode.i_block[0] = blk; 7110 7111 /* 7112 * Next, write out the inode. 7113 */ 7114 pctx.errcode = ext2fs_write_new_inode(fs, ino, &inode); 7115 if (pctx.errcode) { 7116 pctx.str = "ext2fs_write_inode"; 7117 fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx); 7118 return 0; 7119 } 7120 /* 7121 * Finally, create the directory link 7122 */ 7123 pctx.errcode = ext2fs_link(fs, EXT2_ROOT_INO, name, ino, EXT2_FT_DIR); 7124 if (pctx.errcode) { 7125 pctx.str = "ext2fs_link"; 7126 fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx); 7127 return 0; 7128 } 7129 7130 /* 7131 * Miscellaneous bookkeeping that needs to be kept straight. 7132 */ 7133 e2fsck_add_dir_info(ctx, ino, EXT2_ROOT_INO); 7134 e2fsck_adjust_inode_count(ctx, EXT2_ROOT_INO, 1); 7135 ext2fs_icount_store(ctx->inode_count, ino, 2); 7136 ext2fs_icount_store(ctx->inode_link_info, ino, 2); 7137 ctx->lost_and_found = ino; 7138 return ino; 7139} 7140 7141/* 7142 * This routine will connect a file to lost+found 7143 */ 7144int e2fsck_reconnect_file(e2fsck_t ctx, ext2_ino_t ino) 7145{ 7146 ext2_filsys fs = ctx->fs; 7147 errcode_t retval; 7148 char name[80]; 7149 struct problem_context pctx; 7150 struct ext2_inode inode; 7151 int file_type = 0; 7152 7153 clear_problem_context(&pctx); 7154 pctx.ino = ino; 7155 7156 if (!ctx->bad_lost_and_found && !ctx->lost_and_found) { 7157 if (e2fsck_get_lost_and_found(ctx, 1) == 0) 7158 ctx->bad_lost_and_found++; 7159 } 7160 if (ctx->bad_lost_and_found) { 7161 fix_problem(ctx, PR_3_NO_LPF, &pctx); 7162 return 1; 7163 } 7164 7165 sprintf(name, "#%u", ino); 7166 if (ext2fs_read_inode(fs, ino, &inode) == 0) 7167 file_type = ext2_file_type(inode.i_mode); 7168 retval = ext2fs_link(fs, ctx->lost_and_found, name, ino, file_type); 7169 if (retval == EXT2_ET_DIR_NO_SPACE) { 7170 if (!fix_problem(ctx, PR_3_EXPAND_LF_DIR, &pctx)) 7171 return 1; 7172 retval = e2fsck_expand_directory(ctx, ctx->lost_and_found, 7173 1, 0); 7174 if (retval) { 7175 pctx.errcode = retval; 7176 fix_problem(ctx, PR_3_CANT_EXPAND_LPF, &pctx); 7177 return 1; 7178 } 7179 retval = ext2fs_link(fs, ctx->lost_and_found, name, 7180 ino, file_type); 7181 } 7182 if (retval) { 7183 pctx.errcode = retval; 7184 fix_problem(ctx, PR_3_CANT_RECONNECT, &pctx); 7185 return 1; 7186 } 7187 e2fsck_adjust_inode_count(ctx, ino, 1); 7188 7189 return 0; 7190} 7191 7192/* 7193 * Utility routine to adjust the inode counts on an inode. 7194 */ 7195errcode_t e2fsck_adjust_inode_count(e2fsck_t ctx, ext2_ino_t ino, int adj) 7196{ 7197 ext2_filsys fs = ctx->fs; 7198 errcode_t retval; 7199 struct ext2_inode inode; 7200 7201 if (!ino) 7202 return 0; 7203 7204 retval = ext2fs_read_inode(fs, ino, &inode); 7205 if (retval) 7206 return retval; 7207 7208 if (adj == 1) { 7209 ext2fs_icount_increment(ctx->inode_count, ino, 0); 7210 if (inode.i_links_count == (__u16) ~0) 7211 return 0; 7212 ext2fs_icount_increment(ctx->inode_link_info, ino, 0); 7213 inode.i_links_count++; 7214 } else if (adj == -1) { 7215 ext2fs_icount_decrement(ctx->inode_count, ino, 0); 7216 if (inode.i_links_count == 0) 7217 return 0; 7218 ext2fs_icount_decrement(ctx->inode_link_info, ino, 0); 7219 inode.i_links_count--; 7220 } 7221 7222 retval = ext2fs_write_inode(fs, ino, &inode); 7223 if (retval) 7224 return retval; 7225 7226 return 0; 7227} 7228 7229/* 7230 * Fix parent --- this routine fixes up the parent of a directory. 7231 */ 7232struct fix_dotdot_struct { 7233 ext2_filsys fs; 7234 ext2_ino_t parent; 7235 int done; 7236 e2fsck_t ctx; 7237}; 7238 7239static int fix_dotdot_proc(struct ext2_dir_entry *dirent, 7240 int offset FSCK_ATTR((unused)), 7241 int blocksize FSCK_ATTR((unused)), 7242 char *buf FSCK_ATTR((unused)), 7243 void *priv_data) 7244{ 7245 struct fix_dotdot_struct *fp = (struct fix_dotdot_struct *) priv_data; 7246 errcode_t retval; 7247 struct problem_context pctx; 7248 7249 if ((dirent->name_len & 0xFF) != 2) 7250 return 0; 7251 if (strncmp(dirent->name, "..", 2)) 7252 return 0; 7253 7254 clear_problem_context(&pctx); 7255 7256 retval = e2fsck_adjust_inode_count(fp->ctx, dirent->inode, -1); 7257 if (retval) { 7258 pctx.errcode = retval; 7259 fix_problem(fp->ctx, PR_3_ADJUST_INODE, &pctx); 7260 } 7261 retval = e2fsck_adjust_inode_count(fp->ctx, fp->parent, 1); 7262 if (retval) { 7263 pctx.errcode = retval; 7264 fix_problem(fp->ctx, PR_3_ADJUST_INODE, &pctx); 7265 } 7266 dirent->inode = fp->parent; 7267 7268 fp->done++; 7269 return DIRENT_ABORT | DIRENT_CHANGED; 7270} 7271 7272static void fix_dotdot(e2fsck_t ctx, struct dir_info *dir, ext2_ino_t parent) 7273{ 7274 ext2_filsys fs = ctx->fs; 7275 errcode_t retval; 7276 struct fix_dotdot_struct fp; 7277 struct problem_context pctx; 7278 7279 fp.fs = fs; 7280 fp.parent = parent; 7281 fp.done = 0; 7282 fp.ctx = ctx; 7283 7284 retval = ext2fs_dir_iterate(fs, dir->ino, DIRENT_FLAG_INCLUDE_EMPTY, 7285 0, fix_dotdot_proc, &fp); 7286 if (retval || !fp.done) { 7287 clear_problem_context(&pctx); 7288 pctx.ino = dir->ino; 7289 pctx.errcode = retval; 7290 fix_problem(ctx, retval ? PR_3_FIX_PARENT_ERR : 7291 PR_3_FIX_PARENT_NOFIND, &pctx); 7292 ext2fs_unmark_valid(fs); 7293 } 7294 dir->dotdot = parent; 7295} 7296 7297/* 7298 * These routines are responsible for expanding a /lost+found if it is 7299 * too small. 7300 */ 7301 7302struct expand_dir_struct { 7303 int num; 7304 int guaranteed_size; 7305 int newblocks; 7306 int last_block; 7307 errcode_t err; 7308 e2fsck_t ctx; 7309}; 7310 7311static int expand_dir_proc(ext2_filsys fs, 7312 blk_t *blocknr, 7313 e2_blkcnt_t blockcnt, 7314 blk_t ref_block FSCK_ATTR((unused)), 7315 int ref_offset FSCK_ATTR((unused)), 7316 void *priv_data) 7317{ 7318 struct expand_dir_struct *es = (struct expand_dir_struct *) priv_data; 7319 blk_t new_blk; 7320 static blk_t last_blk = 0; 7321 char *block; 7322 errcode_t retval; 7323 e2fsck_t ctx; 7324 7325 ctx = es->ctx; 7326 7327 if (es->guaranteed_size && blockcnt >= es->guaranteed_size) 7328 return BLOCK_ABORT; 7329 7330 if (blockcnt > 0) 7331 es->last_block = blockcnt; 7332 if (*blocknr) { 7333 last_blk = *blocknr; 7334 return 0; 7335 } 7336 retval = ext2fs_new_block(fs, last_blk, ctx->block_found_map, 7337 &new_blk); 7338 if (retval) { 7339 es->err = retval; 7340 return BLOCK_ABORT; 7341 } 7342 if (blockcnt > 0) { 7343 retval = ext2fs_new_dir_block(fs, 0, 0, &block); 7344 if (retval) { 7345 es->err = retval; 7346 return BLOCK_ABORT; 7347 } 7348 es->num--; 7349 retval = ext2fs_write_dir_block(fs, new_blk, block); 7350 } else { 7351 retval = ext2fs_get_mem(fs->blocksize, &block); 7352 if (retval) { 7353 es->err = retval; 7354 return BLOCK_ABORT; 7355 } 7356 memset(block, 0, fs->blocksize); 7357 retval = io_channel_write_blk(fs->io, new_blk, 1, block); 7358 } 7359 if (retval) { 7360 es->err = retval; 7361 return BLOCK_ABORT; 7362 } 7363 ext2fs_free_mem(&block); 7364 *blocknr = new_blk; 7365 ext2fs_mark_block_bitmap(ctx->block_found_map, new_blk); 7366 ext2fs_block_alloc_stats(fs, new_blk, +1); 7367 es->newblocks++; 7368 7369 if (es->num == 0) 7370 return (BLOCK_CHANGED | BLOCK_ABORT); 7371 else 7372 return BLOCK_CHANGED; 7373} 7374 7375errcode_t e2fsck_expand_directory(e2fsck_t ctx, ext2_ino_t dir, 7376 int num, int guaranteed_size) 7377{ 7378 ext2_filsys fs = ctx->fs; 7379 errcode_t retval; 7380 struct expand_dir_struct es; 7381 struct ext2_inode inode; 7382 7383 if (!(fs->flags & EXT2_FLAG_RW)) 7384 return EXT2_ET_RO_FILSYS; 7385 7386 /* 7387 * Read the inode and block bitmaps in; we'll be messing with 7388 * them. 7389 */ 7390 e2fsck_read_bitmaps(ctx); 7391 7392 retval = ext2fs_check_directory(fs, dir); 7393 if (retval) 7394 return retval; 7395 7396 es.num = num; 7397 es.guaranteed_size = guaranteed_size; 7398 es.last_block = 0; 7399 es.err = 0; 7400 es.newblocks = 0; 7401 es.ctx = ctx; 7402 7403 retval = ext2fs_block_iterate2(fs, dir, BLOCK_FLAG_APPEND, 7404 0, expand_dir_proc, &es); 7405 7406 if (es.err) 7407 return es.err; 7408 7409 /* 7410 * Update the size and block count fields in the inode. 7411 */ 7412 retval = ext2fs_read_inode(fs, dir, &inode); 7413 if (retval) 7414 return retval; 7415 7416 inode.i_size = (es.last_block + 1) * fs->blocksize; 7417 inode.i_blocks += (fs->blocksize / 512) * es.newblocks; 7418 7419 e2fsck_write_inode(ctx, dir, &inode, "expand_directory"); 7420 7421 return 0; 7422} 7423 7424/* 7425 * pass4.c -- pass #4 of e2fsck: Check reference counts 7426 * 7427 * Pass 4 frees the following data structures: 7428 * - A bitmap of which inodes are imagic inodes. (inode_imagic_map) 7429 */ 7430 7431/* 7432 * This routine is called when an inode is not connected to the 7433 * directory tree. 7434 * 7435 * This subroutine returns 1 then the caller shouldn't bother with the 7436 * rest of the pass 4 tests. 7437 */ 7438static int disconnect_inode(e2fsck_t ctx, ext2_ino_t i) 7439{ 7440 ext2_filsys fs = ctx->fs; 7441 struct ext2_inode inode; 7442 struct problem_context pctx; 7443 7444 e2fsck_read_inode(ctx, i, &inode, "pass4: disconnect_inode"); 7445 clear_problem_context(&pctx); 7446 pctx.ino = i; 7447 pctx.inode = &inode; 7448 7449 /* 7450 * Offer to delete any zero-length files that does not have 7451 * blocks. If there is an EA block, it might have useful 7452 * information, so we won't prompt to delete it, but let it be 7453 * reconnected to lost+found. 7454 */ 7455 if (!inode.i_blocks && (LINUX_S_ISREG(inode.i_mode) || 7456 LINUX_S_ISDIR(inode.i_mode))) { 7457 if (fix_problem(ctx, PR_4_ZERO_LEN_INODE, &pctx)) { 7458 ext2fs_icount_store(ctx->inode_link_info, i, 0); 7459 inode.i_links_count = 0; 7460 inode.i_dtime = time(0); 7461 e2fsck_write_inode(ctx, i, &inode, 7462 "disconnect_inode"); 7463 /* 7464 * Fix up the bitmaps... 7465 */ 7466 e2fsck_read_bitmaps(ctx); 7467 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, i); 7468 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, i); 7469 ext2fs_inode_alloc_stats2(fs, i, -1, 7470 LINUX_S_ISDIR(inode.i_mode)); 7471 return 0; 7472 } 7473 } 7474 7475 /* 7476 * Prompt to reconnect. 7477 */ 7478 if (fix_problem(ctx, PR_4_UNATTACHED_INODE, &pctx)) { 7479 if (e2fsck_reconnect_file(ctx, i)) 7480 ext2fs_unmark_valid(fs); 7481 } else { 7482 /* 7483 * If we don't attach the inode, then skip the 7484 * i_links_test since there's no point in trying to 7485 * force i_links_count to zero. 7486 */ 7487 ext2fs_unmark_valid(fs); 7488 return 1; 7489 } 7490 return 0; 7491} 7492 7493 7494static void e2fsck_pass4(e2fsck_t ctx) 7495{ 7496 ext2_filsys fs = ctx->fs; 7497 ext2_ino_t i; 7498 struct ext2_inode inode; 7499 struct problem_context pctx; 7500 __u16 link_count, link_counted; 7501 char *buf = 0; 7502 int group, maxgroup; 7503 7504 /* Pass 4 */ 7505 7506 clear_problem_context(&pctx); 7507 7508 if (!(ctx->options & E2F_OPT_PREEN)) 7509 fix_problem(ctx, PR_4_PASS_HEADER, &pctx); 7510 7511 group = 0; 7512 maxgroup = fs->group_desc_count; 7513 if (ctx->progress) 7514 if ((ctx->progress)(ctx, 4, 0, maxgroup)) 7515 return; 7516 7517 for (i=1; i <= fs->super->s_inodes_count; i++) { 7518 if (ctx->flags & E2F_FLAG_SIGNAL_MASK) 7519 return; 7520 if ((i % fs->super->s_inodes_per_group) == 0) { 7521 group++; 7522 if (ctx->progress) 7523 if ((ctx->progress)(ctx, 4, group, maxgroup)) 7524 return; 7525 } 7526 if (i == EXT2_BAD_INO || 7527 (i > EXT2_ROOT_INO && i < EXT2_FIRST_INODE(fs->super))) 7528 continue; 7529 if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map, i)) || 7530 (ctx->inode_imagic_map && 7531 ext2fs_test_inode_bitmap(ctx->inode_imagic_map, i))) 7532 continue; 7533 ext2fs_icount_fetch(ctx->inode_link_info, i, &link_count); 7534 ext2fs_icount_fetch(ctx->inode_count, i, &link_counted); 7535 if (link_counted == 0) { 7536 if (!buf) 7537 buf = e2fsck_allocate_memory(ctx, 7538 fs->blocksize, "bad_inode buffer"); 7539 if (e2fsck_process_bad_inode(ctx, 0, i, buf)) 7540 continue; 7541 if (disconnect_inode(ctx, i)) 7542 continue; 7543 ext2fs_icount_fetch(ctx->inode_link_info, i, 7544 &link_count); 7545 ext2fs_icount_fetch(ctx->inode_count, i, 7546 &link_counted); 7547 } 7548 if (link_counted != link_count) { 7549 e2fsck_read_inode(ctx, i, &inode, "pass4"); 7550 pctx.ino = i; 7551 pctx.inode = &inode; 7552 if (link_count != inode.i_links_count) { 7553 pctx.num = link_count; 7554 fix_problem(ctx, 7555 PR_4_INCONSISTENT_COUNT, &pctx); 7556 } 7557 pctx.num = link_counted; 7558 if (fix_problem(ctx, PR_4_BAD_REF_COUNT, &pctx)) { 7559 inode.i_links_count = link_counted; 7560 e2fsck_write_inode(ctx, i, &inode, "pass4"); 7561 } 7562 } 7563 } 7564 ext2fs_free_icount(ctx->inode_link_info); ctx->inode_link_info = 0; 7565 ext2fs_free_icount(ctx->inode_count); ctx->inode_count = 0; 7566 ext2fs_free_inode_bitmap(ctx->inode_imagic_map); 7567 ctx->inode_imagic_map = 0; 7568 ext2fs_free_mem(&buf); 7569} 7570 7571/* 7572 * pass5.c --- check block and inode bitmaps against on-disk bitmaps 7573 */ 7574 7575#define NO_BLK ((blk_t) -1) 7576 7577static void print_bitmap_problem(e2fsck_t ctx, int problem, 7578 struct problem_context *pctx) 7579{ 7580 switch (problem) { 7581 case PR_5_BLOCK_UNUSED: 7582 if (pctx->blk == pctx->blk2) 7583 pctx->blk2 = 0; 7584 else 7585 problem = PR_5_BLOCK_RANGE_UNUSED; 7586 break; 7587 case PR_5_BLOCK_USED: 7588 if (pctx->blk == pctx->blk2) 7589 pctx->blk2 = 0; 7590 else 7591 problem = PR_5_BLOCK_RANGE_USED; 7592 break; 7593 case PR_5_INODE_UNUSED: 7594 if (pctx->ino == pctx->ino2) 7595 pctx->ino2 = 0; 7596 else 7597 problem = PR_5_INODE_RANGE_UNUSED; 7598 break; 7599 case PR_5_INODE_USED: 7600 if (pctx->ino == pctx->ino2) 7601 pctx->ino2 = 0; 7602 else 7603 problem = PR_5_INODE_RANGE_USED; 7604 break; 7605 } 7606 fix_problem(ctx, problem, pctx); 7607 pctx->blk = pctx->blk2 = NO_BLK; 7608 pctx->ino = pctx->ino2 = 0; 7609} 7610 7611static void check_block_bitmaps(e2fsck_t ctx) 7612{ 7613 ext2_filsys fs = ctx->fs; 7614 blk_t i; 7615 int *free_array; 7616 int group = 0; 7617 unsigned int blocks = 0; 7618 unsigned int free_blocks = 0; 7619 int group_free = 0; 7620 int actual, bitmap; 7621 struct problem_context pctx; 7622 int problem, save_problem, fixit, had_problem; 7623 errcode_t retval; 7624 7625 clear_problem_context(&pctx); 7626 free_array = (int *) e2fsck_allocate_memory(ctx, 7627 fs->group_desc_count * sizeof(int), "free block count array"); 7628 7629 if ((fs->super->s_first_data_block < 7630 ext2fs_get_block_bitmap_start(ctx->block_found_map)) || 7631 (fs->super->s_blocks_count-1 > 7632 ext2fs_get_block_bitmap_end(ctx->block_found_map))) { 7633 pctx.num = 1; 7634 pctx.blk = fs->super->s_first_data_block; 7635 pctx.blk2 = fs->super->s_blocks_count -1; 7636 pctx.ino = ext2fs_get_block_bitmap_start(ctx->block_found_map); 7637 pctx.ino2 = ext2fs_get_block_bitmap_end(ctx->block_found_map); 7638 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx); 7639 7640 ctx->flags |= E2F_FLAG_ABORT; /* fatal */ 7641 return; 7642 } 7643 7644 if ((fs->super->s_first_data_block < 7645 ext2fs_get_block_bitmap_start(fs->block_map)) || 7646 (fs->super->s_blocks_count-1 > 7647 ext2fs_get_block_bitmap_end(fs->block_map))) { 7648 pctx.num = 2; 7649 pctx.blk = fs->super->s_first_data_block; 7650 pctx.blk2 = fs->super->s_blocks_count -1; 7651 pctx.ino = ext2fs_get_block_bitmap_start(fs->block_map); 7652 pctx.ino2 = ext2fs_get_block_bitmap_end(fs->block_map); 7653 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx); 7654 7655 ctx->flags |= E2F_FLAG_ABORT; /* fatal */ 7656 return; 7657 } 7658 7659redo_counts: 7660 had_problem = 0; 7661 save_problem = 0; 7662 pctx.blk = pctx.blk2 = NO_BLK; 7663 for (i = fs->super->s_first_data_block; 7664 i < fs->super->s_blocks_count; 7665 i++) { 7666 actual = ext2fs_fast_test_block_bitmap(ctx->block_found_map, i); 7667 bitmap = ext2fs_fast_test_block_bitmap(fs->block_map, i); 7668 7669 if (actual == bitmap) 7670 goto do_counts; 7671 7672 if (!actual && bitmap) { 7673 /* 7674 * Block not used, but marked in use in the bitmap. 7675 */ 7676 problem = PR_5_BLOCK_UNUSED; 7677 } else { 7678 /* 7679 * Block used, but not marked in use in the bitmap. 7680 */ 7681 problem = PR_5_BLOCK_USED; 7682 } 7683 if (pctx.blk == NO_BLK) { 7684 pctx.blk = pctx.blk2 = i; 7685 save_problem = problem; 7686 } else { 7687 if ((problem == save_problem) && 7688 (pctx.blk2 == i-1)) 7689 pctx.blk2++; 7690 else { 7691 print_bitmap_problem(ctx, save_problem, &pctx); 7692 pctx.blk = pctx.blk2 = i; 7693 save_problem = problem; 7694 } 7695 } 7696 ctx->flags |= E2F_FLAG_PROG_SUPPRESS; 7697 had_problem++; 7698 7699 do_counts: 7700 if (!bitmap) { 7701 group_free++; 7702 free_blocks++; 7703 } 7704 blocks ++; 7705 if ((blocks == fs->super->s_blocks_per_group) || 7706 (i == fs->super->s_blocks_count-1)) { 7707 free_array[group] = group_free; 7708 group ++; 7709 blocks = 0; 7710 group_free = 0; 7711 if (ctx->progress) 7712 if ((ctx->progress)(ctx, 5, group, 7713 fs->group_desc_count*2)) 7714 return; 7715 } 7716 } 7717 if (pctx.blk != NO_BLK) 7718 print_bitmap_problem(ctx, save_problem, &pctx); 7719 if (had_problem) 7720 fixit = end_problem_latch(ctx, PR_LATCH_BBITMAP); 7721 else 7722 fixit = -1; 7723 ctx->flags &= ~E2F_FLAG_PROG_SUPPRESS; 7724 7725 if (fixit == 1) { 7726 ext2fs_free_block_bitmap(fs->block_map); 7727 retval = ext2fs_copy_bitmap(ctx->block_found_map, 7728 &fs->block_map); 7729 if (retval) { 7730 clear_problem_context(&pctx); 7731 fix_problem(ctx, PR_5_COPY_BBITMAP_ERROR, &pctx); 7732 ctx->flags |= E2F_FLAG_ABORT; 7733 return; 7734 } 7735 ext2fs_set_bitmap_padding(fs->block_map); 7736 ext2fs_mark_bb_dirty(fs); 7737 7738 /* Redo the counts */ 7739 blocks = 0; free_blocks = 0; group_free = 0; group = 0; 7740 memset(free_array, 0, fs->group_desc_count * sizeof(int)); 7741 goto redo_counts; 7742 } else if (fixit == 0) 7743 ext2fs_unmark_valid(fs); 7744 7745 for (i = 0; i < fs->group_desc_count; i++) { 7746 if (free_array[i] != fs->group_desc[i].bg_free_blocks_count) { 7747 pctx.group = i; 7748 pctx.blk = fs->group_desc[i].bg_free_blocks_count; 7749 pctx.blk2 = free_array[i]; 7750 7751 if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT_GROUP, 7752 &pctx)) { 7753 fs->group_desc[i].bg_free_blocks_count = 7754 free_array[i]; 7755 ext2fs_mark_super_dirty(fs); 7756 } else 7757 ext2fs_unmark_valid(fs); 7758 } 7759 } 7760 if (free_blocks != fs->super->s_free_blocks_count) { 7761 pctx.group = 0; 7762 pctx.blk = fs->super->s_free_blocks_count; 7763 pctx.blk2 = free_blocks; 7764 7765 if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT, &pctx)) { 7766 fs->super->s_free_blocks_count = free_blocks; 7767 ext2fs_mark_super_dirty(fs); 7768 } else 7769 ext2fs_unmark_valid(fs); 7770 } 7771 ext2fs_free_mem(&free_array); 7772} 7773 7774static void check_inode_bitmaps(e2fsck_t ctx) 7775{ 7776 ext2_filsys fs = ctx->fs; 7777 ext2_ino_t i; 7778 unsigned int free_inodes = 0; 7779 int group_free = 0; 7780 int dirs_count = 0; 7781 int group = 0; 7782 unsigned int inodes = 0; 7783 int *free_array; 7784 int *dir_array; 7785 int actual, bitmap; 7786 errcode_t retval; 7787 struct problem_context pctx; 7788 int problem, save_problem, fixit, had_problem; 7789 7790 clear_problem_context(&pctx); 7791 free_array = (int *) e2fsck_allocate_memory(ctx, 7792 fs->group_desc_count * sizeof(int), "free inode count array"); 7793 7794 dir_array = (int *) e2fsck_allocate_memory(ctx, 7795 fs->group_desc_count * sizeof(int), "directory count array"); 7796 7797 if ((1 < ext2fs_get_inode_bitmap_start(ctx->inode_used_map)) || 7798 (fs->super->s_inodes_count > 7799 ext2fs_get_inode_bitmap_end(ctx->inode_used_map))) { 7800 pctx.num = 3; 7801 pctx.blk = 1; 7802 pctx.blk2 = fs->super->s_inodes_count; 7803 pctx.ino = ext2fs_get_inode_bitmap_start(ctx->inode_used_map); 7804 pctx.ino2 = ext2fs_get_inode_bitmap_end(ctx->inode_used_map); 7805 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx); 7806 7807 ctx->flags |= E2F_FLAG_ABORT; /* fatal */ 7808 return; 7809 } 7810 if ((1 < ext2fs_get_inode_bitmap_start(fs->inode_map)) || 7811 (fs->super->s_inodes_count > 7812 ext2fs_get_inode_bitmap_end(fs->inode_map))) { 7813 pctx.num = 4; 7814 pctx.blk = 1; 7815 pctx.blk2 = fs->super->s_inodes_count; 7816 pctx.ino = ext2fs_get_inode_bitmap_start(fs->inode_map); 7817 pctx.ino2 = ext2fs_get_inode_bitmap_end(fs->inode_map); 7818 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx); 7819 7820 ctx->flags |= E2F_FLAG_ABORT; /* fatal */ 7821 return; 7822 } 7823 7824redo_counts: 7825 had_problem = 0; 7826 save_problem = 0; 7827 pctx.ino = pctx.ino2 = 0; 7828 for (i = 1; i <= fs->super->s_inodes_count; i++) { 7829 actual = ext2fs_fast_test_inode_bitmap(ctx->inode_used_map, i); 7830 bitmap = ext2fs_fast_test_inode_bitmap(fs->inode_map, i); 7831 7832 if (actual == bitmap) 7833 goto do_counts; 7834 7835 if (!actual && bitmap) { 7836 /* 7837 * Inode wasn't used, but marked in bitmap 7838 */ 7839 problem = PR_5_INODE_UNUSED; 7840 } else /* if (actual && !bitmap) */ { 7841 /* 7842 * Inode used, but not in bitmap 7843 */ 7844 problem = PR_5_INODE_USED; 7845 } 7846 if (pctx.ino == 0) { 7847 pctx.ino = pctx.ino2 = i; 7848 save_problem = problem; 7849 } else { 7850 if ((problem == save_problem) && 7851 (pctx.ino2 == i-1)) 7852 pctx.ino2++; 7853 else { 7854 print_bitmap_problem(ctx, save_problem, &pctx); 7855 pctx.ino = pctx.ino2 = i; 7856 save_problem = problem; 7857 } 7858 } 7859 ctx->flags |= E2F_FLAG_PROG_SUPPRESS; 7860 had_problem++; 7861 7862do_counts: 7863 if (!bitmap) { 7864 group_free++; 7865 free_inodes++; 7866 } else { 7867 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, i)) 7868 dirs_count++; 7869 } 7870 inodes++; 7871 if ((inodes == fs->super->s_inodes_per_group) || 7872 (i == fs->super->s_inodes_count)) { 7873 free_array[group] = group_free; 7874 dir_array[group] = dirs_count; 7875 group ++; 7876 inodes = 0; 7877 group_free = 0; 7878 dirs_count = 0; 7879 if (ctx->progress) 7880 if ((ctx->progress)(ctx, 5, 7881 group + fs->group_desc_count, 7882 fs->group_desc_count*2)) 7883 return; 7884 } 7885 } 7886 if (pctx.ino) 7887 print_bitmap_problem(ctx, save_problem, &pctx); 7888 7889 if (had_problem) 7890 fixit = end_problem_latch(ctx, PR_LATCH_IBITMAP); 7891 else 7892 fixit = -1; 7893 ctx->flags &= ~E2F_FLAG_PROG_SUPPRESS; 7894 7895 if (fixit == 1) { 7896 ext2fs_free_inode_bitmap(fs->inode_map); 7897 retval = ext2fs_copy_bitmap(ctx->inode_used_map, 7898 &fs->inode_map); 7899 if (retval) { 7900 clear_problem_context(&pctx); 7901 fix_problem(ctx, PR_5_COPY_IBITMAP_ERROR, &pctx); 7902 ctx->flags |= E2F_FLAG_ABORT; 7903 return; 7904 } 7905 ext2fs_set_bitmap_padding(fs->inode_map); 7906 ext2fs_mark_ib_dirty(fs); 7907 7908 /* redo counts */ 7909 inodes = 0; free_inodes = 0; group_free = 0; 7910 dirs_count = 0; group = 0; 7911 memset(free_array, 0, fs->group_desc_count * sizeof(int)); 7912 memset(dir_array, 0, fs->group_desc_count * sizeof(int)); 7913 goto redo_counts; 7914 } else if (fixit == 0) 7915 ext2fs_unmark_valid(fs); 7916 7917 for (i = 0; i < fs->group_desc_count; i++) { 7918 if (free_array[i] != fs->group_desc[i].bg_free_inodes_count) { 7919 pctx.group = i; 7920 pctx.ino = fs->group_desc[i].bg_free_inodes_count; 7921 pctx.ino2 = free_array[i]; 7922 if (fix_problem(ctx, PR_5_FREE_INODE_COUNT_GROUP, 7923 &pctx)) { 7924 fs->group_desc[i].bg_free_inodes_count = 7925 free_array[i]; 7926 ext2fs_mark_super_dirty(fs); 7927 } else 7928 ext2fs_unmark_valid(fs); 7929 } 7930 if (dir_array[i] != fs->group_desc[i].bg_used_dirs_count) { 7931 pctx.group = i; 7932 pctx.ino = fs->group_desc[i].bg_used_dirs_count; 7933 pctx.ino2 = dir_array[i]; 7934 7935 if (fix_problem(ctx, PR_5_FREE_DIR_COUNT_GROUP, 7936 &pctx)) { 7937 fs->group_desc[i].bg_used_dirs_count = 7938 dir_array[i]; 7939 ext2fs_mark_super_dirty(fs); 7940 } else 7941 ext2fs_unmark_valid(fs); 7942 } 7943 } 7944 if (free_inodes != fs->super->s_free_inodes_count) { 7945 pctx.group = -1; 7946 pctx.ino = fs->super->s_free_inodes_count; 7947 pctx.ino2 = free_inodes; 7948 7949 if (fix_problem(ctx, PR_5_FREE_INODE_COUNT, &pctx)) { 7950 fs->super->s_free_inodes_count = free_inodes; 7951 ext2fs_mark_super_dirty(fs); 7952 } else 7953 ext2fs_unmark_valid(fs); 7954 } 7955 ext2fs_free_mem(&free_array); 7956 ext2fs_free_mem(&dir_array); 7957} 7958 7959static void check_inode_end(e2fsck_t ctx) 7960{ 7961 ext2_filsys fs = ctx->fs; 7962 ext2_ino_t end, save_inodes_count, i; 7963 struct problem_context pctx; 7964 7965 clear_problem_context(&pctx); 7966 7967 end = EXT2_INODES_PER_GROUP(fs->super) * fs->group_desc_count; 7968 pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map, end, 7969 &save_inodes_count); 7970 if (pctx.errcode) { 7971 pctx.num = 1; 7972 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx); 7973 ctx->flags |= E2F_FLAG_ABORT; /* fatal */ 7974 return; 7975 } 7976 if (save_inodes_count == end) 7977 return; 7978 7979 for (i = save_inodes_count + 1; i <= end; i++) { 7980 if (!ext2fs_test_inode_bitmap(fs->inode_map, i)) { 7981 if (fix_problem(ctx, PR_5_INODE_BMAP_PADDING, &pctx)) { 7982 for (i = save_inodes_count + 1; i <= end; i++) 7983 ext2fs_mark_inode_bitmap(fs->inode_map, 7984 i); 7985 ext2fs_mark_ib_dirty(fs); 7986 } else 7987 ext2fs_unmark_valid(fs); 7988 break; 7989 } 7990 } 7991 7992 pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map, 7993 save_inodes_count, 0); 7994 if (pctx.errcode) { 7995 pctx.num = 2; 7996 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx); 7997 ctx->flags |= E2F_FLAG_ABORT; /* fatal */ 7998 return; 7999 } 8000} 8001 8002static void check_block_end(e2fsck_t ctx) 8003{ 8004 ext2_filsys fs = ctx->fs; 8005 blk_t end, save_blocks_count, i; 8006 struct problem_context pctx; 8007 8008 clear_problem_context(&pctx); 8009 8010 end = fs->block_map->start + 8011 (EXT2_BLOCKS_PER_GROUP(fs->super) * fs->group_desc_count) - 1; 8012 pctx.errcode = ext2fs_fudge_block_bitmap_end(fs->block_map, end, 8013 &save_blocks_count); 8014 if (pctx.errcode) { 8015 pctx.num = 3; 8016 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx); 8017 ctx->flags |= E2F_FLAG_ABORT; /* fatal */ 8018 return; 8019 } 8020 if (save_blocks_count == end) 8021 return; 8022 8023 for (i = save_blocks_count + 1; i <= end; i++) { 8024 if (!ext2fs_test_block_bitmap(fs->block_map, i)) { 8025 if (fix_problem(ctx, PR_5_BLOCK_BMAP_PADDING, &pctx)) { 8026 for (i = save_blocks_count + 1; i <= end; i++) 8027 ext2fs_mark_block_bitmap(fs->block_map, 8028 i); 8029 ext2fs_mark_bb_dirty(fs); 8030 } else 8031 ext2fs_unmark_valid(fs); 8032 break; 8033 } 8034 } 8035 8036 pctx.errcode = ext2fs_fudge_block_bitmap_end(fs->block_map, 8037 save_blocks_count, 0); 8038 if (pctx.errcode) { 8039 pctx.num = 4; 8040 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx); 8041 ctx->flags |= E2F_FLAG_ABORT; /* fatal */ 8042 return; 8043 } 8044} 8045 8046static void e2fsck_pass5(e2fsck_t ctx) 8047{ 8048 struct problem_context pctx; 8049 8050 /* Pass 5 */ 8051 8052 clear_problem_context(&pctx); 8053 8054 if (!(ctx->options & E2F_OPT_PREEN)) 8055 fix_problem(ctx, PR_5_PASS_HEADER, &pctx); 8056 8057 if (ctx->progress) 8058 if ((ctx->progress)(ctx, 5, 0, ctx->fs->group_desc_count*2)) 8059 return; 8060 8061 e2fsck_read_bitmaps(ctx); 8062 8063 check_block_bitmaps(ctx); 8064 if (ctx->flags & E2F_FLAG_SIGNAL_MASK) 8065 return; 8066 check_inode_bitmaps(ctx); 8067 if (ctx->flags & E2F_FLAG_SIGNAL_MASK) 8068 return; 8069 check_inode_end(ctx); 8070 if (ctx->flags & E2F_FLAG_SIGNAL_MASK) 8071 return; 8072 check_block_end(ctx); 8073 if (ctx->flags & E2F_FLAG_SIGNAL_MASK) 8074 return; 8075 8076 ext2fs_free_inode_bitmap(ctx->inode_used_map); 8077 ctx->inode_used_map = 0; 8078 ext2fs_free_inode_bitmap(ctx->inode_dir_map); 8079 ctx->inode_dir_map = 0; 8080 ext2fs_free_block_bitmap(ctx->block_found_map); 8081 ctx->block_found_map = 0; 8082} 8083 8084/* 8085 * problem.c --- report filesystem problems to the user 8086 */ 8087 8088#define PR_PREEN_OK 0x000001 /* Don't need to do preenhalt */ 8089#define PR_NO_OK 0x000002 /* If user answers no, don't make fs invalid */ 8090#define PR_NO_DEFAULT 0x000004 /* Default to no */ 8091#define PR_MSG_ONLY 0x000008 /* Print message only */ 8092 8093/* Bit positions 0x000ff0 are reserved for the PR_LATCH flags */ 8094 8095#define PR_FATAL 0x001000 /* Fatal error */ 8096#define PR_AFTER_CODE 0x002000 /* After asking the first question, */ 8097 /* ask another */ 8098#define PR_PREEN_NOMSG 0x004000 /* Don't print a message if we're preening */ 8099#define PR_NOCOLLATE 0x008000 /* Don't collate answers for this latch */ 8100#define PR_NO_NOMSG 0x010000 /* Don't print a message if e2fsck -n */ 8101#define PR_PREEN_NO 0x020000 /* Use No as an answer if preening */ 8102#define PR_PREEN_NOHDR 0x040000 /* Don't print the preen header */ 8103 8104 8105#define PROMPT_NONE 0 8106#define PROMPT_FIX 1 8107#define PROMPT_CLEAR 2 8108#define PROMPT_RELOCATE 3 8109#define PROMPT_ALLOCATE 4 8110#define PROMPT_EXPAND 5 8111#define PROMPT_CONNECT 6 8112#define PROMPT_CREATE 7 8113#define PROMPT_SALVAGE 8 8114#define PROMPT_TRUNCATE 9 8115#define PROMPT_CLEAR_INODE 10 8116#define PROMPT_ABORT 11 8117#define PROMPT_SPLIT 12 8118#define PROMPT_CONTINUE 13 8119#define PROMPT_CLONE 14 8120#define PROMPT_DELETE 15 8121#define PROMPT_SUPPRESS 16 8122#define PROMPT_UNLINK 17 8123#define PROMPT_CLEAR_HTREE 18 8124#define PROMPT_RECREATE 19 8125#define PROMPT_NULL 20 8126 8127struct e2fsck_problem { 8128 problem_t e2p_code; 8129 const char * e2p_description; 8130 char prompt; 8131 int flags; 8132 problem_t second_code; 8133}; 8134 8135struct latch_descr { 8136 int latch_code; 8137 problem_t question; 8138 problem_t end_message; 8139 int flags; 8140}; 8141 8142/* 8143 * These are the prompts which are used to ask the user if they want 8144 * to fix a problem. 8145 */ 8146static const char *const prompt[] = { 8147 N_("(no prompt)"), /* 0 */ 8148 N_("Fix"), /* 1 */ 8149 N_("Clear"), /* 2 */ 8150 N_("Relocate"), /* 3 */ 8151 N_("Allocate"), /* 4 */ 8152 N_("Expand"), /* 5 */ 8153 N_("Connect to /lost+found"), /* 6 */ 8154 N_("Create"), /* 7 */ 8155 N_("Salvage"), /* 8 */ 8156 N_("Truncate"), /* 9 */ 8157 N_("Clear inode"), /* 10 */ 8158 N_("Abort"), /* 11 */ 8159 N_("Split"), /* 12 */ 8160 N_("Continue"), /* 13 */ 8161 N_("Clone multiply-claimed blocks"), /* 14 */ 8162 N_("Delete file"), /* 15 */ 8163 N_("Suppress messages"),/* 16 */ 8164 N_("Unlink"), /* 17 */ 8165 N_("Clear HTree index"),/* 18 */ 8166 N_("Recreate"), /* 19 */ 8167 "", /* 20 */ 8168}; 8169 8170/* 8171 * These messages are printed when we are preen mode and we will be 8172 * automatically fixing the problem. 8173 */ 8174static const char *const preen_msg[] = { 8175 N_("(NONE)"), /* 0 */ 8176 N_("FIXED"), /* 1 */ 8177 N_("CLEARED"), /* 2 */ 8178 N_("RELOCATED"), /* 3 */ 8179 N_("ALLOCATED"), /* 4 */ 8180 N_("EXPANDED"), /* 5 */ 8181 N_("RECONNECTED"), /* 6 */ 8182 N_("CREATED"), /* 7 */ 8183 N_("SALVAGED"), /* 8 */ 8184 N_("TRUNCATED"), /* 9 */ 8185 N_("INODE CLEARED"), /* 10 */ 8186 N_("ABORTED"), /* 11 */ 8187 N_("SPLIT"), /* 12 */ 8188 N_("CONTINUING"), /* 13 */ 8189 N_("MULTIPLY-CLAIMED BLOCKS CLONED"), /* 14 */ 8190 N_("FILE DELETED"), /* 15 */ 8191 N_("SUPPRESSED"), /* 16 */ 8192 N_("UNLINKED"), /* 17 */ 8193 N_("HTREE INDEX CLEARED"),/* 18 */ 8194 N_("WILL RECREATE"), /* 19 */ 8195 "", /* 20 */ 8196}; 8197 8198static const struct e2fsck_problem problem_table[] = { 8199 8200 /* Pre-Pass 1 errors */ 8201 8202 /* Block bitmap not in group */ 8203 { PR_0_BB_NOT_GROUP, N_("@b @B for @g %g is not in @g. (@b %b)\n"), 8204 PROMPT_RELOCATE, PR_LATCH_RELOC }, 8205 8206 /* Inode bitmap not in group */ 8207 { PR_0_IB_NOT_GROUP, N_("@i @B for @g %g is not in @g. (@b %b)\n"), 8208 PROMPT_RELOCATE, PR_LATCH_RELOC }, 8209 8210 /* Inode table not in group */ 8211 { PR_0_ITABLE_NOT_GROUP, 8212 N_("@i table for @g %g is not in @g. (@b %b)\n" 8213 "WARNING: SEVERE DATA LOSS POSSIBLE.\n"), 8214 PROMPT_RELOCATE, PR_LATCH_RELOC }, 8215 8216 /* Superblock corrupt */ 8217 { PR_0_SB_CORRUPT, 8218 N_("\nThe @S could not be read or does not describe a correct ext2\n" 8219 "@f. If the @v is valid and it really contains an ext2\n" 8220 "@f (and not swap or ufs or something else), then the @S\n" 8221 "is corrupt, and you might try running e2fsck with an alternate @S:\n" 8222 " e2fsck -b %S <@v>\n\n"), 8223 PROMPT_NONE, PR_FATAL }, 8224 8225 /* Filesystem size is wrong */ 8226 { PR_0_FS_SIZE_WRONG, 8227 N_("The @f size (according to the @S) is %b @bs\n" 8228 "The physical size of the @v is %c @bs\n" 8229 "Either the @S or the partition table is likely to be corrupt!\n"), 8230 PROMPT_ABORT, 0 }, 8231 8232 /* Fragments not supported */ 8233 { PR_0_NO_FRAGMENTS, 8234 N_("@S @b_size = %b, fragsize = %c.\n" 8235 "This version of e2fsck does not support fragment sizes different\n" 8236 "from the @b size.\n"), 8237 PROMPT_NONE, PR_FATAL }, 8238 8239 /* Bad blocks_per_group */ 8240 { PR_0_BLOCKS_PER_GROUP, 8241 N_("@S @bs_per_group = %b, should have been %c\n"), 8242 PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT }, 8243 8244 /* Bad first_data_block */ 8245 { PR_0_FIRST_DATA_BLOCK, 8246 N_("@S first_data_@b = %b, should have been %c\n"), 8247 PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT }, 8248 8249 /* Adding UUID to filesystem */ 8250 { PR_0_ADD_UUID, 8251 N_("@f did not have a UUID; generating one.\n\n"), 8252 PROMPT_NONE, 0 }, 8253 8254 /* Relocate hint */ 8255 { PR_0_RELOCATE_HINT, 8256 N_("Note: if several inode or block bitmap blocks or part\n" 8257 "of the inode table require relocation, you may wish to try\n" 8258 "running e2fsck with the '-b %S' option first. The problem\n" 8259 "may lie only with the primary block group descriptors, and\n" 8260 "the backup block group descriptors may be OK.\n\n"), 8261 PROMPT_NONE, PR_PREEN_OK | PR_NOCOLLATE }, 8262 8263 /* Miscellaneous superblock corruption */ 8264 { PR_0_MISC_CORRUPT_SUPER, 8265 N_("Corruption found in @S. (%s = %N).\n"), 8266 PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT }, 8267 8268 /* Error determing physical device size of filesystem */ 8269 { PR_0_GETSIZE_ERROR, 8270 N_("Error determining size of the physical @v: %m\n"), 8271 PROMPT_NONE, PR_FATAL }, 8272 8273 /* Inode count in superblock is incorrect */ 8274 { PR_0_INODE_COUNT_WRONG, 8275 N_("@i count in @S is %i, @s %j.\n"), 8276 PROMPT_FIX, 0 }, 8277 8278 { PR_0_HURD_CLEAR_FILETYPE, 8279 N_("The Hurd does not support the filetype feature.\n"), 8280 PROMPT_CLEAR, 0 }, 8281 8282 /* Journal inode is invalid */ 8283 { PR_0_JOURNAL_BAD_INODE, 8284 N_("@S has an @n ext3 @j (@i %i).\n"), 8285 PROMPT_CLEAR, PR_PREEN_OK }, 8286 8287 /* The external journal has (unsupported) multiple filesystems */ 8288 { PR_0_JOURNAL_UNSUPP_MULTIFS, 8289 N_("External @j has multiple @f users (unsupported).\n"), 8290 PROMPT_NONE, PR_FATAL }, 8291 8292 /* Can't find external journal */ 8293 { PR_0_CANT_FIND_JOURNAL, 8294 N_("Can't find external @j\n"), 8295 PROMPT_NONE, PR_FATAL }, 8296 8297 /* External journal has bad superblock */ 8298 { PR_0_EXT_JOURNAL_BAD_SUPER, 8299 N_("External @j has bad @S\n"), 8300 PROMPT_NONE, PR_FATAL }, 8301 8302 /* Superblock has a bad journal UUID */ 8303 { PR_0_JOURNAL_BAD_UUID, 8304 N_("External @j does not support this @f\n"), 8305 PROMPT_NONE, PR_FATAL }, 8306 8307 /* Journal has an unknown superblock type */ 8308 { PR_0_JOURNAL_UNSUPP_SUPER, 8309 N_("Ext3 @j @S is unknown type %N (unsupported).\n" 8310 "It is likely that your copy of e2fsck is old and/or doesn't " 8311 "support this @j format.\n" 8312 "It is also possible the @j @S is corrupt.\n"), 8313 PROMPT_ABORT, PR_NO_OK | PR_AFTER_CODE, PR_0_JOURNAL_BAD_SUPER }, 8314 8315 /* Journal superblock is corrupt */ 8316 { PR_0_JOURNAL_BAD_SUPER, 8317 N_("Ext3 @j @S is corrupt.\n"), 8318 PROMPT_FIX, PR_PREEN_OK }, 8319 8320 /* Superblock flag should be cleared */ 8321 { PR_0_JOURNAL_HAS_JOURNAL, 8322 N_("@S doesn't have has_@j flag, but has ext3 @j %s.\n"), 8323 PROMPT_CLEAR, PR_PREEN_OK }, 8324 8325 /* Superblock flag is incorrect */ 8326 { PR_0_JOURNAL_RECOVER_SET, 8327 N_("@S has ext3 needs_recovery flag set, but no @j.\n"), 8328 PROMPT_CLEAR, PR_PREEN_OK }, 8329 8330 /* Journal has data, but recovery flag is clear */ 8331 { PR_0_JOURNAL_RECOVERY_CLEAR, 8332 N_("ext3 recovery flag is clear, but @j has data.\n"), 8333 PROMPT_NONE, 0 }, 8334 8335 /* Ask if we should clear the journal */ 8336 { PR_0_JOURNAL_RESET_JOURNAL, 8337 N_("Clear @j"), 8338 PROMPT_NULL, PR_PREEN_NOMSG }, 8339 8340 /* Ask if we should run the journal anyway */ 8341 { PR_0_JOURNAL_RUN, 8342 N_("Run @j anyway"), 8343 PROMPT_NULL, 0 }, 8344 8345 /* Run the journal by default */ 8346 { PR_0_JOURNAL_RUN_DEFAULT, 8347 N_("Recovery flag not set in backup @S, so running @j anyway.\n"), 8348 PROMPT_NONE, 0 }, 8349 8350 /* Clearing orphan inode */ 8351 { PR_0_ORPHAN_CLEAR_INODE, 8352 N_("%s @o @i %i (uid=%Iu, gid=%Ig, mode=%Im, size=%Is)\n"), 8353 PROMPT_NONE, 0 }, 8354 8355 /* Illegal block found in orphaned inode */ 8356 { PR_0_ORPHAN_ILLEGAL_BLOCK_NUM, 8357 N_("@I @b #%B (%b) found in @o @i %i.\n"), 8358 PROMPT_NONE, 0 }, 8359 8360 /* Already cleared block found in orphaned inode */ 8361 { PR_0_ORPHAN_ALREADY_CLEARED_BLOCK, 8362 N_("Already cleared @b #%B (%b) found in @o @i %i.\n"), 8363 PROMPT_NONE, 0 }, 8364 8365 /* Illegal orphan inode in superblock */ 8366 { PR_0_ORPHAN_ILLEGAL_HEAD_INODE, 8367 N_("@I @o @i %i in @S.\n"), 8368 PROMPT_NONE, 0 }, 8369 8370 /* Illegal inode in orphaned inode list */ 8371 { PR_0_ORPHAN_ILLEGAL_INODE, 8372 N_("@I @i %i in @o @i list.\n"), 8373 PROMPT_NONE, 0 }, 8374 8375 /* Filesystem revision is 0, but feature flags are set */ 8376 { PR_0_FS_REV_LEVEL, 8377 N_("@f has feature flag(s) set, but is a revision 0 @f. "), 8378 PROMPT_FIX, PR_PREEN_OK | PR_NO_OK }, 8379 8380 /* Journal superblock has an unknown read-only feature flag set */ 8381 { PR_0_JOURNAL_UNSUPP_ROCOMPAT, 8382 N_("Ext3 @j @S has an unknown read-only feature flag set.\n"), 8383 PROMPT_ABORT, 0 }, 8384 8385 /* Journal superblock has an unknown incompatible feature flag set */ 8386 { PR_0_JOURNAL_UNSUPP_INCOMPAT, 8387 N_("Ext3 @j @S has an unknown incompatible feature flag set.\n"), 8388 PROMPT_ABORT, 0 }, 8389 8390 /* Journal has unsupported version number */ 8391 { PR_0_JOURNAL_UNSUPP_VERSION, 8392 N_("@j version not supported by this e2fsck.\n"), 8393 PROMPT_ABORT, 0 }, 8394 8395 /* Moving journal to hidden file */ 8396 { PR_0_MOVE_JOURNAL, 8397 N_("Moving @j from /%s to hidden @i.\n\n"), 8398 PROMPT_NONE, 0 }, 8399 8400 /* Error moving journal to hidden file */ 8401 { PR_0_ERR_MOVE_JOURNAL, 8402 N_("Error moving @j: %m\n\n"), 8403 PROMPT_NONE, 0 }, 8404 8405 /* Clearing V2 journal superblock */ 8406 { PR_0_CLEAR_V2_JOURNAL, 8407 N_("Found @n V2 @j @S fields (from V1 @j).\n" 8408 "Clearing fields beyond the V1 @j @S...\n\n"), 8409 PROMPT_NONE, 0 }, 8410 8411 /* Backup journal inode blocks */ 8412 { PR_0_BACKUP_JNL, 8413 N_("Backing up @j @i @b information.\n\n"), 8414 PROMPT_NONE, 0 }, 8415 8416 /* Reserved blocks w/o resize_inode */ 8417 { PR_0_NONZERO_RESERVED_GDT_BLOCKS, 8418 N_("@f does not have resize_@i enabled, but s_reserved_gdt_@bs\n" 8419 "is %N; @s zero. "), 8420 PROMPT_FIX, 0 }, 8421 8422 /* Resize_inode not enabled, but resize inode is non-zero */ 8423 { PR_0_CLEAR_RESIZE_INODE, 8424 N_("Resize_@i not enabled, but the resize @i is non-zero. "), 8425 PROMPT_CLEAR, 0 }, 8426 8427 /* Resize inode invalid */ 8428 { PR_0_RESIZE_INODE_INVALID, 8429 N_("Resize @i not valid. "), 8430 PROMPT_RECREATE, 0 }, 8431 8432 /* Pass 1 errors */ 8433 8434 /* Pass 1: Checking inodes, blocks, and sizes */ 8435 { PR_1_PASS_HEADER, 8436 N_("Pass 1: Checking @is, @bs, and sizes\n"), 8437 PROMPT_NONE, 0 }, 8438 8439 /* Root directory is not an inode */ 8440 { PR_1_ROOT_NO_DIR, N_("@r is not a @d. "), 8441 PROMPT_CLEAR, 0 }, 8442 8443 /* Root directory has dtime set */ 8444 { PR_1_ROOT_DTIME, 8445 N_("@r has dtime set (probably due to old mke2fs). "), 8446 PROMPT_FIX, PR_PREEN_OK }, 8447 8448 /* Reserved inode has bad mode */ 8449 { PR_1_RESERVED_BAD_MODE, 8450 N_("Reserved @i %i (%Q) has @n mode. "), 8451 PROMPT_CLEAR, PR_PREEN_OK }, 8452 8453 /* Deleted inode has zero dtime */ 8454 { PR_1_ZERO_DTIME, 8455 N_("@D @i %i has zero dtime. "), 8456 PROMPT_FIX, PR_PREEN_OK }, 8457 8458 /* Inode in use, but dtime set */ 8459 { PR_1_SET_DTIME, 8460 N_("@i %i is in use, but has dtime set. "), 8461 PROMPT_FIX, PR_PREEN_OK }, 8462 8463 /* Zero-length directory */ 8464 { PR_1_ZERO_LENGTH_DIR, 8465 N_("@i %i is a @z @d. "), 8466 PROMPT_CLEAR, PR_PREEN_OK }, 8467 8468 /* Block bitmap conflicts with some other fs block */ 8469 { PR_1_BB_CONFLICT, 8470 N_("@g %g's @b @B at %b @C.\n"), 8471 PROMPT_RELOCATE, 0 }, 8472 8473 /* Inode bitmap conflicts with some other fs block */ 8474 { PR_1_IB_CONFLICT, 8475 N_("@g %g's @i @B at %b @C.\n"), 8476 PROMPT_RELOCATE, 0 }, 8477 8478 /* Inode table conflicts with some other fs block */ 8479 { PR_1_ITABLE_CONFLICT, 8480 N_("@g %g's @i table at %b @C.\n"), 8481 PROMPT_RELOCATE, 0 }, 8482 8483 /* Block bitmap is on a bad block */ 8484 { PR_1_BB_BAD_BLOCK, 8485 N_("@g %g's @b @B (%b) is bad. "), 8486 PROMPT_RELOCATE, 0 }, 8487 8488 /* Inode bitmap is on a bad block */ 8489 { PR_1_IB_BAD_BLOCK, 8490 N_("@g %g's @i @B (%b) is bad. "), 8491 PROMPT_RELOCATE, 0 }, 8492 8493 /* Inode has incorrect i_size */ 8494 { PR_1_BAD_I_SIZE, 8495 N_("@i %i, i_size is %Is, @s %N. "), 8496 PROMPT_FIX, PR_PREEN_OK }, 8497 8498 /* Inode has incorrect i_blocks */ 8499 { PR_1_BAD_I_BLOCKS, 8500 N_("@i %i, i_@bs is %Ib, @s %N. "), 8501 PROMPT_FIX, PR_PREEN_OK }, 8502 8503 /* Illegal blocknumber in inode */ 8504 { PR_1_ILLEGAL_BLOCK_NUM, 8505 N_("@I @b #%B (%b) in @i %i. "), 8506 PROMPT_CLEAR, PR_LATCH_BLOCK }, 8507 8508 /* Block number overlaps fs metadata */ 8509 { PR_1_BLOCK_OVERLAPS_METADATA, 8510 N_("@b #%B (%b) overlaps @f metadata in @i %i. "), 8511 PROMPT_CLEAR, PR_LATCH_BLOCK }, 8512 8513 /* Inode has illegal blocks (latch question) */ 8514 { PR_1_INODE_BLOCK_LATCH, 8515 N_("@i %i has illegal @b(s). "), 8516 PROMPT_CLEAR, 0 }, 8517 8518 /* Too many bad blocks in inode */ 8519 { PR_1_TOO_MANY_BAD_BLOCKS, 8520 N_("Too many illegal @bs in @i %i.\n"), 8521 PROMPT_CLEAR_INODE, PR_NO_OK }, 8522 8523 /* Illegal block number in bad block inode */ 8524 { PR_1_BB_ILLEGAL_BLOCK_NUM, 8525 N_("@I @b #%B (%b) in bad @b @i. "), 8526 PROMPT_CLEAR, PR_LATCH_BBLOCK }, 8527 8528 /* Bad block inode has illegal blocks (latch question) */ 8529 { PR_1_INODE_BBLOCK_LATCH, 8530 N_("Bad @b @i has illegal @b(s). "), 8531 PROMPT_CLEAR, 0 }, 8532 8533 /* Duplicate or bad blocks in use! */ 8534 { PR_1_DUP_BLOCKS_PREENSTOP, 8535 N_("Duplicate or bad @b in use!\n"), 8536 PROMPT_NONE, 0 }, 8537 8538 /* Bad block used as bad block indirect block */ 8539 { PR_1_BBINODE_BAD_METABLOCK, 8540 N_("Bad @b %b used as bad @b @i indirect @b. "), 8541 PROMPT_CLEAR, PR_LATCH_BBLOCK }, 8542 8543 /* Inconsistency can't be fixed prompt */ 8544 { PR_1_BBINODE_BAD_METABLOCK_PROMPT, 8545 N_("\nThe bad @b @i has probably been corrupted. You probably\n" 8546 "should stop now and run ""e2fsck -c"" to scan for bad blocks\n" 8547 "in the @f.\n"), 8548 PROMPT_CONTINUE, PR_PREEN_NOMSG }, 8549 8550 /* Bad primary block */ 8551 { PR_1_BAD_PRIMARY_BLOCK, 8552 N_("\nIf the @b is really bad, the @f cannot be fixed.\n"), 8553 PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK_PROMPT }, 8554 8555 /* Bad primary block prompt */ 8556 { PR_1_BAD_PRIMARY_BLOCK_PROMPT, 8557 N_("You can remove this @b from the bad @b list and hope\n" 8558 "that the @b is really OK. But there are no guarantees.\n\n"), 8559 PROMPT_CLEAR, PR_PREEN_NOMSG }, 8560 8561 /* Bad primary superblock */ 8562 { PR_1_BAD_PRIMARY_SUPERBLOCK, 8563 N_("The primary @S (%b) is on the bad @b list.\n"), 8564 PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK }, 8565 8566 /* Bad primary block group descriptors */ 8567 { PR_1_BAD_PRIMARY_GROUP_DESCRIPTOR, 8568 N_("Block %b in the primary @g descriptors " 8569 "is on the bad @b list\n"), 8570 PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK }, 8571 8572 /* Bad superblock in group */ 8573 { PR_1_BAD_SUPERBLOCK, 8574 N_("Warning: Group %g's @S (%b) is bad.\n"), 8575 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG }, 8576 8577 /* Bad block group descriptors in group */ 8578 { PR_1_BAD_GROUP_DESCRIPTORS, 8579 N_("Warning: Group %g's copy of the @g descriptors has a bad " 8580 "@b (%b).\n"), 8581 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG }, 8582 8583 /* Block claimed for no reason */ 8584 { PR_1_PROGERR_CLAIMED_BLOCK, 8585 N_("Programming error? @b #%b claimed for no reason in " 8586 "process_bad_@b.\n"), 8587 PROMPT_NONE, PR_PREEN_OK }, 8588 8589 /* Error allocating blocks for relocating metadata */ 8590 { PR_1_RELOC_BLOCK_ALLOCATE, 8591 N_("@A %N contiguous @b(s) in @b @g %g for %s: %m\n"), 8592 PROMPT_NONE, PR_PREEN_OK }, 8593 8594 /* Error allocating block buffer during relocation process */ 8595 { PR_1_RELOC_MEMORY_ALLOCATE, 8596 N_("@A @b buffer for relocating %s\n"), 8597 PROMPT_NONE, PR_PREEN_OK }, 8598 8599 /* Relocating metadata group information from X to Y */ 8600 { PR_1_RELOC_FROM_TO, 8601 N_("Relocating @g %g's %s from %b to %c...\n"), 8602 PROMPT_NONE, PR_PREEN_OK }, 8603 8604 /* Relocating metatdata group information to X */ 8605 { PR_1_RELOC_TO, 8606 N_("Relocating @g %g's %s to %c...\n"), /* xgettext:no-c-format */ 8607 PROMPT_NONE, PR_PREEN_OK }, 8608 8609 /* Block read error during relocation process */ 8610 { PR_1_RELOC_READ_ERR, 8611 N_("Warning: could not read @b %b of %s: %m\n"), 8612 PROMPT_NONE, PR_PREEN_OK }, 8613 8614 /* Block write error during relocation process */ 8615 { PR_1_RELOC_WRITE_ERR, 8616 N_("Warning: could not write @b %b for %s: %m\n"), 8617 PROMPT_NONE, PR_PREEN_OK }, 8618 8619 /* Error allocating inode bitmap */ 8620 { PR_1_ALLOCATE_IBITMAP_ERROR, 8621 N_("@A @i @B (%N): %m\n"), 8622 PROMPT_NONE, PR_FATAL }, 8623 8624 /* Error allocating block bitmap */ 8625 { PR_1_ALLOCATE_BBITMAP_ERROR, 8626 N_("@A @b @B (%N): %m\n"), 8627 PROMPT_NONE, PR_FATAL }, 8628 8629 /* Error allocating icount structure */ 8630 { PR_1_ALLOCATE_ICOUNT, 8631 N_("@A icount link information: %m\n"), 8632 PROMPT_NONE, PR_FATAL }, 8633 8634 /* Error allocating dbcount */ 8635 { PR_1_ALLOCATE_DBCOUNT, 8636 N_("@A @d @b array: %m\n"), 8637 PROMPT_NONE, PR_FATAL }, 8638 8639 /* Error while scanning inodes */ 8640 { PR_1_ISCAN_ERROR, 8641 N_("Error while scanning @is (%i): %m\n"), 8642 PROMPT_NONE, PR_FATAL }, 8643 8644 /* Error while iterating over blocks */ 8645 { PR_1_BLOCK_ITERATE, 8646 N_("Error while iterating over @bs in @i %i: %m\n"), 8647 PROMPT_NONE, PR_FATAL }, 8648 8649 /* Error while storing inode count information */ 8650 { PR_1_ICOUNT_STORE, 8651 N_("Error storing @i count information (@i=%i, count=%N): %m\n"), 8652 PROMPT_NONE, PR_FATAL }, 8653 8654 /* Error while storing directory block information */ 8655 { PR_1_ADD_DBLOCK, 8656 N_("Error storing @d @b information " 8657 "(@i=%i, @b=%b, num=%N): %m\n"), 8658 PROMPT_NONE, PR_FATAL }, 8659 8660 /* Error while reading inode (for clearing) */ 8661 { PR_1_READ_INODE, 8662 N_("Error reading @i %i: %m\n"), 8663 PROMPT_NONE, PR_FATAL }, 8664 8665 /* Suppress messages prompt */ 8666 { PR_1_SUPPRESS_MESSAGES, "", PROMPT_SUPPRESS, PR_NO_OK }, 8667 8668 /* Imagic flag set on an inode when filesystem doesn't support it */ 8669 { PR_1_SET_IMAGIC, 8670 N_("@i %i has imagic flag set. "), 8671 PROMPT_CLEAR, 0 }, 8672 8673 /* Immutable flag set on a device or socket inode */ 8674 { PR_1_SET_IMMUTABLE, 8675 N_("Special (@v/socket/fifo/symlink) file (@i %i) has immutable\n" 8676 "or append-only flag set. "), 8677 PROMPT_CLEAR, PR_PREEN_OK | PR_PREEN_NO | PR_NO_OK }, 8678 8679 /* Compression flag set on an inode when filesystem doesn't support it */ 8680 { PR_1_COMPR_SET, 8681 N_("@i %i has @cion flag set on @f without @cion support. "), 8682 PROMPT_CLEAR, 0 }, 8683 8684 /* Non-zero size for device, fifo or socket inode */ 8685 { PR_1_SET_NONZSIZE, 8686 N_("Special (@v/socket/fifo) @i %i has non-zero size. "), 8687 PROMPT_FIX, PR_PREEN_OK }, 8688 8689 /* Filesystem revision is 0, but feature flags are set */ 8690 { PR_1_FS_REV_LEVEL, 8691 N_("@f has feature flag(s) set, but is a revision 0 @f. "), 8692 PROMPT_FIX, PR_PREEN_OK | PR_NO_OK }, 8693 8694 /* Journal inode is not in use, but contains data */ 8695 { PR_1_JOURNAL_INODE_NOT_CLEAR, 8696 N_("@j @i is not in use, but contains data. "), 8697 PROMPT_CLEAR, PR_PREEN_OK }, 8698 8699 /* Journal has bad mode */ 8700 { PR_1_JOURNAL_BAD_MODE, 8701 N_("@j is not regular file. "), 8702 PROMPT_FIX, PR_PREEN_OK }, 8703 8704 /* Deal with inodes that were part of orphan linked list */ 8705 { PR_1_LOW_DTIME, 8706 N_("@i %i was part of the @o @i list. "), 8707 PROMPT_FIX, PR_LATCH_LOW_DTIME, 0 }, 8708 8709 /* Deal with inodes that were part of corrupted orphan linked 8710 list (latch question) */ 8711 { PR_1_ORPHAN_LIST_REFUGEES, 8712 N_("@is that were part of a corrupted orphan linked list found. "), 8713 PROMPT_FIX, 0 }, 8714 8715 /* Error allocating refcount structure */ 8716 { PR_1_ALLOCATE_REFCOUNT, 8717 N_("@A refcount structure (%N): %m\n"), 8718 PROMPT_NONE, PR_FATAL }, 8719 8720 /* Error reading extended attribute block */ 8721 { PR_1_READ_EA_BLOCK, 8722 N_("Error reading @a @b %b for @i %i. "), 8723 PROMPT_CLEAR, 0 }, 8724 8725 /* Invalid extended attribute block */ 8726 { PR_1_BAD_EA_BLOCK, 8727 N_("@i %i has a bad @a @b %b. "), 8728 PROMPT_CLEAR, 0 }, 8729 8730 /* Error reading Extended Attribute block while fixing refcount */ 8731 { PR_1_EXTATTR_READ_ABORT, 8732 N_("Error reading @a @b %b (%m). "), 8733 PROMPT_ABORT, 0 }, 8734 8735 /* Extended attribute reference count incorrect */ 8736 { PR_1_EXTATTR_REFCOUNT, 8737 N_("@a @b %b has reference count %B, @s %N. "), 8738 PROMPT_FIX, 0 }, 8739 8740 /* Error writing Extended Attribute block while fixing refcount */ 8741 { PR_1_EXTATTR_WRITE, 8742 N_("Error writing @a @b %b (%m). "), 8743 PROMPT_ABORT, 0 }, 8744 8745 /* Multiple EA blocks not supported */ 8746 { PR_1_EA_MULTI_BLOCK, 8747 N_("@a @b %b has h_@bs > 1. "), 8748 PROMPT_CLEAR, 0}, 8749 8750 /* Error allocating EA region allocation structure */ 8751 { PR_1_EA_ALLOC_REGION, 8752 N_("@A @a @b %b. "), 8753 PROMPT_ABORT, 0}, 8754 8755 /* Error EA allocation collision */ 8756 { PR_1_EA_ALLOC_COLLISION, 8757 N_("@a @b %b is corrupt (allocation collision). "), 8758 PROMPT_CLEAR, 0}, 8759 8760 /* Bad extended attribute name */ 8761 { PR_1_EA_BAD_NAME, 8762 N_("@a @b %b is corrupt (@n name). "), 8763 PROMPT_CLEAR, 0}, 8764 8765 /* Bad extended attribute value */ 8766 { PR_1_EA_BAD_VALUE, 8767 N_("@a @b %b is corrupt (@n value). "), 8768 PROMPT_CLEAR, 0}, 8769 8770 /* Inode too big (latch question) */ 8771 { PR_1_INODE_TOOBIG, 8772 N_("@i %i is too big. "), PROMPT_TRUNCATE, 0 }, 8773 8774 /* Directory too big */ 8775 { PR_1_TOOBIG_DIR, 8776 N_("@b #%B (%b) causes @d to be too big. "), 8777 PROMPT_CLEAR, PR_LATCH_TOOBIG }, 8778 8779 /* Regular file too big */ 8780 { PR_1_TOOBIG_REG, 8781 N_("@b #%B (%b) causes file to be too big. "), 8782 PROMPT_CLEAR, PR_LATCH_TOOBIG }, 8783 8784 /* Symlink too big */ 8785 { PR_1_TOOBIG_SYMLINK, 8786 N_("@b #%B (%b) causes symlink to be too big. "), 8787 PROMPT_CLEAR, PR_LATCH_TOOBIG }, 8788 8789 /* INDEX_FL flag set on a non-HTREE filesystem */ 8790 { PR_1_HTREE_SET, 8791 N_("@i %i has INDEX_FL flag set on @f without htree support.\n"), 8792 PROMPT_CLEAR_HTREE, PR_PREEN_OK }, 8793 8794 /* INDEX_FL flag set on a non-directory */ 8795 { PR_1_HTREE_NODIR, 8796 N_("@i %i has INDEX_FL flag set but is not a @d.\n"), 8797 PROMPT_CLEAR_HTREE, PR_PREEN_OK }, 8798 8799 /* Invalid root node in HTREE directory */ 8800 { PR_1_HTREE_BADROOT, 8801 N_("@h %i has an @n root node.\n"), 8802 PROMPT_CLEAR_HTREE, PR_PREEN_OK }, 8803 8804 /* Unsupported hash version in HTREE directory */ 8805 { PR_1_HTREE_HASHV, 8806 N_("@h %i has an unsupported hash version (%N)\n"), 8807 PROMPT_CLEAR_HTREE, PR_PREEN_OK }, 8808 8809 /* Incompatible flag in HTREE root node */ 8810 { PR_1_HTREE_INCOMPAT, 8811 N_("@h %i uses an incompatible htree root node flag.\n"), 8812 PROMPT_CLEAR_HTREE, PR_PREEN_OK }, 8813 8814 /* HTREE too deep */ 8815 { PR_1_HTREE_DEPTH, 8816 N_("@h %i has a tree depth (%N) which is too big\n"), 8817 PROMPT_CLEAR_HTREE, PR_PREEN_OK }, 8818 8819 /* Bad block has indirect block that conflicts with filesystem block */ 8820 { PR_1_BB_FS_BLOCK, 8821 N_("Bad @b @i has an indirect @b (%b) that conflicts with\n" 8822 "@f metadata. "), 8823 PROMPT_CLEAR, PR_LATCH_BBLOCK }, 8824 8825 /* Resize inode failed */ 8826 { PR_1_RESIZE_INODE_CREATE, 8827 N_("Resize @i (re)creation failed: %m."), 8828 PROMPT_ABORT, 0 }, 8829 8830 /* invalid inode->i_extra_isize */ 8831 { PR_1_EXTRA_ISIZE, 8832 N_("@i %i has a extra size (%IS) which is @n\n"), 8833 PROMPT_FIX, PR_PREEN_OK }, 8834 8835 /* invalid ea entry->e_name_len */ 8836 { PR_1_ATTR_NAME_LEN, 8837 N_("@a in @i %i has a namelen (%N) which is @n\n"), 8838 PROMPT_CLEAR, PR_PREEN_OK }, 8839 8840 /* invalid ea entry->e_value_size */ 8841 { PR_1_ATTR_VALUE_SIZE, 8842 N_("@a in @i %i has a value size (%N) which is @n\n"), 8843 PROMPT_CLEAR, PR_PREEN_OK }, 8844 8845 /* invalid ea entry->e_value_offs */ 8846 { PR_1_ATTR_VALUE_OFFSET, 8847 N_("@a in @i %i has a value offset (%N) which is @n\n"), 8848 PROMPT_CLEAR, PR_PREEN_OK }, 8849 8850 /* invalid ea entry->e_value_block */ 8851 { PR_1_ATTR_VALUE_BLOCK, 8852 N_("@a in @i %i has a value @b (%N) which is @n (must be 0)\n"), 8853 PROMPT_CLEAR, PR_PREEN_OK }, 8854 8855 /* invalid ea entry->e_hash */ 8856 { PR_1_ATTR_HASH, 8857 N_("@a in @i %i has a hash (%N) which is @n (must be 0)\n"), 8858 PROMPT_CLEAR, PR_PREEN_OK }, 8859 8860 /* Pass 1b errors */ 8861 8862 /* Pass 1B: Rescan for duplicate/bad blocks */ 8863 { PR_1B_PASS_HEADER, 8864 N_("\nRunning additional passes to resolve @bs claimed by more than one @i...\n" 8865 "Pass 1B: Rescanning for @m @bs\n"), 8866 PROMPT_NONE, 0 }, 8867 8868 /* Duplicate/bad block(s) header */ 8869 { PR_1B_DUP_BLOCK_HEADER, 8870 N_("@m @b(s) in @i %i:"), 8871 PROMPT_NONE, 0 }, 8872 8873 /* Duplicate/bad block(s) in inode */ 8874 { PR_1B_DUP_BLOCK, 8875 " %b", 8876 PROMPT_NONE, PR_LATCH_DBLOCK | PR_PREEN_NOHDR }, 8877 8878 /* Duplicate/bad block(s) end */ 8879 { PR_1B_DUP_BLOCK_END, 8880 "\n", 8881 PROMPT_NONE, PR_PREEN_NOHDR }, 8882 8883 /* Error while scanning inodes */ 8884 { PR_1B_ISCAN_ERROR, 8885 N_("Error while scanning inodes (%i): %m\n"), 8886 PROMPT_NONE, PR_FATAL }, 8887 8888 /* Error allocating inode bitmap */ 8889 { PR_1B_ALLOCATE_IBITMAP_ERROR, 8890 N_("@A @i @B (@i_dup_map): %m\n"), 8891 PROMPT_NONE, PR_FATAL }, 8892 8893 /* Error while iterating over blocks */ 8894 { PR_1B_BLOCK_ITERATE, 8895 N_("Error while iterating over @bs in @i %i (%s): %m\n"), 8896 PROMPT_NONE, 0 }, 8897 8898 /* Error adjusting EA refcount */ 8899 { PR_1B_ADJ_EA_REFCOUNT, 8900 N_("Error adjusting refcount for @a @b %b (@i %i): %m\n"), 8901 PROMPT_NONE, 0 }, 8902 8903 8904 /* Pass 1C: Scan directories for inodes with multiply-claimed blocks. */ 8905 { PR_1C_PASS_HEADER, 8906 N_("Pass 1C: Scanning directories for @is with @m @bs.\n"), 8907 PROMPT_NONE, 0 }, 8908 8909 8910 /* Pass 1D: Reconciling multiply-claimed blocks */ 8911 { PR_1D_PASS_HEADER, 8912 N_("Pass 1D: Reconciling @m @bs\n"), 8913 PROMPT_NONE, 0 }, 8914 8915 /* File has duplicate blocks */ 8916 { PR_1D_DUP_FILE, 8917 N_("File %Q (@i #%i, mod time %IM)\n" 8918 " has %B @m @b(s), shared with %N file(s):\n"), 8919 PROMPT_NONE, 0 }, 8920 8921 /* List of files sharing duplicate blocks */ 8922 { PR_1D_DUP_FILE_LIST, 8923 N_("\t%Q (@i #%i, mod time %IM)\n"), 8924 PROMPT_NONE, 0 }, 8925 8926 /* File sharing blocks with filesystem metadata */ 8927 { PR_1D_SHARE_METADATA, 8928 N_("\t<@f metadata>\n"), 8929 PROMPT_NONE, 0 }, 8930 8931 /* Report of how many duplicate/bad inodes */ 8932 { PR_1D_NUM_DUP_INODES, 8933 N_("(There are %N @is containing @m @bs.)\n\n"), 8934 PROMPT_NONE, 0 }, 8935 8936 /* Duplicated blocks already reassigned or cloned. */ 8937 { PR_1D_DUP_BLOCKS_DEALT, 8938 N_("@m @bs already reassigned or cloned.\n\n"), 8939 PROMPT_NONE, 0 }, 8940 8941 /* Clone duplicate/bad blocks? */ 8942 { PR_1D_CLONE_QUESTION, 8943 "", PROMPT_CLONE, PR_NO_OK }, 8944 8945 /* Delete file? */ 8946 { PR_1D_DELETE_QUESTION, 8947 "", PROMPT_DELETE, 0 }, 8948 8949 /* Couldn't clone file (error) */ 8950 { PR_1D_CLONE_ERROR, 8951 N_("Couldn't clone file: %m\n"), PROMPT_NONE, 0 }, 8952 8953 /* Pass 2 errors */ 8954 8955 /* Pass 2: Checking directory structure */ 8956 { PR_2_PASS_HEADER, 8957 N_("Pass 2: Checking @d structure\n"), 8958 PROMPT_NONE, 0 }, 8959 8960 /* Bad inode number for '.' */ 8961 { PR_2_BAD_INODE_DOT, 8962 N_("@n @i number for '.' in @d @i %i.\n"), 8963 PROMPT_FIX, 0 }, 8964 8965 /* Directory entry has bad inode number */ 8966 { PR_2_BAD_INO, 8967 N_("@E has @n @i #: %Di.\n"), 8968 PROMPT_CLEAR, 0 }, 8969 8970 /* Directory entry has deleted or unused inode */ 8971 { PR_2_UNUSED_INODE, 8972 N_("@E has @D/unused @i %Di. "), 8973 PROMPT_CLEAR, PR_PREEN_OK }, 8974 8975 /* Directry entry is link to '.' */ 8976 { PR_2_LINK_DOT, 8977 N_("@E @L to '.' "), 8978 PROMPT_CLEAR, 0 }, 8979 8980 /* Directory entry points to inode now located in a bad block */ 8981 { PR_2_BB_INODE, 8982 N_("@E points to @i (%Di) located in a bad @b.\n"), 8983 PROMPT_CLEAR, 0 }, 8984 8985 /* Directory entry contains a link to a directory */ 8986 { PR_2_LINK_DIR, 8987 N_("@E @L to @d %P (%Di).\n"), 8988 PROMPT_CLEAR, 0 }, 8989 8990 /* Directory entry contains a link to the root directry */ 8991 { PR_2_LINK_ROOT, 8992 N_("@E @L to the @r.\n"), 8993 PROMPT_CLEAR, 0 }, 8994 8995 /* Directory entry has illegal characters in its name */ 8996 { PR_2_BAD_NAME, 8997 N_("@E has illegal characters in its name.\n"), 8998 PROMPT_FIX, 0 }, 8999 9000 /* Missing '.' in directory inode */ 9001 { PR_2_MISSING_DOT, 9002 N_("Missing '.' in @d @i %i.\n"), 9003 PROMPT_FIX, 0 }, 9004 9005 /* Missing '..' in directory inode */ 9006 { PR_2_MISSING_DOT_DOT, 9007 N_("Missing '..' in @d @i %i.\n"), 9008 PROMPT_FIX, 0 }, 9009 9010 /* First entry in directory inode doesn't contain '.' */ 9011 { PR_2_1ST_NOT_DOT, 9012 N_("First @e '%Dn' (@i=%Di) in @d @i %i (%p) @s '.'\n"), 9013 PROMPT_FIX, 0 }, 9014 9015 /* Second entry in directory inode doesn't contain '..' */ 9016 { PR_2_2ND_NOT_DOT_DOT, 9017 N_("Second @e '%Dn' (@i=%Di) in @d @i %i @s '..'\n"), 9018 PROMPT_FIX, 0 }, 9019 9020 /* i_faddr should be zero */ 9021 { PR_2_FADDR_ZERO, 9022 N_("i_faddr @F %IF, @s zero.\n"), 9023 PROMPT_CLEAR, 0 }, 9024 9025 /* i_file_acl should be zero */ 9026 { PR_2_FILE_ACL_ZERO, 9027 N_("i_file_acl @F %If, @s zero.\n"), 9028 PROMPT_CLEAR, 0 }, 9029 9030 /* i_dir_acl should be zero */ 9031 { PR_2_DIR_ACL_ZERO, 9032 N_("i_dir_acl @F %Id, @s zero.\n"), 9033 PROMPT_CLEAR, 0 }, 9034 9035 /* i_frag should be zero */ 9036 { PR_2_FRAG_ZERO, 9037 N_("i_frag @F %N, @s zero.\n"), 9038 PROMPT_CLEAR, 0 }, 9039 9040 /* i_fsize should be zero */ 9041 { PR_2_FSIZE_ZERO, 9042 N_("i_fsize @F %N, @s zero.\n"), 9043 PROMPT_CLEAR, 0 }, 9044 9045 /* inode has bad mode */ 9046 { PR_2_BAD_MODE, 9047 N_("@i %i (%Q) has @n mode (%Im).\n"), 9048 PROMPT_CLEAR, 0 }, 9049 9050 /* directory corrupted */ 9051 { PR_2_DIR_CORRUPTED, 9052 N_("@d @i %i, @b %B, offset %N: @d corrupted\n"), 9053 PROMPT_SALVAGE, 0 }, 9054 9055 /* filename too long */ 9056 { PR_2_FILENAME_LONG, 9057 N_("@d @i %i, @b %B, offset %N: filename too long\n"), 9058 PROMPT_TRUNCATE, 0 }, 9059 9060 /* Directory inode has a missing block (hole) */ 9061 { PR_2_DIRECTORY_HOLE, 9062 N_("@d @i %i has an unallocated @b #%B. "), 9063 PROMPT_ALLOCATE, 0 }, 9064 9065 /* '.' is not NULL terminated */ 9066 { PR_2_DOT_NULL_TERM, 9067 N_("'.' @d @e in @d @i %i is not NULL terminated\n"), 9068 PROMPT_FIX, 0 }, 9069 9070 /* '..' is not NULL terminated */ 9071 { PR_2_DOT_DOT_NULL_TERM, 9072 N_("'..' @d @e in @d @i %i is not NULL terminated\n"), 9073 PROMPT_FIX, 0 }, 9074 9075 /* Illegal character device inode */ 9076 { PR_2_BAD_CHAR_DEV, 9077 N_("@i %i (%Q) is an @I character @v.\n"), 9078 PROMPT_CLEAR, 0 }, 9079 9080 /* Illegal block device inode */ 9081 { PR_2_BAD_BLOCK_DEV, 9082 N_("@i %i (%Q) is an @I @b @v.\n"), 9083 PROMPT_CLEAR, 0 }, 9084 9085 /* Duplicate '.' entry */ 9086 { PR_2_DUP_DOT, 9087 N_("@E is duplicate '.' @e.\n"), 9088 PROMPT_FIX, 0 }, 9089 9090 /* Duplicate '..' entry */ 9091 { PR_2_DUP_DOT_DOT, 9092 N_("@E is duplicate '..' @e.\n"), 9093 PROMPT_FIX, 0 }, 9094 9095 /* Internal error: couldn't find dir_info */ 9096 { PR_2_NO_DIRINFO, 9097 N_("Internal error: cannot find dir_info for %i.\n"), 9098 PROMPT_NONE, PR_FATAL }, 9099 9100 /* Final rec_len is wrong */ 9101 { PR_2_FINAL_RECLEN, 9102 N_("@E has rec_len of %Dr, @s %N.\n"), 9103 PROMPT_FIX, 0 }, 9104 9105 /* Error allocating icount structure */ 9106 { PR_2_ALLOCATE_ICOUNT, 9107 N_("@A icount structure: %m\n"), 9108 PROMPT_NONE, PR_FATAL }, 9109 9110 /* Error iterating over directory blocks */ 9111 { PR_2_DBLIST_ITERATE, 9112 N_("Error iterating over @d @bs: %m\n"), 9113 PROMPT_NONE, PR_FATAL }, 9114 9115 /* Error reading directory block */ 9116 { PR_2_READ_DIRBLOCK, 9117 N_("Error reading @d @b %b (@i %i): %m\n"), 9118 PROMPT_CONTINUE, 0 }, 9119 9120 /* Error writing directory block */ 9121 { PR_2_WRITE_DIRBLOCK, 9122 N_("Error writing @d @b %b (@i %i): %m\n"), 9123 PROMPT_CONTINUE, 0 }, 9124 9125 /* Error allocating new directory block */ 9126 { PR_2_ALLOC_DIRBOCK, 9127 N_("@A new @d @b for @i %i (%s): %m\n"), 9128 PROMPT_NONE, 0 }, 9129 9130 /* Error deallocating inode */ 9131 { PR_2_DEALLOC_INODE, 9132 N_("Error deallocating @i %i: %m\n"), 9133 PROMPT_NONE, PR_FATAL }, 9134 9135 /* Directory entry for '.' is big. Split? */ 9136 { PR_2_SPLIT_DOT, 9137 N_("@d @e for '.' is big. "), 9138 PROMPT_SPLIT, PR_NO_OK }, 9139 9140 /* Illegal FIFO inode */ 9141 { PR_2_BAD_FIFO, 9142 N_("@i %i (%Q) is an @I FIFO.\n"), 9143 PROMPT_CLEAR, 0 }, 9144 9145 /* Illegal socket inode */ 9146 { PR_2_BAD_SOCKET, 9147 N_("@i %i (%Q) is an @I socket.\n"), 9148 PROMPT_CLEAR, 0 }, 9149 9150 /* Directory filetype not set */ 9151 { PR_2_SET_FILETYPE, 9152 N_("Setting filetype for @E to %N.\n"), 9153 PROMPT_NONE, PR_PREEN_OK | PR_NO_OK | PR_NO_NOMSG }, 9154 9155 /* Directory filetype incorrect */ 9156 { PR_2_BAD_FILETYPE, 9157 N_("@E has an incorrect filetype (was %Dt, @s %N).\n"), 9158 PROMPT_FIX, 0 }, 9159 9160 /* Directory filetype set on filesystem */ 9161 { PR_2_CLEAR_FILETYPE, 9162 N_("@E has filetype set.\n"), 9163 PROMPT_CLEAR, PR_PREEN_OK }, 9164 9165 /* Directory filename is null */ 9166 { PR_2_NULL_NAME, 9167 N_("@E has a @z name.\n"), 9168 PROMPT_CLEAR, 0 }, 9169 9170 /* Invalid symlink */ 9171 { PR_2_INVALID_SYMLINK, 9172 N_("Symlink %Q (@i #%i) is @n.\n"), 9173 PROMPT_CLEAR, 0 }, 9174 9175 /* i_file_acl (extended attribute block) is bad */ 9176 { PR_2_FILE_ACL_BAD, 9177 N_("@a @b @F @n (%If).\n"), 9178 PROMPT_CLEAR, 0 }, 9179 9180 /* Filesystem contains large files, but has no such flag in sb */ 9181 { PR_2_FEATURE_LARGE_FILES, 9182 N_("@f contains large files, but lacks LARGE_FILE flag in @S.\n"), 9183 PROMPT_FIX, 0 }, 9184 9185 /* Node in HTREE directory not referenced */ 9186 { PR_2_HTREE_NOTREF, 9187 N_("@p @h %d: node (%B) not referenced\n"), 9188 PROMPT_NONE, 0 }, 9189 9190 /* Node in HTREE directory referenced twice */ 9191 { PR_2_HTREE_DUPREF, 9192 N_("@p @h %d: node (%B) referenced twice\n"), 9193 PROMPT_NONE, 0 }, 9194 9195 /* Node in HTREE directory has bad min hash */ 9196 { PR_2_HTREE_MIN_HASH, 9197 N_("@p @h %d: node (%B) has bad min hash\n"), 9198 PROMPT_NONE, 0 }, 9199 9200 /* Node in HTREE directory has bad max hash */ 9201 { PR_2_HTREE_MAX_HASH, 9202 N_("@p @h %d: node (%B) has bad max hash\n"), 9203 PROMPT_NONE, 0 }, 9204 9205 /* Clear invalid HTREE directory */ 9206 { PR_2_HTREE_CLEAR, 9207 N_("@n @h %d (%q). "), PROMPT_CLEAR, 0 }, 9208 9209 /* Bad block in htree interior node */ 9210 { PR_2_HTREE_BADBLK, 9211 N_("@p @h %d (%q): bad @b number %b.\n"), 9212 PROMPT_CLEAR_HTREE, 0 }, 9213 9214 /* Error adjusting EA refcount */ 9215 { PR_2_ADJ_EA_REFCOUNT, 9216 N_("Error adjusting refcount for @a @b %b (@i %i): %m\n"), 9217 PROMPT_NONE, PR_FATAL }, 9218 9219 /* Invalid HTREE root node */ 9220 { PR_2_HTREE_BAD_ROOT, 9221 N_("@p @h %d: root node is @n\n"), 9222 PROMPT_CLEAR_HTREE, PR_PREEN_OK }, 9223 9224 /* Invalid HTREE limit */ 9225 { PR_2_HTREE_BAD_LIMIT, 9226 N_("@p @h %d: node (%B) has @n limit (%N)\n"), 9227 PROMPT_CLEAR_HTREE, PR_PREEN_OK }, 9228 9229 /* Invalid HTREE count */ 9230 { PR_2_HTREE_BAD_COUNT, 9231 N_("@p @h %d: node (%B) has @n count (%N)\n"), 9232 PROMPT_CLEAR_HTREE, PR_PREEN_OK }, 9233 9234 /* HTREE interior node has out-of-order hashes in table */ 9235 { PR_2_HTREE_HASH_ORDER, 9236 N_("@p @h %d: node (%B) has an unordered hash table\n"), 9237 PROMPT_CLEAR_HTREE, PR_PREEN_OK }, 9238 9239 /* Node in HTREE directory has invalid depth */ 9240 { PR_2_HTREE_BAD_DEPTH, 9241 N_("@p @h %d: node (%B) has @n depth\n"), 9242 PROMPT_NONE, 0 }, 9243 9244 /* Duplicate directory entry found */ 9245 { PR_2_DUPLICATE_DIRENT, 9246 N_("Duplicate @E found. "), 9247 PROMPT_CLEAR, 0 }, 9248 9249 /* Non-unique filename found */ 9250 { PR_2_NON_UNIQUE_FILE, /* xgettext: no-c-format */ 9251 N_("@E has a non-unique filename.\nRename to %s"), 9252 PROMPT_NULL, 0 }, 9253 9254 /* Duplicate directory entry found */ 9255 { PR_2_REPORT_DUP_DIRENT, 9256 N_("Duplicate @e '%Dn' found.\n\tMarking %p (%i) to be rebuilt.\n\n"), 9257 PROMPT_NONE, 0 }, 9258 9259 /* Pass 3 errors */ 9260 9261 /* Pass 3: Checking directory connectivity */ 9262 { PR_3_PASS_HEADER, 9263 N_("Pass 3: Checking @d connectivity\n"), 9264 PROMPT_NONE, 0 }, 9265 9266 /* Root inode not allocated */ 9267 { PR_3_NO_ROOT_INODE, 9268 N_("@r not allocated. "), 9269 PROMPT_ALLOCATE, 0 }, 9270 9271 /* No room in lost+found */ 9272 { PR_3_EXPAND_LF_DIR, 9273 N_("No room in @l @d. "), 9274 PROMPT_EXPAND, 0 }, 9275 9276 /* Unconnected directory inode */ 9277 { PR_3_UNCONNECTED_DIR, 9278 N_("Unconnected @d @i %i (%p)\n"), 9279 PROMPT_CONNECT, 0 }, 9280 9281 /* /lost+found not found */ 9282 { PR_3_NO_LF_DIR, 9283 N_("/@l not found. "), 9284 PROMPT_CREATE, PR_PREEN_OK }, 9285 9286 /* .. entry is incorrect */ 9287 { PR_3_BAD_DOT_DOT, 9288 N_("'..' in %Q (%i) is %P (%j), @s %q (%d).\n"), 9289 PROMPT_FIX, 0 }, 9290 9291 /* Bad or non-existent /lost+found. Cannot reconnect */ 9292 { PR_3_NO_LPF, 9293 N_("Bad or non-existent /@l. Cannot reconnect.\n"), 9294 PROMPT_NONE, 0 }, 9295 9296 /* Could not expand /lost+found */ 9297 { PR_3_CANT_EXPAND_LPF, 9298 N_("Could not expand /@l: %m\n"), 9299 PROMPT_NONE, 0 }, 9300 9301 /* Could not reconnect inode */ 9302 { PR_3_CANT_RECONNECT, 9303 N_("Could not reconnect %i: %m\n"), 9304 PROMPT_NONE, 0 }, 9305 9306 /* Error while trying to find /lost+found */ 9307 { PR_3_ERR_FIND_LPF, 9308 N_("Error while trying to find /@l: %m\n"), 9309 PROMPT_NONE, 0 }, 9310 9311 /* Error in ext2fs_new_block while creating /lost+found */ 9312 { PR_3_ERR_LPF_NEW_BLOCK, 9313 N_("ext2fs_new_@b: %m while trying to create /@l @d\n"), 9314 PROMPT_NONE, 0 }, 9315 9316 /* Error in ext2fs_new_inode while creating /lost+found */ 9317 { PR_3_ERR_LPF_NEW_INODE, 9318 N_("ext2fs_new_@i: %m while trying to create /@l @d\n"), 9319 PROMPT_NONE, 0 }, 9320 9321 /* Error in ext2fs_new_dir_block while creating /lost+found */ 9322 { PR_3_ERR_LPF_NEW_DIR_BLOCK, 9323 N_("ext2fs_new_dir_@b: %m while creating new @d @b\n"), 9324 PROMPT_NONE, 0 }, 9325 9326 /* Error while writing directory block for /lost+found */ 9327 { PR_3_ERR_LPF_WRITE_BLOCK, 9328 N_("ext2fs_write_dir_@b: %m while writing the @d @b for /@l\n"), 9329 PROMPT_NONE, 0 }, 9330 9331 /* Error while adjusting inode count */ 9332 { PR_3_ADJUST_INODE, 9333 N_("Error while adjusting @i count on @i %i\n"), 9334 PROMPT_NONE, 0 }, 9335 9336 /* Couldn't fix parent directory -- error */ 9337 { PR_3_FIX_PARENT_ERR, 9338 N_("Couldn't fix parent of @i %i: %m\n\n"), 9339 PROMPT_NONE, 0 }, 9340 9341 /* Couldn't fix parent directory -- couldn't find it */ 9342 { PR_3_FIX_PARENT_NOFIND, 9343 N_("Couldn't fix parent of @i %i: Couldn't find parent @d @e\n\n"), 9344 PROMPT_NONE, 0 }, 9345 9346 /* Error allocating inode bitmap */ 9347 { PR_3_ALLOCATE_IBITMAP_ERROR, 9348 N_("@A @i @B (%N): %m\n"), 9349 PROMPT_NONE, PR_FATAL }, 9350 9351 /* Error creating root directory */ 9352 { PR_3_CREATE_ROOT_ERROR, 9353 N_("Error creating root @d (%s): %m\n"), 9354 PROMPT_NONE, PR_FATAL }, 9355 9356 /* Error creating lost and found directory */ 9357 { PR_3_CREATE_LPF_ERROR, 9358 N_("Error creating /@l @d (%s): %m\n"), 9359 PROMPT_NONE, PR_FATAL }, 9360 9361 /* Root inode is not directory; aborting */ 9362 { PR_3_ROOT_NOT_DIR_ABORT, 9363 N_("@r is not a @d; aborting.\n"), 9364 PROMPT_NONE, PR_FATAL }, 9365 9366 /* Cannot proceed without a root inode. */ 9367 { PR_3_NO_ROOT_INODE_ABORT, 9368 N_("Cannot proceed without a @r.\n"), 9369 PROMPT_NONE, PR_FATAL }, 9370 9371 /* Internal error: couldn't find dir_info */ 9372 { PR_3_NO_DIRINFO, 9373 N_("Internal error: cannot find dir_info for %i.\n"), 9374 PROMPT_NONE, PR_FATAL }, 9375 9376 /* Lost+found not a directory */ 9377 { PR_3_LPF_NOTDIR, 9378 N_("/@l is not a @d (ino=%i)\n"), 9379 PROMPT_UNLINK, 0 }, 9380 9381 /* Pass 3A Directory Optimization */ 9382 9383 /* Pass 3A: Optimizing directories */ 9384 { PR_3A_PASS_HEADER, 9385 N_("Pass 3A: Optimizing directories\n"), 9386 PROMPT_NONE, PR_PREEN_NOMSG }, 9387 9388 /* Error iterating over directories */ 9389 { PR_3A_OPTIMIZE_ITER, 9390 N_("Failed to create dirs_to_hash iterator: %m"), 9391 PROMPT_NONE, 0 }, 9392 9393 /* Error rehash directory */ 9394 { PR_3A_OPTIMIZE_DIR_ERR, 9395 N_("Failed to optimize directory %q (%d): %m"), 9396 PROMPT_NONE, 0 }, 9397 9398 /* Rehashing dir header */ 9399 { PR_3A_OPTIMIZE_DIR_HEADER, 9400 N_("Optimizing directories: "), 9401 PROMPT_NONE, PR_MSG_ONLY }, 9402 9403 /* Rehashing directory %d */ 9404 { PR_3A_OPTIMIZE_DIR, 9405 " %d", 9406 PROMPT_NONE, PR_LATCH_OPTIMIZE_DIR | PR_PREEN_NOHDR}, 9407 9408 /* Rehashing dir end */ 9409 { PR_3A_OPTIMIZE_DIR_END, 9410 "\n", 9411 PROMPT_NONE, PR_PREEN_NOHDR }, 9412 9413 /* Pass 4 errors */ 9414 9415 /* Pass 4: Checking reference counts */ 9416 { PR_4_PASS_HEADER, 9417 N_("Pass 4: Checking reference counts\n"), 9418 PROMPT_NONE, 0 }, 9419 9420 /* Unattached zero-length inode */ 9421 { PR_4_ZERO_LEN_INODE, 9422 N_("@u @z @i %i. "), 9423 PROMPT_CLEAR, PR_PREEN_OK|PR_NO_OK }, 9424 9425 /* Unattached inode */ 9426 { PR_4_UNATTACHED_INODE, 9427 N_("@u @i %i\n"), 9428 PROMPT_CONNECT, 0 }, 9429 9430 /* Inode ref count wrong */ 9431 { PR_4_BAD_REF_COUNT, 9432 N_("@i %i ref count is %Il, @s %N. "), 9433 PROMPT_FIX, PR_PREEN_OK }, 9434 9435 { PR_4_INCONSISTENT_COUNT, 9436 N_("WARNING: PROGRAMMING BUG IN E2FSCK!\n" 9437 "\tOR SOME BONEHEAD (YOU) IS CHECKING A MOUNTED (LIVE) FILESYSTEM.\n" 9438 "@i_link_info[%i] is %N, @i.i_links_count is %Il. " 9439 "They @s the same!\n"), 9440 PROMPT_NONE, 0 }, 9441 9442 /* Pass 5 errors */ 9443 9444 /* Pass 5: Checking group summary information */ 9445 { PR_5_PASS_HEADER, 9446 N_("Pass 5: Checking @g summary information\n"), 9447 PROMPT_NONE, 0 }, 9448 9449 /* Padding at end of inode bitmap is not set. */ 9450 { PR_5_INODE_BMAP_PADDING, 9451 N_("Padding at end of @i @B is not set. "), 9452 PROMPT_FIX, PR_PREEN_OK }, 9453 9454 /* Padding at end of block bitmap is not set. */ 9455 { PR_5_BLOCK_BMAP_PADDING, 9456 N_("Padding at end of @b @B is not set. "), 9457 PROMPT_FIX, PR_PREEN_OK }, 9458 9459 /* Block bitmap differences header */ 9460 { PR_5_BLOCK_BITMAP_HEADER, 9461 N_("@b @B differences: "), 9462 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG}, 9463 9464 /* Block not used, but marked in bitmap */ 9465 { PR_5_BLOCK_UNUSED, 9466 " -%b", 9467 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG }, 9468 9469 /* Block used, but not marked used in bitmap */ 9470 { PR_5_BLOCK_USED, 9471 " +%b", 9472 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG }, 9473 9474 /* Block bitmap differences end */ 9475 { PR_5_BLOCK_BITMAP_END, 9476 "\n", 9477 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG }, 9478 9479 /* Inode bitmap differences header */ 9480 { PR_5_INODE_BITMAP_HEADER, 9481 N_("@i @B differences: "), 9482 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG }, 9483 9484 /* Inode not used, but marked in bitmap */ 9485 { PR_5_INODE_UNUSED, 9486 " -%i", 9487 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG }, 9488 9489 /* Inode used, but not marked used in bitmap */ 9490 { PR_5_INODE_USED, 9491 " +%i", 9492 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG }, 9493 9494 /* Inode bitmap differences end */ 9495 { PR_5_INODE_BITMAP_END, 9496 "\n", 9497 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG }, 9498 9499 /* Free inodes count for group wrong */ 9500 { PR_5_FREE_INODE_COUNT_GROUP, 9501 N_("Free @is count wrong for @g #%g (%i, counted=%j).\n"), 9502 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG }, 9503 9504 /* Directories count for group wrong */ 9505 { PR_5_FREE_DIR_COUNT_GROUP, 9506 N_("Directories count wrong for @g #%g (%i, counted=%j).\n"), 9507 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG }, 9508 9509 /* Free inodes count wrong */ 9510 { PR_5_FREE_INODE_COUNT, 9511 N_("Free @is count wrong (%i, counted=%j).\n"), 9512 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG }, 9513 9514 /* Free blocks count for group wrong */ 9515 { PR_5_FREE_BLOCK_COUNT_GROUP, 9516 N_("Free @bs count wrong for @g #%g (%b, counted=%c).\n"), 9517 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG }, 9518 9519 /* Free blocks count wrong */ 9520 { PR_5_FREE_BLOCK_COUNT, 9521 N_("Free @bs count wrong (%b, counted=%c).\n"), 9522 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG }, 9523 9524 /* Programming error: bitmap endpoints don't match */ 9525 { PR_5_BMAP_ENDPOINTS, 9526 N_("PROGRAMMING ERROR: @f (#%N) @B endpoints (%b, %c) don't " 9527 "match calculated @B endpoints (%i, %j)\n"), 9528 PROMPT_NONE, PR_FATAL }, 9529 9530 /* Internal error: fudging end of bitmap */ 9531 { PR_5_FUDGE_BITMAP_ERROR, 9532 N_("Internal error: fudging end of bitmap (%N)\n"), 9533 PROMPT_NONE, PR_FATAL }, 9534 9535 /* Error copying in replacement inode bitmap */ 9536 { PR_5_COPY_IBITMAP_ERROR, 9537 N_("Error copying in replacement @i @B: %m\n"), 9538 PROMPT_NONE, PR_FATAL }, 9539 9540 /* Error copying in replacement block bitmap */ 9541 { PR_5_COPY_BBITMAP_ERROR, 9542 N_("Error copying in replacement @b @B: %m\n"), 9543 PROMPT_NONE, PR_FATAL }, 9544 9545 /* Block range not used, but marked in bitmap */ 9546 { PR_5_BLOCK_RANGE_UNUSED, 9547 " -(%b--%c)", 9548 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG }, 9549 9550 /* Block range used, but not marked used in bitmap */ 9551 { PR_5_BLOCK_RANGE_USED, 9552 " +(%b--%c)", 9553 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG }, 9554 9555 /* Inode range not used, but marked in bitmap */ 9556 { PR_5_INODE_RANGE_UNUSED, 9557 " -(%i--%j)", 9558 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG }, 9559 9560 /* Inode range used, but not marked used in bitmap */ 9561 { PR_5_INODE_RANGE_USED, 9562 " +(%i--%j)", 9563 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG }, 9564 9565 { 0 } 9566}; 9567 9568/* 9569 * This is the latch flags register. It allows several problems to be 9570 * "latched" together. This means that the user has to answer but one 9571 * question for the set of problems, and all of the associated 9572 * problems will be either fixed or not fixed. 9573 */ 9574static struct latch_descr pr_latch_info[] = { 9575 { PR_LATCH_BLOCK, PR_1_INODE_BLOCK_LATCH, 0 }, 9576 { PR_LATCH_BBLOCK, PR_1_INODE_BBLOCK_LATCH, 0 }, 9577 { PR_LATCH_IBITMAP, PR_5_INODE_BITMAP_HEADER, PR_5_INODE_BITMAP_END }, 9578 { PR_LATCH_BBITMAP, PR_5_BLOCK_BITMAP_HEADER, PR_5_BLOCK_BITMAP_END }, 9579 { PR_LATCH_RELOC, PR_0_RELOCATE_HINT, 0 }, 9580 { PR_LATCH_DBLOCK, PR_1B_DUP_BLOCK_HEADER, PR_1B_DUP_BLOCK_END }, 9581 { PR_LATCH_LOW_DTIME, PR_1_ORPHAN_LIST_REFUGEES, 0 }, 9582 { PR_LATCH_TOOBIG, PR_1_INODE_TOOBIG, 0 }, 9583 { PR_LATCH_OPTIMIZE_DIR, PR_3A_OPTIMIZE_DIR_HEADER, PR_3A_OPTIMIZE_DIR_END }, 9584 { -1, 0, 0 }, 9585}; 9586 9587static const struct e2fsck_problem *find_problem(problem_t code) 9588{ 9589 int i; 9590 9591 for (i=0; problem_table[i].e2p_code; i++) { 9592 if (problem_table[i].e2p_code == code) 9593 return &problem_table[i]; 9594 } 9595 return 0; 9596} 9597 9598static struct latch_descr *find_latch(int code) 9599{ 9600 int i; 9601 9602 for (i=0; pr_latch_info[i].latch_code >= 0; i++) { 9603 if (pr_latch_info[i].latch_code == code) 9604 return &pr_latch_info[i]; 9605 } 9606 return 0; 9607} 9608 9609int end_problem_latch(e2fsck_t ctx, int mask) 9610{ 9611 struct latch_descr *ldesc; 9612 struct problem_context pctx; 9613 int answer = -1; 9614 9615 ldesc = find_latch(mask); 9616 if (ldesc->end_message && (ldesc->flags & PRL_LATCHED)) { 9617 clear_problem_context(&pctx); 9618 answer = fix_problem(ctx, ldesc->end_message, &pctx); 9619 } 9620 ldesc->flags &= ~(PRL_VARIABLE); 9621 return answer; 9622} 9623 9624int set_latch_flags(int mask, int setflags, int clearflags) 9625{ 9626 struct latch_descr *ldesc; 9627 9628 ldesc = find_latch(mask); 9629 if (!ldesc) 9630 return -1; 9631 ldesc->flags |= setflags; 9632 ldesc->flags &= ~clearflags; 9633 return 0; 9634} 9635 9636void clear_problem_context(struct problem_context *ctx) 9637{ 9638 memset(ctx, 0, sizeof(struct problem_context)); 9639 ctx->blkcount = -1; 9640 ctx->group = -1; 9641} 9642 9643int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx) 9644{ 9645 ext2_filsys fs = ctx->fs; 9646 const struct e2fsck_problem *ptr; 9647 struct latch_descr *ldesc = 0; 9648 const char *message; 9649 int def_yn, answer, ans; 9650 int print_answer = 0; 9651 int suppress = 0; 9652 9653 ptr = find_problem(code); 9654 if (!ptr) { 9655 printf(_("Unhandled error code (0x%x)!\n"), code); 9656 return 0; 9657 } 9658 def_yn = 1; 9659 if ((ptr->flags & PR_NO_DEFAULT) || 9660 ((ptr->flags & PR_PREEN_NO) && (ctx->options & E2F_OPT_PREEN)) || 9661 (ctx->options & E2F_OPT_NO)) 9662 def_yn= 0; 9663 9664 /* 9665 * Do special latch processing. This is where we ask the 9666 * latch question, if it exists 9667 */ 9668 if (ptr->flags & PR_LATCH_MASK) { 9669 ldesc = find_latch(ptr->flags & PR_LATCH_MASK); 9670 if (ldesc->question && !(ldesc->flags & PRL_LATCHED)) { 9671 ans = fix_problem(ctx, ldesc->question, pctx); 9672 if (ans == 1) 9673 ldesc->flags |= PRL_YES; 9674 if (ans == 0) 9675 ldesc->flags |= PRL_NO; 9676 ldesc->flags |= PRL_LATCHED; 9677 } 9678 if (ldesc->flags & PRL_SUPPRESS) 9679 suppress++; 9680 } 9681 if ((ptr->flags & PR_PREEN_NOMSG) && 9682 (ctx->options & E2F_OPT_PREEN)) 9683 suppress++; 9684 if ((ptr->flags & PR_NO_NOMSG) && 9685 (ctx->options & E2F_OPT_NO)) 9686 suppress++; 9687 if (!suppress) { 9688 message = ptr->e2p_description; 9689 if ((ctx->options & E2F_OPT_PREEN) && 9690 !(ptr->flags & PR_PREEN_NOHDR)) { 9691 printf("%s: ", ctx->device_name ? 9692 ctx->device_name : ctx->filesystem_name); 9693 } 9694 if (*message) 9695 print_e2fsck_message(ctx, _(message), pctx, 1); 9696 } 9697 if (!(ptr->flags & PR_PREEN_OK) && (ptr->prompt != PROMPT_NONE)) 9698 preenhalt(ctx); 9699 9700 if (ptr->flags & PR_FATAL) 9701 bb_error_msg_and_die(0); 9702 9703 if (ptr->prompt == PROMPT_NONE) { 9704 if (ptr->flags & PR_NOCOLLATE) 9705 answer = -1; 9706 else 9707 answer = def_yn; 9708 } else { 9709 if (ctx->options & E2F_OPT_PREEN) { 9710 answer = def_yn; 9711 if (!(ptr->flags & PR_PREEN_NOMSG)) 9712 print_answer = 1; 9713 } else if ((ptr->flags & PR_LATCH_MASK) && 9714 (ldesc->flags & (PRL_YES | PRL_NO))) { 9715 if (!suppress) 9716 print_answer = 1; 9717 if (ldesc->flags & PRL_YES) 9718 answer = 1; 9719 else 9720 answer = 0; 9721 } else 9722 answer = ask(ctx, _(prompt[(int) ptr->prompt]), def_yn); 9723 if (!answer && !(ptr->flags & PR_NO_OK)) 9724 ext2fs_unmark_valid(fs); 9725 9726 if (print_answer) 9727 printf("%s.\n", answer ? 9728 _(preen_msg[(int) ptr->prompt]) : _("IGNORED")); 9729 9730 } 9731 9732 if ((ptr->prompt == PROMPT_ABORT) && answer) 9733 bb_error_msg_and_die(0); 9734 9735 if (ptr->flags & PR_AFTER_CODE) 9736 answer = fix_problem(ctx, ptr->second_code, pctx); 9737 9738 return answer; 9739} 9740 9741/* 9742 * linux/fs/recovery.c 9743 * 9744 * Written by Stephen C. Tweedie <sct@redhat.com>, 1999 9745 */ 9746 9747/* 9748 * Maintain information about the progress of the recovery job, so that 9749 * the different passes can carry information between them. 9750 */ 9751struct recovery_info 9752{ 9753 tid_t start_transaction; 9754 tid_t end_transaction; 9755 9756 int nr_replays; 9757 int nr_revokes; 9758 int nr_revoke_hits; 9759}; 9760 9761enum passtype {PASS_SCAN, PASS_REVOKE, PASS_REPLAY}; 9762static int do_one_pass(journal_t *journal, 9763 struct recovery_info *info, enum passtype pass); 9764static int scan_revoke_records(journal_t *, struct buffer_head *, 9765 tid_t, struct recovery_info *); 9766 9767/* 9768 * Read a block from the journal 9769 */ 9770 9771static int jread(struct buffer_head **bhp, journal_t *journal, 9772 unsigned int offset) 9773{ 9774 int err; 9775 unsigned long blocknr; 9776 struct buffer_head *bh; 9777 9778 *bhp = NULL; 9779 9780 err = journal_bmap(journal, offset, &blocknr); 9781 9782 if (err) { 9783 printf("JBD: bad block at offset %u\n", offset); 9784 return err; 9785 } 9786 9787 bh = getblk(journal->j_dev, blocknr, journal->j_blocksize); 9788 if (!bh) 9789 return -ENOMEM; 9790 9791 if (!buffer_uptodate(bh)) { 9792 /* If this is a brand new buffer, start readahead. 9793 Otherwise, we assume we are already reading it. */ 9794 if (!buffer_req(bh)) 9795 do_readahead(journal, offset); 9796 wait_on_buffer(bh); 9797 } 9798 9799 if (!buffer_uptodate(bh)) { 9800 printf("JBD: Failed to read block at offset %u\n", offset); 9801 brelse(bh); 9802 return -EIO; 9803 } 9804 9805 *bhp = bh; 9806 return 0; 9807} 9808 9809 9810/* 9811 * Count the number of in-use tags in a journal descriptor block. 9812 */ 9813 9814static int count_tags(struct buffer_head *bh, int size) 9815{ 9816 char * tagp; 9817 journal_block_tag_t * tag; 9818 int nr = 0; 9819 9820 tagp = &bh->b_data[sizeof(journal_header_t)]; 9821 9822 while ((tagp - bh->b_data + sizeof(journal_block_tag_t)) <= size) { 9823 tag = (journal_block_tag_t *) tagp; 9824 9825 nr++; 9826 tagp += sizeof(journal_block_tag_t); 9827 if (!(tag->t_flags & htonl(JFS_FLAG_SAME_UUID))) 9828 tagp += 16; 9829 9830 if (tag->t_flags & htonl(JFS_FLAG_LAST_TAG)) 9831 break; 9832 } 9833 9834 return nr; 9835} 9836 9837 9838/* Make sure we wrap around the log correctly! */ 9839#define wrap(journal, var) \ 9840do { \ 9841 if (var >= (journal)->j_last) \ 9842 var -= ((journal)->j_last - (journal)->j_first); \ 9843} while (0) 9844 9845/** 9846 * int journal_recover(journal_t *journal) - recovers a on-disk journal 9847 * @journal: the journal to recover 9848 * 9849 * The primary function for recovering the log contents when mounting a 9850 * journaled device. 9851 * 9852 * Recovery is done in three passes. In the first pass, we look for the 9853 * end of the log. In the second, we assemble the list of revoke 9854 * blocks. In the third and final pass, we replay any un-revoked blocks 9855 * in the log. 9856 */ 9857int journal_recover(journal_t *journal) 9858{ 9859 int err; 9860 journal_superblock_t * sb; 9861 9862 struct recovery_info info; 9863 9864 memset(&info, 0, sizeof(info)); 9865 sb = journal->j_superblock; 9866 9867 /* 9868 * The journal superblock's s_start field (the current log head) 9869 * is always zero if, and only if, the journal was cleanly 9870 * unmounted. 9871 */ 9872 9873 if (!sb->s_start) { 9874 journal->j_transaction_sequence = ntohl(sb->s_sequence) + 1; 9875 return 0; 9876 } 9877 9878 err = do_one_pass(journal, &info, PASS_SCAN); 9879 if (!err) 9880 err = do_one_pass(journal, &info, PASS_REVOKE); 9881 if (!err) 9882 err = do_one_pass(journal, &info, PASS_REPLAY); 9883 9884 /* Restart the log at the next transaction ID, thus invalidating 9885 * any existing commit records in the log. */ 9886 journal->j_transaction_sequence = ++info.end_transaction; 9887 9888 journal_clear_revoke(journal); 9889 sync_blockdev(journal->j_fs_dev); 9890 return err; 9891} 9892 9893static int do_one_pass(journal_t *journal, 9894 struct recovery_info *info, enum passtype pass) 9895{ 9896 unsigned int first_commit_ID, next_commit_ID; 9897 unsigned long next_log_block; 9898 int err, success = 0; 9899 journal_superblock_t * sb; 9900 journal_header_t * tmp; 9901 struct buffer_head * bh; 9902 unsigned int sequence; 9903 int blocktype; 9904 9905 /* Precompute the maximum metadata descriptors in a descriptor block */ 9906 int MAX_BLOCKS_PER_DESC; 9907 MAX_BLOCKS_PER_DESC = ((journal->j_blocksize-sizeof(journal_header_t)) 9908 / sizeof(journal_block_tag_t)); 9909 9910 /* 9911 * First thing is to establish what we expect to find in the log 9912 * (in terms of transaction IDs), and where (in terms of log 9913 * block offsets): query the superblock. 9914 */ 9915 9916 sb = journal->j_superblock; 9917 next_commit_ID = ntohl(sb->s_sequence); 9918 next_log_block = ntohl(sb->s_start); 9919 9920 first_commit_ID = next_commit_ID; 9921 if (pass == PASS_SCAN) 9922 info->start_transaction = first_commit_ID; 9923 9924 /* 9925 * Now we walk through the log, transaction by transaction, 9926 * making sure that each transaction has a commit block in the 9927 * expected place. Each complete transaction gets replayed back 9928 * into the main filesystem. 9929 */ 9930 9931 while (1) { 9932 int flags; 9933 char * tagp; 9934 journal_block_tag_t * tag; 9935 struct buffer_head * obh; 9936 struct buffer_head * nbh; 9937 9938 /* If we already know where to stop the log traversal, 9939 * check right now that we haven't gone past the end of 9940 * the log. */ 9941 9942 if (pass != PASS_SCAN) 9943 if (tid_geq(next_commit_ID, info->end_transaction)) 9944 break; 9945 9946 /* Skip over each chunk of the transaction looking 9947 * either the next descriptor block or the final commit 9948 * record. */ 9949 9950 err = jread(&bh, journal, next_log_block); 9951 if (err) 9952 goto failed; 9953 9954 next_log_block++; 9955 wrap(journal, next_log_block); 9956 9957 /* What kind of buffer is it? 9958 * 9959 * If it is a descriptor block, check that it has the 9960 * expected sequence number. Otherwise, we're all done 9961 * here. */ 9962 9963 tmp = (journal_header_t *)bh->b_data; 9964 9965 if (tmp->h_magic != htonl(JFS_MAGIC_NUMBER)) { 9966 brelse(bh); 9967 break; 9968 } 9969 9970 blocktype = ntohl(tmp->h_blocktype); 9971 sequence = ntohl(tmp->h_sequence); 9972 9973 if (sequence != next_commit_ID) { 9974 brelse(bh); 9975 break; 9976 } 9977 9978 /* OK, we have a valid descriptor block which matches 9979 * all of the sequence number checks. What are we going 9980 * to do with it? That depends on the pass... */ 9981 9982 switch(blocktype) { 9983 case JFS_DESCRIPTOR_BLOCK: 9984 /* If it is a valid descriptor block, replay it 9985 * in pass REPLAY; otherwise, just skip over the 9986 * blocks it describes. */ 9987 if (pass != PASS_REPLAY) { 9988 next_log_block += 9989 count_tags(bh, journal->j_blocksize); 9990 wrap(journal, next_log_block); 9991 brelse(bh); 9992 continue; 9993 } 9994 9995 /* A descriptor block: we can now write all of 9996 * the data blocks. Yay, useful work is finally 9997 * getting done here! */ 9998 9999 tagp = &bh->b_data[sizeof(journal_header_t)]; 10000 while ((tagp - bh->b_data +sizeof(journal_block_tag_t)) 10001 <= journal->j_blocksize) { 10002 unsigned long io_block; 10003 10004 tag = (journal_block_tag_t *) tagp; 10005 flags = ntohl(tag->t_flags); 10006 10007 io_block = next_log_block++; 10008 wrap(journal, next_log_block); 10009 err = jread(&obh, journal, io_block); 10010 if (err) { 10011 /* Recover what we can, but 10012 * report failure at the end. */ 10013 success = err; 10014 printf("JBD: IO error %d recovering " 10015 "block %ld in log\n", 10016 err, io_block); 10017 } else { 10018 unsigned long blocknr; 10019 10020 blocknr = ntohl(tag->t_blocknr); 10021 10022 /* If the block has been 10023 * revoked, then we're all done 10024 * here. */ 10025 if (journal_test_revoke 10026 (journal, blocknr, 10027 next_commit_ID)) { 10028 brelse(obh); 10029 ++info->nr_revoke_hits; 10030 goto skip_write; 10031 } 10032 10033 /* Find a buffer for the new 10034 * data being restored */ 10035 nbh = getblk(journal->j_fs_dev, 10036 blocknr, 10037 journal->j_blocksize); 10038 if (nbh == NULL) { 10039 printf("JBD: Out of memory " 10040 "during recovery.\n"); 10041 err = -ENOMEM; 10042 brelse(bh); 10043 brelse(obh); 10044 goto failed; 10045 } 10046 10047 lock_buffer(nbh); 10048 memcpy(nbh->b_data, obh->b_data, 10049 journal->j_blocksize); 10050 if (flags & JFS_FLAG_ESCAPE) { 10051 *((unsigned int *)bh->b_data) = 10052 htonl(JFS_MAGIC_NUMBER); 10053 } 10054 10055 mark_buffer_uptodate(nbh, 1); 10056 mark_buffer_dirty(nbh); 10057 ++info->nr_replays; 10058 /* ll_rw_block(WRITE, 1, &nbh); */ 10059 unlock_buffer(nbh); 10060 brelse(obh); 10061 brelse(nbh); 10062 } 10063 10064 skip_write: 10065 tagp += sizeof(journal_block_tag_t); 10066 if (!(flags & JFS_FLAG_SAME_UUID)) 10067 tagp += 16; 10068 10069 if (flags & JFS_FLAG_LAST_TAG) 10070 break; 10071 } 10072 10073 brelse(bh); 10074 continue; 10075 10076 case JFS_COMMIT_BLOCK: 10077 /* Found an expected commit block: not much to 10078 * do other than move on to the next sequence 10079 * number. */ 10080 brelse(bh); 10081 next_commit_ID++; 10082 continue; 10083 10084 case JFS_REVOKE_BLOCK: 10085 /* If we aren't in the REVOKE pass, then we can 10086 * just skip over this block. */ 10087 if (pass != PASS_REVOKE) { 10088 brelse(bh); 10089 continue; 10090 } 10091 10092 err = scan_revoke_records(journal, bh, 10093 next_commit_ID, info); 10094 brelse(bh); 10095 if (err) 10096 goto failed; 10097 continue; 10098 10099 default: 10100 goto done; 10101 } 10102 } 10103 10104 done: 10105 /* 10106 * We broke out of the log scan loop: either we came to the 10107 * known end of the log or we found an unexpected block in the 10108 * log. If the latter happened, then we know that the "current" 10109 * transaction marks the end of the valid log. 10110 */ 10111 10112 if (pass == PASS_SCAN) 10113 info->end_transaction = next_commit_ID; 10114 else { 10115 /* It's really bad news if different passes end up at 10116 * different places (but possible due to IO errors). */ 10117 if (info->end_transaction != next_commit_ID) { 10118 printf("JBD: recovery pass %d ended at " 10119 "transaction %u, expected %u\n", 10120 pass, next_commit_ID, info->end_transaction); 10121 if (!success) 10122 success = -EIO; 10123 } 10124 } 10125 10126 return success; 10127 10128 failed: 10129 return err; 10130} 10131 10132 10133/* Scan a revoke record, marking all blocks mentioned as revoked. */ 10134 10135static int scan_revoke_records(journal_t *journal, struct buffer_head *bh, 10136 tid_t sequence, struct recovery_info *info) 10137{ 10138 journal_revoke_header_t *header; 10139 int offset, max; 10140 10141 header = (journal_revoke_header_t *) bh->b_data; 10142 offset = sizeof(journal_revoke_header_t); 10143 max = ntohl(header->r_count); 10144 10145 while (offset < max) { 10146 unsigned long blocknr; 10147 int err; 10148 10149 blocknr = ntohl(* ((unsigned int *) (bh->b_data+offset))); 10150 offset += 4; 10151 err = journal_set_revoke(journal, blocknr, sequence); 10152 if (err) 10153 return err; 10154 ++info->nr_revokes; 10155 } 10156 return 0; 10157} 10158 10159 10160/* 10161 * rehash.c --- rebuild hash tree directories 10162 * 10163 * This algorithm is designed for simplicity of implementation and to 10164 * pack the directory as much as possible. It however requires twice 10165 * as much memory as the size of the directory. The maximum size 10166 * directory supported using a 4k blocksize is roughly a gigabyte, and 10167 * so there may very well be problems with machines that don't have 10168 * virtual memory, and obscenely large directories. 10169 * 10170 * An alternate algorithm which is much more disk intensive could be 10171 * written, and probably will need to be written in the future. The 10172 * design goals of such an algorithm are: (a) use (roughly) constant 10173 * amounts of memory, no matter how large the directory, (b) the 10174 * directory must be safe at all times, even if e2fsck is interrupted 10175 * in the middle, (c) we must use minimal amounts of extra disk 10176 * blocks. This pretty much requires an incremental approach, where 10177 * we are reading from one part of the directory, and inserting into 10178 * the front half. So the algorithm will have to keep track of a 10179 * moving block boundary between the new tree and the old tree, and 10180 * files will need to be moved from the old directory and inserted 10181 * into the new tree. If the new directory requires space which isn't 10182 * yet available, blocks from the beginning part of the old directory 10183 * may need to be moved to the end of the directory to make room for 10184 * the new tree: 10185 * 10186 * -------------------------------------------------------- 10187 * | new tree | | old tree | 10188 * -------------------------------------------------------- 10189 * ^ ptr ^ptr 10190 * tail new head old 10191 * 10192 * This is going to be a pain in the tuckus to implement, and will 10193 * require a lot more disk accesses. So I'm going to skip it for now; 10194 * it's only really going to be an issue for really, really big 10195 * filesystems (when we reach the level of tens of millions of files 10196 * in a single directory). It will probably be easier to simply 10197 * require that e2fsck use VM first. 10198 */ 10199 10200struct fill_dir_struct { 10201 char *buf; 10202 struct ext2_inode *inode; 10203 int err; 10204 e2fsck_t ctx; 10205 struct hash_entry *harray; 10206 int max_array, num_array; 10207 int dir_size; 10208 int compress; 10209 ino_t parent; 10210}; 10211 10212struct hash_entry { 10213 ext2_dirhash_t hash; 10214 ext2_dirhash_t minor_hash; 10215 struct ext2_dir_entry *dir; 10216}; 10217 10218struct out_dir { 10219 int num; 10220 int max; 10221 char *buf; 10222 ext2_dirhash_t *hashes; 10223}; 10224 10225static int fill_dir_block(ext2_filsys fs, 10226 blk_t *block_nr, 10227 e2_blkcnt_t blockcnt, 10228 blk_t ref_block FSCK_ATTR((unused)), 10229 int ref_offset FSCK_ATTR((unused)), 10230 void *priv_data) 10231{ 10232 struct fill_dir_struct *fd = (struct fill_dir_struct *) priv_data; 10233 struct hash_entry *new_array, *ent; 10234 struct ext2_dir_entry *dirent; 10235 char *dir; 10236 unsigned int offset, dir_offset; 10237 10238 if (blockcnt < 0) 10239 return 0; 10240 10241 offset = blockcnt * fs->blocksize; 10242 if (offset + fs->blocksize > fd->inode->i_size) { 10243 fd->err = EXT2_ET_DIR_CORRUPTED; 10244 return BLOCK_ABORT; 10245 } 10246 dir = (fd->buf+offset); 10247 if (HOLE_BLKADDR(*block_nr)) { 10248 memset(dir, 0, fs->blocksize); 10249 dirent = (struct ext2_dir_entry *) dir; 10250 dirent->rec_len = fs->blocksize; 10251 } else { 10252 fd->err = ext2fs_read_dir_block(fs, *block_nr, dir); 10253 if (fd->err) 10254 return BLOCK_ABORT; 10255 } 10256 /* While the directory block is "hot", index it. */ 10257 dir_offset = 0; 10258 while (dir_offset < fs->blocksize) { 10259 dirent = (struct ext2_dir_entry *) (dir + dir_offset); 10260 if (((dir_offset + dirent->rec_len) > fs->blocksize) || 10261 (dirent->rec_len < 8) || 10262 ((dirent->rec_len % 4) != 0) || 10263 (((dirent->name_len & 0xFF)+8) > dirent->rec_len)) { 10264 fd->err = EXT2_ET_DIR_CORRUPTED; 10265 return BLOCK_ABORT; 10266 } 10267 dir_offset += dirent->rec_len; 10268 if (dirent->inode == 0) 10269 continue; 10270 if (!fd->compress && ((dirent->name_len&0xFF) == 1) && 10271 (dirent->name[0] == '.')) 10272 continue; 10273 if (!fd->compress && ((dirent->name_len&0xFF) == 2) && 10274 (dirent->name[0] == '.') && (dirent->name[1] == '.')) { 10275 fd->parent = dirent->inode; 10276 continue; 10277 } 10278 if (fd->num_array >= fd->max_array) { 10279 new_array = realloc(fd->harray, 10280 sizeof(struct hash_entry) * (fd->max_array+500)); 10281 if (!new_array) { 10282 fd->err = ENOMEM; 10283 return BLOCK_ABORT; 10284 } 10285 fd->harray = new_array; 10286 fd->max_array += 500; 10287 } 10288 ent = fd->harray + fd->num_array++; 10289 ent->dir = dirent; 10290 fd->dir_size += EXT2_DIR_REC_LEN(dirent->name_len & 0xFF); 10291 if (fd->compress) 10292 ent->hash = ent->minor_hash = 0; 10293 else { 10294 fd->err = ext2fs_dirhash(fs->super->s_def_hash_version, 10295 dirent->name, 10296 dirent->name_len & 0xFF, 10297 fs->super->s_hash_seed, 10298 &ent->hash, &ent->minor_hash); 10299 if (fd->err) 10300 return BLOCK_ABORT; 10301 } 10302 } 10303 10304 return 0; 10305} 10306 10307/* Used for sorting the hash entry */ 10308static int name_cmp(const void *a, const void *b) 10309{ 10310 const struct hash_entry *he_a = (const struct hash_entry *) a; 10311 const struct hash_entry *he_b = (const struct hash_entry *) b; 10312 int ret; 10313 int min_len; 10314 10315 min_len = he_a->dir->name_len; 10316 if (min_len > he_b->dir->name_len) 10317 min_len = he_b->dir->name_len; 10318 10319 ret = strncmp(he_a->dir->name, he_b->dir->name, min_len); 10320 if (ret == 0) { 10321 if (he_a->dir->name_len > he_b->dir->name_len) 10322 ret = 1; 10323 else if (he_a->dir->name_len < he_b->dir->name_len) 10324 ret = -1; 10325 else 10326 ret = he_b->dir->inode - he_a->dir->inode; 10327 } 10328 return ret; 10329} 10330 10331/* Used for sorting the hash entry */ 10332static int hash_cmp(const void *a, const void *b) 10333{ 10334 const struct hash_entry *he_a = (const struct hash_entry *) a; 10335 const struct hash_entry *he_b = (const struct hash_entry *) b; 10336 int ret; 10337 10338 if (he_a->hash > he_b->hash) 10339 ret = 1; 10340 else if (he_a->hash < he_b->hash) 10341 ret = -1; 10342 else { 10343 if (he_a->minor_hash > he_b->minor_hash) 10344 ret = 1; 10345 else if (he_a->minor_hash < he_b->minor_hash) 10346 ret = -1; 10347 else 10348 ret = name_cmp(a, b); 10349 } 10350 return ret; 10351} 10352 10353static errcode_t alloc_size_dir(ext2_filsys fs, struct out_dir *outdir, 10354 int blocks) 10355{ 10356 void *new_mem; 10357 10358 if (outdir->max) { 10359 new_mem = realloc(outdir->buf, blocks * fs->blocksize); 10360 if (!new_mem) 10361 return ENOMEM; 10362 outdir->buf = new_mem; 10363 new_mem = realloc(outdir->hashes, 10364 blocks * sizeof(ext2_dirhash_t)); 10365 if (!new_mem) 10366 return ENOMEM; 10367 outdir->hashes = new_mem; 10368 } else { 10369 outdir->buf = malloc(blocks * fs->blocksize); 10370 outdir->hashes = malloc(blocks * sizeof(ext2_dirhash_t)); 10371 outdir->num = 0; 10372 } 10373 outdir->max = blocks; 10374 return 0; 10375} 10376 10377static void free_out_dir(struct out_dir *outdir) 10378{ 10379 free(outdir->buf); 10380 free(outdir->hashes); 10381 outdir->max = 0; 10382 outdir->num =0; 10383} 10384 10385static errcode_t get_next_block(ext2_filsys fs, struct out_dir *outdir, 10386 char ** ret) 10387{ 10388 errcode_t retval; 10389 10390 if (outdir->num >= outdir->max) { 10391 retval = alloc_size_dir(fs, outdir, outdir->max + 50); 10392 if (retval) 10393 return retval; 10394 } 10395 *ret = outdir->buf + (outdir->num++ * fs->blocksize); 10396 memset(*ret, 0, fs->blocksize); 10397 return 0; 10398} 10399 10400/* 10401 * This function is used to make a unique filename. We do this by 10402 * appending ~0, and then incrementing the number. However, we cannot 10403 * expand the length of the filename beyond the padding available in 10404 * the directory entry. 10405 */ 10406static void mutate_name(char *str, __u16 *len) 10407{ 10408 int i; 10409 __u16 l = *len & 0xFF, h = *len & 0xff00; 10410 10411 /* 10412 * First check to see if it looks the name has been mutated 10413 * already 10414 */ 10415 for (i = l-1; i > 0; i--) { 10416 if (!isdigit(str[i])) 10417 break; 10418 } 10419 if ((i == l-1) || (str[i] != '~')) { 10420 if (((l-1) & 3) < 2) 10421 l += 2; 10422 else 10423 l = (l+3) & ~3; 10424 str[l-2] = '~'; 10425 str[l-1] = '0'; 10426 *len = l | h; 10427 return; 10428 } 10429 for (i = l-1; i >= 0; i--) { 10430 if (isdigit(str[i])) { 10431 if (str[i] == '9') 10432 str[i] = '0'; 10433 else { 10434 str[i]++; 10435 return; 10436 } 10437 continue; 10438 } 10439 if (i == 1) { 10440 if (str[0] == 'z') 10441 str[0] = 'A'; 10442 else if (str[0] == 'Z') { 10443 str[0] = '~'; 10444 str[1] = '0'; 10445 } else 10446 str[0]++; 10447 } else if (i > 0) { 10448 str[i] = '1'; 10449 str[i-1] = '~'; 10450 } else { 10451 if (str[0] == '~') 10452 str[0] = 'a'; 10453 else 10454 str[0]++; 10455 } 10456 break; 10457 } 10458} 10459 10460static int duplicate_search_and_fix(e2fsck_t ctx, ext2_filsys fs, 10461 ext2_ino_t ino, 10462 struct fill_dir_struct *fd) 10463{ 10464 struct problem_context pctx; 10465 struct hash_entry *ent, *prev; 10466 int i, j; 10467 int fixed = 0; 10468 char new_name[256]; 10469 __u16 new_len; 10470 10471 clear_problem_context(&pctx); 10472 pctx.ino = ino; 10473 10474 for (i=1; i < fd->num_array; i++) { 10475 ent = fd->harray + i; 10476 prev = ent - 1; 10477 if (!ent->dir->inode || 10478 ((ent->dir->name_len & 0xFF) != 10479 (prev->dir->name_len & 0xFF)) || 10480 (strncmp(ent->dir->name, prev->dir->name, 10481 ent->dir->name_len & 0xFF))) 10482 continue; 10483 pctx.dirent = ent->dir; 10484 if ((ent->dir->inode == prev->dir->inode) && 10485 fix_problem(ctx, PR_2_DUPLICATE_DIRENT, &pctx)) { 10486 e2fsck_adjust_inode_count(ctx, ent->dir->inode, -1); 10487 ent->dir->inode = 0; 10488 fixed++; 10489 continue; 10490 } 10491 memcpy(new_name, ent->dir->name, ent->dir->name_len & 0xFF); 10492 new_len = ent->dir->name_len; 10493 mutate_name(new_name, &new_len); 10494 for (j=0; j < fd->num_array; j++) { 10495 if ((i==j) || 10496 ((ent->dir->name_len & 0xFF) != 10497 (fd->harray[j].dir->name_len & 0xFF)) || 10498 (strncmp(new_name, fd->harray[j].dir->name, 10499 new_len & 0xFF))) 10500 continue; 10501 mutate_name(new_name, &new_len); 10502 10503 j = -1; 10504 } 10505 new_name[new_len & 0xFF] = 0; 10506 pctx.str = new_name; 10507 if (fix_problem(ctx, PR_2_NON_UNIQUE_FILE, &pctx)) { 10508 memcpy(ent->dir->name, new_name, new_len & 0xFF); 10509 ent->dir->name_len = new_len; 10510 ext2fs_dirhash(fs->super->s_def_hash_version, 10511 ent->dir->name, 10512 ent->dir->name_len & 0xFF, 10513 fs->super->s_hash_seed, 10514 &ent->hash, &ent->minor_hash); 10515 fixed++; 10516 } 10517 } 10518 return fixed; 10519} 10520 10521 10522static errcode_t copy_dir_entries(ext2_filsys fs, 10523 struct fill_dir_struct *fd, 10524 struct out_dir *outdir) 10525{ 10526 errcode_t retval; 10527 char *block_start; 10528 struct hash_entry *ent; 10529 struct ext2_dir_entry *dirent; 10530 int i, rec_len, left; 10531 ext2_dirhash_t prev_hash; 10532 int offset; 10533 10534 outdir->max = 0; 10535 retval = alloc_size_dir(fs, outdir, 10536 (fd->dir_size / fs->blocksize) + 2); 10537 if (retval) 10538 return retval; 10539 outdir->num = fd->compress ? 0 : 1; 10540 offset = 0; 10541 outdir->hashes[0] = 0; 10542 prev_hash = 1; 10543 if ((retval = get_next_block(fs, outdir, &block_start))) 10544 return retval; 10545 dirent = (struct ext2_dir_entry *) block_start; 10546 left = fs->blocksize; 10547 for (i=0; i < fd->num_array; i++) { 10548 ent = fd->harray + i; 10549 if (ent->dir->inode == 0) 10550 continue; 10551 rec_len = EXT2_DIR_REC_LEN(ent->dir->name_len & 0xFF); 10552 if (rec_len > left) { 10553 if (left) 10554 dirent->rec_len += left; 10555 if ((retval = get_next_block(fs, outdir, 10556 &block_start))) 10557 return retval; 10558 offset = 0; 10559 } 10560 left = fs->blocksize - offset; 10561 dirent = (struct ext2_dir_entry *) (block_start + offset); 10562 if (offset == 0) { 10563 if (ent->hash == prev_hash) 10564 outdir->hashes[outdir->num-1] = ent->hash | 1; 10565 else 10566 outdir->hashes[outdir->num-1] = ent->hash; 10567 } 10568 dirent->inode = ent->dir->inode; 10569 dirent->name_len = ent->dir->name_len; 10570 dirent->rec_len = rec_len; 10571 memcpy(dirent->name, ent->dir->name, dirent->name_len & 0xFF); 10572 offset += rec_len; 10573 left -= rec_len; 10574 if (left < 12) { 10575 dirent->rec_len += left; 10576 offset += left; 10577 left = 0; 10578 } 10579 prev_hash = ent->hash; 10580 } 10581 if (left) 10582 dirent->rec_len += left; 10583 10584 return 0; 10585} 10586 10587 10588static struct ext2_dx_root_info *set_root_node(ext2_filsys fs, char *buf, 10589 ext2_ino_t ino, ext2_ino_t parent) 10590{ 10591 struct ext2_dir_entry *dir; 10592 struct ext2_dx_root_info *root; 10593 struct ext2_dx_countlimit *limits; 10594 int filetype = 0; 10595 10596 if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_FILETYPE) 10597 filetype = EXT2_FT_DIR << 8; 10598 10599 memset(buf, 0, fs->blocksize); 10600 dir = (struct ext2_dir_entry *) buf; 10601 dir->inode = ino; 10602 dir->name[0] = '.'; 10603 dir->name_len = 1 | filetype; 10604 dir->rec_len = 12; 10605 dir = (struct ext2_dir_entry *) (buf + 12); 10606 dir->inode = parent; 10607 dir->name[0] = '.'; 10608 dir->name[1] = '.'; 10609 dir->name_len = 2 | filetype; 10610 dir->rec_len = fs->blocksize - 12; 10611 10612 root = (struct ext2_dx_root_info *) (buf+24); 10613 root->reserved_zero = 0; 10614 root->hash_version = fs->super->s_def_hash_version; 10615 root->info_length = 8; 10616 root->indirect_levels = 0; 10617 root->unused_flags = 0; 10618 10619 limits = (struct ext2_dx_countlimit *) (buf+32); 10620 limits->limit = (fs->blocksize - 32) / sizeof(struct ext2_dx_entry); 10621 limits->count = 0; 10622 10623 return root; 10624} 10625 10626 10627static struct ext2_dx_entry *set_int_node(ext2_filsys fs, char *buf) 10628{ 10629 struct ext2_dir_entry *dir; 10630 struct ext2_dx_countlimit *limits; 10631 10632 memset(buf, 0, fs->blocksize); 10633 dir = (struct ext2_dir_entry *) buf; 10634 dir->inode = 0; 10635 dir->rec_len = fs->blocksize; 10636 10637 limits = (struct ext2_dx_countlimit *) (buf+8); 10638 limits->limit = (fs->blocksize - 8) / sizeof(struct ext2_dx_entry); 10639 limits->count = 0; 10640 10641 return (struct ext2_dx_entry *) limits; 10642} 10643 10644/* 10645 * This function takes the leaf nodes which have been written in 10646 * outdir, and populates the root node and any necessary interior nodes. 10647 */ 10648static errcode_t calculate_tree(ext2_filsys fs, 10649 struct out_dir *outdir, 10650 ext2_ino_t ino, 10651 ext2_ino_t parent) 10652{ 10653 struct ext2_dx_root_info *root_info; 10654 struct ext2_dx_entry *root, *dx_ent = 0; 10655 struct ext2_dx_countlimit *root_limit, *limit; 10656 errcode_t retval; 10657 char * block_start; 10658 int i, c1, c2, nblks; 10659 int limit_offset, root_offset; 10660 10661 root_info = set_root_node(fs, outdir->buf, ino, parent); 10662 root_offset = limit_offset = ((char *) root_info - outdir->buf) + 10663 root_info->info_length; 10664 root_limit = (struct ext2_dx_countlimit *) (outdir->buf + limit_offset); 10665 c1 = root_limit->limit; 10666 nblks = outdir->num; 10667 10668 /* Write out the pointer blocks */ 10669 if (nblks-1 <= c1) { 10670 /* Just write out the root block, and we're done */ 10671 root = (struct ext2_dx_entry *) (outdir->buf + root_offset); 10672 for (i=1; i < nblks; i++) { 10673 root->block = ext2fs_cpu_to_le32(i); 10674 if (i != 1) 10675 root->hash = 10676 ext2fs_cpu_to_le32(outdir->hashes[i]); 10677 root++; 10678 c1--; 10679 } 10680 } else { 10681 c2 = 0; 10682 limit = 0; 10683 root_info->indirect_levels = 1; 10684 for (i=1; i < nblks; i++) { 10685 if (c1 == 0) 10686 return ENOSPC; 10687 if (c2 == 0) { 10688 if (limit) 10689 limit->limit = limit->count = 10690 ext2fs_cpu_to_le16(limit->limit); 10691 root = (struct ext2_dx_entry *) 10692 (outdir->buf + root_offset); 10693 root->block = ext2fs_cpu_to_le32(outdir->num); 10694 if (i != 1) 10695 root->hash = 10696 ext2fs_cpu_to_le32(outdir->hashes[i]); 10697 if ((retval = get_next_block(fs, outdir, 10698 &block_start))) 10699 return retval; 10700 dx_ent = set_int_node(fs, block_start); 10701 limit = (struct ext2_dx_countlimit *) dx_ent; 10702 c2 = limit->limit; 10703 root_offset += sizeof(struct ext2_dx_entry); 10704 c1--; 10705 } 10706 dx_ent->block = ext2fs_cpu_to_le32(i); 10707 if (c2 != limit->limit) 10708 dx_ent->hash = 10709 ext2fs_cpu_to_le32(outdir->hashes[i]); 10710 dx_ent++; 10711 c2--; 10712 } 10713 limit->count = ext2fs_cpu_to_le16(limit->limit - c2); 10714 limit->limit = ext2fs_cpu_to_le16(limit->limit); 10715 } 10716 root_limit = (struct ext2_dx_countlimit *) (outdir->buf + limit_offset); 10717 root_limit->count = ext2fs_cpu_to_le16(root_limit->limit - c1); 10718 root_limit->limit = ext2fs_cpu_to_le16(root_limit->limit); 10719 10720 return 0; 10721} 10722 10723struct write_dir_struct { 10724 struct out_dir *outdir; 10725 errcode_t err; 10726 e2fsck_t ctx; 10727 int cleared; 10728}; 10729 10730/* 10731 * Helper function which writes out a directory block. 10732 */ 10733static int write_dir_block(ext2_filsys fs, 10734 blk_t *block_nr, 10735 e2_blkcnt_t blockcnt, 10736 blk_t ref_block FSCK_ATTR((unused)), 10737 int ref_offset FSCK_ATTR((unused)), 10738 void *priv_data) 10739{ 10740 struct write_dir_struct *wd = (struct write_dir_struct *) priv_data; 10741 blk_t blk; 10742 char *dir; 10743 10744 if (*block_nr == 0) 10745 return 0; 10746 if (blockcnt >= wd->outdir->num) { 10747 e2fsck_read_bitmaps(wd->ctx); 10748 blk = *block_nr; 10749 ext2fs_unmark_block_bitmap(wd->ctx->block_found_map, blk); 10750 ext2fs_block_alloc_stats(fs, blk, -1); 10751 *block_nr = 0; 10752 wd->cleared++; 10753 return BLOCK_CHANGED; 10754 } 10755 if (blockcnt < 0) 10756 return 0; 10757 10758 dir = wd->outdir->buf + (blockcnt * fs->blocksize); 10759 wd->err = ext2fs_write_dir_block(fs, *block_nr, dir); 10760 if (wd->err) 10761 return BLOCK_ABORT; 10762 return 0; 10763} 10764 10765static errcode_t write_directory(e2fsck_t ctx, ext2_filsys fs, 10766 struct out_dir *outdir, 10767 ext2_ino_t ino, int compress) 10768{ 10769 struct write_dir_struct wd; 10770 errcode_t retval; 10771 struct ext2_inode inode; 10772 10773 retval = e2fsck_expand_directory(ctx, ino, -1, outdir->num); 10774 if (retval) 10775 return retval; 10776 10777 wd.outdir = outdir; 10778 wd.err = 0; 10779 wd.ctx = ctx; 10780 wd.cleared = 0; 10781 10782 retval = ext2fs_block_iterate2(fs, ino, 0, 0, 10783 write_dir_block, &wd); 10784 if (retval) 10785 return retval; 10786 if (wd.err) 10787 return wd.err; 10788 10789 e2fsck_read_inode(ctx, ino, &inode, "rehash_dir"); 10790 if (compress) 10791 inode.i_flags &= ~EXT2_INDEX_FL; 10792 else 10793 inode.i_flags |= EXT2_INDEX_FL; 10794 inode.i_size = outdir->num * fs->blocksize; 10795 inode.i_blocks -= (fs->blocksize / 512) * wd.cleared; 10796 e2fsck_write_inode(ctx, ino, &inode, "rehash_dir"); 10797 10798 return 0; 10799} 10800 10801static errcode_t e2fsck_rehash_dir(e2fsck_t ctx, ext2_ino_t ino) 10802{ 10803 ext2_filsys fs = ctx->fs; 10804 errcode_t retval; 10805 struct ext2_inode inode; 10806 char *dir_buf = 0; 10807 struct fill_dir_struct fd; 10808 struct out_dir outdir; 10809 10810 outdir.max = outdir.num = 0; 10811 outdir.buf = 0; 10812 outdir.hashes = 0; 10813 e2fsck_read_inode(ctx, ino, &inode, "rehash_dir"); 10814 10815 retval = ENOMEM; 10816 fd.harray = 0; 10817 dir_buf = malloc(inode.i_size); 10818 if (!dir_buf) 10819 goto errout; 10820 10821 fd.max_array = inode.i_size / 32; 10822 fd.num_array = 0; 10823 fd.harray = malloc(fd.max_array * sizeof(struct hash_entry)); 10824 if (!fd.harray) 10825 goto errout; 10826 10827 fd.ctx = ctx; 10828 fd.buf = dir_buf; 10829 fd.inode = &inode; 10830 fd.err = 0; 10831 fd.dir_size = 0; 10832 fd.compress = 0; 10833 if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) || 10834 (inode.i_size / fs->blocksize) < 2) 10835 fd.compress = 1; 10836 fd.parent = 0; 10837 10838 /* Read in the entire directory into memory */ 10839 retval = ext2fs_block_iterate2(fs, ino, 0, 0, 10840 fill_dir_block, &fd); 10841 if (fd.err) { 10842 retval = fd.err; 10843 goto errout; 10844 } 10845 10846 /* Sort the list */ 10847resort: 10848 if (fd.compress) 10849 qsort(fd.harray+2, fd.num_array-2, 10850 sizeof(struct hash_entry), name_cmp); 10851 else 10852 qsort(fd.harray, fd.num_array, 10853 sizeof(struct hash_entry), hash_cmp); 10854 10855 /* 10856 * Look for duplicates 10857 */ 10858 if (duplicate_search_and_fix(ctx, fs, ino, &fd)) 10859 goto resort; 10860 10861 if (ctx->options & E2F_OPT_NO) { 10862 retval = 0; 10863 goto errout; 10864 } 10865 10866 /* 10867 * Copy the directory entries. In a htree directory these 10868 * will become the leaf nodes. 10869 */ 10870 retval = copy_dir_entries(fs, &fd, &outdir); 10871 if (retval) 10872 goto errout; 10873 10874 free(dir_buf); dir_buf = 0; 10875 10876 if (!fd.compress) { 10877 /* Calculate the interior nodes */ 10878 retval = calculate_tree(fs, &outdir, ino, fd.parent); 10879 if (retval) 10880 goto errout; 10881 } 10882 10883 retval = write_directory(ctx, fs, &outdir, ino, fd.compress); 10884 10885errout: 10886 free(dir_buf); 10887 free(fd.harray); 10888 10889 free_out_dir(&outdir); 10890 return retval; 10891} 10892 10893void e2fsck_rehash_directories(e2fsck_t ctx) 10894{ 10895 struct problem_context pctx; 10896 struct dir_info *dir; 10897 ext2_u32_iterate iter; 10898 ext2_ino_t ino; 10899 errcode_t retval; 10900 int i, cur, max, all_dirs, dir_index, first = 1; 10901 10902 all_dirs = ctx->options & E2F_OPT_COMPRESS_DIRS; 10903 10904 if (!ctx->dirs_to_hash && !all_dirs) 10905 return; 10906 10907 e2fsck_get_lost_and_found(ctx, 0); 10908 10909 clear_problem_context(&pctx); 10910 10911 dir_index = ctx->fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX; 10912 cur = 0; 10913 if (all_dirs) { 10914 i = 0; 10915 max = e2fsck_get_num_dirinfo(ctx); 10916 } else { 10917 retval = ext2fs_u32_list_iterate_begin(ctx->dirs_to_hash, 10918 &iter); 10919 if (retval) { 10920 pctx.errcode = retval; 10921 fix_problem(ctx, PR_3A_OPTIMIZE_ITER, &pctx); 10922 return; 10923 } 10924 max = ext2fs_u32_list_count(ctx->dirs_to_hash); 10925 } 10926 while (1) { 10927 if (all_dirs) { 10928 if ((dir = e2fsck_dir_info_iter(ctx, &i)) == 0) 10929 break; 10930 ino = dir->ino; 10931 } else { 10932 if (!ext2fs_u32_list_iterate(iter, &ino)) 10933 break; 10934 } 10935 if (ino == ctx->lost_and_found) 10936 continue; 10937 pctx.dir = ino; 10938 if (first) { 10939 fix_problem(ctx, PR_3A_PASS_HEADER, &pctx); 10940 first = 0; 10941 } 10942 pctx.errcode = e2fsck_rehash_dir(ctx, ino); 10943 if (pctx.errcode) { 10944 end_problem_latch(ctx, PR_LATCH_OPTIMIZE_DIR); 10945 fix_problem(ctx, PR_3A_OPTIMIZE_DIR_ERR, &pctx); 10946 } 10947 if (ctx->progress && !ctx->progress_fd) 10948 e2fsck_simple_progress(ctx, "Rebuilding directory", 10949 100.0 * (float) (++cur) / (float) max, ino); 10950 } 10951 end_problem_latch(ctx, PR_LATCH_OPTIMIZE_DIR); 10952 if (!all_dirs) 10953 ext2fs_u32_list_iterate_end(iter); 10954 10955 ext2fs_u32_list_free(ctx->dirs_to_hash); 10956 ctx->dirs_to_hash = 0; 10957} 10958 10959/* 10960 * linux/fs/revoke.c 10961 * 10962 * Journal revoke routines for the generic filesystem journaling code; 10963 * part of the ext2fs journaling system. 10964 * 10965 * Revoke is the mechanism used to prevent old log records for deleted 10966 * metadata from being replayed on top of newer data using the same 10967 * blocks. The revoke mechanism is used in two separate places: 10968 * 10969 * + Commit: during commit we write the entire list of the current 10970 * transaction's revoked blocks to the journal 10971 * 10972 * + Recovery: during recovery we record the transaction ID of all 10973 * revoked blocks. If there are multiple revoke records in the log 10974 * for a single block, only the last one counts, and if there is a log 10975 * entry for a block beyond the last revoke, then that log entry still 10976 * gets replayed. 10977 * 10978 * We can get interactions between revokes and new log data within a 10979 * single transaction: 10980 * 10981 * Block is revoked and then journaled: 10982 * The desired end result is the journaling of the new block, so we 10983 * cancel the revoke before the transaction commits. 10984 * 10985 * Block is journaled and then revoked: 10986 * The revoke must take precedence over the write of the block, so we 10987 * need either to cancel the journal entry or to write the revoke 10988 * later in the log than the log block. In this case, we choose the 10989 * latter: journaling a block cancels any revoke record for that block 10990 * in the current transaction, so any revoke for that block in the 10991 * transaction must have happened after the block was journaled and so 10992 * the revoke must take precedence. 10993 * 10994 * Block is revoked and then written as data: 10995 * The data write is allowed to succeed, but the revoke is _not_ 10996 * cancelled. We still need to prevent old log records from 10997 * overwriting the new data. We don't even need to clear the revoke 10998 * bit here. 10999 * 11000 * Revoke information on buffers is a tri-state value: 11001 * 11002 * RevokeValid clear: no cached revoke status, need to look it up 11003 * RevokeValid set, Revoked clear: 11004 * buffer has not been revoked, and cancel_revoke 11005 * need do nothing. 11006 * RevokeValid set, Revoked set: 11007 * buffer has been revoked. 11008 */ 11009 11010static kmem_cache_t *revoke_record_cache; 11011static kmem_cache_t *revoke_table_cache; 11012 11013/* Each revoke record represents one single revoked block. During 11014 journal replay, this involves recording the transaction ID of the 11015 last transaction to revoke this block. */ 11016 11017struct jbd_revoke_record_s 11018{ 11019 struct list_head hash; 11020 tid_t sequence; /* Used for recovery only */ 11021 unsigned long blocknr; 11022}; 11023 11024 11025/* The revoke table is just a simple hash table of revoke records. */ 11026struct jbd_revoke_table_s 11027{ 11028 /* It is conceivable that we might want a larger hash table 11029 * for recovery. Must be a power of two. */ 11030 int hash_size; 11031 int hash_shift; 11032 struct list_head *hash_table; 11033}; 11034 11035 11036/* Utility functions to maintain the revoke table */ 11037 11038/* Borrowed from buffer.c: this is a tried and tested block hash function */ 11039static int hash(journal_t *journal, unsigned long block) 11040{ 11041 struct jbd_revoke_table_s *table = journal->j_revoke; 11042 int hash_shift = table->hash_shift; 11043 11044 return ((block << (hash_shift - 6)) ^ 11045 (block >> 13) ^ 11046 (block << (hash_shift - 12))) & (table->hash_size - 1); 11047} 11048 11049static int insert_revoke_hash(journal_t *journal, unsigned long blocknr, 11050 tid_t seq) 11051{ 11052 struct list_head *hash_list; 11053 struct jbd_revoke_record_s *record; 11054 11055 record = kmem_cache_alloc(revoke_record_cache, GFP_NOFS); 11056 if (!record) 11057 goto oom; 11058 11059 record->sequence = seq; 11060 record->blocknr = blocknr; 11061 hash_list = &journal->j_revoke->hash_table[hash(journal, blocknr)]; 11062 list_add(&record->hash, hash_list); 11063 return 0; 11064 11065oom: 11066 return -ENOMEM; 11067} 11068 11069/* Find a revoke record in the journal's hash table. */ 11070 11071static struct jbd_revoke_record_s *find_revoke_record(journal_t *journal, 11072 unsigned long blocknr) 11073{ 11074 struct list_head *hash_list; 11075 struct jbd_revoke_record_s *record; 11076 11077 hash_list = &journal->j_revoke->hash_table[hash(journal, blocknr)]; 11078 11079 record = (struct jbd_revoke_record_s *) hash_list->next; 11080 while (&(record->hash) != hash_list) { 11081 if (record->blocknr == blocknr) 11082 return record; 11083 record = (struct jbd_revoke_record_s *) record->hash.next; 11084 } 11085 return NULL; 11086} 11087 11088int journal_init_revoke_caches(void) 11089{ 11090 revoke_record_cache = do_cache_create(sizeof(struct jbd_revoke_record_s)); 11091 if (revoke_record_cache == 0) 11092 return -ENOMEM; 11093 11094 revoke_table_cache = do_cache_create(sizeof(struct jbd_revoke_table_s)); 11095 if (revoke_table_cache == 0) { 11096 do_cache_destroy(revoke_record_cache); 11097 revoke_record_cache = NULL; 11098 return -ENOMEM; 11099 } 11100 return 0; 11101} 11102 11103void journal_destroy_revoke_caches(void) 11104{ 11105 do_cache_destroy(revoke_record_cache); 11106 revoke_record_cache = 0; 11107 do_cache_destroy(revoke_table_cache); 11108 revoke_table_cache = 0; 11109} 11110 11111/* Initialise the revoke table for a given journal to a given size. */ 11112 11113int journal_init_revoke(journal_t *journal, int hash_size) 11114{ 11115 int shift, tmp; 11116 11117 journal->j_revoke = kmem_cache_alloc(revoke_table_cache, GFP_KERNEL); 11118 if (!journal->j_revoke) 11119 return -ENOMEM; 11120 11121 /* Check that the hash_size is a power of two */ 11122 journal->j_revoke->hash_size = hash_size; 11123 11124 shift = 0; 11125 tmp = hash_size; 11126 while((tmp >>= 1UL) != 0UL) 11127 shift++; 11128 journal->j_revoke->hash_shift = shift; 11129 11130 journal->j_revoke->hash_table = malloc(hash_size * sizeof(struct list_head)); 11131 if (!journal->j_revoke->hash_table) { 11132 free(journal->j_revoke); 11133 journal->j_revoke = NULL; 11134 return -ENOMEM; 11135 } 11136 11137 for (tmp = 0; tmp < hash_size; tmp++) 11138 INIT_LIST_HEAD(&journal->j_revoke->hash_table[tmp]); 11139 11140 return 0; 11141} 11142 11143/* Destoy a journal's revoke table. The table must already be empty! */ 11144 11145void journal_destroy_revoke(journal_t *journal) 11146{ 11147 struct jbd_revoke_table_s *table; 11148 struct list_head *hash_list; 11149 int i; 11150 11151 table = journal->j_revoke; 11152 if (!table) 11153 return; 11154 11155 for (i=0; i<table->hash_size; i++) { 11156 hash_list = &table->hash_table[i]; 11157 } 11158 11159 free(table->hash_table); 11160 free(table); 11161 journal->j_revoke = NULL; 11162} 11163 11164/* 11165 * Revoke support for recovery. 11166 * 11167 * Recovery needs to be able to: 11168 * 11169 * record all revoke records, including the tid of the latest instance 11170 * of each revoke in the journal 11171 * 11172 * check whether a given block in a given transaction should be replayed 11173 * (ie. has not been revoked by a revoke record in that or a subsequent 11174 * transaction) 11175 * 11176 * empty the revoke table after recovery. 11177 */ 11178 11179/* 11180 * First, setting revoke records. We create a new revoke record for 11181 * every block ever revoked in the log as we scan it for recovery, and 11182 * we update the existing records if we find multiple revokes for a 11183 * single block. 11184 */ 11185 11186int journal_set_revoke(journal_t *journal, unsigned long blocknr, 11187 tid_t sequence) 11188{ 11189 struct jbd_revoke_record_s *record; 11190 11191 record = find_revoke_record(journal, blocknr); 11192 if (record) { 11193 /* If we have multiple occurences, only record the 11194 * latest sequence number in the hashed record */ 11195 if (tid_gt(sequence, record->sequence)) 11196 record->sequence = sequence; 11197 return 0; 11198 } 11199 return insert_revoke_hash(journal, blocknr, sequence); 11200} 11201 11202/* 11203 * Test revoke records. For a given block referenced in the log, has 11204 * that block been revoked? A revoke record with a given transaction 11205 * sequence number revokes all blocks in that transaction and earlier 11206 * ones, but later transactions still need replayed. 11207 */ 11208 11209int journal_test_revoke(journal_t *journal, unsigned long blocknr, 11210 tid_t sequence) 11211{ 11212 struct jbd_revoke_record_s *record; 11213 11214 record = find_revoke_record(journal, blocknr); 11215 if (!record) 11216 return 0; 11217 if (tid_gt(sequence, record->sequence)) 11218 return 0; 11219 return 1; 11220} 11221 11222/* 11223 * Finally, once recovery is over, we need to clear the revoke table so 11224 * that it can be reused by the running filesystem. 11225 */ 11226 11227void journal_clear_revoke(journal_t *journal) 11228{ 11229 int i; 11230 struct list_head *hash_list; 11231 struct jbd_revoke_record_s *record; 11232 struct jbd_revoke_table_s *revoke_var; 11233 11234 revoke_var = journal->j_revoke; 11235 11236 for (i = 0; i < revoke_var->hash_size; i++) { 11237 hash_list = &revoke_var->hash_table[i]; 11238 while (!list_empty(hash_list)) { 11239 record = (struct jbd_revoke_record_s*) hash_list->next; 11240 list_del(&record->hash); 11241 free(record); 11242 } 11243 } 11244} 11245 11246/* 11247 * e2fsck.c - superblock checks 11248 */ 11249 11250#define MIN_CHECK 1 11251#define MAX_CHECK 2 11252 11253static void check_super_value(e2fsck_t ctx, const char *descr, 11254 unsigned long value, int flags, 11255 unsigned long min_val, unsigned long max_val) 11256{ 11257 struct problem_context pctx; 11258 11259 if (((flags & MIN_CHECK) && (value < min_val)) || 11260 ((flags & MAX_CHECK) && (value > max_val))) { 11261 clear_problem_context(&pctx); 11262 pctx.num = value; 11263 pctx.str = descr; 11264 fix_problem(ctx, PR_0_MISC_CORRUPT_SUPER, &pctx); 11265 ctx->flags |= E2F_FLAG_ABORT; /* never get here! */ 11266 } 11267} 11268 11269/* 11270 * This routine may get stubbed out in special compilations of the 11271 * e2fsck code.. 11272 */ 11273#ifndef EXT2_SPECIAL_DEVICE_SIZE 11274static errcode_t e2fsck_get_device_size(e2fsck_t ctx) 11275{ 11276 return (ext2fs_get_device_size(ctx->filesystem_name, 11277 EXT2_BLOCK_SIZE(ctx->fs->super), 11278 &ctx->num_blocks)); 11279} 11280#endif 11281 11282/* 11283 * helper function to release an inode 11284 */ 11285struct process_block_struct { 11286 e2fsck_t ctx; 11287 char *buf; 11288 struct problem_context *pctx; 11289 int truncating; 11290 int truncate_offset; 11291 e2_blkcnt_t truncate_block; 11292 int truncated_blocks; 11293 int abort; 11294 errcode_t errcode; 11295}; 11296 11297static int release_inode_block(ext2_filsys fs, blk_t *block_nr, 11298 e2_blkcnt_t blockcnt, 11299 blk_t ref_blk FSCK_ATTR((unused)), 11300 int ref_offset FSCK_ATTR((unused)), 11301 void *priv_data) 11302{ 11303 struct process_block_struct *pb; 11304 e2fsck_t ctx; 11305 struct problem_context *pctx; 11306 blk_t blk = *block_nr; 11307 int retval = 0; 11308 11309 pb = (struct process_block_struct *) priv_data; 11310 ctx = pb->ctx; 11311 pctx = pb->pctx; 11312 11313 pctx->blk = blk; 11314 pctx->blkcount = blockcnt; 11315 11316 if (HOLE_BLKADDR(blk)) 11317 return 0; 11318 11319 if ((blk < fs->super->s_first_data_block) || 11320 (blk >= fs->super->s_blocks_count)) { 11321 fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_BLOCK_NUM, pctx); 11322 return_abort: 11323 pb->abort = 1; 11324 return BLOCK_ABORT; 11325 } 11326 11327 if (!ext2fs_test_block_bitmap(fs->block_map, blk)) { 11328 fix_problem(ctx, PR_0_ORPHAN_ALREADY_CLEARED_BLOCK, pctx); 11329 goto return_abort; 11330 } 11331 11332 /* 11333 * If we are deleting an orphan, then we leave the fields alone. 11334 * If we are truncating an orphan, then update the inode fields 11335 * and clean up any partial block data. 11336 */ 11337 if (pb->truncating) { 11338 /* 11339 * We only remove indirect blocks if they are 11340 * completely empty. 11341 */ 11342 if (blockcnt < 0) { 11343 int i, limit; 11344 blk_t *bp; 11345 11346 pb->errcode = io_channel_read_blk(fs->io, blk, 1, 11347 pb->buf); 11348 if (pb->errcode) 11349 goto return_abort; 11350 11351 limit = fs->blocksize >> 2; 11352 for (i = 0, bp = (blk_t *) pb->buf; 11353 i < limit; i++, bp++) 11354 if (*bp) 11355 return 0; 11356 } 11357 /* 11358 * We don't remove direct blocks until we've reached 11359 * the truncation block. 11360 */ 11361 if (blockcnt >= 0 && blockcnt < pb->truncate_block) 11362 return 0; 11363 /* 11364 * If part of the last block needs truncating, we do 11365 * it here. 11366 */ 11367 if ((blockcnt == pb->truncate_block) && pb->truncate_offset) { 11368 pb->errcode = io_channel_read_blk(fs->io, blk, 1, 11369 pb->buf); 11370 if (pb->errcode) 11371 goto return_abort; 11372 memset(pb->buf + pb->truncate_offset, 0, 11373 fs->blocksize - pb->truncate_offset); 11374 pb->errcode = io_channel_write_blk(fs->io, blk, 1, 11375 pb->buf); 11376 if (pb->errcode) 11377 goto return_abort; 11378 } 11379 pb->truncated_blocks++; 11380 *block_nr = 0; 11381 retval |= BLOCK_CHANGED; 11382 } 11383 11384 ext2fs_block_alloc_stats(fs, blk, -1); 11385 return retval; 11386} 11387 11388/* 11389 * This function releases an inode. Returns 1 if an inconsistency was 11390 * found. If the inode has a link count, then it is being truncated and 11391 * not deleted. 11392 */ 11393static int release_inode_blocks(e2fsck_t ctx, ext2_ino_t ino, 11394 struct ext2_inode *inode, char *block_buf, 11395 struct problem_context *pctx) 11396{ 11397 struct process_block_struct pb; 11398 ext2_filsys fs = ctx->fs; 11399 errcode_t retval; 11400 __u32 count; 11401 11402 if (!ext2fs_inode_has_valid_blocks(inode)) 11403 return 0; 11404 11405 pb.buf = block_buf + 3 * ctx->fs->blocksize; 11406 pb.ctx = ctx; 11407 pb.abort = 0; 11408 pb.errcode = 0; 11409 pb.pctx = pctx; 11410 if (inode->i_links_count) { 11411 pb.truncating = 1; 11412 pb.truncate_block = (e2_blkcnt_t) 11413 ((((long long)inode->i_size_high << 32) + 11414 inode->i_size + fs->blocksize - 1) / 11415 fs->blocksize); 11416 pb.truncate_offset = inode->i_size % fs->blocksize; 11417 } else { 11418 pb.truncating = 0; 11419 pb.truncate_block = 0; 11420 pb.truncate_offset = 0; 11421 } 11422 pb.truncated_blocks = 0; 11423 retval = ext2fs_block_iterate2(fs, ino, BLOCK_FLAG_DEPTH_TRAVERSE, 11424 block_buf, release_inode_block, &pb); 11425 if (retval) { 11426 bb_error_msg(_("while calling ext2fs_block_iterate for inode %d"), 11427 ino); 11428 return 1; 11429 } 11430 if (pb.abort) 11431 return 1; 11432 11433 /* Refresh the inode since ext2fs_block_iterate may have changed it */ 11434 e2fsck_read_inode(ctx, ino, inode, "release_inode_blocks"); 11435 11436 if (pb.truncated_blocks) 11437 inode->i_blocks -= pb.truncated_blocks * 11438 (fs->blocksize / 512); 11439 11440 if (inode->i_file_acl) { 11441 retval = ext2fs_adjust_ea_refcount(fs, inode->i_file_acl, 11442 block_buf, -1, &count); 11443 if (retval == EXT2_ET_BAD_EA_BLOCK_NUM) { 11444 retval = 0; 11445 count = 1; 11446 } 11447 if (retval) { 11448 bb_error_msg(_("while calling ext2fs_adjust_ea_refocunt for inode %d"), 11449 ino); 11450 return 1; 11451 } 11452 if (count == 0) 11453 ext2fs_block_alloc_stats(fs, inode->i_file_acl, -1); 11454 inode->i_file_acl = 0; 11455 } 11456 return 0; 11457} 11458 11459/* 11460 * This function releases all of the orphan inodes. It returns 1 if 11461 * it hit some error, and 0 on success. 11462 */ 11463static int release_orphan_inodes(e2fsck_t ctx) 11464{ 11465 ext2_filsys fs = ctx->fs; 11466 ext2_ino_t ino, next_ino; 11467 struct ext2_inode inode; 11468 struct problem_context pctx; 11469 char *block_buf; 11470 11471 if ((ino = fs->super->s_last_orphan) == 0) 11472 return 0; 11473 11474 /* 11475 * Win or lose, we won't be using the head of the orphan inode 11476 * list again. 11477 */ 11478 fs->super->s_last_orphan = 0; 11479 ext2fs_mark_super_dirty(fs); 11480 11481 /* 11482 * If the filesystem contains errors, don't run the orphan 11483 * list, since the orphan list can't be trusted; and we're 11484 * going to be running a full e2fsck run anyway... 11485 */ 11486 if (fs->super->s_state & EXT2_ERROR_FS) 11487 return 0; 11488 11489 if ((ino < EXT2_FIRST_INODE(fs->super)) || 11490 (ino > fs->super->s_inodes_count)) { 11491 clear_problem_context(&pctx); 11492 pctx.ino = ino; 11493 fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_HEAD_INODE, &pctx); 11494 return 1; 11495 } 11496 11497 block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 4, 11498 "block iterate buffer"); 11499 e2fsck_read_bitmaps(ctx); 11500 11501 while (ino) { 11502 e2fsck_read_inode(ctx, ino, &inode, "release_orphan_inodes"); 11503 clear_problem_context(&pctx); 11504 pctx.ino = ino; 11505 pctx.inode = &inode; 11506 pctx.str = inode.i_links_count ? _("Truncating") : 11507 _("Clearing"); 11508 11509 fix_problem(ctx, PR_0_ORPHAN_CLEAR_INODE, &pctx); 11510 11511 next_ino = inode.i_dtime; 11512 if (next_ino && 11513 ((next_ino < EXT2_FIRST_INODE(fs->super)) || 11514 (next_ino > fs->super->s_inodes_count))) { 11515 pctx.ino = next_ino; 11516 fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_INODE, &pctx); 11517 goto return_abort; 11518 } 11519 11520 if (release_inode_blocks(ctx, ino, &inode, block_buf, &pctx)) 11521 goto return_abort; 11522 11523 if (!inode.i_links_count) { 11524 ext2fs_inode_alloc_stats2(fs, ino, -1, 11525 LINUX_S_ISDIR(inode.i_mode)); 11526 inode.i_dtime = time(0); 11527 } else { 11528 inode.i_dtime = 0; 11529 } 11530 e2fsck_write_inode(ctx, ino, &inode, "delete_file"); 11531 ino = next_ino; 11532 } 11533 ext2fs_free_mem(&block_buf); 11534 return 0; 11535return_abort: 11536 ext2fs_free_mem(&block_buf); 11537 return 1; 11538} 11539 11540/* 11541 * Check the resize inode to make sure it is sane. We check both for 11542 * the case where on-line resizing is not enabled (in which case the 11543 * resize inode should be cleared) as well as the case where on-line 11544 * resizing is enabled. 11545 */ 11546static void check_resize_inode(e2fsck_t ctx) 11547{ 11548 ext2_filsys fs = ctx->fs; 11549 struct ext2_inode inode; 11550 struct problem_context pctx; 11551 int i, j, gdt_off, ind_off; 11552 blk_t blk, pblk, expect; 11553 __u32 *dind_buf = 0, *ind_buf; 11554 errcode_t retval; 11555 11556 clear_problem_context(&pctx); 11557 11558 /* 11559 * If the resize inode feature isn't set, then 11560 * s_reserved_gdt_blocks must be zero. 11561 */ 11562 if (!(fs->super->s_feature_compat & 11563 EXT2_FEATURE_COMPAT_RESIZE_INODE)) { 11564 if (fs->super->s_reserved_gdt_blocks) { 11565 pctx.num = fs->super->s_reserved_gdt_blocks; 11566 if (fix_problem(ctx, PR_0_NONZERO_RESERVED_GDT_BLOCKS, 11567 &pctx)) { 11568 fs->super->s_reserved_gdt_blocks = 0; 11569 ext2fs_mark_super_dirty(fs); 11570 } 11571 } 11572 } 11573 11574 /* Read the resize inode */ 11575 pctx.ino = EXT2_RESIZE_INO; 11576 retval = ext2fs_read_inode(fs, EXT2_RESIZE_INO, &inode); 11577 if (retval) { 11578 if (fs->super->s_feature_compat & 11579 EXT2_FEATURE_COMPAT_RESIZE_INODE) 11580 ctx->flags |= E2F_FLAG_RESIZE_INODE; 11581 return; 11582 } 11583 11584 /* 11585 * If the resize inode feature isn't set, check to make sure 11586 * the resize inode is cleared; then we're done. 11587 */ 11588 if (!(fs->super->s_feature_compat & 11589 EXT2_FEATURE_COMPAT_RESIZE_INODE)) { 11590 for (i=0; i < EXT2_N_BLOCKS; i++) { 11591 if (inode.i_block[i]) 11592 break; 11593 } 11594 if ((i < EXT2_N_BLOCKS) && 11595 fix_problem(ctx, PR_0_CLEAR_RESIZE_INODE, &pctx)) { 11596 memset(&inode, 0, sizeof(inode)); 11597 e2fsck_write_inode(ctx, EXT2_RESIZE_INO, &inode, 11598 "clear_resize"); 11599 } 11600 return; 11601 } 11602 11603 /* 11604 * The resize inode feature is enabled; check to make sure the 11605 * only block in use is the double indirect block 11606 */ 11607 blk = inode.i_block[EXT2_DIND_BLOCK]; 11608 for (i=0; i < EXT2_N_BLOCKS; i++) { 11609 if (i != EXT2_DIND_BLOCK && inode.i_block[i]) 11610 break; 11611 } 11612 if ((i < EXT2_N_BLOCKS) || !blk || !inode.i_links_count || 11613 !(inode.i_mode & LINUX_S_IFREG) || 11614 (blk < fs->super->s_first_data_block || 11615 blk >= fs->super->s_blocks_count)) { 11616 resize_inode_invalid: 11617 if (fix_problem(ctx, PR_0_RESIZE_INODE_INVALID, &pctx)) { 11618 memset(&inode, 0, sizeof(inode)); 11619 e2fsck_write_inode(ctx, EXT2_RESIZE_INO, &inode, 11620 "clear_resize"); 11621 ctx->flags |= E2F_FLAG_RESIZE_INODE; 11622 } 11623 if (!(ctx->options & E2F_OPT_READONLY)) { 11624 fs->super->s_state &= ~EXT2_VALID_FS; 11625 ext2fs_mark_super_dirty(fs); 11626 } 11627 goto cleanup; 11628 } 11629 dind_buf = (__u32 *) e2fsck_allocate_memory(ctx, fs->blocksize * 2, 11630 "resize dind buffer"); 11631 ind_buf = (__u32 *) ((char *) dind_buf + fs->blocksize); 11632 11633 retval = ext2fs_read_ind_block(fs, blk, dind_buf); 11634 if (retval) 11635 goto resize_inode_invalid; 11636 11637 gdt_off = fs->desc_blocks; 11638 pblk = fs->super->s_first_data_block + 1 + fs->desc_blocks; 11639 for (i = 0; i < fs->super->s_reserved_gdt_blocks / 4; 11640 i++, gdt_off++, pblk++) { 11641 gdt_off %= fs->blocksize/4; 11642 if (dind_buf[gdt_off] != pblk) 11643 goto resize_inode_invalid; 11644 retval = ext2fs_read_ind_block(fs, pblk, ind_buf); 11645 if (retval) 11646 goto resize_inode_invalid; 11647 ind_off = 0; 11648 for (j = 1; j < fs->group_desc_count; j++) { 11649 if (!ext2fs_bg_has_super(fs, j)) 11650 continue; 11651 expect = pblk + (j * fs->super->s_blocks_per_group); 11652 if (ind_buf[ind_off] != expect) 11653 goto resize_inode_invalid; 11654 ind_off++; 11655 } 11656 } 11657 11658cleanup: 11659 ext2fs_free_mem(&dind_buf); 11660 11661 } 11662 11663static void check_super_block(e2fsck_t ctx) 11664{ 11665 ext2_filsys fs = ctx->fs; 11666 blk_t first_block, last_block; 11667 struct ext2_super_block *sb = fs->super; 11668 struct ext2_group_desc *gd; 11669 blk_t blocks_per_group = fs->super->s_blocks_per_group; 11670 blk_t bpg_max; 11671 int inodes_per_block; 11672 int ipg_max; 11673 int inode_size; 11674 dgrp_t i; 11675 blk_t should_be; 11676 struct problem_context pctx; 11677 __u32 free_blocks = 0, free_inodes = 0; 11678 11679 inodes_per_block = EXT2_INODES_PER_BLOCK(fs->super); 11680 ipg_max = inodes_per_block * (blocks_per_group - 4); 11681 if (ipg_max > EXT2_MAX_INODES_PER_GROUP(sb)) 11682 ipg_max = EXT2_MAX_INODES_PER_GROUP(sb); 11683 bpg_max = 8 * EXT2_BLOCK_SIZE(sb); 11684 if (bpg_max > EXT2_MAX_BLOCKS_PER_GROUP(sb)) 11685 bpg_max = EXT2_MAX_BLOCKS_PER_GROUP(sb); 11686 11687 ctx->invalid_inode_bitmap_flag = (int *) e2fsck_allocate_memory(ctx, 11688 sizeof(int) * fs->group_desc_count, "invalid_inode_bitmap"); 11689 ctx->invalid_block_bitmap_flag = (int *) e2fsck_allocate_memory(ctx, 11690 sizeof(int) * fs->group_desc_count, "invalid_block_bitmap"); 11691 ctx->invalid_inode_table_flag = (int *) e2fsck_allocate_memory(ctx, 11692 sizeof(int) * fs->group_desc_count, "invalid_inode_table"); 11693 11694 clear_problem_context(&pctx); 11695 11696 /* 11697 * Verify the super block constants... 11698 */ 11699 check_super_value(ctx, "inodes_count", sb->s_inodes_count, 11700 MIN_CHECK, 1, 0); 11701 check_super_value(ctx, "blocks_count", sb->s_blocks_count, 11702 MIN_CHECK, 1, 0); 11703 check_super_value(ctx, "first_data_block", sb->s_first_data_block, 11704 MAX_CHECK, 0, sb->s_blocks_count); 11705 check_super_value(ctx, "log_block_size", sb->s_log_block_size, 11706 MIN_CHECK | MAX_CHECK, 0, 11707 EXT2_MAX_BLOCK_LOG_SIZE - EXT2_MIN_BLOCK_LOG_SIZE); 11708 check_super_value(ctx, "log_frag_size", sb->s_log_frag_size, 11709 MIN_CHECK | MAX_CHECK, 0, sb->s_log_block_size); 11710 check_super_value(ctx, "frags_per_group", sb->s_frags_per_group, 11711 MIN_CHECK | MAX_CHECK, sb->s_blocks_per_group, 11712 bpg_max); 11713 check_super_value(ctx, "blocks_per_group", sb->s_blocks_per_group, 11714 MIN_CHECK | MAX_CHECK, 8, bpg_max); 11715 check_super_value(ctx, "inodes_per_group", sb->s_inodes_per_group, 11716 MIN_CHECK | MAX_CHECK, inodes_per_block, ipg_max); 11717 check_super_value(ctx, "r_blocks_count", sb->s_r_blocks_count, 11718 MAX_CHECK, 0, sb->s_blocks_count / 2); 11719 check_super_value(ctx, "reserved_gdt_blocks", 11720 sb->s_reserved_gdt_blocks, MAX_CHECK, 0, 11721 fs->blocksize/4); 11722 inode_size = EXT2_INODE_SIZE(sb); 11723 check_super_value(ctx, "inode_size", 11724 inode_size, MIN_CHECK | MAX_CHECK, 11725 EXT2_GOOD_OLD_INODE_SIZE, fs->blocksize); 11726 if (inode_size & (inode_size - 1)) { 11727 pctx.num = inode_size; 11728 pctx.str = "inode_size"; 11729 fix_problem(ctx, PR_0_MISC_CORRUPT_SUPER, &pctx); 11730 ctx->flags |= E2F_FLAG_ABORT; /* never get here! */ 11731 return; 11732 } 11733 11734 if (!ctx->num_blocks) { 11735 pctx.errcode = e2fsck_get_device_size(ctx); 11736 if (pctx.errcode && pctx.errcode != EXT2_ET_UNIMPLEMENTED) { 11737 fix_problem(ctx, PR_0_GETSIZE_ERROR, &pctx); 11738 ctx->flags |= E2F_FLAG_ABORT; 11739 return; 11740 } 11741 if ((pctx.errcode != EXT2_ET_UNIMPLEMENTED) && 11742 (ctx->num_blocks < sb->s_blocks_count)) { 11743 pctx.blk = sb->s_blocks_count; 11744 pctx.blk2 = ctx->num_blocks; 11745 if (fix_problem(ctx, PR_0_FS_SIZE_WRONG, &pctx)) { 11746 ctx->flags |= E2F_FLAG_ABORT; 11747 return; 11748 } 11749 } 11750 } 11751 11752 if (sb->s_log_block_size != (__u32) sb->s_log_frag_size) { 11753 pctx.blk = EXT2_BLOCK_SIZE(sb); 11754 pctx.blk2 = EXT2_FRAG_SIZE(sb); 11755 fix_problem(ctx, PR_0_NO_FRAGMENTS, &pctx); 11756 ctx->flags |= E2F_FLAG_ABORT; 11757 return; 11758 } 11759 11760 should_be = sb->s_frags_per_group >> 11761 (sb->s_log_block_size - sb->s_log_frag_size); 11762 if (sb->s_blocks_per_group != should_be) { 11763 pctx.blk = sb->s_blocks_per_group; 11764 pctx.blk2 = should_be; 11765 fix_problem(ctx, PR_0_BLOCKS_PER_GROUP, &pctx); 11766 ctx->flags |= E2F_FLAG_ABORT; 11767 return; 11768 } 11769 11770 should_be = (sb->s_log_block_size == 0) ? 1 : 0; 11771 if (sb->s_first_data_block != should_be) { 11772 pctx.blk = sb->s_first_data_block; 11773 pctx.blk2 = should_be; 11774 fix_problem(ctx, PR_0_FIRST_DATA_BLOCK, &pctx); 11775 ctx->flags |= E2F_FLAG_ABORT; 11776 return; 11777 } 11778 11779 should_be = sb->s_inodes_per_group * fs->group_desc_count; 11780 if (sb->s_inodes_count != should_be) { 11781 pctx.ino = sb->s_inodes_count; 11782 pctx.ino2 = should_be; 11783 if (fix_problem(ctx, PR_0_INODE_COUNT_WRONG, &pctx)) { 11784 sb->s_inodes_count = should_be; 11785 ext2fs_mark_super_dirty(fs); 11786 } 11787 } 11788 11789 /* 11790 * Verify the group descriptors.... 11791 */ 11792 first_block = sb->s_first_data_block; 11793 last_block = first_block + blocks_per_group; 11794 11795 for (i = 0, gd=fs->group_desc; i < fs->group_desc_count; i++, gd++) { 11796 pctx.group = i; 11797 11798 if (i == fs->group_desc_count - 1) 11799 last_block = sb->s_blocks_count; 11800 if ((gd->bg_block_bitmap < first_block) || 11801 (gd->bg_block_bitmap >= last_block)) { 11802 pctx.blk = gd->bg_block_bitmap; 11803 if (fix_problem(ctx, PR_0_BB_NOT_GROUP, &pctx)) 11804 gd->bg_block_bitmap = 0; 11805 } 11806 if (gd->bg_block_bitmap == 0) { 11807 ctx->invalid_block_bitmap_flag[i]++; 11808 ctx->invalid_bitmaps++; 11809 } 11810 if ((gd->bg_inode_bitmap < first_block) || 11811 (gd->bg_inode_bitmap >= last_block)) { 11812 pctx.blk = gd->bg_inode_bitmap; 11813 if (fix_problem(ctx, PR_0_IB_NOT_GROUP, &pctx)) 11814 gd->bg_inode_bitmap = 0; 11815 } 11816 if (gd->bg_inode_bitmap == 0) { 11817 ctx->invalid_inode_bitmap_flag[i]++; 11818 ctx->invalid_bitmaps++; 11819 } 11820 if ((gd->bg_inode_table < first_block) || 11821 ((gd->bg_inode_table + 11822 fs->inode_blocks_per_group - 1) >= last_block)) { 11823 pctx.blk = gd->bg_inode_table; 11824 if (fix_problem(ctx, PR_0_ITABLE_NOT_GROUP, &pctx)) 11825 gd->bg_inode_table = 0; 11826 } 11827 if (gd->bg_inode_table == 0) { 11828 ctx->invalid_inode_table_flag[i]++; 11829 ctx->invalid_bitmaps++; 11830 } 11831 free_blocks += gd->bg_free_blocks_count; 11832 free_inodes += gd->bg_free_inodes_count; 11833 first_block += sb->s_blocks_per_group; 11834 last_block += sb->s_blocks_per_group; 11835 11836 if ((gd->bg_free_blocks_count > sb->s_blocks_per_group) || 11837 (gd->bg_free_inodes_count > sb->s_inodes_per_group) || 11838 (gd->bg_used_dirs_count > sb->s_inodes_per_group)) 11839 ext2fs_unmark_valid(fs); 11840 11841 } 11842 11843 /* 11844 * Update the global counts from the block group counts. This 11845 * is needed for an experimental patch which eliminates 11846 * locking the entire filesystem when allocating blocks or 11847 * inodes; if the filesystem is not unmounted cleanly, the 11848 * global counts may not be accurate. 11849 */ 11850 if ((free_blocks != sb->s_free_blocks_count) || 11851 (free_inodes != sb->s_free_inodes_count)) { 11852 if (ctx->options & E2F_OPT_READONLY) 11853 ext2fs_unmark_valid(fs); 11854 else { 11855 sb->s_free_blocks_count = free_blocks; 11856 sb->s_free_inodes_count = free_inodes; 11857 ext2fs_mark_super_dirty(fs); 11858 } 11859 } 11860 11861 if ((sb->s_free_blocks_count > sb->s_blocks_count) || 11862 (sb->s_free_inodes_count > sb->s_inodes_count)) 11863 ext2fs_unmark_valid(fs); 11864 11865 11866 /* 11867 * If we have invalid bitmaps, set the error state of the 11868 * filesystem. 11869 */ 11870 if (ctx->invalid_bitmaps && !(ctx->options & E2F_OPT_READONLY)) { 11871 sb->s_state &= ~EXT2_VALID_FS; 11872 ext2fs_mark_super_dirty(fs); 11873 } 11874 11875 clear_problem_context(&pctx); 11876 11877 /* 11878 * If the UUID field isn't assigned, assign it. 11879 */ 11880 if (!(ctx->options & E2F_OPT_READONLY) && uuid_is_null(sb->s_uuid)) { 11881 if (fix_problem(ctx, PR_0_ADD_UUID, &pctx)) { 11882 uuid_generate(sb->s_uuid); 11883 ext2fs_mark_super_dirty(fs); 11884 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY; 11885 } 11886 } 11887 11888 if (!(ctx->options & E2F_OPT_READONLY) && 11889 fs->super->s_creator_os == EXT2_OS_HURD && 11890 (fs->super->s_feature_incompat & 11891 EXT2_FEATURE_INCOMPAT_FILETYPE)) { 11892 if (fix_problem(ctx, PR_0_HURD_CLEAR_FILETYPE, &pctx)) { 11893 fs->super->s_feature_incompat &= 11894 ~EXT2_FEATURE_INCOMPAT_FILETYPE; 11895 ext2fs_mark_super_dirty(fs); 11896 11897 } 11898 } 11899 11900 /* 11901 * If we have any of the compatibility flags set, we need to have a 11902 * revision 1 filesystem. Most kernels will not check the flags on 11903 * a rev 0 filesystem and we may have corruption issues because of 11904 * the incompatible changes to the filesystem. 11905 */ 11906 if (!(ctx->options & E2F_OPT_READONLY) && 11907 fs->super->s_rev_level == EXT2_GOOD_OLD_REV && 11908 (fs->super->s_feature_compat || 11909 fs->super->s_feature_ro_compat || 11910 fs->super->s_feature_incompat) && 11911 fix_problem(ctx, PR_0_FS_REV_LEVEL, &pctx)) { 11912 ext2fs_update_dynamic_rev(fs); 11913 ext2fs_mark_super_dirty(fs); 11914 } 11915 11916 check_resize_inode(ctx); 11917 11918 /* 11919 * Clean up any orphan inodes, if present. 11920 */ 11921 if (!(ctx->options & E2F_OPT_READONLY) && release_orphan_inodes(ctx)) { 11922 fs->super->s_state &= ~EXT2_VALID_FS; 11923 ext2fs_mark_super_dirty(fs); 11924 } 11925 11926 /* 11927 * Move the ext3 journal file, if necessary. 11928 */ 11929 e2fsck_move_ext3_journal(ctx); 11930} 11931 11932/* 11933 * swapfs.c --- byte-swap an ext2 filesystem 11934 */ 11935 11936#ifdef ENABLE_SWAPFS 11937 11938struct swap_block_struct { 11939 ext2_ino_t ino; 11940 int isdir; 11941 errcode_t errcode; 11942 char *dir_buf; 11943 struct ext2_inode *inode; 11944}; 11945 11946/* 11947 * This is a helper function for block_iterate. We mark all of the 11948 * indirect and direct blocks as changed, so that block_iterate will 11949 * write them out. 11950 */ 11951static int swap_block(ext2_filsys fs, blk_t *block_nr, int blockcnt, 11952 void *priv_data) 11953{ 11954 errcode_t retval; 11955 11956 struct swap_block_struct *sb = (struct swap_block_struct *) priv_data; 11957 11958 if (sb->isdir && (blockcnt >= 0) && *block_nr) { 11959 retval = ext2fs_read_dir_block(fs, *block_nr, sb->dir_buf); 11960 if (retval) { 11961 sb->errcode = retval; 11962 return BLOCK_ABORT; 11963 } 11964 retval = ext2fs_write_dir_block(fs, *block_nr, sb->dir_buf); 11965 if (retval) { 11966 sb->errcode = retval; 11967 return BLOCK_ABORT; 11968 } 11969 } 11970 if (blockcnt >= 0) { 11971 if (blockcnt < EXT2_NDIR_BLOCKS) 11972 return 0; 11973 return BLOCK_CHANGED; 11974 } 11975 if (blockcnt == BLOCK_COUNT_IND) { 11976 if (*block_nr == sb->inode->i_block[EXT2_IND_BLOCK]) 11977 return 0; 11978 return BLOCK_CHANGED; 11979 } 11980 if (blockcnt == BLOCK_COUNT_DIND) { 11981 if (*block_nr == sb->inode->i_block[EXT2_DIND_BLOCK]) 11982 return 0; 11983 return BLOCK_CHANGED; 11984 } 11985 if (blockcnt == BLOCK_COUNT_TIND) { 11986 if (*block_nr == sb->inode->i_block[EXT2_TIND_BLOCK]) 11987 return 0; 11988 return BLOCK_CHANGED; 11989 } 11990 return BLOCK_CHANGED; 11991} 11992 11993/* 11994 * This function is responsible for byte-swapping all of the indirect, 11995 * block pointers. It is also responsible for byte-swapping directories. 11996 */ 11997static void swap_inode_blocks(e2fsck_t ctx, ext2_ino_t ino, char *block_buf, 11998 struct ext2_inode *inode) 11999{ 12000 errcode_t retval; 12001 struct swap_block_struct sb; 12002 12003 sb.ino = ino; 12004 sb.inode = inode; 12005 sb.dir_buf = block_buf + ctx->fs->blocksize*3; 12006 sb.errcode = 0; 12007 sb.isdir = 0; 12008 if (LINUX_S_ISDIR(inode->i_mode)) 12009 sb.isdir = 1; 12010 12011 retval = ext2fs_block_iterate(ctx->fs, ino, 0, block_buf, 12012 swap_block, &sb); 12013 if (retval) { 12014 bb_error_msg(_("while calling ext2fs_block_iterate")); 12015 ctx->flags |= E2F_FLAG_ABORT; 12016 return; 12017 } 12018 if (sb.errcode) { 12019 bb_error_msg(_("while calling iterator function")); 12020 ctx->flags |= E2F_FLAG_ABORT; 12021 return; 12022 } 12023} 12024 12025static void swap_inodes(e2fsck_t ctx) 12026{ 12027 ext2_filsys fs = ctx->fs; 12028 dgrp_t group; 12029 unsigned int i; 12030 ext2_ino_t ino = 1; 12031 char *buf, *block_buf; 12032 errcode_t retval; 12033 struct ext2_inode * inode; 12034 12035 e2fsck_use_inode_shortcuts(ctx, 1); 12036 12037 retval = ext2fs_get_mem(fs->blocksize * fs->inode_blocks_per_group, 12038 &buf); 12039 if (retval) { 12040 bb_error_msg(_("while allocating inode buffer")); 12041 ctx->flags |= E2F_FLAG_ABORT; 12042 return; 12043 } 12044 block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 4, 12045 "block interate buffer"); 12046 for (group = 0; group < fs->group_desc_count; group++) { 12047 retval = io_channel_read_blk(fs->io, 12048 fs->group_desc[group].bg_inode_table, 12049 fs->inode_blocks_per_group, buf); 12050 if (retval) { 12051 bb_error_msg(_("while reading inode table (group %d)"), 12052 group); 12053 ctx->flags |= E2F_FLAG_ABORT; 12054 return; 12055 } 12056 inode = (struct ext2_inode *) buf; 12057 for (i=0; i < fs->super->s_inodes_per_group; 12058 i++, ino++, inode++) { 12059 ctx->stashed_ino = ino; 12060 ctx->stashed_inode = inode; 12061 12062 if (fs->flags & EXT2_FLAG_SWAP_BYTES_READ) 12063 ext2fs_swap_inode(fs, inode, inode, 0); 12064 12065 /* 12066 * Skip deleted files. 12067 */ 12068 if (inode->i_links_count == 0) 12069 continue; 12070 12071 if (LINUX_S_ISDIR(inode->i_mode) || 12072 ((inode->i_block[EXT2_IND_BLOCK] || 12073 inode->i_block[EXT2_DIND_BLOCK] || 12074 inode->i_block[EXT2_TIND_BLOCK]) && 12075 ext2fs_inode_has_valid_blocks(inode))) 12076 swap_inode_blocks(ctx, ino, block_buf, inode); 12077 12078 if (ctx->flags & E2F_FLAG_SIGNAL_MASK) 12079 return; 12080 12081 if (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE) 12082 ext2fs_swap_inode(fs, inode, inode, 1); 12083 } 12084 retval = io_channel_write_blk(fs->io, 12085 fs->group_desc[group].bg_inode_table, 12086 fs->inode_blocks_per_group, buf); 12087 if (retval) { 12088 bb_error_msg(_("while writing inode table (group %d)"), 12089 group); 12090 ctx->flags |= E2F_FLAG_ABORT; 12091 return; 12092 } 12093 } 12094 ext2fs_free_mem(&buf); 12095 ext2fs_free_mem(&block_buf); 12096 e2fsck_use_inode_shortcuts(ctx, 0); 12097 ext2fs_flush_icache(fs); 12098} 12099 12100#if defined(__powerpc__) && BB_BIG_ENDIAN 12101/* 12102 * On the PowerPC, the big-endian variant of the ext2 filesystem 12103 * has its bitmaps stored as 32-bit words with bit 0 as the LSB 12104 * of each word. Thus a bitmap with only bit 0 set would be, as 12105 * a string of bytes, 00 00 00 01 00 ... 12106 * To cope with this, we byte-reverse each word of a bitmap if 12107 * we have a big-endian filesystem, that is, if we are *not* 12108 * byte-swapping other word-sized numbers. 12109 */ 12110#define EXT2_BIG_ENDIAN_BITMAPS 12111#endif 12112 12113#ifdef EXT2_BIG_ENDIAN_BITMAPS 12114static void ext2fs_swap_bitmap(ext2fs_generic_bitmap bmap) 12115{ 12116 __u32 *p = (__u32 *) bmap->bitmap; 12117 int n, nbytes = (bmap->end - bmap->start + 7) / 8; 12118 12119 for (n = nbytes / sizeof(__u32); n > 0; --n, ++p) 12120 *p = ext2fs_swab32(*p); 12121} 12122#endif 12123 12124 12125#ifdef ENABLE_SWAPFS 12126static void swap_filesys(e2fsck_t ctx) 12127{ 12128 ext2_filsys fs = ctx->fs; 12129 if (!(ctx->options & E2F_OPT_PREEN)) 12130 printf(_("Pass 0: Doing byte-swap of filesystem\n")); 12131 12132 /* Byte swap */ 12133 12134 if (fs->super->s_mnt_count) { 12135 fprintf(stderr, _("%s: the filesystem must be freshly " 12136 "checked using fsck\n" 12137 "and not mounted before trying to " 12138 "byte-swap it.\n"), ctx->device_name); 12139 ctx->flags |= E2F_FLAG_ABORT; 12140 return; 12141 } 12142 if (fs->flags & EXT2_FLAG_SWAP_BYTES) { 12143 fs->flags &= ~(EXT2_FLAG_SWAP_BYTES| 12144 EXT2_FLAG_SWAP_BYTES_WRITE); 12145 fs->flags |= EXT2_FLAG_SWAP_BYTES_READ; 12146 } else { 12147 fs->flags &= ~EXT2_FLAG_SWAP_BYTES_READ; 12148 fs->flags |= EXT2_FLAG_SWAP_BYTES_WRITE; 12149 } 12150 swap_inodes(ctx); 12151 if (ctx->flags & E2F_FLAG_SIGNAL_MASK) 12152 return; 12153 if (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE) 12154 fs->flags |= EXT2_FLAG_SWAP_BYTES; 12155 fs->flags &= ~(EXT2_FLAG_SWAP_BYTES_READ| 12156 EXT2_FLAG_SWAP_BYTES_WRITE); 12157 12158#ifdef EXT2_BIG_ENDIAN_BITMAPS 12159 e2fsck_read_bitmaps(ctx); 12160 ext2fs_swap_bitmap(fs->inode_map); 12161 ext2fs_swap_bitmap(fs->block_map); 12162 fs->flags |= EXT2_FLAG_BB_DIRTY | EXT2_FLAG_IB_DIRTY; 12163#endif 12164 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY; 12165 ext2fs_flush(fs); 12166 fs->flags |= EXT2_FLAG_MASTER_SB_ONLY; 12167} 12168#endif /* ENABLE_SWAPFS */ 12169 12170#endif 12171 12172/* 12173 * util.c --- miscellaneous utilities 12174 */ 12175 12176 12177void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned int size, 12178 const char *description) 12179{ 12180 void *ret; 12181 char buf[256]; 12182 12183 ret = malloc(size); 12184 if (!ret) { 12185 sprintf(buf, "Can't allocate %s\n", description); 12186 bb_error_msg_and_die(buf); 12187 } 12188 memset(ret, 0, size); 12189 return ret; 12190} 12191 12192static char *string_copy(const char *str, int len) 12193{ 12194 char *ret; 12195 12196 if (!str) 12197 return NULL; 12198 if (!len) 12199 len = strlen(str); 12200 ret = malloc(len+1); 12201 if (ret) { 12202 strncpy(ret, str, len); 12203 ret[len] = 0; 12204 } 12205 return ret; 12206} 12207 12208#ifndef HAVE_CONIO_H 12209static int read_a_char(void) 12210{ 12211 char c; 12212 int r; 12213 int fail = 0; 12214 12215 while(1) { 12216 if (e2fsck_global_ctx && 12217 (e2fsck_global_ctx->flags & E2F_FLAG_CANCEL)) { 12218 return 3; 12219 } 12220 r = read(0, &c, 1); 12221 if (r == 1) 12222 return c; 12223 if (fail++ > 100) 12224 break; 12225 } 12226 return EOF; 12227} 12228#endif 12229 12230static int ask_yn(const char * string, int def) 12231{ 12232 int c; 12233 const char *defstr; 12234 static const char short_yes[] = "yY"; 12235 static const char short_no[] = "nN"; 12236 12237#ifdef HAVE_TERMIOS_H 12238 struct termios termios, tmp; 12239 12240 tcgetattr (0, &termios); 12241 tmp = termios; 12242 tmp.c_lflag &= ~(ICANON | ECHO); 12243 tmp.c_cc[VMIN] = 1; 12244 tmp.c_cc[VTIME] = 0; 12245 tcsetattr (0, TCSANOW, &tmp); 12246#endif 12247 12248 if (def == 1) 12249 defstr = "<y>"; 12250 else if (def == 0) 12251 defstr = "<n>"; 12252 else 12253 defstr = " (y/n)"; 12254 printf("%s%s? ", string, defstr); 12255 while (1) { 12256 fflush (stdout); 12257 if ((c = read_a_char()) == EOF) 12258 break; 12259 if (c == 3) { 12260#ifdef HAVE_TERMIOS_H 12261 tcsetattr (0, TCSANOW, &termios); 12262#endif 12263 if (e2fsck_global_ctx && 12264 e2fsck_global_ctx->flags & E2F_FLAG_SETJMP_OK) { 12265 puts("\n"); 12266 longjmp(e2fsck_global_ctx->abort_loc, 1); 12267 } 12268 puts(_("cancelled!\n")); 12269 return 0; 12270 } 12271 if (strchr(short_yes, (char) c)) { 12272 def = 1; 12273 break; 12274 } 12275 else if (strchr(short_no, (char) c)) { 12276 def = 0; 12277 break; 12278 } 12279 else if ((c == ' ' || c == '\n') && (def != -1)) 12280 break; 12281 } 12282 if (def) 12283 puts("yes\n"); 12284 else 12285 puts ("no\n"); 12286#ifdef HAVE_TERMIOS_H 12287 tcsetattr (0, TCSANOW, &termios); 12288#endif 12289 return def; 12290} 12291 12292int ask (e2fsck_t ctx, const char * string, int def) 12293{ 12294 if (ctx->options & E2F_OPT_NO) { 12295 printf(_("%s? no\n\n"), string); 12296 return 0; 12297 } 12298 if (ctx->options & E2F_OPT_YES) { 12299 printf(_("%s? yes\n\n"), string); 12300 return 1; 12301 } 12302 if (ctx->options & E2F_OPT_PREEN) { 12303 printf("%s? %s\n\n", string, def ? _("yes") : _("no")); 12304 return def; 12305 } 12306 return ask_yn(string, def); 12307} 12308 12309void e2fsck_read_bitmaps(e2fsck_t ctx) 12310{ 12311 ext2_filsys fs = ctx->fs; 12312 errcode_t retval; 12313 12314 if (ctx->invalid_bitmaps) { 12315 bb_error_msg(_("e2fsck_read_bitmaps: illegal bitmap block(s) for %s"), 12316 ctx->device_name); 12317 bb_error_msg_and_die(0); 12318 } 12319 12320 ehandler_operation(_("reading inode and block bitmaps")); 12321 retval = ext2fs_read_bitmaps(fs); 12322 ehandler_operation(0); 12323 if (retval) { 12324 bb_error_msg(_("while retrying to read bitmaps for %s"), 12325 ctx->device_name); 12326 bb_error_msg_and_die(0); 12327 } 12328} 12329 12330static void e2fsck_write_bitmaps(e2fsck_t ctx) 12331{ 12332 ext2_filsys fs = ctx->fs; 12333 errcode_t retval; 12334 12335 if (ext2fs_test_bb_dirty(fs)) { 12336 ehandler_operation(_("writing block bitmaps")); 12337 retval = ext2fs_write_block_bitmap(fs); 12338 ehandler_operation(0); 12339 if (retval) { 12340 bb_error_msg(_("while retrying to write block bitmaps for %s"), 12341 ctx->device_name); 12342 bb_error_msg_and_die(0); 12343 } 12344 } 12345 12346 if (ext2fs_test_ib_dirty(fs)) { 12347 ehandler_operation(_("writing inode bitmaps")); 12348 retval = ext2fs_write_inode_bitmap(fs); 12349 ehandler_operation(0); 12350 if (retval) { 12351 bb_error_msg(_("while retrying to write inode bitmaps for %s"), 12352 ctx->device_name); 12353 bb_error_msg_and_die(0); 12354 } 12355 } 12356} 12357 12358void preenhalt(e2fsck_t ctx) 12359{ 12360 ext2_filsys fs = ctx->fs; 12361 12362 if (!(ctx->options & E2F_OPT_PREEN)) 12363 return; 12364 fprintf(stderr, _("\n\n%s: UNEXPECTED INCONSISTENCY; " 12365 "RUN fsck MANUALLY.\n\t(i.e., without -a or -p options)\n"), 12366 ctx->device_name); 12367 if (fs != NULL) { 12368 fs->super->s_state |= EXT2_ERROR_FS; 12369 ext2fs_mark_super_dirty(fs); 12370 ext2fs_close(fs); 12371 } 12372 exit(EXIT_UNCORRECTED); 12373} 12374 12375void e2fsck_read_inode(e2fsck_t ctx, unsigned long ino, 12376 struct ext2_inode * inode, const char *proc) 12377{ 12378 int retval; 12379 12380 retval = ext2fs_read_inode(ctx->fs, ino, inode); 12381 if (retval) { 12382 bb_error_msg(_("while reading inode %ld in %s"), ino, proc); 12383 bb_error_msg_and_die(0); 12384 } 12385} 12386 12387extern void e2fsck_write_inode_full(e2fsck_t ctx, unsigned long ino, 12388 struct ext2_inode * inode, int bufsize, 12389 const char *proc) 12390{ 12391 int retval; 12392 12393 retval = ext2fs_write_inode_full(ctx->fs, ino, inode, bufsize); 12394 if (retval) { 12395 bb_error_msg(_("while writing inode %ld in %s"), ino, proc); 12396 bb_error_msg_and_die(0); 12397 } 12398} 12399 12400extern void e2fsck_write_inode(e2fsck_t ctx, unsigned long ino, 12401 struct ext2_inode * inode, const char *proc) 12402{ 12403 int retval; 12404 12405 retval = ext2fs_write_inode(ctx->fs, ino, inode); 12406 if (retval) { 12407 bb_error_msg(_("while writing inode %ld in %s"), ino, proc); 12408 bb_error_msg_and_die(0); 12409 } 12410} 12411 12412blk_t get_backup_sb(e2fsck_t ctx, ext2_filsys fs, const char *name, 12413 io_manager manager) 12414{ 12415 struct ext2_super_block *sb; 12416 io_channel io = NULL; 12417 void *buf = NULL; 12418 int blocksize; 12419 blk_t superblock, ret_sb = 8193; 12420 12421 if (fs && fs->super) { 12422 ret_sb = (fs->super->s_blocks_per_group + 12423 fs->super->s_first_data_block); 12424 if (ctx) { 12425 ctx->superblock = ret_sb; 12426 ctx->blocksize = fs->blocksize; 12427 } 12428 return ret_sb; 12429 } 12430 12431 if (ctx) { 12432 if (ctx->blocksize) { 12433 ret_sb = ctx->blocksize * 8; 12434 if (ctx->blocksize == 1024) 12435 ret_sb++; 12436 ctx->superblock = ret_sb; 12437 return ret_sb; 12438 } 12439 ctx->superblock = ret_sb; 12440 ctx->blocksize = 1024; 12441 } 12442 12443 if (!name || !manager) 12444 goto cleanup; 12445 12446 if (manager->open(name, 0, &io) != 0) 12447 goto cleanup; 12448 12449 if (ext2fs_get_mem(SUPERBLOCK_SIZE, &buf)) 12450 goto cleanup; 12451 sb = (struct ext2_super_block *) buf; 12452 12453 for (blocksize = EXT2_MIN_BLOCK_SIZE; 12454 blocksize <= EXT2_MAX_BLOCK_SIZE; blocksize *= 2) { 12455 superblock = blocksize*8; 12456 if (blocksize == 1024) 12457 superblock++; 12458 io_channel_set_blksize(io, blocksize); 12459 if (io_channel_read_blk(io, superblock, 12460 -SUPERBLOCK_SIZE, buf)) 12461 continue; 12462#if BB_BIG_ENDIAN 12463 if (sb->s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC)) 12464 ext2fs_swap_super(sb); 12465#endif 12466 if (sb->s_magic == EXT2_SUPER_MAGIC) { 12467 ret_sb = superblock; 12468 if (ctx) { 12469 ctx->superblock = superblock; 12470 ctx->blocksize = blocksize; 12471 } 12472 break; 12473 } 12474 } 12475 12476cleanup: 12477 if (io) 12478 io_channel_close(io); 12479 ext2fs_free_mem(&buf); 12480 return ret_sb; 12481} 12482 12483 12484/* 12485 * This function runs through the e2fsck passes and calls them all, 12486 * returning restart, abort, or cancel as necessary... 12487 */ 12488typedef void (*pass_t)(e2fsck_t ctx); 12489 12490static const pass_t e2fsck_passes[] = { 12491 e2fsck_pass1, e2fsck_pass2, e2fsck_pass3, e2fsck_pass4, 12492 e2fsck_pass5, 0 }; 12493 12494#define E2F_FLAG_RUN_RETURN (E2F_FLAG_SIGNAL_MASK|E2F_FLAG_RESTART) 12495 12496static int e2fsck_run(e2fsck_t ctx) 12497{ 12498 int i; 12499 pass_t e2fsck_pass; 12500 12501 if (setjmp(ctx->abort_loc)) { 12502 ctx->flags &= ~E2F_FLAG_SETJMP_OK; 12503 return (ctx->flags & E2F_FLAG_RUN_RETURN); 12504 } 12505 ctx->flags |= E2F_FLAG_SETJMP_OK; 12506 12507 for (i=0; (e2fsck_pass = e2fsck_passes[i]); i++) { 12508 if (ctx->flags & E2F_FLAG_RUN_RETURN) 12509 break; 12510 e2fsck_pass(ctx); 12511 if (ctx->progress) 12512 (void) (ctx->progress)(ctx, 0, 0, 0); 12513 } 12514 ctx->flags &= ~E2F_FLAG_SETJMP_OK; 12515 12516 if (ctx->flags & E2F_FLAG_RUN_RETURN) 12517 return (ctx->flags & E2F_FLAG_RUN_RETURN); 12518 return 0; 12519} 12520 12521 12522/* 12523 * unix.c - The unix-specific code for e2fsck 12524 */ 12525 12526 12527/* Command line options */ 12528static int swapfs; 12529#ifdef ENABLE_SWAPFS 12530static int normalize_swapfs; 12531#endif 12532static int cflag; /* check disk */ 12533static int show_version_only; 12534static int verbose; 12535 12536#define P_E2(singular, plural, n) n, ((n) == 1 ? singular : plural) 12537 12538static void show_stats(e2fsck_t ctx) 12539{ 12540 ext2_filsys fs = ctx->fs; 12541 int inodes, inodes_used, blocks, blocks_used; 12542 int dir_links; 12543 int num_files, num_links; 12544 int frag_percent; 12545 12546 dir_links = 2 * ctx->fs_directory_count - 1; 12547 num_files = ctx->fs_total_count - dir_links; 12548 num_links = ctx->fs_links_count - dir_links; 12549 inodes = fs->super->s_inodes_count; 12550 inodes_used = (fs->super->s_inodes_count - 12551 fs->super->s_free_inodes_count); 12552 blocks = fs->super->s_blocks_count; 12553 blocks_used = (fs->super->s_blocks_count - 12554 fs->super->s_free_blocks_count); 12555 12556 frag_percent = (10000 * ctx->fs_fragmented) / inodes_used; 12557 frag_percent = (frag_percent + 5) / 10; 12558 12559 if (!verbose) { 12560 printf("%s: %d/%d files (%0d.%d%% non-contiguous), %d/%d blocks\n", 12561 ctx->device_name, inodes_used, inodes, 12562 frag_percent / 10, frag_percent % 10, 12563 blocks_used, blocks); 12564 return; 12565 } 12566 printf("\n%8d inode%s used (%d%%)\n", P_E2("", "s", inodes_used), 12567 100 * inodes_used / inodes); 12568 printf("%8d non-contiguous inode%s (%0d.%d%%)\n", 12569 P_E2("", "s", ctx->fs_fragmented), 12570 frag_percent / 10, frag_percent % 10); 12571 printf(_(" # of inodes with ind/dind/tind blocks: %d/%d/%d\n"), 12572 ctx->fs_ind_count, ctx->fs_dind_count, ctx->fs_tind_count); 12573 printf("%8d block%s used (%d%%)\n", P_E2("", "s", blocks_used), 12574 (int) ((long long) 100 * blocks_used / blocks)); 12575 printf("%8d large file%s\n", P_E2("", "s", ctx->large_files)); 12576 printf("\n%8d regular file%s\n", P_E2("", "s", ctx->fs_regular_count)); 12577 printf("%8d director%s\n", P_E2("y", "ies", ctx->fs_directory_count)); 12578 printf("%8d character device file%s\n", P_E2("", "s", ctx->fs_chardev_count)); 12579 printf("%8d block device file%s\n", P_E2("", "s", ctx->fs_blockdev_count)); 12580 printf("%8d fifo%s\n", P_E2("", "s", ctx->fs_fifo_count)); 12581 printf("%8d link%s\n", P_E2("", "s", ctx->fs_links_count - dir_links)); 12582 printf("%8d symbolic link%s", P_E2("", "s", ctx->fs_symlinks_count)); 12583 printf(" (%d fast symbolic link%s)\n", P_E2("", "s", ctx->fs_fast_symlinks_count)); 12584 printf("%8d socket%s--------\n\n", P_E2("", "s", ctx->fs_sockets_count)); 12585 printf("%8d file%s\n", P_E2("", "s", ctx->fs_total_count - dir_links)); 12586} 12587 12588static void check_mount(e2fsck_t ctx) 12589{ 12590 errcode_t retval; 12591 int cont; 12592 12593 retval = ext2fs_check_if_mounted(ctx->filesystem_name, 12594 &ctx->mount_flags); 12595 if (retval) { 12596 bb_error_msg(_("while determining whether %s is mounted."), 12597 ctx->filesystem_name); 12598 return; 12599 } 12600 12601 /* 12602 * If the filesystem isn't mounted, or it's the root filesystem 12603 * and it's mounted read-only, then everything's fine. 12604 */ 12605 if ((!(ctx->mount_flags & EXT2_MF_MOUNTED)) || 12606 ((ctx->mount_flags & EXT2_MF_ISROOT) && 12607 (ctx->mount_flags & EXT2_MF_READONLY))) 12608 return; 12609 12610 if (ctx->options & E2F_OPT_READONLY) { 12611 printf(_("Warning! %s is mounted.\n"), ctx->filesystem_name); 12612 return; 12613 } 12614 12615 printf(_("%s is mounted. "), ctx->filesystem_name); 12616 if (!ctx->interactive) 12617 bb_error_msg_and_die(_("Cannot continue, aborting.")); 12618 printf(_("\n\n\007\007\007\007WARNING!!! " 12619 "Running e2fsck on a mounted filesystem may cause\n" 12620 "SEVERE filesystem damage.\007\007\007\n\n")); 12621 cont = ask_yn(_("Do you really want to continue"), -1); 12622 if (!cont) { 12623 printf(_("check aborted.\n")); 12624 exit(0); 12625 } 12626} 12627 12628static int is_on_batt(void) 12629{ 12630 FILE *f; 12631 DIR *d; 12632 char tmp[80], tmp2[80], fname[80]; 12633 unsigned int acflag; 12634 struct dirent* de; 12635 12636 f = fopen("/proc/apm", "r"); 12637 if (f) { 12638 if (fscanf(f, "%s %s %s %x", tmp, tmp, tmp, &acflag) != 4) 12639 acflag = 1; 12640 fclose(f); 12641 return (acflag != 1); 12642 } 12643 d = opendir("/proc/acpi/ac_adapter"); 12644 if (d) { 12645 while ((de=readdir(d)) != NULL) { 12646 if (!strncmp(".", de->d_name, 1)) 12647 continue; 12648 snprintf(fname, 80, "/proc/acpi/ac_adapter/%s/state", 12649 de->d_name); 12650 f = fopen(fname, "r"); 12651 if (!f) 12652 continue; 12653 if (fscanf(f, "%s %s", tmp2, tmp) != 2) 12654 tmp[0] = 0; 12655 fclose(f); 12656 if (strncmp(tmp, "off-line", 8) == 0) { 12657 closedir(d); 12658 return 1; 12659 } 12660 } 12661 closedir(d); 12662 } 12663 return 0; 12664} 12665 12666/* 12667 * This routine checks to see if a filesystem can be skipped; if so, 12668 * it will exit with EXIT_OK. Under some conditions it will print a 12669 * message explaining why a check is being forced. 12670 */ 12671static void check_if_skip(e2fsck_t ctx) 12672{ 12673 ext2_filsys fs = ctx->fs; 12674 const char *reason = NULL; 12675 unsigned int reason_arg = 0; 12676 long next_check; 12677 int batt = is_on_batt(); 12678 time_t now = time(0); 12679 12680 if ((ctx->options & E2F_OPT_FORCE) || cflag || swapfs) 12681 return; 12682 12683 if ((fs->super->s_state & EXT2_ERROR_FS) || 12684 !ext2fs_test_valid(fs)) 12685 reason = _(" contains a file system with errors"); 12686 else if ((fs->super->s_state & EXT2_VALID_FS) == 0) 12687 reason = _(" was not cleanly unmounted"); 12688 else if ((fs->super->s_max_mnt_count > 0) && 12689 (fs->super->s_mnt_count >= 12690 (unsigned) fs->super->s_max_mnt_count)) { 12691 reason = _(" has been mounted %u times without being checked"); 12692 reason_arg = fs->super->s_mnt_count; 12693 if (batt && (fs->super->s_mnt_count < 12694 (unsigned) fs->super->s_max_mnt_count*2)) 12695 reason = 0; 12696 } else if (fs->super->s_checkinterval && 12697 ((now - fs->super->s_lastcheck) >= 12698 fs->super->s_checkinterval)) { 12699 reason = _(" has gone %u days without being checked"); 12700 reason_arg = (now - fs->super->s_lastcheck)/(3600*24); 12701 if (batt && ((now - fs->super->s_lastcheck) < 12702 fs->super->s_checkinterval*2)) 12703 reason = 0; 12704 } 12705 if (reason) { 12706 fputs(ctx->device_name, stdout); 12707 printf(reason, reason_arg); 12708 fputs(_(", check forced.\n"), stdout); 12709 return; 12710 } 12711 printf(_("%s: clean, %d/%d files, %d/%d blocks"), ctx->device_name, 12712 fs->super->s_inodes_count - fs->super->s_free_inodes_count, 12713 fs->super->s_inodes_count, 12714 fs->super->s_blocks_count - fs->super->s_free_blocks_count, 12715 fs->super->s_blocks_count); 12716 next_check = 100000; 12717 if (fs->super->s_max_mnt_count > 0) { 12718 next_check = fs->super->s_max_mnt_count - fs->super->s_mnt_count; 12719 if (next_check <= 0) 12720 next_check = 1; 12721 } 12722 if (fs->super->s_checkinterval && 12723 ((now - fs->super->s_lastcheck) >= fs->super->s_checkinterval)) 12724 next_check = 1; 12725 if (next_check <= 5) { 12726 if (next_check == 1) 12727 fputs(_(" (check after next mount)"), stdout); 12728 else 12729 printf(_(" (check in %ld mounts)"), next_check); 12730 } 12731 fputc('\n', stdout); 12732 ext2fs_close(fs); 12733 ctx->fs = NULL; 12734 e2fsck_free_context(ctx); 12735 exit(EXIT_OK); 12736} 12737 12738/* 12739 * For completion notice 12740 */ 12741struct percent_tbl { 12742 int max_pass; 12743 int table[32]; 12744}; 12745static const struct percent_tbl e2fsck_tbl = { 12746 5, { 0, 70, 90, 92, 95, 100 } 12747}; 12748 12749static char bar[128], spaces[128]; 12750 12751static float calc_percent(const struct percent_tbl *tbl, int pass, int curr, 12752 int max) 12753{ 12754 float percent; 12755 12756 if (pass <= 0) 12757 return 0.0; 12758 if (pass > tbl->max_pass || max == 0) 12759 return 100.0; 12760 percent = ((float) curr) / ((float) max); 12761 return ((percent * (tbl->table[pass] - tbl->table[pass-1])) 12762 + tbl->table[pass-1]); 12763} 12764 12765void e2fsck_clear_progbar(e2fsck_t ctx) 12766{ 12767 if (!(ctx->flags & E2F_FLAG_PROG_BAR)) 12768 return; 12769 12770 printf("%s%s\r%s", ctx->start_meta, spaces + (sizeof(spaces) - 80), 12771 ctx->stop_meta); 12772 fflush(stdout); 12773 ctx->flags &= ~E2F_FLAG_PROG_BAR; 12774} 12775 12776int e2fsck_simple_progress(e2fsck_t ctx, const char *label, float percent, 12777 unsigned int dpynum) 12778{ 12779 static const char spinner[] = "\\|/-"; 12780 int i; 12781 unsigned int tick; 12782 struct timeval tv; 12783 int dpywidth; 12784 int fixed_percent; 12785 12786 if (ctx->flags & E2F_FLAG_PROG_SUPPRESS) 12787 return 0; 12788 12789 /* 12790 * Calculate the new progress position. If the 12791 * percentage hasn't changed, then we skip out right 12792 * away. 12793 */ 12794 fixed_percent = (int) ((10 * percent) + 0.5); 12795 if (ctx->progress_last_percent == fixed_percent) 12796 return 0; 12797 ctx->progress_last_percent = fixed_percent; 12798 12799 /* 12800 * If we've already updated the spinner once within 12801 * the last 1/8th of a second, no point doing it 12802 * again. 12803 */ 12804 gettimeofday(&tv, NULL); 12805 tick = (tv.tv_sec << 3) + (tv.tv_usec / (1000000 / 8)); 12806 if ((tick == ctx->progress_last_time) && 12807 (fixed_percent != 0) && (fixed_percent != 1000)) 12808 return 0; 12809 ctx->progress_last_time = tick; 12810 12811 /* 12812 * Advance the spinner, and note that the progress bar 12813 * will be on the screen 12814 */ 12815 ctx->progress_pos = (ctx->progress_pos+1) & 3; 12816 ctx->flags |= E2F_FLAG_PROG_BAR; 12817 12818 dpywidth = 66 - strlen(label); 12819 dpywidth = 8 * (dpywidth / 8); 12820 if (dpynum) 12821 dpywidth -= 8; 12822 12823 i = ((percent * dpywidth) + 50) / 100; 12824 printf("%s%s: |%s%s", ctx->start_meta, label, 12825 bar + (sizeof(bar) - (i+1)), 12826 spaces + (sizeof(spaces) - (dpywidth - i + 1))); 12827 if (fixed_percent == 1000) 12828 fputc('|', stdout); 12829 else 12830 fputc(spinner[ctx->progress_pos & 3], stdout); 12831 printf(" %4.1f%% ", percent); 12832 if (dpynum) 12833 printf("%u\r", dpynum); 12834 else 12835 fputs(" \r", stdout); 12836 fputs(ctx->stop_meta, stdout); 12837 12838 if (fixed_percent == 1000) 12839 e2fsck_clear_progbar(ctx); 12840 fflush(stdout); 12841 12842 return 0; 12843} 12844 12845static int e2fsck_update_progress(e2fsck_t ctx, int pass, 12846 unsigned long cur, unsigned long max) 12847{ 12848 char buf[80]; 12849 float percent; 12850 12851 if (pass == 0) 12852 return 0; 12853 12854 if (ctx->progress_fd) { 12855 sprintf(buf, "%d %lu %lu\n", pass, cur, max); 12856 write(ctx->progress_fd, buf, strlen(buf)); 12857 } else { 12858 percent = calc_percent(&e2fsck_tbl, pass, cur, max); 12859 e2fsck_simple_progress(ctx, ctx->device_name, 12860 percent, 0); 12861 } 12862 return 0; 12863} 12864 12865static void reserve_stdio_fds(void) 12866{ 12867 int fd; 12868 12869 while (1) { 12870 fd = open(bb_dev_null, O_RDWR); 12871 if (fd > 2) 12872 break; 12873 if (fd < 0) { 12874 fprintf(stderr, _("ERROR: Cannot open " 12875 "/dev/null (%s)\n"), 12876 strerror(errno)); 12877 break; 12878 } 12879 } 12880 close(fd); 12881} 12882 12883static void signal_progress_on(int sig FSCK_ATTR((unused))) 12884{ 12885 e2fsck_t ctx = e2fsck_global_ctx; 12886 12887 if (!ctx) 12888 return; 12889 12890 ctx->progress = e2fsck_update_progress; 12891 ctx->progress_fd = 0; 12892} 12893 12894static void signal_progress_off(int sig FSCK_ATTR((unused))) 12895{ 12896 e2fsck_t ctx = e2fsck_global_ctx; 12897 12898 if (!ctx) 12899 return; 12900 12901 e2fsck_clear_progbar(ctx); 12902 ctx->progress = 0; 12903} 12904 12905static void signal_cancel(int sig FSCK_ATTR((unused))) 12906{ 12907 e2fsck_t ctx = e2fsck_global_ctx; 12908 12909 if (!ctx) 12910 exit(FSCK_CANCELED); 12911 12912 ctx->flags |= E2F_FLAG_CANCEL; 12913} 12914 12915static void parse_extended_opts(e2fsck_t ctx, const char *opts) 12916{ 12917 char *buf, *token, *next, *p, *arg; 12918 int ea_ver; 12919 int extended_usage = 0; 12920 12921 buf = string_copy(opts, 0); 12922 for (token = buf; token && *token; token = next) { 12923 p = strchr(token, ','); 12924 next = 0; 12925 if (p) { 12926 *p = 0; 12927 next = p+1; 12928 } 12929 arg = strchr(token, '='); 12930 if (arg) { 12931 *arg = 0; 12932 arg++; 12933 } 12934 if (strcmp(token, "ea_ver") == 0) { 12935 if (!arg) { 12936 extended_usage++; 12937 continue; 12938 } 12939 ea_ver = strtoul(arg, &p, 0); 12940 if (*p || 12941 ((ea_ver != 1) && (ea_ver != 2))) { 12942 fprintf(stderr, 12943 _("Invalid EA version.\n")); 12944 extended_usage++; 12945 continue; 12946 } 12947 ctx->ext_attr_ver = ea_ver; 12948 } else { 12949 fprintf(stderr, _("Unknown extended option: %s\n"), 12950 token); 12951 extended_usage++; 12952 } 12953 } 12954 if (extended_usage) { 12955 bb_error_msg_and_die( 12956 "Extended options are separated by commas, " 12957 "and may take an argument which\n" 12958 "is set off by an equals ('=') sign. " 12959 "Valid extended options are:\n" 12960 "\tea_ver=<ea_version (1 or 2)>\n\n"); 12961 } 12962} 12963 12964 12965static errcode_t PRS(int argc, char **argv, e2fsck_t *ret_ctx) 12966{ 12967 int flush = 0; 12968 int c, fd; 12969 e2fsck_t ctx; 12970 errcode_t retval; 12971 struct sigaction sa; 12972 char *extended_opts = 0; 12973 12974 retval = e2fsck_allocate_context(&ctx); 12975 if (retval) 12976 return retval; 12977 12978 *ret_ctx = ctx; 12979 12980 setvbuf(stdout, NULL, _IONBF, BUFSIZ); 12981 setvbuf(stderr, NULL, _IONBF, BUFSIZ); 12982 if (isatty(0) && isatty(1)) { 12983 ctx->interactive = 1; 12984 } else { 12985 ctx->start_meta[0] = '\001'; 12986 ctx->stop_meta[0] = '\002'; 12987 } 12988 memset(bar, '=', sizeof(bar)-1); 12989 memset(spaces, ' ', sizeof(spaces)-1); 12990 blkid_get_cache(&ctx->blkid, NULL); 12991 12992 if (argc && *argv) 12993 ctx->program_name = *argv; 12994 else 12995 ctx->program_name = "e2fsck"; 12996 while ((c = getopt (argc, argv, "panyrcC:B:dE:fvtFVM:b:I:j:P:l:L:N:SsDk")) != EOF) 12997 switch (c) { 12998 case 'C': 12999 ctx->progress = e2fsck_update_progress; 13000 ctx->progress_fd = atoi(optarg); 13001 if (!ctx->progress_fd) 13002 break; 13003 /* Validate the file descriptor to avoid disasters */ 13004 fd = dup(ctx->progress_fd); 13005 if (fd < 0) { 13006 fprintf(stderr, 13007 _("Error validating file descriptor %d: %s\n"), 13008 ctx->progress_fd, 13009 error_message(errno)); 13010 bb_error_msg_and_die(_("Invalid completion information file descriptor")); 13011 } else 13012 close(fd); 13013 break; 13014 case 'D': 13015 ctx->options |= E2F_OPT_COMPRESS_DIRS; 13016 break; 13017 case 'E': 13018 extended_opts = optarg; 13019 break; 13020 case 'p': 13021 case 'a': 13022 if (ctx->options & (E2F_OPT_YES|E2F_OPT_NO)) { 13023 conflict_opt: 13024 bb_error_msg_and_die(_("Only one the options -p/-a, -n or -y may be specified.")); 13025 } 13026 ctx->options |= E2F_OPT_PREEN; 13027 break; 13028 case 'n': 13029 if (ctx->options & (E2F_OPT_YES|E2F_OPT_PREEN)) 13030 goto conflict_opt; 13031 ctx->options |= E2F_OPT_NO; 13032 break; 13033 case 'y': 13034 if (ctx->options & (E2F_OPT_PREEN|E2F_OPT_NO)) 13035 goto conflict_opt; 13036 ctx->options |= E2F_OPT_YES; 13037 break; 13038 case 't': 13039 fprintf(stderr, _("The -t option is not " 13040 "supported on this version of e2fsck.\n")); 13041 break; 13042 case 'c': 13043 if (cflag++) 13044 ctx->options |= E2F_OPT_WRITECHECK; 13045 ctx->options |= E2F_OPT_CHECKBLOCKS; 13046 break; 13047 case 'r': 13048 /* What we do by default, anyway! */ 13049 break; 13050 case 'b': 13051 ctx->use_superblock = atoi(optarg); 13052 ctx->flags |= E2F_FLAG_SB_SPECIFIED; 13053 break; 13054 case 'B': 13055 ctx->blocksize = atoi(optarg); 13056 break; 13057 case 'I': 13058 ctx->inode_buffer_blocks = atoi(optarg); 13059 break; 13060 case 'j': 13061 ctx->journal_name = string_copy(optarg, 0); 13062 break; 13063 case 'P': 13064 ctx->process_inode_size = atoi(optarg); 13065 break; 13066 case 'd': 13067 ctx->options |= E2F_OPT_DEBUG; 13068 break; 13069 case 'f': 13070 ctx->options |= E2F_OPT_FORCE; 13071 break; 13072 case 'F': 13073 flush = 1; 13074 break; 13075 case 'v': 13076 verbose = 1; 13077 break; 13078 case 'V': 13079 show_version_only = 1; 13080 break; 13081 case 'N': 13082 ctx->device_name = optarg; 13083 break; 13084#ifdef ENABLE_SWAPFS 13085 case 's': 13086 normalize_swapfs = 1; 13087 case 'S': 13088 swapfs = 1; 13089 break; 13090#else 13091 case 's': 13092 case 'S': 13093 fprintf(stderr, _("Byte-swapping filesystems " 13094 "not compiled in this version " 13095 "of e2fsck\n")); 13096 exit(1); 13097#endif 13098 default: 13099 bb_show_usage(); 13100 } 13101 if (show_version_only) 13102 return 0; 13103 if (optind != argc - 1) 13104 bb_show_usage(); 13105 if ((ctx->options & E2F_OPT_NO) && 13106 !cflag && !swapfs && !(ctx->options & E2F_OPT_COMPRESS_DIRS)) 13107 ctx->options |= E2F_OPT_READONLY; 13108 ctx->io_options = strchr(argv[optind], '?'); 13109 if (ctx->io_options) 13110 *ctx->io_options++ = 0; 13111 ctx->filesystem_name = blkid_get_devname(ctx->blkid, argv[optind], 0); 13112 if (!ctx->filesystem_name) { 13113 bb_error_msg(_("Unable to resolve '%s'"), argv[optind]); 13114 bb_error_msg_and_die(0); 13115 } 13116 if (extended_opts) 13117 parse_extended_opts(ctx, extended_opts); 13118 13119 if (flush) { 13120 fd = open(ctx->filesystem_name, O_RDONLY, 0); 13121 if (fd < 0) { 13122 bb_error_msg(_("while opening %s for flushing"), 13123 ctx->filesystem_name); 13124 bb_error_msg_and_die(0); 13125 } 13126 if ((retval = ext2fs_sync_device(fd, 1))) { 13127 bb_error_msg(_("while trying to flush %s"), 13128 ctx->filesystem_name); 13129 bb_error_msg_and_die(0); 13130 } 13131 close(fd); 13132 } 13133#ifdef ENABLE_SWAPFS 13134 if (swapfs && cflag) { 13135 fprintf(stderr, _("Incompatible options not " 13136 "allowed when byte-swapping.\n")); 13137 exit(EXIT_USAGE); 13138 } 13139#endif 13140 /* 13141 * Set up signal action 13142 */ 13143 memset(&sa, 0, sizeof(struct sigaction)); 13144 sa.sa_handler = signal_cancel; 13145 sigaction(SIGINT, &sa, 0); 13146 sigaction(SIGTERM, &sa, 0); 13147#ifdef SA_RESTART 13148 sa.sa_flags = SA_RESTART; 13149#endif 13150 e2fsck_global_ctx = ctx; 13151 sa.sa_handler = signal_progress_on; 13152 sigaction(SIGUSR1, &sa, 0); 13153 sa.sa_handler = signal_progress_off; 13154 sigaction(SIGUSR2, &sa, 0); 13155 13156 /* Update our PATH to include /sbin if we need to run badblocks */ 13157 if (cflag) 13158 e2fs_set_sbin_path(); 13159 return 0; 13160} 13161 13162static const char my_ver_string[] = E2FSPROGS_VERSION; 13163static const char my_ver_date[] = E2FSPROGS_DATE; 13164 13165int e2fsck_main (int argc, char **argv); 13166int e2fsck_main (int argc, char **argv) 13167{ 13168 errcode_t retval; 13169 int exit_value = EXIT_OK; 13170 ext2_filsys fs = 0; 13171 io_manager io_ptr; 13172 struct ext2_super_block *sb; 13173 const char *lib_ver_date; 13174 int my_ver, lib_ver; 13175 e2fsck_t ctx; 13176 struct problem_context pctx; 13177 int flags, run_result; 13178 13179 clear_problem_context(&pctx); 13180 13181 my_ver = ext2fs_parse_version_string(my_ver_string); 13182 lib_ver = ext2fs_get_library_version(0, &lib_ver_date); 13183 if (my_ver > lib_ver) { 13184 fprintf( stderr, _("Error: ext2fs library version " 13185 "out of date!\n")); 13186 show_version_only++; 13187 } 13188 13189 retval = PRS(argc, argv, &ctx); 13190 if (retval) { 13191 bb_error_msg(_("while trying to initialize program")); 13192 exit(EXIT_ERROR); 13193 } 13194 reserve_stdio_fds(); 13195 13196 if (!(ctx->options & E2F_OPT_PREEN) || show_version_only) 13197 fprintf(stderr, "e2fsck %s (%s)\n", my_ver_string, 13198 my_ver_date); 13199 13200 if (show_version_only) { 13201 fprintf(stderr, _("\tUsing %s, %s\n"), 13202 error_message(EXT2_ET_BASE), lib_ver_date); 13203 exit(EXIT_OK); 13204 } 13205 13206 check_mount(ctx); 13207 13208 if (!(ctx->options & E2F_OPT_PREEN) && 13209 !(ctx->options & E2F_OPT_NO) && 13210 !(ctx->options & E2F_OPT_YES)) { 13211 if (!ctx->interactive) 13212 bb_error_msg_and_die(_("need terminal for interactive repairs")); 13213 } 13214 ctx->superblock = ctx->use_superblock; 13215restart: 13216#ifdef CONFIG_TESTIO_DEBUG 13217 io_ptr = test_io_manager; 13218 test_io_backing_manager = unix_io_manager; 13219#else 13220 io_ptr = unix_io_manager; 13221#endif 13222 flags = 0; 13223 if ((ctx->options & E2F_OPT_READONLY) == 0) 13224 flags |= EXT2_FLAG_RW; 13225 13226 if (ctx->superblock && ctx->blocksize) { 13227 retval = ext2fs_open2(ctx->filesystem_name, ctx->io_options, 13228 flags, ctx->superblock, ctx->blocksize, 13229 io_ptr, &fs); 13230 } else if (ctx->superblock) { 13231 int blocksize; 13232 for (blocksize = EXT2_MIN_BLOCK_SIZE; 13233 blocksize <= EXT2_MAX_BLOCK_SIZE; blocksize *= 2) { 13234 retval = ext2fs_open2(ctx->filesystem_name, 13235 ctx->io_options, flags, 13236 ctx->superblock, blocksize, 13237 io_ptr, &fs); 13238 if (!retval) 13239 break; 13240 } 13241 } else 13242 retval = ext2fs_open2(ctx->filesystem_name, ctx->io_options, 13243 flags, 0, 0, io_ptr, &fs); 13244 if (!ctx->superblock && !(ctx->options & E2F_OPT_PREEN) && 13245 !(ctx->flags & E2F_FLAG_SB_SPECIFIED) && 13246 ((retval == EXT2_ET_BAD_MAGIC) || 13247 ((retval == 0) && ext2fs_check_desc(fs)))) { 13248 if (!fs || (fs->group_desc_count > 1)) { 13249 printf(_("%s trying backup blocks...\n"), 13250 retval ? _("Couldn't find ext2 superblock,") : 13251 _("Group descriptors look bad...")); 13252 get_backup_sb(ctx, fs, ctx->filesystem_name, io_ptr); 13253 if (fs) 13254 ext2fs_close(fs); 13255 goto restart; 13256 } 13257 } 13258 if (retval) { 13259 bb_error_msg(_("while trying to open %s"), 13260 ctx->filesystem_name); 13261 if (retval == EXT2_ET_REV_TOO_HIGH) { 13262 printf(_("The filesystem revision is apparently " 13263 "too high for this version of e2fsck.\n" 13264 "(Or the filesystem superblock " 13265 "is corrupt)\n\n")); 13266 fix_problem(ctx, PR_0_SB_CORRUPT, &pctx); 13267 } else if (retval == EXT2_ET_SHORT_READ) 13268 printf(_("Could this be a zero-length partition?\n")); 13269 else if ((retval == EPERM) || (retval == EACCES)) 13270 printf(_("You must have %s access to the " 13271 "filesystem or be root\n"), 13272 (ctx->options & E2F_OPT_READONLY) ? 13273 "r/o" : "r/w"); 13274 else if (retval == ENXIO) 13275 printf(_("Possibly non-existent or swap device?\n")); 13276#ifdef EROFS 13277 else if (retval == EROFS) 13278 printf(_("Disk write-protected; use the -n option " 13279 "to do a read-only\n" 13280 "check of the device.\n")); 13281#endif 13282 else 13283 fix_problem(ctx, PR_0_SB_CORRUPT, &pctx); 13284 bb_error_msg_and_die(0); 13285 } 13286 ctx->fs = fs; 13287 fs->priv_data = ctx; 13288 sb = fs->super; 13289 if (sb->s_rev_level > E2FSCK_CURRENT_REV) { 13290 bb_error_msg(_("while trying to open %s"), 13291 ctx->filesystem_name); 13292 get_newer: 13293 bb_error_msg_and_die(_("Get a newer version of e2fsck!")); 13294 } 13295 13296 /* 13297 * Set the device name, which is used whenever we print error 13298 * or informational messages to the user. 13299 */ 13300 if (ctx->device_name == 0 && 13301 (sb->s_volume_name[0] != 0)) { 13302 ctx->device_name = string_copy(sb->s_volume_name, 13303 sizeof(sb->s_volume_name)); 13304 } 13305 if (ctx->device_name == 0) 13306 ctx->device_name = ctx->filesystem_name; 13307 13308 /* 13309 * Make sure the ext3 superblock fields are consistent. 13310 */ 13311 retval = e2fsck_check_ext3_journal(ctx); 13312 if (retval) { 13313 bb_error_msg(_("while checking ext3 journal for %s"), 13314 ctx->device_name); 13315 bb_error_msg_and_die(0); 13316 } 13317 13318 /* 13319 * Check to see if we need to do ext3-style recovery. If so, 13320 * do it, and then restart the fsck. 13321 */ 13322 if (sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) { 13323 if (ctx->options & E2F_OPT_READONLY) { 13324 printf(_("Warning: skipping journal recovery " 13325 "because doing a read-only filesystem " 13326 "check.\n")); 13327 io_channel_flush(ctx->fs->io); 13328 } else { 13329 if (ctx->flags & E2F_FLAG_RESTARTED) { 13330 /* 13331 * Whoops, we attempted to run the 13332 * journal twice. This should never 13333 * happen, unless the hardware or 13334 * device driver is being bogus. 13335 */ 13336 bb_error_msg(_("cannot set superblock flags on %s"), ctx->device_name); 13337 bb_error_msg_and_die(0); 13338 } 13339 retval = e2fsck_run_ext3_journal(ctx); 13340 if (retval) { 13341 bb_error_msg(_("while recovering ext3 journal of %s"), 13342 ctx->device_name); 13343 bb_error_msg_and_die(0); 13344 } 13345 ext2fs_close(ctx->fs); 13346 ctx->fs = 0; 13347 ctx->flags |= E2F_FLAG_RESTARTED; 13348 goto restart; 13349 } 13350 } 13351 13352 /* 13353 * Check for compatibility with the feature sets. We need to 13354 * be more stringent than ext2fs_open(). 13355 */ 13356 if ((sb->s_feature_compat & ~EXT2_LIB_FEATURE_COMPAT_SUPP) || 13357 (sb->s_feature_incompat & ~EXT2_LIB_FEATURE_INCOMPAT_SUPP)) { 13358 bb_error_msg("(%s)", ctx->device_name); 13359 goto get_newer; 13360 } 13361 if (sb->s_feature_ro_compat & ~EXT2_LIB_FEATURE_RO_COMPAT_SUPP) { 13362 bb_error_msg("(%s)", ctx->device_name); 13363 goto get_newer; 13364 } 13365#ifdef ENABLE_COMPRESSION 13366 if (sb->s_feature_incompat & EXT2_FEATURE_INCOMPAT_COMPRESSION) 13367 bb_error_msg(_("Warning: compression support is experimental.")); 13368#endif 13369#ifndef ENABLE_HTREE 13370 if (sb->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) { 13371 bb_error_msg(_("E2fsck not compiled with HTREE support,\n\t" 13372 "but filesystem %s has HTREE directories."), 13373 ctx->device_name); 13374 goto get_newer; 13375 } 13376#endif 13377 13378 /* 13379 * If the user specified a specific superblock, presumably the 13380 * master superblock has been trashed. So we mark the 13381 * superblock as dirty, so it can be written out. 13382 */ 13383 if (ctx->superblock && 13384 !(ctx->options & E2F_OPT_READONLY)) 13385 ext2fs_mark_super_dirty(fs); 13386 13387 /* 13388 * We only update the master superblock because (a) paranoia; 13389 * we don't want to corrupt the backup superblocks, and (b) we 13390 * don't need to update the mount count and last checked 13391 * fields in the backup superblock (the kernel doesn't 13392 * update the backup superblocks anyway). 13393 */ 13394 fs->flags |= EXT2_FLAG_MASTER_SB_ONLY; 13395 13396 ehandler_init(fs->io); 13397 13398 if (ctx->superblock) 13399 set_latch_flags(PR_LATCH_RELOC, PRL_LATCHED, 0); 13400 ext2fs_mark_valid(fs); 13401 check_super_block(ctx); 13402 if (ctx->flags & E2F_FLAG_SIGNAL_MASK) 13403 bb_error_msg_and_die(0); 13404 check_if_skip(ctx); 13405 if (ctx->flags & E2F_FLAG_SIGNAL_MASK) 13406 bb_error_msg_and_die(0); 13407#ifdef ENABLE_SWAPFS 13408 13409#ifdef WORDS_BIGENDIAN 13410#define NATIVE_FLAG EXT2_FLAG_SWAP_BYTES 13411#else 13412#define NATIVE_FLAG 0 13413#endif 13414 13415 13416 if (normalize_swapfs) { 13417 if ((fs->flags & EXT2_FLAG_SWAP_BYTES) == NATIVE_FLAG) { 13418 fprintf(stderr, _("%s: Filesystem byte order " 13419 "already normalized.\n"), ctx->device_name); 13420 bb_error_msg_and_die(0); 13421 } 13422 } 13423 if (swapfs) { 13424 swap_filesys(ctx); 13425 if (ctx->flags & E2F_FLAG_SIGNAL_MASK) 13426 bb_error_msg_and_die(0); 13427 } 13428#endif 13429 13430 /* 13431 * Mark the system as valid, 'til proven otherwise 13432 */ 13433 ext2fs_mark_valid(fs); 13434 13435 retval = ext2fs_read_bb_inode(fs, &fs->badblocks); 13436 if (retval) { 13437 bb_error_msg(_("while reading bad blocks inode")); 13438 preenhalt(ctx); 13439 printf(_("This doesn't bode well," 13440 " but we'll try to go on...\n")); 13441 } 13442 13443 run_result = e2fsck_run(ctx); 13444 e2fsck_clear_progbar(ctx); 13445 if (run_result == E2F_FLAG_RESTART) { 13446 printf(_("Restarting e2fsck from the beginning...\n")); 13447 retval = e2fsck_reset_context(ctx); 13448 if (retval) { 13449 bb_error_msg(_("while resetting context")); 13450 bb_error_msg_and_die(0); 13451 } 13452 ext2fs_close(fs); 13453 goto restart; 13454 } 13455 if (run_result & E2F_FLAG_CANCEL) { 13456 printf(_("%s: e2fsck canceled.\n"), ctx->device_name ? 13457 ctx->device_name : ctx->filesystem_name); 13458 exit_value |= FSCK_CANCELED; 13459 } 13460 if (run_result & E2F_FLAG_ABORT) 13461 bb_error_msg_and_die(_("aborted")); 13462 13463 /* Cleanup */ 13464 if (ext2fs_test_changed(fs)) { 13465 exit_value |= EXIT_NONDESTRUCT; 13466 if (!(ctx->options & E2F_OPT_PREEN)) 13467 printf(_("\n%s: ***** FILE SYSTEM WAS MODIFIED *****\n"), 13468 ctx->device_name); 13469 if (ctx->mount_flags & EXT2_MF_ISROOT) { 13470 printf(_("%s: ***** REBOOT LINUX *****\n"), 13471 ctx->device_name); 13472 exit_value |= EXIT_DESTRUCT; 13473 } 13474 } 13475 if (!ext2fs_test_valid(fs)) { 13476 printf(_("\n%s: ********** WARNING: Filesystem still has " 13477 "errors **********\n\n"), ctx->device_name); 13478 exit_value |= EXIT_UNCORRECTED; 13479 exit_value &= ~EXIT_NONDESTRUCT; 13480 } 13481 if (exit_value & FSCK_CANCELED) 13482 exit_value &= ~EXIT_NONDESTRUCT; 13483 else { 13484 show_stats(ctx); 13485 if (!(ctx->options & E2F_OPT_READONLY)) { 13486 if (ext2fs_test_valid(fs)) { 13487 if (!(sb->s_state & EXT2_VALID_FS)) 13488 exit_value |= EXIT_NONDESTRUCT; 13489 sb->s_state = EXT2_VALID_FS; 13490 } else 13491 sb->s_state &= ~EXT2_VALID_FS; 13492 sb->s_mnt_count = 0; 13493 sb->s_lastcheck = time(NULL); 13494 ext2fs_mark_super_dirty(fs); 13495 } 13496 } 13497 13498 e2fsck_write_bitmaps(ctx); 13499 13500 ext2fs_close(fs); 13501 ctx->fs = NULL; 13502 free(ctx->filesystem_name); 13503 free(ctx->journal_name); 13504 e2fsck_free_context(ctx); 13505 13506 return exit_value; 13507} 13508