1 /* 2 * pass1b.c --- Pass #1b of e2fsck 3 * 4 * This file contains pass1B, pass1C, and pass1D of e2fsck. They are 5 * only invoked if pass 1 discovered blocks which are in use by more 6 * than one inode. 7 * 8 * Pass1B scans the data blocks of all the inodes again, generating a 9 * complete list of duplicate blocks and which inodes have claimed 10 * them. 11 * 12 * Pass1C does a tree-traversal of the filesystem, to determine the 13 * parent directories of these inodes. This step is necessary so that 14 * e2fsck can print out the pathnames of affected inodes. 15 * 16 * Pass1D is a reconciliation pass. For each inode with duplicate 17 * blocks, the user is prompted if s/he would like to clone the file 18 * (so that the file gets a fresh copy of the duplicated blocks) or 19 * simply to delete the file. 20 * 21 * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o. 22 * 23 * %Begin-Header% 24 * This file may be redistributed under the terms of the GNU Public 25 * License. 26 * %End-Header% 27 * 28 */ 29 30 #include "config.h" 31 #include <time.h> 32 #ifdef HAVE_ERRNO_H 33 #include <errno.h> 34 #endif 35 36 #ifdef HAVE_INTTYPES_H 37 #include <inttypes.h> 38 #endif 39 40 #ifndef HAVE_INTPTR_T 41 typedef long intptr_t; 42 #endif 43 44 /* Needed for architectures where sizeof(int) != sizeof(void *) */ 45 #define INT_TO_VOIDPTR(val) ((void *)(intptr_t)(val)) 46 #define VOIDPTR_TO_INT(ptr) ((int)(intptr_t)(ptr)) 47 48 #include <et/com_err.h> 49 #include "e2fsck.h" 50 51 #include "problem.h" 52 #include "support/dict.h" 53 54 /* Define an extension to the ext2 library's block count information */ 55 #define BLOCK_COUNT_EXTATTR (-5) 56 57 struct cluster_el { 58 blk64_t cluster; 59 struct cluster_el *next; 60 }; 61 62 struct inode_el { 63 ext2_ino_t inode; 64 struct inode_el *next; 65 }; 66 67 struct dup_cluster { 68 int num_bad; 69 struct inode_el *inode_list; 70 }; 71 72 /* 73 * This structure stores information about a particular inode which 74 * is sharing blocks with other inodes. This information is collected 75 * to display to the user, so that the user knows what files he or she 76 * is dealing with, when trying to decide how to resolve the conflict 77 * of multiply-claimed blocks. 78 */ 79 struct dup_inode { 80 ext2_ino_t dir; 81 int num_dupblocks; 82 struct ext2_inode_large inode; 83 struct cluster_el *cluster_list; 84 }; 85 86 static int process_pass1b_block(ext2_filsys fs, blk64_t *blocknr, 87 e2_blkcnt_t blockcnt, blk64_t ref_blk, 88 int ref_offset, void *priv_data); 89 static void delete_file(e2fsck_t ctx, ext2_ino_t ino, 90 struct dup_inode *dp, char *block_buf); 91 static errcode_t clone_file(e2fsck_t ctx, ext2_ino_t ino, 92 struct dup_inode *dp, char* block_buf); 93 static int check_if_fs_block(e2fsck_t ctx, blk64_t test_block); 94 static int check_if_fs_cluster(e2fsck_t ctx, blk64_t cluster); 95 96 static void pass1b(e2fsck_t ctx, char *block_buf); 97 static void pass1c(e2fsck_t ctx, char *block_buf); 98 static void pass1d(e2fsck_t ctx, char *block_buf); 99 100 static int dup_inode_count = 0; 101 static int dup_inode_founddir = 0; 102 103 static dict_t clstr_dict, ino_dict; 104 105 static ext2fs_inode_bitmap inode_dup_map; 106 107 static int dict_int_cmp(const void *a, const void *b) 108 { 109 intptr_t ia, ib; 110 111 ia = (intptr_t)a; 112 ib = (intptr_t)b; 113 114 return (ia-ib); 115 } 116 117 /* 118 * Add a duplicate block record 119 */ 120 static void add_dupe(e2fsck_t ctx, ext2_ino_t ino, blk64_t cluster, 121 struct ext2_inode_large *inode) 122 { 123 dnode_t *n; 124 struct dup_cluster *db; 125 struct dup_inode *di; 126 struct cluster_el *cluster_el; 127 struct inode_el *ino_el; 128 129 n = dict_lookup(&clstr_dict, INT_TO_VOIDPTR(cluster)); 130 if (n) 131 db = (struct dup_cluster *) dnode_get(n); 132 else { 133 db = (struct dup_cluster *) e2fsck_allocate_memory(ctx, 134 sizeof(struct dup_cluster), "duplicate cluster header"); 135 db->num_bad = 0; 136 db->inode_list = 0; 137 dict_alloc_insert(&clstr_dict, INT_TO_VOIDPTR(cluster), db); 138 } 139 ino_el = (struct inode_el *) e2fsck_allocate_memory(ctx, 140 sizeof(struct inode_el), "inode element"); 141 ino_el->inode = ino; 142 ino_el->next = db->inode_list; 143 db->inode_list = ino_el; 144 db->num_bad++; 145 146 n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(ino)); 147 if (n) 148 di = (struct dup_inode *) dnode_get(n); 149 else { 150 di = (struct dup_inode *) e2fsck_allocate_memory(ctx, 151 sizeof(struct dup_inode), "duplicate inode header"); 152 if (ino == EXT2_ROOT_INO) { 153 di->dir = EXT2_ROOT_INO; 154 dup_inode_founddir++; 155 } else 156 di->dir = 0; 157 158 di->num_dupblocks = 0; 159 di->cluster_list = 0; 160 di->inode = *inode; 161 dict_alloc_insert(&ino_dict, INT_TO_VOIDPTR(ino), di); 162 } 163 cluster_el = (struct cluster_el *) e2fsck_allocate_memory(ctx, 164 sizeof(struct cluster_el), "cluster element"); 165 cluster_el->cluster = cluster; 166 cluster_el->next = di->cluster_list; 167 di->cluster_list = cluster_el; 168 di->num_dupblocks++; 169 } 170 171 /* 172 * Free a duplicate inode record 173 */ 174 static void inode_dnode_free(dnode_t *node, 175 void *context EXT2FS_ATTR((unused))) 176 { 177 struct dup_inode *di; 178 struct cluster_el *p, *next; 179 180 di = (struct dup_inode *) dnode_get(node); 181 for (p = di->cluster_list; p; p = next) { 182 next = p->next; 183 free(p); 184 } 185 free(di); 186 free(node); 187 } 188 189 /* 190 * Free a duplicate cluster record 191 */ 192 static void cluster_dnode_free(dnode_t *node, 193 void *context EXT2FS_ATTR((unused))) 194 { 195 struct dup_cluster *dc; 196 struct inode_el *p, *next; 197 198 dc = (struct dup_cluster *) dnode_get(node); 199 for (p = dc->inode_list; p; p = next) { 200 next = p->next; 201 free(p); 202 } 203 free(dc); 204 free(node); 205 } 206 207 208 /* 209 * Main procedure for handling duplicate blocks 210 */ 211 void e2fsck_pass1_dupblocks(e2fsck_t ctx, char *block_buf) 212 { 213 ext2_filsys fs = ctx->fs; 214 struct problem_context pctx; 215 #ifdef RESOURCE_TRACK 216 struct resource_track rtrack; 217 #endif 218 219 clear_problem_context(&pctx); 220 221 pctx.errcode = e2fsck_allocate_inode_bitmap(fs, 222 _("multiply claimed inode map"), 223 EXT2FS_BMAP64_RBTREE, "inode_dup_map", 224 &inode_dup_map); 225 if (pctx.errcode) { 226 fix_problem(ctx, PR_1B_ALLOCATE_IBITMAP_ERROR, &pctx); 227 ctx->flags |= E2F_FLAG_ABORT; 228 return; 229 } 230 231 dict_init(&ino_dict, DICTCOUNT_T_MAX, dict_int_cmp); 232 dict_init(&clstr_dict, DICTCOUNT_T_MAX, dict_int_cmp); 233 dict_set_allocator(&ino_dict, NULL, inode_dnode_free, NULL); 234 dict_set_allocator(&clstr_dict, NULL, cluster_dnode_free, NULL); 235 236 init_resource_track(&rtrack, ctx->fs->io); 237 pass1b(ctx, block_buf); 238 print_resource_track(ctx, "Pass 1b", &rtrack, ctx->fs->io); 239 240 init_resource_track(&rtrack, ctx->fs->io); 241 pass1c(ctx, block_buf); 242 print_resource_track(ctx, "Pass 1c", &rtrack, ctx->fs->io); 243 244 init_resource_track(&rtrack, ctx->fs->io); 245 pass1d(ctx, block_buf); 246 print_resource_track(ctx, "Pass 1d", &rtrack, ctx->fs->io); 247 248 /* 249 * Time to free all of the accumulated data structures that we 250 * don't need anymore. 251 */ 252 dict_free_nodes(&ino_dict); 253 dict_free_nodes(&clstr_dict); 254 ext2fs_free_inode_bitmap(inode_dup_map); 255 } 256 257 /* 258 * Scan the inodes looking for inodes that contain duplicate blocks. 259 */ 260 struct process_block_struct { 261 e2fsck_t ctx; 262 ext2_ino_t ino; 263 int dup_blocks; 264 blk64_t cur_cluster, phys_cluster; 265 blk64_t last_blk; 266 struct ext2_inode_large *inode; 267 struct problem_context *pctx; 268 }; 269 270 static void pass1b(e2fsck_t ctx, char *block_buf) 271 { 272 ext2_filsys fs = ctx->fs; 273 ext2_ino_t ino = 0; 274 struct ext2_inode_large inode; 275 ext2_inode_scan scan; 276 struct process_block_struct pb; 277 struct problem_context pctx; 278 problem_t op; 279 280 clear_problem_context(&pctx); 281 282 if (!(ctx->options & E2F_OPT_PREEN)) 283 fix_problem(ctx, PR_1B_PASS_HEADER, &pctx); 284 pctx.errcode = ext2fs_open_inode_scan(fs, ctx->inode_buffer_blocks, 285 &scan); 286 if (pctx.errcode) { 287 fix_problem(ctx, PR_1B_ISCAN_ERROR, &pctx); 288 ctx->flags |= E2F_FLAG_ABORT; 289 return; 290 } 291 ctx->stashed_inode = EXT2_INODE(&inode); 292 pb.ctx = ctx; 293 pb.pctx = &pctx; 294 pctx.str = "pass1b"; 295 while (1) { 296 if (ino % (fs->super->s_inodes_per_group * 4) == 1) { 297 if (e2fsck_mmp_update(fs)) 298 fatal_error(ctx, 0); 299 } 300 pctx.errcode = ext2fs_get_next_inode_full(scan, &ino, 301 EXT2_INODE(&inode), sizeof(inode)); 302 if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE) 303 continue; 304 if (pctx.errcode) { 305 pctx.ino = ino; 306 fix_problem(ctx, PR_1B_ISCAN_ERROR, &pctx); 307 ctx->flags |= E2F_FLAG_ABORT; 308 return; 309 } 310 if (!ino) 311 break; 312 pctx.ino = ctx->stashed_ino = ino; 313 if ((ino != EXT2_BAD_INO) && 314 !ext2fs_test_inode_bitmap2(ctx->inode_used_map, ino)) 315 continue; 316 317 pb.ino = ino; 318 pb.dup_blocks = 0; 319 pb.inode = &inode; 320 pb.cur_cluster = ~0; 321 pb.phys_cluster = ~0; 322 pb.last_blk = 0; 323 pb.pctx->blk = pb.pctx->blk2 = 0; 324 325 if (ext2fs_inode_has_valid_blocks2(fs, EXT2_INODE(&inode)) || 326 (ino == EXT2_BAD_INO)) 327 pctx.errcode = ext2fs_block_iterate3(fs, ino, 328 BLOCK_FLAG_READ_ONLY, block_buf, 329 process_pass1b_block, &pb); 330 /* If the feature is not set, attrs will be cleared later anyway */ 331 if (ext2fs_has_feature_xattr(fs->super) && 332 ext2fs_file_acl_block(fs, EXT2_INODE(&inode))) { 333 blk64_t blk = ext2fs_file_acl_block(fs, EXT2_INODE(&inode)); 334 process_pass1b_block(fs, &blk, 335 BLOCK_COUNT_EXTATTR, 0, 0, &pb); 336 ext2fs_file_acl_block_set(fs, EXT2_INODE(&inode), blk); 337 } 338 if (pb.dup_blocks) { 339 if (ino != EXT2_BAD_INO) { 340 op = pctx.blk == pctx.blk2 ? 341 PR_1B_DUP_BLOCK : PR_1B_DUP_RANGE; 342 fix_problem(ctx, op, pb.pctx); 343 } 344 end_problem_latch(ctx, PR_LATCH_DBLOCK); 345 if (ino >= EXT2_FIRST_INODE(fs->super) || 346 ino == EXT2_ROOT_INO) 347 dup_inode_count++; 348 } 349 if (pctx.errcode) 350 fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx); 351 } 352 ext2fs_close_inode_scan(scan); 353 e2fsck_use_inode_shortcuts(ctx, 0); 354 } 355 356 static int process_pass1b_block(ext2_filsys fs EXT2FS_ATTR((unused)), 357 blk64_t *block_nr, 358 e2_blkcnt_t blockcnt, 359 blk64_t ref_blk EXT2FS_ATTR((unused)), 360 int ref_offset EXT2FS_ATTR((unused)), 361 void *priv_data) 362 { 363 struct process_block_struct *p; 364 e2fsck_t ctx; 365 blk64_t lc, pc; 366 problem_t op; 367 368 if (*block_nr == 0) 369 return 0; 370 p = (struct process_block_struct *) priv_data; 371 ctx = p->ctx; 372 lc = EXT2FS_B2C(fs, blockcnt); 373 pc = EXT2FS_B2C(fs, *block_nr); 374 375 if (!ext2fs_test_block_bitmap2(ctx->block_dup_map, *block_nr)) 376 goto finish; 377 378 /* OK, this is a duplicate block */ 379 if (p->ino != EXT2_BAD_INO) { 380 if (p->last_blk + 1 != *block_nr) { 381 if (p->last_blk) { 382 op = p->pctx->blk == p->pctx->blk2 ? 383 PR_1B_DUP_BLOCK : 384 PR_1B_DUP_RANGE; 385 fix_problem(ctx, op, p->pctx); 386 } 387 p->pctx->blk = *block_nr; 388 } 389 p->pctx->blk2 = *block_nr; 390 p->last_blk = *block_nr; 391 } 392 p->dup_blocks++; 393 ext2fs_mark_inode_bitmap2(inode_dup_map, p->ino); 394 395 /* 396 * Qualifications for submitting a block for duplicate processing: 397 * It's an extent/indirect block (and has a negative logical offset); 398 * we've crossed a logical cluster boundary; or the physical cluster 399 * suddenly changed, which indicates that blocks in a logical cluster 400 * are mapped to multiple physical clusters. 401 */ 402 if (blockcnt < 0 || lc != p->cur_cluster || pc != p->phys_cluster) 403 add_dupe(ctx, p->ino, EXT2FS_B2C(fs, *block_nr), p->inode); 404 405 finish: 406 p->cur_cluster = lc; 407 p->phys_cluster = pc; 408 return 0; 409 } 410 411 /* 412 * Pass 1c: Scan directories for inodes with duplicate blocks. This 413 * is used so that we can print pathnames when prompting the user for 414 * what to do. 415 */ 416 struct search_dir_struct { 417 int count; 418 ext2_ino_t first_inode; 419 ext2_ino_t max_inode; 420 }; 421 422 static int search_dirent_proc(ext2_ino_t dir, int entry, 423 struct ext2_dir_entry *dirent, 424 int offset EXT2FS_ATTR((unused)), 425 int blocksize EXT2FS_ATTR((unused)), 426 char *buf EXT2FS_ATTR((unused)), 427 void *priv_data) 428 { 429 struct search_dir_struct *sd; 430 struct dup_inode *p; 431 dnode_t *n; 432 433 sd = (struct search_dir_struct *) priv_data; 434 435 if (dirent->inode > sd->max_inode) 436 /* Should abort this inode, but not everything */ 437 return 0; 438 439 if ((dirent->inode < sd->first_inode) || (entry < DIRENT_OTHER_FILE) || 440 !ext2fs_test_inode_bitmap2(inode_dup_map, dirent->inode)) 441 return 0; 442 443 n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(dirent->inode)); 444 if (!n) 445 return 0; 446 p = (struct dup_inode *) dnode_get(n); 447 if (!p->dir) { 448 p->dir = dir; 449 sd->count--; 450 } 451 452 return(sd->count ? 0 : DIRENT_ABORT); 453 } 454 455 456 static void pass1c(e2fsck_t ctx, char *block_buf) 457 { 458 ext2_filsys fs = ctx->fs; 459 struct search_dir_struct sd; 460 struct problem_context pctx; 461 462 clear_problem_context(&pctx); 463 464 if (!(ctx->options & E2F_OPT_PREEN)) 465 fix_problem(ctx, PR_1C_PASS_HEADER, &pctx); 466 467 /* 468 * Search through all directories to translate inodes to names 469 * (by searching for the containing directory for that inode.) 470 */ 471 sd.count = dup_inode_count - dup_inode_founddir; 472 sd.first_inode = EXT2_FIRST_INODE(fs->super); 473 sd.max_inode = fs->super->s_inodes_count; 474 ext2fs_dblist_dir_iterate(fs->dblist, 0, block_buf, 475 search_dirent_proc, &sd); 476 } 477 478 static void pass1d(e2fsck_t ctx, char *block_buf) 479 { 480 ext2_filsys fs = ctx->fs; 481 struct dup_inode *p, *t; 482 struct dup_cluster *q; 483 ext2_ino_t *shared, ino; 484 int shared_len; 485 int i; 486 int file_ok; 487 int meta_data = 0; 488 struct problem_context pctx; 489 dnode_t *n, *m; 490 struct cluster_el *s; 491 struct inode_el *r; 492 493 clear_problem_context(&pctx); 494 495 if (!(ctx->options & E2F_OPT_PREEN)) 496 fix_problem(ctx, PR_1D_PASS_HEADER, &pctx); 497 e2fsck_read_bitmaps(ctx); 498 499 pctx.num = dup_inode_count; /* dict_count(&ino_dict); */ 500 fix_problem(ctx, PR_1D_NUM_DUP_INODES, &pctx); 501 shared = (ext2_ino_t *) e2fsck_allocate_memory(ctx, 502 sizeof(ext2_ino_t) * dict_count(&ino_dict), 503 "Shared inode list"); 504 for (n = dict_first(&ino_dict); n; n = dict_next(&ino_dict, n)) { 505 p = (struct dup_inode *) dnode_get(n); 506 shared_len = 0; 507 file_ok = 1; 508 ino = (ext2_ino_t)VOIDPTR_TO_INT(dnode_getkey(n)); 509 if (ino == EXT2_BAD_INO || ino == EXT2_RESIZE_INO) 510 continue; 511 512 /* 513 * Find all of the inodes which share blocks with this 514 * one. First we find all of the duplicate blocks 515 * belonging to this inode, and then search each block 516 * get the list of inodes, and merge them together. 517 */ 518 for (s = p->cluster_list; s; s = s->next) { 519 m = dict_lookup(&clstr_dict, 520 INT_TO_VOIDPTR(s->cluster)); 521 if (!m) 522 continue; /* Should never happen... */ 523 q = (struct dup_cluster *) dnode_get(m); 524 if (q->num_bad > 1) 525 file_ok = 0; 526 if (check_if_fs_cluster(ctx, s->cluster)) { 527 file_ok = 0; 528 meta_data = 1; 529 } 530 531 /* 532 * Add all inodes used by this block to the 533 * shared[] --- which is a unique list, so 534 * if an inode is already in shared[], don't 535 * add it again. 536 */ 537 for (r = q->inode_list; r; r = r->next) { 538 if (r->inode == ino) 539 continue; 540 for (i = 0; i < shared_len; i++) 541 if (shared[i] == r->inode) 542 break; 543 if (i == shared_len) { 544 shared[shared_len++] = r->inode; 545 } 546 } 547 } 548 549 /* 550 * Report the inode that we are working on 551 */ 552 pctx.inode = EXT2_INODE(&p->inode); 553 pctx.ino = ino; 554 pctx.dir = p->dir; 555 pctx.blkcount = p->num_dupblocks; 556 pctx.num = meta_data ? shared_len+1 : shared_len; 557 fix_problem(ctx, PR_1D_DUP_FILE, &pctx); 558 pctx.blkcount = 0; 559 pctx.num = 0; 560 561 if (meta_data) 562 fix_problem(ctx, PR_1D_SHARE_METADATA, &pctx); 563 564 for (i = 0; i < shared_len; i++) { 565 m = dict_lookup(&ino_dict, INT_TO_VOIDPTR(shared[i])); 566 if (!m) 567 continue; /* should never happen */ 568 t = (struct dup_inode *) dnode_get(m); 569 /* 570 * Report the inode that we are sharing with 571 */ 572 pctx.inode = EXT2_INODE(&t->inode); 573 pctx.ino = shared[i]; 574 pctx.dir = t->dir; 575 fix_problem(ctx, PR_1D_DUP_FILE_LIST, &pctx); 576 } 577 /* 578 * Even if the file shares blocks with itself, we still need to 579 * clone the blocks. 580 */ 581 if (file_ok && (meta_data ? shared_len+1 : shared_len) != 0) { 582 fix_problem(ctx, PR_1D_DUP_BLOCKS_DEALT, &pctx); 583 continue; 584 } 585 if (fix_problem(ctx, PR_1D_CLONE_QUESTION, &pctx)) { 586 pctx.errcode = clone_file(ctx, ino, p, block_buf); 587 if (pctx.errcode) 588 fix_problem(ctx, PR_1D_CLONE_ERROR, &pctx); 589 else 590 continue; 591 } 592 if (fix_problem(ctx, PR_1D_DELETE_QUESTION, &pctx)) 593 delete_file(ctx, ino, p, block_buf); 594 else 595 ext2fs_unmark_valid(fs); 596 } 597 ext2fs_free_mem(&shared); 598 } 599 600 /* 601 * Drop the refcount on the dup_block structure, and clear the entry 602 * in the block_dup_map if appropriate. 603 */ 604 static void decrement_badcount(e2fsck_t ctx, blk64_t block, 605 struct dup_cluster *p) 606 { 607 p->num_bad--; 608 if (p->num_bad <= 0 || 609 (p->num_bad == 1 && !check_if_fs_block(ctx, block))) { 610 if (check_if_fs_cluster(ctx, EXT2FS_B2C(ctx->fs, block))) 611 return; 612 ext2fs_unmark_block_bitmap2(ctx->block_dup_map, block); 613 } 614 } 615 616 static int delete_file_block(ext2_filsys fs, 617 blk64_t *block_nr, 618 e2_blkcnt_t blockcnt, 619 blk64_t ref_block EXT2FS_ATTR((unused)), 620 int ref_offset EXT2FS_ATTR((unused)), 621 void *priv_data) 622 { 623 struct process_block_struct *pb; 624 struct dup_cluster *p; 625 dnode_t *n; 626 e2fsck_t ctx; 627 blk64_t c, lc; 628 629 pb = (struct process_block_struct *) priv_data; 630 ctx = pb->ctx; 631 632 if (*block_nr == 0) 633 return 0; 634 635 c = EXT2FS_B2C(fs, *block_nr); 636 lc = EXT2FS_B2C(fs, blockcnt); 637 if (ext2fs_test_block_bitmap2(ctx->block_dup_map, *block_nr)) { 638 n = dict_lookup(&clstr_dict, INT_TO_VOIDPTR(c)); 639 if (n) { 640 p = (struct dup_cluster *) dnode_get(n); 641 if (lc != pb->cur_cluster) 642 decrement_badcount(ctx, *block_nr, p); 643 } else 644 com_err("delete_file_block", 0, 645 _("internal error: can't find dup_blk for %llu\n"), 646 *block_nr); 647 } else { 648 if ((*block_nr % EXT2FS_CLUSTER_RATIO(ctx->fs)) == 0) 649 ext2fs_block_alloc_stats2(fs, *block_nr, -1); 650 pb->dup_blocks++; 651 } 652 pb->cur_cluster = lc; 653 654 return 0; 655 } 656 657 static void delete_file(e2fsck_t ctx, ext2_ino_t ino, 658 struct dup_inode *dp, char* block_buf) 659 { 660 ext2_filsys fs = ctx->fs; 661 struct process_block_struct pb; 662 struct problem_context pctx; 663 unsigned int count; 664 665 clear_problem_context(&pctx); 666 pctx.ino = pb.ino = ino; 667 pb.dup_blocks = 0; 668 pb.ctx = ctx; 669 pctx.str = "delete_file"; 670 pb.cur_cluster = ~0; 671 672 if (ext2fs_inode_has_valid_blocks2(fs, EXT2_INODE(&dp->inode))) 673 pctx.errcode = ext2fs_block_iterate3(fs, ino, 674 BLOCK_FLAG_READ_ONLY, 675 block_buf, 676 delete_file_block, &pb); 677 if (pctx.errcode) 678 fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx); 679 if (ctx->inode_bad_map) 680 ext2fs_unmark_inode_bitmap2(ctx->inode_bad_map, ino); 681 ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(dp->inode.i_mode)); 682 quota_data_sub(ctx->qctx, &dp->inode, ino, 683 pb.dup_blocks * fs->blocksize); 684 quota_data_inodes(ctx->qctx, &dp->inode, ino, -1); 685 686 /* Inode may have changed by block_iterate, so reread it */ 687 e2fsck_read_inode_full(ctx, ino, EXT2_INODE(&dp->inode), 688 sizeof(dp->inode), "delete_file"); 689 e2fsck_clear_inode(ctx, ino, EXT2_INODE(&dp->inode), 0, "delete_file"); 690 if (ext2fs_file_acl_block(fs, EXT2_INODE(&dp->inode)) && 691 ext2fs_has_feature_xattr(fs->super)) { 692 blk64_t file_acl_block = ext2fs_file_acl_block(fs, 693 EXT2_INODE(&dp->inode)); 694 695 count = 1; 696 pctx.errcode = ext2fs_adjust_ea_refcount3(fs, file_acl_block, 697 block_buf, -1, &count, ino); 698 if (pctx.errcode == EXT2_ET_BAD_EA_BLOCK_NUM) { 699 pctx.errcode = 0; 700 count = 1; 701 } 702 if (pctx.errcode) { 703 pctx.blk = file_acl_block; 704 fix_problem(ctx, PR_1B_ADJ_EA_REFCOUNT, &pctx); 705 } 706 /* 707 * If the count is zero, then arrange to have the 708 * block deleted. If the block is in the block_dup_map, 709 * also call delete_file_block since it will take care 710 * of keeping the accounting straight. 711 */ 712 if ((count == 0) || 713 ext2fs_test_block_bitmap2(ctx->block_dup_map, 714 file_acl_block)) { 715 delete_file_block(fs, &file_acl_block, 716 BLOCK_COUNT_EXTATTR, 0, 0, &pb); 717 ext2fs_file_acl_block_set(fs, EXT2_INODE(&dp->inode), 718 file_acl_block); 719 quota_data_sub(ctx->qctx, &dp->inode, ino, 720 fs->blocksize); 721 } 722 } 723 } 724 725 struct clone_struct { 726 errcode_t errcode; 727 blk64_t dup_cluster; 728 blk64_t alloc_block; 729 ext2_ino_t dir, ino; 730 char *buf; 731 e2fsck_t ctx; 732 struct ext2_inode_large *inode; 733 734 struct dup_cluster *save_dup_cluster; 735 blk64_t save_blocknr; 736 }; 737 738 /* 739 * Decrement the bad count *after* we've shown that (a) we can allocate a 740 * replacement block and (b) remap the file blocks. Unfortunately, there's no 741 * way to find out if the remap succeeded until either the next 742 * clone_file_block() call (an error when remapping the block after returning 743 * BLOCK_CHANGED will halt the iteration) or after block_iterate() returns. 744 * Otherwise, it's possible that we decrease the badcount once in preparation 745 * to remap, then the remap fails (either we can't find a replacement block or 746 * we have to split the extent tree and can't find a new extent block), so we 747 * delete the file, which decreases the badcount again. 748 */ 749 static void deferred_dec_badcount(struct clone_struct *cs) 750 { 751 if (!cs->save_dup_cluster) 752 return; 753 decrement_badcount(cs->ctx, cs->save_blocknr, cs->save_dup_cluster); 754 cs->save_dup_cluster = NULL; 755 } 756 757 static int clone_file_block(ext2_filsys fs, 758 blk64_t *block_nr, 759 e2_blkcnt_t blockcnt, 760 blk64_t ref_block EXT2FS_ATTR((unused)), 761 int ref_offset EXT2FS_ATTR((unused)), 762 void *priv_data) 763 { 764 struct dup_cluster *p = NULL; 765 blk64_t new_block; 766 errcode_t retval; 767 struct clone_struct *cs = (struct clone_struct *) priv_data; 768 dnode_t *n; 769 e2fsck_t ctx; 770 blk64_t c; 771 int is_meta = 0; 772 773 ctx = cs->ctx; 774 deferred_dec_badcount(cs); 775 776 if (*block_nr == 0) 777 return 0; 778 779 c = EXT2FS_B2C(fs, blockcnt); 780 if (check_if_fs_cluster(ctx, EXT2FS_B2C(fs, *block_nr))) 781 is_meta = 1; 782 783 if (c == cs->dup_cluster && cs->alloc_block) { 784 new_block = cs->alloc_block; 785 goto got_block; 786 } 787 788 if (ext2fs_test_block_bitmap2(ctx->block_dup_map, *block_nr)) { 789 n = dict_lookup(&clstr_dict, 790 INT_TO_VOIDPTR(EXT2FS_B2C(fs, *block_nr))); 791 if (!n) { 792 com_err("clone_file_block", 0, 793 _("internal error: can't find dup_blk for %llu\n"), 794 *block_nr); 795 return 0; 796 } 797 798 p = (struct dup_cluster *) dnode_get(n); 799 800 cs->dup_cluster = c; 801 /* 802 * Let's try an implied cluster allocation. If we get the same 803 * cluster back, then we need to find a new block; otherwise, 804 * we're merely fixing the problem of one logical cluster being 805 * mapped to multiple physical clusters. 806 */ 807 new_block = 0; 808 retval = ext2fs_map_cluster_block(fs, cs->ino, 809 EXT2_INODE(cs->inode), 810 blockcnt, &new_block); 811 if (retval == 0 && new_block != 0 && 812 EXT2FS_B2C(ctx->fs, new_block) != 813 EXT2FS_B2C(ctx->fs, *block_nr)) 814 goto cluster_alloc_ok; 815 retval = ext2fs_new_block2(fs, 0, ctx->block_found_map, 816 &new_block); 817 if (retval) { 818 cs->errcode = retval; 819 return BLOCK_ABORT; 820 } 821 cluster_alloc_ok: 822 cs->alloc_block = new_block; 823 824 got_block: 825 new_block &= ~EXT2FS_CLUSTER_MASK(fs); 826 new_block += EXT2FS_CLUSTER_MASK(fs) & blockcnt; 827 if (cs->dir && (blockcnt >= 0)) { 828 retval = ext2fs_set_dir_block2(fs->dblist, 829 cs->dir, new_block, blockcnt); 830 if (retval) { 831 cs->errcode = retval; 832 return BLOCK_ABORT; 833 } 834 } 835 #if 0 836 printf("Cloning block #%lld from %llu to %llu\n", 837 blockcnt, *block_nr, new_block); 838 #endif 839 retval = io_channel_read_blk64(fs->io, *block_nr, 1, cs->buf); 840 if (retval) { 841 cs->errcode = retval; 842 return BLOCK_ABORT; 843 } 844 retval = io_channel_write_blk64(fs->io, new_block, 1, cs->buf); 845 if (retval) { 846 cs->errcode = retval; 847 return BLOCK_ABORT; 848 } 849 cs->save_dup_cluster = (is_meta ? NULL : p); 850 cs->save_blocknr = *block_nr; 851 *block_nr = new_block; 852 ext2fs_mark_block_bitmap2(ctx->block_found_map, new_block); 853 ext2fs_mark_block_bitmap2(fs->block_map, new_block); 854 return BLOCK_CHANGED; 855 } 856 return 0; 857 } 858 859 static errcode_t clone_file(e2fsck_t ctx, ext2_ino_t ino, 860 struct dup_inode *dp, char* block_buf) 861 { 862 ext2_filsys fs = ctx->fs; 863 errcode_t retval; 864 struct clone_struct cs; 865 struct problem_context pctx; 866 blk64_t blk, new_blk; 867 dnode_t *n; 868 struct inode_el *ino_el; 869 struct dup_cluster *dc; 870 struct dup_inode *di; 871 872 clear_problem_context(&pctx); 873 cs.errcode = 0; 874 cs.dir = 0; 875 cs.dup_cluster = ~0; 876 cs.alloc_block = 0; 877 cs.ctx = ctx; 878 cs.ino = ino; 879 cs.inode = &dp->inode; 880 cs.save_dup_cluster = NULL; 881 cs.save_blocknr = 0; 882 retval = ext2fs_get_mem(fs->blocksize, &cs.buf); 883 if (retval) 884 return retval; 885 886 if (ext2fs_test_inode_bitmap2(ctx->inode_dir_map, ino)) 887 cs.dir = ino; 888 889 pctx.ino = ino; 890 pctx.str = "clone_file"; 891 if (ext2fs_inode_has_valid_blocks2(fs, EXT2_INODE(&dp->inode))) 892 pctx.errcode = ext2fs_block_iterate3(fs, ino, 0, block_buf, 893 clone_file_block, &cs); 894 deferred_dec_badcount(&cs); 895 ext2fs_mark_bb_dirty(fs); 896 if (pctx.errcode) { 897 fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx); 898 retval = pctx.errcode; 899 goto errout; 900 } 901 if (cs.errcode) { 902 com_err("clone_file", cs.errcode, "%s", 903 _("returned from clone_file_block")); 904 retval = cs.errcode; 905 goto errout; 906 } 907 /* The inode may have changed on disk, so we have to re-read it */ 908 e2fsck_read_inode_full(ctx, ino, EXT2_INODE(&dp->inode), 909 sizeof(dp->inode), "clone file EA"); 910 blk = ext2fs_file_acl_block(fs, EXT2_INODE(&dp->inode)); 911 new_blk = blk; 912 if (blk && (clone_file_block(fs, &new_blk, 913 BLOCK_COUNT_EXTATTR, 0, 0, &cs) == 914 BLOCK_CHANGED)) { 915 ext2fs_file_acl_block_set(fs, EXT2_INODE(&dp->inode), new_blk); 916 e2fsck_write_inode_full(ctx, ino, EXT2_INODE(&dp->inode), 917 sizeof(dp->inode), "clone file EA"); 918 /* 919 * If we cloned the EA block, find all other inodes 920 * which refered to that EA block, and modify 921 * them to point to the new EA block. 922 */ 923 n = dict_lookup(&clstr_dict, 924 INT_TO_VOIDPTR(EXT2FS_B2C(fs, blk))); 925 if (!n) { 926 com_err("clone_file", 0, 927 _("internal error: couldn't lookup EA " 928 "block record for %llu"), blk); 929 retval = 0; /* OK to stumble on... */ 930 goto errout; 931 } 932 dc = (struct dup_cluster *) dnode_get(n); 933 for (ino_el = dc->inode_list; ino_el; ino_el = ino_el->next) { 934 if (ino_el->inode == ino) 935 continue; 936 n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(ino_el->inode)); 937 if (!n) { 938 com_err("clone_file", 0, 939 _("internal error: couldn't lookup EA " 940 "inode record for %u"), 941 ino_el->inode); 942 retval = 0; /* OK to stumble on... */ 943 goto errout; 944 } 945 di = (struct dup_inode *) dnode_get(n); 946 if (ext2fs_file_acl_block(fs, 947 EXT2_INODE(&di->inode)) == blk) { 948 ext2fs_file_acl_block_set(fs, 949 EXT2_INODE(&di->inode), 950 ext2fs_file_acl_block(fs, EXT2_INODE(&dp->inode))); 951 e2fsck_write_inode_full(ctx, ino_el->inode, 952 EXT2_INODE(&di->inode), 953 sizeof(di->inode), "clone file EA"); 954 decrement_badcount(ctx, blk, dc); 955 } 956 } 957 } 958 retval = 0; 959 errout: 960 ext2fs_free_mem(&cs.buf); 961 return retval; 962 } 963 964 /* 965 * This routine returns 1 if a block overlaps with one of the superblocks, 966 * group descriptors, inode bitmaps, or block bitmaps. 967 */ 968 static int check_if_fs_block(e2fsck_t ctx, blk64_t test_block) 969 { 970 ext2_filsys fs = ctx->fs; 971 blk64_t first_block; 972 dgrp_t i; 973 974 first_block = fs->super->s_first_data_block; 975 for (i = 0; i < fs->group_desc_count; i++) { 976 977 /* Check superblocks/block group descriptors */ 978 if (ext2fs_bg_has_super(fs, i)) { 979 if (test_block >= first_block && 980 (test_block <= first_block + fs->desc_blocks)) 981 return 1; 982 } 983 984 /* Check the inode table */ 985 if ((ext2fs_inode_table_loc(fs, i)) && 986 (test_block >= ext2fs_inode_table_loc(fs, i)) && 987 (test_block < (ext2fs_inode_table_loc(fs, i) + 988 fs->inode_blocks_per_group))) 989 return 1; 990 991 /* Check the bitmap blocks */ 992 if ((test_block == ext2fs_block_bitmap_loc(fs, i)) || 993 (test_block == ext2fs_inode_bitmap_loc(fs, i))) 994 return 1; 995 996 first_block += fs->super->s_blocks_per_group; 997 } 998 return 0; 999 } 1000 1001 /* 1002 * This routine returns 1 if a cluster overlaps with one of the superblocks, 1003 * group descriptors, inode bitmaps, or block bitmaps. 1004 */ 1005 static int check_if_fs_cluster(e2fsck_t ctx, blk64_t cluster) 1006 { 1007 ext2_filsys fs = ctx->fs; 1008 blk64_t first_block; 1009 dgrp_t i; 1010 1011 first_block = fs->super->s_first_data_block; 1012 for (i = 0; i < fs->group_desc_count; i++) { 1013 1014 /* Check superblocks/block group descriptors */ 1015 if (ext2fs_bg_has_super(fs, i)) { 1016 if (cluster >= EXT2FS_B2C(fs, first_block) && 1017 (cluster <= EXT2FS_B2C(fs, first_block + 1018 fs->desc_blocks))) 1019 return 1; 1020 } 1021 1022 /* Check the inode table */ 1023 if ((ext2fs_inode_table_loc(fs, i)) && 1024 (cluster >= EXT2FS_B2C(fs, 1025 ext2fs_inode_table_loc(fs, i))) && 1026 (cluster <= EXT2FS_B2C(fs, 1027 ext2fs_inode_table_loc(fs, i) + 1028 fs->inode_blocks_per_group - 1))) 1029 return 1; 1030 1031 /* Check the bitmap blocks */ 1032 if ((cluster == EXT2FS_B2C(fs, 1033 ext2fs_block_bitmap_loc(fs, i))) || 1034 (cluster == EXT2FS_B2C(fs, 1035 ext2fs_inode_bitmap_loc(fs, i)))) 1036 return 1; 1037 1038 first_block += fs->super->s_blocks_per_group; 1039 } 1040 return 0; 1041 } 1042