1/** 2 * ntfsresize - Part of the Linux-NTFS project. 3 * 4 * Copyright (c) 2002-2006 Szabolcs Szakacsits 5 * Copyright (c) 2002-2005 Anton Altaparmakov 6 * Copyright (c) 2002-2003 Richard Russon 7 * Copyright (c) 2007 Yura Pakhuchiy 8 * Copyright (c) 2011-2018 Jean-Pierre Andre 9 * 10 * This utility will resize an NTFS volume without data loss. 11 * 12 * WARNING FOR DEVELOPERS!!! Several external tools grep for text messages 13 * to control execution thus if you would like to change any message 14 * then PLEASE think twice before doing so then don't modify it. Thanks! 15 * 16 * This program is free software; you can redistribute it and/or modify 17 * it under the terms of the GNU General Public License as published by 18 * the Free Software Foundation; either version 2 of the License, or 19 * (at your option) any later version. 20 * 21 * This program is distributed in the hope that it will be useful, 22 * but WITHOUT ANY WARRANTY; without even the implied warranty of 23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 24 * GNU General Public License for more details. 25 * 26 * You should have received a copy of the GNU General Public License 27 * along with this program (in the main directory of the Linux-NTFS 28 * distribution in the file COPYING); if not, write to the Free Software 29 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 30 */ 31 32#include "config.h" 33 34#ifdef HAVE_UNISTD_H 35#include <unistd.h> 36#endif 37#ifdef HAVE_STDLIB_H 38#include <stdlib.h> 39#endif 40#ifdef HAVE_STDIO_H 41#include <stdio.h> 42#endif 43#ifdef HAVE_STDARG_H 44#include <stdarg.h> 45#endif 46#ifdef HAVE_STRING_H 47#include <string.h> 48#endif 49#ifdef HAVE_ERRNO_H 50#include <errno.h> 51#endif 52#ifdef HAVE_LIMITS_H 53#include <limits.h> 54#endif 55#ifdef HAVE_GETOPT_H 56#include <getopt.h> 57#endif 58#ifdef HAVE_FCNTL_H 59#include <fcntl.h> 60#endif 61 62#include "param.h" 63#include "debug.h" 64#include "types.h" 65#include "support.h" 66#include "endians.h" 67#include "bootsect.h" 68#include "device.h" 69#include "attrib.h" 70#include "volume.h" 71#include "mft.h" 72#include "bitmap.h" 73#include "inode.h" 74#include "runlist.h" 75#include "utils.h" 76/* #include "version.h" */ 77#include "misc.h" 78 79#define BAN_NEW_TEXT 1 /* Respect the ban on new messages */ 80#define CLEAN_EXIT 0 /* traditionnally volume is not closed, there must be a reason */ 81 82static const char *EXEC_NAME = "ntfsresize"; 83 84static const char *resize_warning_msg = 85"WARNING: Every sanity check passed and only the dangerous operations left.\n" 86"Make sure that important data has been backed up! Power outage or computer\n" 87"crash may result major data loss!\n"; 88 89static const char *resize_important_msg = 90"You can go on to shrink the device for example with Linux fdisk.\n" 91"IMPORTANT: When recreating the partition, make sure that you\n" 92" 1) create it at the same disk sector (use sector as the unit!)\n" 93" 2) create it with the same partition type (usually 7, HPFS/NTFS)\n" 94" 3) do not make it smaller than the new NTFS filesystem size\n" 95" 4) set the bootable flag for the partition if it existed before\n" 96"Otherwise you won't be able to access NTFS or can't boot from the disk!\n" 97"If you make a mistake and don't have a partition table backup then you\n" 98"can recover the partition table by TestDisk or Parted's rescue mode.\n"; 99 100static const char *invalid_ntfs_msg = 101"The device '%s' doesn't have a valid NTFS.\n" 102"Maybe you selected the wrong partition? Or the whole disk instead of a\n" 103"partition (e.g. /dev/hda, not /dev/hda1)? This error might also occur\n" 104"if the disk was incorrectly repartitioned (see the ntfsresize FAQ).\n"; 105 106static const char *corrupt_volume_msg = 107"NTFS is inconsistent. Run chkdsk /f on Windows then reboot it TWICE!\n" 108"The usage of the /f parameter is very IMPORTANT! No modification was\n" 109"and will be made to NTFS by this software until it gets repaired.\n"; 110 111static const char *hibernated_volume_msg = 112"The NTFS partition is hibernated. Windows must be resumed and turned off\n" 113"properly, so resizing could be done safely.\n"; 114 115static const char *unclean_journal_msg = 116"The NTFS journal file is unclean. Please shutdown Windows properly before\n" 117"using this software! Note, if you have run chkdsk previously then boot\n" 118"Windows again which will automatically initialize the journal correctly.\n"; 119 120static const char *opened_volume_msg = 121"This software has detected that the NTFS volume is already opened by another\n" 122"software thus it refuses to progress to preserve data consistency.\n"; 123 124static const char *bad_sectors_warning_msg = 125"****************************************************************************\n" 126"* WARNING: The disk has bad sector. This means physical damage on the disk *\n" 127"* surface caused by deterioration, manufacturing faults or other reason. *\n" 128"* The reliability of the disk may stay stable or degrade fast. We suggest *\n" 129"* making a full backup urgently by running 'ntfsclone --rescue ...' then *\n" 130"* run 'chkdsk /f /r' on Windows and rebooot it TWICE! Then you can resize *\n" 131"* NTFS safely by additionally using the --bad-sectors option of ntfsresize.*\n" 132"****************************************************************************\n"; 133 134static const char *many_bad_sectors_msg = 135"***************************************************************************\n" 136"* WARNING: The disk has many bad sectors. This means physical damage *\n" 137"* on the disk surface caused by deterioration, manufacturing faults or *\n" 138"* other reason. We suggest to get a replacement disk as soon as possible. *\n" 139"***************************************************************************\n"; 140 141enum mirror_source { MIRR_OLD, MIRR_NEWMFT, MIRR_MFT }; 142 143static struct { 144 int verbose; 145 int debug; 146 int ro_flag; 147 int force; 148 int info; 149 int infombonly; 150 int expand; 151 int reliable_size; 152 int show_progress; 153 int badsectors; 154 int check; 155 s64 bytes; 156 char *volume; 157} opt; 158 159struct bitmap { 160 s64 size; 161 u8 *bm; 162}; 163 164#define NTFS_PROGBAR 0x0001 165#define NTFS_PROGBAR_SUPPRESS 0x0002 166 167struct progress_bar { 168 u64 start; 169 u64 stop; 170 int resolution; 171 int flags; 172 float unit; 173}; 174 175struct llcn_t { 176 s64 lcn; /* last used LCN for a "special" file/attr type */ 177 s64 inode; /* inode using it */ 178}; 179 180#define NTFSCK_PROGBAR 0x0001 181 182 /* runlists which have to be processed later */ 183struct DELAYED { 184 struct DELAYED *next; 185 ATTR_TYPES type; 186 MFT_REF mref; 187 VCN lowest_vcn; 188 int name_len; 189 ntfschar *attr_name; 190 runlist_element *rl; 191 runlist *head_rl; 192} ; 193 194typedef struct { 195 ntfs_inode *ni; /* inode being processed */ 196 ntfs_attr_search_ctx *ctx; /* inode attribute being processed */ 197 s64 inuse; /* num of clusters in use */ 198 int multi_ref; /* num of clusters referenced many times */ 199 int outsider; /* num of clusters outside the volume */ 200 int show_outsider; /* controls showing the above information */ 201 int flags; 202 struct bitmap lcn_bitmap; 203} ntfsck_t; 204 205typedef struct { 206 ntfs_volume *vol; 207 ntfs_inode *ni; /* inode being processed */ 208 s64 new_volume_size; /* in clusters; 0 = --info w/o --size */ 209 MFT_REF mref; /* mft reference */ 210 MFT_RECORD *mrec; /* mft record */ 211 ntfs_attr_search_ctx *ctx; /* inode attribute being processed */ 212 u64 relocations; /* num of clusters to relocate */ 213 s64 inuse; /* num of clusters in use */ 214 runlist mftmir_rl; /* $MFTMirr AT_DATA's new position */ 215 s64 mftmir_old; /* $MFTMirr AT_DATA's old LCN */ 216 int dirty_inode; /* some inode data got relocated */ 217 int shrink; /* shrink = 1, enlarge = 0 */ 218 s64 badclusters; /* num of physically dead clusters */ 219 VCN mft_highest_vcn; /* used for relocating the $MFT */ 220 runlist_element *new_mft_start; /* new first run for $MFT:$DATA */ 221 struct DELAYED *delayed_runlists; /* runlists to process later */ 222 struct progress_bar progress; 223 struct bitmap lcn_bitmap; 224 /* Temporary statistics until all case is supported */ 225 struct llcn_t last_mft; 226 struct llcn_t last_mftmir; 227 struct llcn_t last_multi_mft; 228 struct llcn_t last_sparse; 229 struct llcn_t last_compressed; 230 struct llcn_t last_lcn; 231 s64 last_unsupp; /* last unsupported cluster */ 232 enum mirror_source mirr_from; 233} ntfs_resize_t; 234 235/* FIXME: This, lcn_bitmap and pos from find_free_cluster() will make a cluster 236 allocation related structure, attached to ntfs_resize_t */ 237static s64 max_free_cluster_range = 0; 238 239#define NTFS_MBYTE (1000 * 1000) 240 241/* WARNING: don't modify the text, external tools grep for it */ 242#define ERR_PREFIX "ERROR" 243#define PERR_PREFIX ERR_PREFIX "(%d): " 244#define NERR_PREFIX ERR_PREFIX ": " 245 246#define DIRTY_NONE (0) 247#define DIRTY_INODE (1) 248#define DIRTY_ATTRIB (2) 249 250static s64 rounded_up_division(s64 numer, s64 denom) 251{ 252 return (numer + (denom - 1)) / denom; 253} 254 255/** 256 * perr_printf 257 * 258 * Print an error message. 259 */ 260__attribute__((format(printf, 1, 2))) 261static void perr_printf(const char *fmt, ...) 262{ 263 va_list ap; 264 int eo = errno; 265 266 fprintf(stdout, PERR_PREFIX, eo); 267 va_start(ap, fmt); 268 vfprintf(stdout, fmt, ap); 269 va_end(ap); 270 fprintf(stdout, ": %s\n", strerror(eo)); 271 fflush(stdout); 272 fflush(stderr); 273} 274 275__attribute__((format(printf, 1, 2))) 276static void err_printf(const char *fmt, ...) 277{ 278 va_list ap; 279 280 fprintf(stdout, NERR_PREFIX); 281 va_start(ap, fmt); 282 vfprintf(stdout, fmt, ap); 283 va_end(ap); 284 fflush(stdout); 285 fflush(stderr); 286} 287 288/** 289 * err_exit 290 * 291 * Print and error message and exit the program. 292 */ 293__attribute__((noreturn)) 294__attribute__((format(printf, 1, 2))) 295static void err_exit(const char *fmt, ...) 296{ 297 va_list ap; 298 299 fprintf(stdout, NERR_PREFIX); 300 va_start(ap, fmt); 301 vfprintf(stdout, fmt, ap); 302 va_end(ap); 303 fflush(stdout); 304 fflush(stderr); 305 exit(1); 306} 307 308/** 309 * perr_exit 310 * 311 * Print and error message and exit the program 312 */ 313__attribute__((noreturn)) 314__attribute__((format(printf, 1, 2))) 315static void perr_exit(const char *fmt, ...) 316{ 317 va_list ap; 318 int eo = errno; 319 320 fprintf(stdout, PERR_PREFIX, eo); 321 va_start(ap, fmt); 322 vfprintf(stdout, fmt, ap); 323 va_end(ap); 324 printf(": %s\n", strerror(eo)); 325 fflush(stdout); 326 fflush(stderr); 327 exit(1); 328} 329 330/** 331 * usage - Print a list of the parameters to the program 332 * 333 * Print a list of the parameters and options for the program. 334 * 335 * Return: none 336 */ 337__attribute__((noreturn)) 338static void usage(int ret) 339{ 340 341 printf("\nUsage: %s [OPTIONS] DEVICE\n" 342 " Resize an NTFS volume non-destructively, safely move any data if needed.\n" 343 "\n" 344 " -c, --check Check to ensure that the device is ready for resize\n" 345 " -i, --info Estimate the smallest shrunken size or the smallest\n" 346 " expansion size\n" 347 " -m, --info-mb-only Estimate the smallest shrunken size possible,\n" 348 " output size in MB only\n" 349 " -s, --size SIZE Resize volume to SIZE[k|M|G] bytes\n" 350 " -x, --expand Expand to full partition\n" 351 "\n" 352 " -n, --no-action Do not write to disk\n" 353 " -b, --bad-sectors Support disks having bad sectors\n" 354 " -f, --force Force to progress\n" 355 " -P, --no-progress-bar Don't show progress bar\n" 356 " -v, --verbose More output\n" 357 " -V, --version Display version information\n" 358 " -h, --help Display this help\n" 359#ifdef DEBUG 360 " -d, --debug Show debug information\n" 361#endif 362 "\n" 363 " The options -i and -x are exclusive of option -s, and -m is exclusive\n" 364 " of option -x. If options -i, -m, -s and -x are are all omitted\n" 365 " then the NTFS volume will be enlarged to the DEVICE size.\n" 366 "\n", EXEC_NAME); 367 printf("%s%s", ntfs_bugs, ntfs_home); 368 printf("Ntfsresize FAQ: http://linux-ntfs.sourceforge.net/info/ntfsresize.html\n"); 369 exit(ret); 370} 371 372/** 373 * proceed_question 374 * 375 * Force the user to confirm an action before performing it. 376 * Copy-paste from e2fsprogs 377 */ 378static void proceed_question(void) 379{ 380 char buf[256]; 381 const char *short_yes = "yY"; 382 383 fflush(stdout); 384 fflush(stderr); 385 printf("Are you sure you want to proceed (y/[n])? "); 386 buf[0] = 0; 387 if (fgets(buf, sizeof(buf), stdin) 388 && !strchr(short_yes, buf[0])) { 389 printf("OK quitting. NO CHANGES have been made to your " 390 "NTFS volume.\n"); 391 exit(1); 392 } 393} 394 395/** 396 * version - Print version information about the program 397 * 398 * Print a copyright statement and a brief description of the program. 399 * 400 * Return: none 401 */ 402static void version(void) 403{ 404 printf("\nResize an NTFS Volume, without data loss.\n\n"); 405 printf("Copyright (c) 2002-2006 Szabolcs Szakacsits\n"); 406 printf("Copyright (c) 2002-2005 Anton Altaparmakov\n"); 407 printf("Copyright (c) 2002-2003 Richard Russon\n"); 408 printf("Copyright (c) 2007 Yura Pakhuchiy\n"); 409 printf("Copyright (c) 2011-2018 Jean-Pierre Andre\n"); 410 printf("\n%s\n%s%s", ntfs_gpl, ntfs_bugs, ntfs_home); 411} 412 413/** 414 * get_new_volume_size 415 * 416 * Convert a user-supplied string into a size. Without any suffix the number 417 * will be assumed to be in bytes. If the number has a suffix of k, M or G it 418 * will be scaled up by 1000, 1000000, or 1000000000. 419 */ 420static s64 get_new_volume_size(char *s) 421{ 422 s64 size; 423 char *suffix; 424 int prefix_kind = 1000; 425 426 size = strtoll(s, &suffix, 10); 427 if (size <= 0 || errno == ERANGE) 428 err_exit("Illegal new volume size\n"); 429 430 if (!*suffix) { 431 opt.reliable_size = 1; 432 return size; 433 } 434 435 if (strlen(suffix) == 2 && suffix[1] == 'i') 436 prefix_kind = 1024; 437 else if (strlen(suffix) > 1) 438 usage(1); 439 440 /* We follow the SI prefixes: 441 http://physics.nist.gov/cuu/Units/prefixes.html 442 http://physics.nist.gov/cuu/Units/binary.html 443 Disk partitioning tools use prefixes as, 444 k M G 445 fdisk 2.11x- 2^10 2^20 10^3*2^20 446 fdisk 2.11y+ 10^3 10^6 10^9 447 cfdisk 10^3 10^6 10^9 448 sfdisk 2^10 2^20 449 parted 2^10 2^20 (may change) 450 fdisk (DOS) 2^10 2^20 451 */ 452 /* FIXME: check for overflow */ 453 switch (*suffix) { 454 case 'G': 455 size *= prefix_kind; 456 /* FALLTHRU */ 457 case 'M': 458 size *= prefix_kind; 459 /* FALLTHRU */ 460 case 'k': 461 size *= prefix_kind; 462 break; 463 default: 464 usage(1); 465 } 466 467 return size; 468} 469 470/** 471 * parse_options - Read and validate the programs command line 472 * 473 * Read the command line, verify the syntax and parse the options. 474 * This function is very long, but quite simple. 475 * 476 * Return: 1 Success 477 * 0 Error, one or more problems 478 */ 479static int parse_options(int argc, char **argv) 480{ 481 static const char *sopt = "-bcdfhimnPs:vVx"; 482 static const struct option lopt[] = { 483 { "bad-sectors",no_argument, NULL, 'b' }, 484 { "check", no_argument, NULL, 'c' }, 485#ifdef DEBUG 486 { "debug", no_argument, NULL, 'd' }, 487#endif 488 { "force", no_argument, NULL, 'f' }, 489 { "help", no_argument, NULL, 'h' }, 490 { "info", no_argument, NULL, 'i' }, 491 { "info-mb-only", no_argument, NULL, 'm' }, 492 { "no-action", no_argument, NULL, 'n' }, 493 { "no-progress-bar", no_argument, NULL, 'P' }, 494 { "size", required_argument, NULL, 's' }, 495 { "expand", no_argument, NULL, 'x' }, 496 { "verbose", no_argument, NULL, 'v' }, 497 { "version", no_argument, NULL, 'V' }, 498 { NULL, 0, NULL, 0 } 499 }; 500 501 int c; 502 int err = 0; 503 int ver = 0; 504 int help = 0; 505 506 memset(&opt, 0, sizeof(opt)); 507 opt.show_progress = 1; 508 509 while ((c = getopt_long(argc, argv, sopt, lopt, NULL)) != -1) { 510 switch (c) { 511 case 1: /* A non-option argument */ 512 if (!err && !opt.volume) 513 opt.volume = argv[optind-1]; 514 else 515 err++; 516 break; 517 case 'b': 518 opt.badsectors++; 519 break; 520 case 'c': 521 opt.check++; 522 break; 523 case 'd': 524 opt.debug++; 525 break; 526 case 'f': 527 opt.force++; 528 break; 529 case 'h': 530 help++; 531 break; 532 case 'i': 533 opt.info++; 534 break; 535 case 'm': 536 opt.infombonly++; 537 break; 538 case 'n': 539 opt.ro_flag = NTFS_MNT_RDONLY; 540 break; 541 case 'P': 542 opt.show_progress = 0; 543 break; 544 case 's': 545 if (!err && (opt.bytes == 0)) 546 opt.bytes = get_new_volume_size(optarg); 547 else 548 err++; 549 break; 550 case 'v': 551 opt.verbose++; 552 ntfs_log_set_levels(NTFS_LOG_LEVEL_VERBOSE); 553 break; 554 case 'V': 555 ver++; 556 break; 557 case 'x': 558 opt.expand++; 559 break; 560 case '?': 561 default: 562 if (optopt == 's') { 563 printf("Option '%s' requires an argument.\n", argv[optind-1]); 564 } else { 565 printf("Unknown option '%s'.\n", argv[optind-1]); 566 } 567 err++; 568 break; 569 } 570 } 571 572 if (!help && !ver) { 573 if (opt.volume == NULL) { 574 if (argc > 1) 575 printf("You must specify exactly one device.\n"); 576 err++; 577 } 578 if (opt.info || opt.infombonly) { 579 opt.ro_flag = NTFS_MNT_RDONLY; 580 } 581 if (opt.bytes 582 && (opt.expand || opt.info || opt.infombonly)) { 583 printf(NERR_PREFIX "Options --info(-mb-only) and --expand " 584 "cannot be used with --size.\n"); 585 usage(1); 586 } 587 if (opt.expand && opt.infombonly) { 588 printf(NERR_PREFIX "Options --info-mb-only " 589 "cannot be used with --expand.\n"); 590 usage(1); 591 } 592 } 593 594 /* Redirect stderr to stdout, note fflush()es are essential! */ 595 fflush(stdout); 596 fflush(stderr); 597 if (dup2(STDOUT_FILENO, STDERR_FILENO) == -1) 598 perr_exit("Failed to redirect stderr to stdout"); 599 fflush(stdout); 600 fflush(stderr); 601 602#ifdef DEBUG 603 if (!opt.debug) 604 if (!freopen("/dev/null", "w", stderr)) 605 perr_exit("Failed to redirect stderr to /dev/null"); 606#endif 607 608 if (ver) 609 version(); 610 if (help || err) 611 usage(err > 0); 612 613 /* tri-state 0 : done, 1 : error, -1 : proceed */ 614 return (err ? 1 : (help || ver ? 0 : -1)); 615} 616 617static void print_advise(ntfs_volume *vol, s64 supp_lcn) 618{ 619 s64 old_b, new_b, freed_b, old_mb, new_mb, freed_mb; 620 621 old_b = vol->nr_clusters * vol->cluster_size; 622 old_mb = rounded_up_division(old_b, NTFS_MBYTE); 623 624 /* Take the next supported cluster (free or relocatable) 625 plus reserve a cluster for the backup boot sector */ 626 supp_lcn += 2; 627 628 if (supp_lcn > vol->nr_clusters) { 629 err_printf("Very rare fragmentation type detected. " 630 "Sorry, it's not supported yet.\n" 631 "Try to defragment your NTFS, perhaps it helps.\n"); 632 exit(1); 633 } 634 635 new_b = supp_lcn * vol->cluster_size; 636 new_mb = rounded_up_division(new_b, NTFS_MBYTE); 637 freed_b = (vol->nr_clusters - supp_lcn + 1) * vol->cluster_size; 638 freed_mb = freed_b / NTFS_MBYTE; 639 640 /* WARNING: don't modify the text, external tools grep for it */ 641 if (!opt.infombonly) 642 printf("You might resize at %lld bytes ", (long long)new_b); 643 if ((new_mb * NTFS_MBYTE) < old_b) { 644 if (!opt.infombonly) 645 printf("or %lld MB ", (long long)new_mb); 646 else 647 printf("Minsize (in MB): %lld\n", (long long)new_mb); 648 } 649 650 if (!opt.infombonly) { 651 printf("(freeing "); 652 if (freed_mb && (old_mb - new_mb)) 653 printf("%lld MB", (long long)(old_mb - new_mb)); 654 else 655 printf("%lld bytes", (long long)freed_b); 656 printf(").\n"); 657 658 printf("Please make a test run using both the -n and -s " 659 "options before real resizing!\n"); 660 } 661} 662 663static void rl_set(runlist *rl, VCN vcn, LCN lcn, s64 len) 664{ 665 rl->vcn = vcn; 666 rl->lcn = lcn; 667 rl->length = len; 668} 669 670static int rl_items(runlist *rl) 671{ 672 int i = 0; 673 674 while (rl[i++].length) 675 ; 676 677 return i; 678} 679 680static void dump_run(runlist_element *r) 681{ 682 ntfs_log_verbose(" %8lld %8lld (0x%08llx) %lld\n", (long long)r->vcn, 683 (long long)r->lcn, (long long)r->lcn, 684 (long long)r->length); 685} 686 687static void dump_runlist(runlist *rl) 688{ 689 while (rl->length) 690 dump_run(rl++); 691} 692 693/** 694 * nr_clusters_to_bitmap_byte_size 695 * 696 * Take the number of clusters in the volume and calculate the size of $Bitmap. 697 * The size must be always a multiple of 8 bytes. 698 */ 699static s64 nr_clusters_to_bitmap_byte_size(s64 nr_clusters) 700{ 701 s64 bm_bsize; 702 703 bm_bsize = rounded_up_division(nr_clusters, 8); 704 bm_bsize = (bm_bsize + 7) & ~7; 705 706 return bm_bsize; 707} 708 709static void collect_resize_constraints(ntfs_resize_t *resize, runlist *rl) 710{ 711 s64 inode, last_lcn; 712 ATTR_FLAGS flags; 713 ATTR_TYPES atype; 714 struct llcn_t *llcn = NULL; 715 int ret, supported = 0; 716 717 last_lcn = rl->lcn + (rl->length - 1); 718 719 inode = resize->ni->mft_no; 720 flags = resize->ctx->attr->flags; 721 atype = resize->ctx->attr->type; 722 723 if ((ret = ntfs_inode_badclus_bad(inode, resize->ctx->attr)) != 0) { 724 if (ret == -1) 725 perr_exit("Bad sector list check failed"); 726 return; 727 } 728 729 if (inode == FILE_Bitmap) { 730 llcn = &resize->last_lcn; 731 if (atype == AT_DATA && NInoAttrList(resize->ni)) 732 err_exit("Highly fragmented $Bitmap isn't supported yet."); 733 734 supported = 1; 735 736 } else if (NInoAttrList(resize->ni)) { 737 llcn = &resize->last_multi_mft; 738 739 if (inode != FILE_MFTMirr) 740 supported = 1; 741 742 } else if (flags & ATTR_IS_SPARSE) { 743 llcn = &resize->last_sparse; 744 supported = 1; 745 746 } else if (flags & ATTR_IS_COMPRESSED) { 747 llcn = &resize->last_compressed; 748 supported = 1; 749 750 } else if (inode == FILE_MFTMirr) { 751 llcn = &resize->last_mftmir; 752 supported = 1; 753 754 /* Fragmented $MFTMirr DATA attribute isn't supported yet */ 755 if (atype == AT_DATA) 756 if (rl[1].length != 0 || rl->vcn) 757 supported = 0; 758 } else { 759 llcn = &resize->last_lcn; 760 supported = 1; 761 } 762 763 if (llcn->lcn < last_lcn) { 764 llcn->lcn = last_lcn; 765 llcn->inode = inode; 766 } 767 768 if (supported) 769 return; 770 771 if (resize->last_unsupp < last_lcn) 772 resize->last_unsupp = last_lcn; 773} 774 775 776static void collect_relocation_info(ntfs_resize_t *resize, runlist *rl) 777{ 778 s64 lcn, lcn_length, start, len, inode; 779 s64 new_vol_size; /* (last LCN on the volume) + 1 */ 780 781 lcn = rl->lcn; 782 lcn_length = rl->length; 783 inode = resize->ni->mft_no; 784 new_vol_size = resize->new_volume_size; 785 786 if (lcn + lcn_length <= new_vol_size) 787 return; 788 789 if (inode == FILE_Bitmap && resize->ctx->attr->type == AT_DATA) 790 return; 791 792 start = lcn; 793 len = lcn_length; 794 795 if (lcn < new_vol_size) { 796 start = new_vol_size; 797 len = lcn_length - (new_vol_size - lcn); 798 799 if ((!opt.info && !opt.infombonly) && (inode == FILE_MFTMirr)) { 800 err_printf("$MFTMirr can't be split up yet. Please try " 801 "a different size.\n"); 802 print_advise(resize->vol, lcn + lcn_length - 1); 803 exit(1); 804 } 805 } 806 807 resize->relocations += len; 808 809 if ((!opt.info && !opt.infombonly) || !resize->new_volume_size) 810 return; 811 812 printf("Relocation needed for inode %8lld attr 0x%x LCN 0x%08llx " 813 "length %6lld\n", (long long)inode, 814 (unsigned int)le32_to_cpu(resize->ctx->attr->type), 815 (unsigned long long)start, (long long)len); 816} 817 818/** 819 * build_lcn_usage_bitmap 820 * 821 * lcn_bitmap has one bit for each cluster on the disk. Initially, lcn_bitmap 822 * has no bits set. As each attribute record is read the bits in lcn_bitmap are 823 * checked to ensure that no other file already references that cluster. 824 * 825 * This serves as a rudimentary "chkdsk" operation. 826 */ 827static void build_lcn_usage_bitmap(ntfs_volume *vol, ntfsck_t *fsck) 828{ 829 s64 inode; 830 ATTR_RECORD *a; 831 runlist *rl; 832 int i, j; 833 struct bitmap *lcn_bitmap = &fsck->lcn_bitmap; 834 835 a = fsck->ctx->attr; 836 inode = fsck->ni->mft_no; 837 838 if (!a->non_resident) 839 return; 840 841 if (!(rl = ntfs_mapping_pairs_decompress(vol, a, NULL))) { 842 int err = errno; 843 perr_printf("ntfs_decompress_mapping_pairs"); 844 if (err == EIO) 845 printf("%s", corrupt_volume_msg); 846 exit(1); 847 } 848 849 850 for (i = 0; rl[i].length; i++) { 851 s64 lcn = rl[i].lcn; 852 s64 lcn_length = rl[i].length; 853 854 /* CHECKME: LCN_RL_NOT_MAPPED check isn't needed */ 855 if (lcn == LCN_HOLE || lcn == LCN_RL_NOT_MAPPED) 856 continue; 857 858 /* FIXME: ntfs_mapping_pairs_decompress should return error */ 859 if (lcn < 0 || lcn_length <= 0) 860 err_exit("Corrupt runlist in inode %lld attr %x LCN " 861 "%llx length %llx\n", (long long)inode, 862 (unsigned int)le32_to_cpu(a->type), 863 (long long)lcn, (long long)lcn_length); 864 865 for (j = 0; j < lcn_length; j++) { 866 u64 k = (u64)lcn + j; 867 868 if (k >= (u64)vol->nr_clusters) { 869 long long outsiders = lcn_length - j; 870 871 fsck->outsider += outsiders; 872 873 if (++fsck->show_outsider <= 10 || opt.verbose) 874 printf("Outside of the volume reference" 875 " for inode %lld at %lld:%lld\n", 876 (long long)inode, (long long)k, 877 (long long)outsiders); 878 879 break; 880 } 881 882 if (ntfs_bit_get_and_set(lcn_bitmap->bm, k, 1)) { 883 if (++fsck->multi_ref <= 10 || opt.verbose) 884 printf("Cluster %lld is referenced " 885 "multiple times!\n", 886 (long long)k); 887 continue; 888 } 889 } 890 fsck->inuse += lcn_length; 891 } 892 free(rl); 893} 894 895 896static ntfs_attr_search_ctx *attr_get_search_ctx(ntfs_inode *ni, MFT_RECORD *mrec) 897{ 898 ntfs_attr_search_ctx *ret; 899 900 if ((ret = ntfs_attr_get_search_ctx(ni, mrec)) == NULL) 901 perr_printf("ntfs_attr_get_search_ctx"); 902 903 return ret; 904} 905 906/** 907 * walk_attributes 908 * 909 * For a given MFT Record, iterate through all its attributes. Any non-resident 910 * data runs will be marked in lcn_bitmap. 911 */ 912static int walk_attributes(ntfs_volume *vol, ntfsck_t *fsck) 913{ 914 if (!(fsck->ctx = attr_get_search_ctx(fsck->ni, NULL))) 915 return -1; 916 917 while (!ntfs_attrs_walk(fsck->ctx)) { 918 if (fsck->ctx->attr->type == AT_END) 919 break; 920 build_lcn_usage_bitmap(vol, fsck); 921 } 922 923 ntfs_attr_put_search_ctx(fsck->ctx); 924 return 0; 925} 926 927/** 928 * compare_bitmaps 929 * 930 * Compare two bitmaps. In this case, $Bitmap as read from the disk and 931 * lcn_bitmap which we built from the MFT Records. 932 */ 933static void compare_bitmaps(ntfs_volume *vol, struct bitmap *a) 934{ 935 s64 i, pos, count; 936 int mismatch = 0; 937 int backup_boot = 0; 938 u8 bm[NTFS_BUF_SIZE]; 939 940 if (!opt.infombonly) 941 printf("Accounting clusters ...\n"); 942 943 pos = 0; 944 while (1) { 945 count = ntfs_attr_pread(vol->lcnbmp_na, pos, NTFS_BUF_SIZE, bm); 946 if (count == -1) 947 perr_exit("Couldn't get $Bitmap $DATA"); 948 949 if (count == 0) { 950 if (a->size > pos) 951 err_exit("$Bitmap size is smaller than expected" 952 " (%lld != %lld)\n", 953 (long long)a->size, (long long)pos); 954 break; 955 } 956 957 for (i = 0; i < count; i++, pos++) { 958 s64 cl; /* current cluster */ 959 960 if (a->size <= pos) 961 goto done; 962 963 if (a->bm[pos] == bm[i]) 964 continue; 965 966 for (cl = pos * 8; cl < (pos + 1) * 8; cl++) { 967 char bit; 968 969 bit = ntfs_bit_get(a->bm, cl); 970 if (bit == ntfs_bit_get(bm, i * 8 + cl % 8)) 971 continue; 972 973 if (!mismatch && !bit && !backup_boot && 974 cl == vol->nr_clusters / 2) { 975 /* FIXME: call also boot sector check */ 976 backup_boot = 1; 977 printf("Found backup boot sector in " 978 "the middle of the volume.\n"); 979 continue; 980 } 981 982 if (++mismatch > 10 && !opt.verbose) 983 continue; 984 985 printf("Cluster accounting failed at %lld " 986 "(0x%llx): %s cluster in " 987 "$Bitmap\n", (long long)cl, 988 (unsigned long long)cl, 989 bit ? "missing" : "extra"); 990 } 991 } 992 } 993done: 994 if (mismatch) { 995 printf("Filesystem check failed! Totally %d cluster " 996 "accounting mismatches.\n", mismatch); 997 err_printf("%s", corrupt_volume_msg); 998 exit(1); 999 } 1000} 1001 1002/** 1003 * progress_init 1004 * 1005 * Create and scale our progress bar. 1006 */ 1007static void progress_init(struct progress_bar *p, u64 start, u64 stop, int flags) 1008{ 1009 p->start = start; 1010 p->stop = stop; 1011 p->unit = 100.0 / (stop - start); 1012 p->resolution = 100; 1013 p->flags = flags; 1014} 1015 1016/** 1017 * progress_update 1018 * 1019 * Update the progress bar and tell the user. 1020 */ 1021static void progress_update(struct progress_bar *p, u64 current) 1022{ 1023 float percent; 1024 1025 if (!(p->flags & NTFS_PROGBAR)) 1026 return; 1027 if (p->flags & NTFS_PROGBAR_SUPPRESS) 1028 return; 1029 1030 /* WARNING: don't modify the texts, external tools grep for them */ 1031 percent = p->unit * current; 1032 if (current != p->stop) { 1033 if ((current - p->start) % p->resolution) 1034 return; 1035 printf("%6.2f percent completed\r", percent); 1036 } else 1037 printf("100.00 percent completed\n"); 1038 fflush(stdout); 1039} 1040 1041static int inode_close(ntfs_inode *ni) 1042{ 1043 if (ntfs_inode_close(ni)) { 1044 perr_printf("ntfs_inode_close for inode %llu", 1045 (unsigned long long)ni->mft_no); 1046 return -1; 1047 } 1048 return 0; 1049} 1050 1051/** 1052 * walk_inodes 1053 * 1054 * Read each record in the MFT, skipping the unused ones, and build up a bitmap 1055 * from all the non-resident attributes. 1056 */ 1057static int build_allocation_bitmap(ntfs_volume *vol, ntfsck_t *fsck) 1058{ 1059 s64 nr_mft_records, inode = 0; 1060 ntfs_inode *ni; 1061 struct progress_bar progress; 1062 int pb_flags = 0; /* progress bar flags */ 1063 1064 /* WARNING: don't modify the text, external tools grep for it */ 1065 if (!opt.infombonly) 1066 printf("Checking filesystem consistency ...\n"); 1067 1068 if (fsck->flags & NTFSCK_PROGBAR) 1069 pb_flags |= NTFS_PROGBAR; 1070 1071 nr_mft_records = vol->mft_na->initialized_size >> 1072 vol->mft_record_size_bits; 1073 1074 progress_init(&progress, inode, nr_mft_records - 1, pb_flags); 1075 1076 for (; inode < nr_mft_records; inode++) { 1077 if (!opt.infombonly) 1078 progress_update(&progress, inode); 1079 1080 if ((ni = ntfs_inode_open(vol, (MFT_REF)inode)) == NULL) { 1081 /* FIXME: continue only if it make sense, e.g. 1082 MFT record not in use based on $MFT bitmap */ 1083 if (errno == EIO || errno == ENOENT) 1084 continue; 1085 perr_printf("Reading inode %lld failed", 1086 (long long)inode); 1087 return -1; 1088 } 1089 1090 if (ni->mrec->base_mft_record) 1091 goto close_inode; 1092 1093 fsck->ni = ni; 1094 if (walk_attributes(vol, fsck) != 0) { 1095 inode_close(ni); 1096 return -1; 1097 } 1098close_inode: 1099 if (inode_close(ni) != 0) 1100 return -1; 1101 } 1102 return 0; 1103} 1104 1105static void build_resize_constraints(ntfs_resize_t *resize) 1106{ 1107 s64 i; 1108 runlist *rl; 1109 1110 if (!resize->ctx->attr->non_resident) 1111 return; 1112 1113 if (!(rl = ntfs_mapping_pairs_decompress(resize->vol, 1114 resize->ctx->attr, NULL))) 1115 perr_exit("ntfs_decompress_mapping_pairs"); 1116 1117 for (i = 0; rl[i].length; i++) { 1118 /* CHECKME: LCN_RL_NOT_MAPPED check isn't needed */ 1119 if (rl[i].lcn == LCN_HOLE || rl[i].lcn == LCN_RL_NOT_MAPPED) 1120 continue; 1121 1122 collect_resize_constraints(resize, rl + i); 1123 if (resize->shrink) 1124 collect_relocation_info(resize, rl + i); 1125 } 1126 free(rl); 1127} 1128 1129static void resize_constraints_by_attributes(ntfs_resize_t *resize) 1130{ 1131 if (!(resize->ctx = attr_get_search_ctx(resize->ni, NULL))) 1132 exit(1); 1133 1134 while (!ntfs_attrs_walk(resize->ctx)) { 1135 if (resize->ctx->attr->type == AT_END) 1136 break; 1137 build_resize_constraints(resize); 1138 } 1139 1140 ntfs_attr_put_search_ctx(resize->ctx); 1141} 1142 1143static void set_resize_constraints(ntfs_resize_t *resize) 1144{ 1145 s64 nr_mft_records, inode; 1146 ntfs_inode *ni; 1147 1148 if (!opt.infombonly) 1149 printf("Collecting resizing constraints ...\n"); 1150 1151 nr_mft_records = resize->vol->mft_na->initialized_size >> 1152 resize->vol->mft_record_size_bits; 1153 1154 for (inode = 0; inode < nr_mft_records; inode++) { 1155 1156 ni = ntfs_inode_open(resize->vol, (MFT_REF)inode); 1157 if (ni == NULL) { 1158 if (errno == EIO || errno == ENOENT) 1159 continue; 1160 perr_exit("Reading inode %lld failed", 1161 (long long)inode); 1162 } 1163 1164 if (ni->mrec->base_mft_record) 1165 goto close_inode; 1166 1167 resize->ni = ni; 1168 resize_constraints_by_attributes(resize); 1169close_inode: 1170 if (inode_close(ni) != 0) 1171 exit(1); 1172 } 1173} 1174 1175static void rl_fixup(runlist **rl) 1176{ 1177 runlist *tmp = *rl; 1178 1179 if (tmp->lcn == LCN_RL_NOT_MAPPED) { 1180 s64 unmapped_len = tmp->length; 1181 1182 ntfs_log_verbose("Skip unmapped run at the beginning ...\n"); 1183 1184 if (!tmp->length) 1185 err_exit("Empty unmapped runlist! Please report!\n"); 1186 (*rl)++; 1187 for (tmp = *rl; tmp->length; tmp++) 1188 tmp->vcn -= unmapped_len; 1189 } 1190 1191 for (tmp = *rl; tmp->length; tmp++) { 1192 if (tmp->lcn == LCN_RL_NOT_MAPPED) { 1193 ntfs_log_verbose("Skip unmapped run at the end ...\n"); 1194 1195 if (tmp[1].length) 1196 err_exit("Unmapped runlist in the middle! " 1197 "Please report!\n"); 1198 tmp->lcn = LCN_ENOENT; 1199 tmp->length = 0; 1200 } 1201 } 1202} 1203 1204/* 1205 * Plug a replacement (partial) runlist into full runlist 1206 * 1207 * Returns 0 if successful 1208 * -1 if failed 1209 */ 1210 1211static int replace_runlist(ntfs_attr *na, const runlist_element *reprl, 1212 VCN lowest_vcn) 1213{ 1214 const runlist_element *prep; 1215 const runlist_element *pold; 1216 runlist_element *pnew; 1217 runlist_element *newrl; 1218 VCN nextvcn; 1219 s32 oldcnt, newcnt; 1220 s32 newsize; 1221 int r; 1222 1223 r = -1; /* default return */ 1224 /* allocate a new runlist able to hold both */ 1225 oldcnt = 0; 1226 while (na->rl[oldcnt].length) 1227 oldcnt++; 1228 newcnt = 0; 1229 while (reprl[newcnt].length) 1230 newcnt++; 1231 newsize = ((oldcnt + newcnt)*sizeof(runlist_element) + 4095) & -4096; 1232 newrl = (runlist_element*)malloc(newsize); 1233 if (newrl) { 1234 /* copy old runs until reaching replaced ones */ 1235 pnew = newrl; 1236 pold = na->rl; 1237 while (pold->length 1238 && ((pold->vcn + pold->length) 1239 <= (reprl[0].vcn + lowest_vcn))) { 1240 *pnew = *pold; 1241 pnew++; 1242 pold++; 1243 } 1244 /* split a possible old run partially overlapped */ 1245 if (pold->length 1246 && (pold->vcn < (reprl[0].vcn + lowest_vcn))) { 1247 pnew->vcn = pold->vcn; 1248 pnew->lcn = pold->lcn; 1249 pnew->length = reprl[0].vcn + lowest_vcn - pold->vcn; 1250 pnew++; 1251 } 1252 /* copy new runs */ 1253 prep = reprl; 1254 nextvcn = prep->vcn + lowest_vcn; 1255 while (prep->length) { 1256 pnew->vcn = prep->vcn + lowest_vcn; 1257 pnew->lcn = prep->lcn; 1258 pnew->length = prep->length; 1259 nextvcn = pnew->vcn + pnew->length; 1260 pnew++; 1261 prep++; 1262 } 1263 /* locate the first fully replaced old run */ 1264 while (pold->length 1265 && ((pold->vcn + pold->length) <= nextvcn)) { 1266 pold++; 1267 } 1268 /* split a possible old run partially overlapped */ 1269 if (pold->length 1270 && (pold->vcn < nextvcn)) { 1271 pnew->vcn = nextvcn; 1272 pnew->lcn = pold->lcn + nextvcn - pold->vcn; 1273 pnew->length = pold->length - nextvcn + pold->vcn; 1274 pnew++; 1275 } 1276 /* copy old runs beyond replaced ones */ 1277 while (pold->length) { 1278 *pnew = *pold; 1279 pnew++; 1280 pold++; 1281 } 1282 /* the terminator is same as the old one */ 1283 *pnew = *pold; 1284 /* deallocate the old runlist and replace */ 1285 free(na->rl); 1286 na->rl = newrl; 1287 r = 0; 1288 } 1289 return (r); 1290} 1291 1292/* 1293 * Expand the new runlist in new extent(s) 1294 * 1295 * This implies allocating inode extents and, generally, creating 1296 * an attribute list and allocating clusters for the list, and 1297 * shuffle the existing attributes accordingly. 1298 * 1299 * Sometimes the runlist being reallocated is within an extent, 1300 * so we have a partial runlist to plug into an existing one 1301 * whose other parts have already been processed or will have 1302 * to be processed later, and we must not interfere with the 1303 * processing of these parts. 1304 * 1305 * This cannot be done on the runlist part stored in a single 1306 * extent, it has to be done globally for the file. 1307 * 1308 * We use the standard library functions, so we must wait until 1309 * the new global bitmap and the new MFT bitmap are saved to 1310 * disk and usable for the allocation of a new extent and creation 1311 * of an attribute list. 1312 * 1313 * Aborts if something goes wrong. There should be no data damage, 1314 * because the old runlist is still in use and the bootsector has 1315 * not been updated yet, so the initial clusters can be accessed. 1316 */ 1317 1318static void expand_attribute_runlist(ntfs_volume *vol, struct DELAYED *delayed) 1319{ 1320 ntfs_inode *ni; 1321 ntfs_attr *na; 1322 ATTR_TYPES type; 1323 MFT_REF mref; 1324 runlist_element *rl; 1325 1326 /* open the inode */ 1327 mref = delayed->mref; 1328#ifndef BAN_NEW_TEXT 1329 ntfs_log_verbose("Processing a delayed update for inode %lld\n", 1330 (long long)mref); 1331#endif 1332 type = delayed->type; 1333 rl = delayed->rl; 1334 1335 /* The MFT inode is permanently open, do not reopen or close */ 1336 if (mref == FILE_MFT) 1337 ni = vol->mft_ni; 1338 else 1339 ni = ntfs_inode_open(vol,mref); 1340 if (ni) { 1341 if (mref == FILE_MFT) 1342 na = (type == AT_DATA ? vol->mft_na : vol->mftbmp_na); 1343 else 1344 na = ntfs_attr_open(ni, type, 1345 delayed->attr_name, delayed->name_len); 1346 if (na) { 1347 /* 1348 * The runlist is first updated in memory, and 1349 * the updated one is used for updating on device 1350 */ 1351 if (!ntfs_attr_map_whole_runlist(na)) { 1352 if (replace_runlist(na,rl,delayed->lowest_vcn) 1353 || ntfs_attr_update_mapping_pairs(na,0)) 1354 perr_exit("Could not update runlist " 1355 "for attribute 0x%lx in inode %lld", 1356 (long)le32_to_cpu(type),(long long)mref); 1357 } else 1358 perr_exit("Could not map attribute 0x%lx in inode %lld", 1359 (long)le32_to_cpu(type),(long long)mref); 1360 if (mref != FILE_MFT) 1361 ntfs_attr_close(na); 1362 } else 1363 perr_exit("Could not open attribute 0x%lx in inode %lld", 1364 (long)le32_to_cpu(type),(long long)mref); 1365 ntfs_inode_mark_dirty(ni); 1366 if ((mref != FILE_MFT) && ntfs_inode_close(ni)) 1367 perr_exit("Failed to close inode %lld through the library", 1368 (long long)mref); 1369 } else 1370 perr_exit("Could not open inode %lld through the library", 1371 (long long)mref); 1372} 1373 1374/* 1375 * Reload the MFT before merging delayed updates of runlist 1376 * 1377 * The delayed updates of runlists are those which imply updating 1378 * the runlists which overflow from their original MFT record. 1379 * Such updates must be done in the new location of the MFT and 1380 * the allocations must be recorded in the new location of the 1381 * MFT bitmap. 1382 * The MFT data and MFT bitmap may themselves have delayed parts 1383 * of their runlists, and at this stage, their runlists may have 1384 * been partially updated on disk, and partially to be updated. 1385 * Their in-memory runlists still point at the old location, they 1386 * are obsolete, and we have to read the partially updated runlist 1387 * from the device before merging the delayed updates. 1388 * 1389 * Returns 0 if successful 1390 * -1 otherwise 1391 */ 1392 1393static int reload_mft(ntfs_resize_t *resize) 1394{ 1395 ntfs_inode *ni; 1396 ntfs_attr *na; 1397 int r; 1398 int xi; 1399 1400 r = 0; 1401 /* get the base inode */ 1402 ni = resize->vol->mft_ni; 1403 if (!ntfs_file_record_read(resize->vol, FILE_MFT, &ni->mrec, NULL)) { 1404 for (xi=0; !r && xi<resize->vol->mft_ni->nr_extents; xi++) { 1405 r = ntfs_file_record_read(resize->vol, 1406 ni->extent_nis[xi]->mft_no, 1407 &ni->extent_nis[xi]->mrec, NULL); 1408 } 1409 1410 if (!r) { 1411 /* reopen the MFT bitmap, and swap vol->mftbmp_na */ 1412 na = ntfs_attr_open(resize->vol->mft_ni, 1413 AT_BITMAP, NULL, 0); 1414 if (na && !ntfs_attr_map_whole_runlist(na)) { 1415 ntfs_attr_close(resize->vol->mftbmp_na); 1416 resize->vol->mftbmp_na = na; 1417 } else 1418 r = -1; 1419 } 1420 1421 if (!r) { 1422 /* reopen the MFT data, and swap vol->mft_na */ 1423 na = ntfs_attr_open(resize->vol->mft_ni, 1424 AT_DATA, NULL, 0); 1425 if (na && !ntfs_attr_map_whole_runlist(na)) { 1426 ntfs_attr_close(resize->vol->mft_na); 1427 resize->vol->mft_na = na; 1428 } else 1429 r = -1; 1430 } 1431 } else 1432 r = -1; 1433 return (r); 1434} 1435 1436/* 1437 * Re-record the MFT extents in MFT bitmap 1438 * 1439 * When both MFT data and MFT bitmap have delayed runlists, MFT data 1440 * is updated first, and the extents may be recorded at old location. 1441 */ 1442 1443static int record_mft_in_bitmap(ntfs_resize_t *resize) 1444{ 1445 ntfs_inode *ni; 1446 int r; 1447 int xi; 1448 1449 r = 0; 1450 /* get the base inode */ 1451 ni = resize->vol->mft_ni; 1452 for (xi=0; !r && xi<resize->vol->mft_ni->nr_extents; xi++) { 1453 r = ntfs_bitmap_set_run(resize->vol->mftbmp_na, 1454 ni->extent_nis[xi]->mft_no, 1); 1455 } 1456 return (r); 1457} 1458 1459/* 1460 * Process delayed runlist updates 1461 */ 1462 1463static void delayed_updates(ntfs_resize_t *resize) 1464{ 1465 struct DELAYED *delayed; 1466 struct DELAYED *delayed_mft_data; 1467 int nr_extents; 1468 1469 if (ntfs_volume_get_free_space(resize->vol)) 1470 err_exit("Failed to determine free space\n"); 1471 1472 delayed_mft_data = (struct DELAYED*)NULL; 1473 if (resize->delayed_runlists && reload_mft(resize)) 1474 err_exit("Failed to reload the MFT for delayed updates\n"); 1475 1476 /* 1477 * Important : updates to MFT must come first, so that 1478 * the new location of MFT is used for adding needed extents. 1479 * Now, there are runlists in the MFT bitmap and MFT data. 1480 * Extents to MFT bitmap have to be stored in the new MFT 1481 * data, and extents to MFT data have to be recorded in 1482 * the MFT bitmap. 1483 * So we update MFT data first, and we record the MFT 1484 * extents again in the MFT bitmap if they were recorded 1485 * in the old location. 1486 * 1487 * However, if we are operating in "no action" mode, the 1488 * MFT records to update are not written to their new location 1489 * and the MFT data runlist has to be updated last in order 1490 * to have the entries read from their old location. 1491 * In this situation the MFT bitmap is never written to 1492 * disk, so the same extents are reallocated repeatedly, 1493 * which is not what would be done in a real resizing. 1494 */ 1495 1496 if (opt.ro_flag 1497 && resize->delayed_runlists 1498 && (resize->delayed_runlists->mref == FILE_MFT) 1499 && (resize->delayed_runlists->type == AT_DATA)) { 1500 /* Update the MFT data runlist later */ 1501 delayed_mft_data = resize->delayed_runlists; 1502 resize->delayed_runlists = resize->delayed_runlists->next; 1503 } 1504 1505 while (resize->delayed_runlists) { 1506 delayed = resize->delayed_runlists; 1507 expand_attribute_runlist(resize->vol, delayed); 1508 if (delayed->mref == FILE_MFT) { 1509 if (delayed->type == AT_BITMAP) 1510 record_mft_in_bitmap(resize); 1511 if (delayed->type == AT_DATA) 1512 resize->mirr_from = MIRR_MFT; 1513 } 1514 resize->delayed_runlists = resize->delayed_runlists->next; 1515 if (delayed->attr_name) 1516 free(delayed->attr_name); 1517 free(delayed->head_rl); 1518 free(delayed); 1519 } 1520 if (opt.ro_flag && delayed_mft_data) { 1521 /* in "no action" mode, check updating the MFT runlist now */ 1522 expand_attribute_runlist(resize->vol, delayed_mft_data); 1523 resize->mirr_from = MIRR_MFT; 1524 if (delayed_mft_data->attr_name) 1525 free(delayed_mft_data->attr_name); 1526 free(delayed_mft_data->head_rl); 1527 free(delayed_mft_data); 1528 } 1529 /* Beware of MFT fragmentation when the target size is too small */ 1530 nr_extents = resize->vol->mft_ni->nr_extents; 1531 if (nr_extents > 2) { 1532 printf("WARNING: The MFT is now severely fragmented" 1533 " (%d extents)\n", nr_extents); 1534 } 1535} 1536 1537/* 1538 * Queue a runlist replacement for later update 1539 * 1540 * Store the attribute identification relative to base inode 1541 */ 1542 1543static void replace_later(ntfs_resize_t *resize, runlist *rl, runlist *head_rl) 1544{ 1545 struct DELAYED *delayed; 1546 struct DELAYED *previous; 1547 ATTR_RECORD *a; 1548 MFT_REF mref; 1549 leMFT_REF lemref; 1550 int name_len; 1551 ntfschar *attr_name; 1552 1553 /* save the attribute parameters, to be able to find it later */ 1554 a = resize->ctx->attr; 1555 name_len = a->name_length; 1556 attr_name = (ntfschar*)NULL; 1557 if (name_len) { 1558 attr_name = (ntfschar*)ntfs_malloc(name_len*sizeof(ntfschar)); 1559 if (attr_name) 1560 memcpy(attr_name,(u8*)a + le16_to_cpu(a->name_offset), 1561 name_len*sizeof(ntfschar)); 1562 } 1563 delayed = (struct DELAYED*)ntfs_malloc(sizeof(struct DELAYED)); 1564 if (delayed && (attr_name || !name_len)) { 1565 lemref = resize->ctx->mrec->base_mft_record; 1566 if (lemref) 1567 mref = le64_to_cpu(lemref); 1568 else 1569 mref = resize->mref; 1570 delayed->mref = MREF(mref); 1571 delayed->type = a->type; 1572 delayed->attr_name = attr_name; 1573 delayed->name_len = name_len; 1574 delayed->lowest_vcn = sle64_to_cpu(a->lowest_vcn); 1575 delayed->rl = rl; 1576 delayed->head_rl = head_rl; 1577 /* Queue ahead of list if this is MFT or head is not MFT */ 1578 if ((delayed->mref == FILE_MFT) 1579 || !resize->delayed_runlists 1580 || (resize->delayed_runlists->mref != FILE_MFT)) { 1581 delayed->next = resize->delayed_runlists; 1582 resize->delayed_runlists = delayed; 1583 } else { 1584 /* Queue after all MFTs is this is not MFT */ 1585 previous = resize->delayed_runlists; 1586 while (previous->next 1587 && (previous->next->mref == FILE_MFT)) 1588 previous = previous->next; 1589 delayed->next = previous->next; 1590 previous->next = delayed; 1591 } 1592 } else 1593 perr_exit("Could not store delayed update data"); 1594} 1595 1596/* 1597 * Replace the runlist in an attribute 1598 * 1599 * This sometimes requires expanding the runlist into another extent, 1600 * which has to be done globally on the attribute. Is so, the action 1601 * is put in a delay queue, and the caller must not free the runlist. 1602 * 1603 * Returns 0 if the replacement could be done 1604 * 1 when it has been put in the delay queue. 1605 */ 1606 1607static int replace_attribute_runlist(ntfs_resize_t *resize, runlist *rl) 1608{ 1609 int mp_size, l; 1610 int must_delay; 1611 void *mp; 1612 runlist *head_rl; 1613 ntfs_volume *vol; 1614 ntfs_attr_search_ctx *ctx; 1615 ATTR_RECORD *a; 1616 1617 vol = resize->vol; 1618 ctx = resize->ctx; 1619 a = ctx->attr; 1620 head_rl = rl; 1621 rl_fixup(&rl); 1622 1623 if ((mp_size = ntfs_get_size_for_mapping_pairs(vol, rl, 0, INT_MAX)) == -1) 1624 perr_exit("ntfs_get_size_for_mapping_pairs"); 1625 1626 if (a->name_length) { 1627 u16 name_offs = le16_to_cpu(a->name_offset); 1628 u16 mp_offs = le16_to_cpu(a->mapping_pairs_offset); 1629 1630 if (name_offs >= mp_offs) 1631 err_exit("Attribute name is after mapping pairs! " 1632 "Please report!\n"); 1633 } 1634 1635 /* CHECKME: don't trust mapping_pairs is always the last item in the 1636 attribute, instead check for the real size/space */ 1637 l = (int)le32_to_cpu(a->length) - le16_to_cpu(a->mapping_pairs_offset); 1638 must_delay = 0; 1639 if (mp_size > l) { 1640 s32 remains_size; 1641 char *next_attr; 1642 1643 ntfs_log_verbose("Enlarging attribute header ...\n"); 1644 1645 mp_size = (mp_size + 7) & ~7; 1646 1647 ntfs_log_verbose("Old mp size : %d\n", l); 1648 ntfs_log_verbose("New mp size : %d\n", mp_size); 1649 ntfs_log_verbose("Bytes in use : %u\n", (unsigned int) 1650 le32_to_cpu(ctx->mrec->bytes_in_use)); 1651 1652 next_attr = (char *)a + le32_to_cpu(a->length); 1653 l = mp_size - l; 1654 1655 ntfs_log_verbose("Bytes in use new : %u\n", l + (unsigned int) 1656 le32_to_cpu(ctx->mrec->bytes_in_use)); 1657 ntfs_log_verbose("Bytes allocated : %u\n", (unsigned int) 1658 le32_to_cpu(ctx->mrec->bytes_allocated)); 1659 1660 remains_size = le32_to_cpu(ctx->mrec->bytes_in_use); 1661 remains_size -= (next_attr - (char *)ctx->mrec); 1662 1663 ntfs_log_verbose("increase : %d\n", l); 1664 ntfs_log_verbose("shift : %lld\n", 1665 (long long)remains_size); 1666 if (le32_to_cpu(ctx->mrec->bytes_in_use) + l > 1667 le32_to_cpu(ctx->mrec->bytes_allocated)) { 1668#ifndef BAN_NEW_TEXT 1669 ntfs_log_verbose("Queuing expansion for later processing\n"); 1670#endif 1671 must_delay = 1; 1672 replace_later(resize,rl,head_rl); 1673 } else { 1674 memmove(next_attr + l, next_attr, remains_size); 1675 ctx->mrec->bytes_in_use = cpu_to_le32(l + 1676 le32_to_cpu(ctx->mrec->bytes_in_use)); 1677 a->length = cpu_to_le32(le32_to_cpu(a->length) + l); 1678 } 1679 } 1680 1681 if (!must_delay) { 1682 mp = ntfs_calloc(mp_size); 1683 if (!mp) 1684 perr_exit("ntfsc_calloc couldn't get memory"); 1685 1686 if (ntfs_mapping_pairs_build(vol, (u8*)mp, mp_size, rl, 0, NULL)) 1687 perr_exit("ntfs_mapping_pairs_build"); 1688 1689 memmove((u8*)a + le16_to_cpu(a->mapping_pairs_offset), mp, mp_size); 1690 1691 free(mp); 1692 } 1693 return (must_delay); 1694} 1695 1696static void set_bitmap_range(struct bitmap *bm, s64 pos, s64 length, u8 bit) 1697{ 1698 while (length--) 1699 ntfs_bit_set(bm->bm, pos++, bit); 1700} 1701 1702static void set_bitmap_clusters(struct bitmap *bm, runlist *rl, u8 bit) 1703{ 1704 for (; rl->length; rl++) 1705 set_bitmap_range(bm, rl->lcn, rl->length, bit); 1706} 1707 1708static void release_bitmap_clusters(struct bitmap *bm, runlist *rl) 1709{ 1710 max_free_cluster_range = 0; 1711 set_bitmap_clusters(bm, rl, 0); 1712} 1713 1714static void set_max_free_zone(s64 length, s64 end, runlist_element *rle) 1715{ 1716 if (length > rle->length) { 1717 rle->lcn = end - length; 1718 rle->length = length; 1719 } 1720} 1721 1722static int find_free_cluster(struct bitmap *bm, 1723 runlist_element *rle, 1724 s64 nr_vol_clusters, 1725 int hint) 1726{ 1727 /* FIXME: get rid of this 'static' variable */ 1728 static s64 pos = 0; 1729 s64 i, items = rle->length; 1730 s64 free_zone = 0; 1731 1732 if (pos >= nr_vol_clusters) 1733 pos = 0; 1734 if (!max_free_cluster_range) 1735 max_free_cluster_range = nr_vol_clusters; 1736 rle->lcn = rle->length = 0; 1737 if (hint) 1738 pos = nr_vol_clusters / 2; 1739 i = pos; 1740 1741 do { 1742 if (!ntfs_bit_get(bm->bm, i)) { 1743 if (++free_zone == items) { 1744 set_max_free_zone(free_zone, i + 1, rle); 1745 break; 1746 } 1747 } else { 1748 set_max_free_zone(free_zone, i, rle); 1749 free_zone = 0; 1750 } 1751 if (++i == nr_vol_clusters) { 1752 set_max_free_zone(free_zone, i, rle); 1753 i = free_zone = 0; 1754 } 1755 if (rle->length == max_free_cluster_range) 1756 break; 1757 } while (i != pos); 1758 1759 if (i) 1760 set_max_free_zone(free_zone, i, rle); 1761 1762 if (!rle->lcn) { 1763 errno = ENOSPC; 1764 return -1; 1765 } 1766 if (rle->length < items && rle->length < max_free_cluster_range) { 1767 max_free_cluster_range = rle->length; 1768 ntfs_log_verbose("Max free range: %7lld \n", 1769 (long long)max_free_cluster_range); 1770 } 1771 pos = rle->lcn + items; 1772 if (pos == nr_vol_clusters) 1773 pos = 0; 1774 1775 set_bitmap_range(bm, rle->lcn, rle->length, 1); 1776 return 0; 1777} 1778 1779static runlist *alloc_cluster(struct bitmap *bm, 1780 s64 items, 1781 s64 nr_vol_clusters, 1782 int hint) 1783{ 1784 runlist_element rle; 1785 runlist *rl = NULL; 1786 int rl_size, runs = 0; 1787 s64 vcn = 0; 1788 1789 if (items <= 0) { 1790 errno = EINVAL; 1791 return NULL; 1792 } 1793 1794 while (items > 0) { 1795 1796 if (runs) 1797 hint = 0; 1798 rle.length = items; 1799 if (find_free_cluster(bm, &rle, nr_vol_clusters, hint) == -1) 1800 return NULL; 1801 1802 rl_size = (runs + 2) * sizeof(runlist_element); 1803 if (!(rl = (runlist *)realloc(rl, rl_size))) 1804 return NULL; 1805 1806 rl_set(rl + runs, vcn, rle.lcn, rle.length); 1807 1808 vcn += rle.length; 1809 items -= rle.length; 1810 runs++; 1811 } 1812 1813 rl_set(rl + runs, vcn, -1LL, 0LL); 1814 1815 if (runs > 1) { 1816 ntfs_log_verbose("Multi-run allocation: \n"); 1817 dump_runlist(rl); 1818 } 1819 return rl; 1820} 1821 1822static int read_all(struct ntfs_device *dev, void *buf, int count) 1823{ 1824 int i; 1825 1826 while (count > 0) { 1827 1828 i = count; 1829 if (!NDevReadOnly(dev)) 1830 i = dev->d_ops->read(dev, buf, count); 1831 1832 if (i < 0) { 1833 if (errno != EAGAIN && errno != EINTR) 1834 return -1; 1835 } else if (i > 0) { 1836 count -= i; 1837 buf = i + (char *)buf; 1838 } else 1839 err_exit("Unexpected end of file!\n"); 1840 } 1841 return 0; 1842} 1843 1844static int write_all(struct ntfs_device *dev, void *buf, int count) 1845{ 1846 int i; 1847 1848 while (count > 0) { 1849 1850 i = count; 1851 if (!NDevReadOnly(dev)) 1852 i = dev->d_ops->write(dev, buf, count); 1853 1854 if (i < 0) { 1855 if (errno != EAGAIN && errno != EINTR) 1856 return -1; 1857 } else { 1858 count -= i; 1859 buf = i + (char *)buf; 1860 } 1861 } 1862 return 0; 1863} 1864 1865/** 1866 * write_mft_record 1867 * 1868 * Write an MFT Record back to the disk. If the read-only command line option 1869 * was given, this function will do nothing. 1870 */ 1871static int write_mft_record(ntfs_volume *v, const MFT_REF mref, MFT_RECORD *buf) 1872{ 1873 if (ntfs_mft_record_write(v, mref, buf)) 1874 perr_exit("ntfs_mft_record_write"); 1875 1876// if (v->dev->d_ops->sync(v->dev) == -1) 1877// perr_exit("Failed to sync device"); 1878 1879 return 0; 1880} 1881 1882static void lseek_to_cluster(ntfs_volume *vol, s64 lcn) 1883{ 1884 off_t pos; 1885 1886 pos = (off_t)(lcn * vol->cluster_size); 1887 1888 if (vol->dev->d_ops->seek(vol->dev, pos, SEEK_SET) == (off_t)-1) 1889 perr_exit("seek failed to position %lld", (long long)lcn); 1890} 1891 1892static void copy_clusters(ntfs_resize_t *resize, s64 dest, s64 src, s64 len) 1893{ 1894 s64 i; 1895 char *buff; 1896 ntfs_volume *vol = resize->vol; 1897 1898 buff = (char*)ntfs_malloc(vol->cluster_size); 1899 if (!buff) 1900 perr_exit("ntfs_malloc"); 1901 1902 for (i = 0; i < len; i++) { 1903 1904 lseek_to_cluster(vol, src + i); 1905 1906 if (read_all(vol->dev, buff, vol->cluster_size) == -1) { 1907 perr_printf("Failed to read from the disk"); 1908 if (errno == EIO) 1909 printf("%s", bad_sectors_warning_msg); 1910 exit(1); 1911 } 1912 1913 lseek_to_cluster(vol, dest + i); 1914 1915 if (write_all(vol->dev, buff, vol->cluster_size) == -1) { 1916 perr_printf("Failed to write to the disk"); 1917 if (errno == EIO) 1918 printf("%s", bad_sectors_warning_msg); 1919 exit(1); 1920 } 1921 1922 resize->relocations++; 1923 progress_update(&resize->progress, resize->relocations); 1924 } 1925 free(buff); 1926} 1927 1928static void relocate_clusters(ntfs_resize_t *r, runlist *dest_rl, s64 src_lcn) 1929{ 1930 /* collect_shrink_constraints() ensured $MFTMir DATA is one run */ 1931 if (r->mref == FILE_MFTMirr && r->ctx->attr->type == AT_DATA) { 1932 if (!r->mftmir_old) { 1933 r->mftmir_rl.lcn = dest_rl->lcn; 1934 r->mftmir_rl.length = dest_rl->length; 1935 r->mftmir_old = src_lcn; 1936 } else 1937 err_exit("Multi-run $MFTMirr. Please report!\n"); 1938 } 1939 1940 for (; dest_rl->length; src_lcn += dest_rl->length, dest_rl++) 1941 copy_clusters(r, dest_rl->lcn, src_lcn, dest_rl->length); 1942} 1943 1944static void rl_split_run(runlist **rl, int run, s64 pos) 1945{ 1946 runlist *rl_new, *rle_new, *rle; 1947 int items, new_size, size_head, size_tail; 1948 s64 len_head, len_tail; 1949 1950 items = rl_items(*rl); 1951 new_size = (items + 1) * sizeof(runlist_element); 1952 size_head = run * sizeof(runlist_element); 1953 size_tail = (items - run - 1) * sizeof(runlist_element); 1954 1955 rl_new = ntfs_malloc(new_size); 1956 if (!rl_new) 1957 perr_exit("ntfs_malloc"); 1958 1959 rle_new = rl_new + run; 1960 rle = *rl + run; 1961 1962 memmove(rl_new, *rl, size_head); 1963 memmove(rle_new + 2, rle + 1, size_tail); 1964 1965 len_tail = rle->length - (pos - rle->lcn); 1966 len_head = rle->length - len_tail; 1967 1968 rl_set(rle_new, rle->vcn, rle->lcn, len_head); 1969 rl_set(rle_new + 1, rle->vcn + len_head, rle->lcn + len_head, len_tail); 1970 1971 ntfs_log_verbose("Splitting run at cluster %lld:\n", (long long)pos); 1972 dump_run(rle); dump_run(rle_new); dump_run(rle_new + 1); 1973 1974 free(*rl); 1975 *rl = rl_new; 1976} 1977 1978static void rl_insert_at_run(runlist **rl, int run, runlist *ins) 1979{ 1980 int items, ins_items; 1981 int new_size, size_tail; 1982 runlist *rle; 1983 s64 vcn; 1984 1985 items = rl_items(*rl); 1986 ins_items = rl_items(ins) - 1; 1987 new_size = ((items - 1) + ins_items) * sizeof(runlist_element); 1988 size_tail = (items - run - 1) * sizeof(runlist_element); 1989 1990 if (!(*rl = (runlist *)realloc(*rl, new_size))) 1991 perr_exit("realloc"); 1992 1993 rle = *rl + run; 1994 1995 memmove(rle + ins_items, rle + 1, size_tail); 1996 1997 for (vcn = rle->vcn; ins->length; rle++, vcn += ins->length, ins++) { 1998 rl_set(rle, vcn, ins->lcn, ins->length); 1999// dump_run(rle); 2000 } 2001 2002 return; 2003 2004 /* FIXME: fast path if ins_items = 1 */ 2005// (*rl + run)->lcn = ins->lcn; 2006} 2007 2008static void relocate_run(ntfs_resize_t *resize, runlist **rl, int run) 2009{ 2010 s64 lcn, lcn_length; 2011 s64 new_vol_size; /* (last LCN on the volume) + 1 */ 2012 runlist *relocate_rl; /* relocate runlist to relocate_rl */ 2013 int hint; 2014 2015 lcn = (*rl + run)->lcn; 2016 lcn_length = (*rl + run)->length; 2017 new_vol_size = resize->new_volume_size; 2018 2019 if (lcn + lcn_length <= new_vol_size) 2020 return; 2021 2022 if (lcn < new_vol_size) { 2023 rl_split_run(rl, run, new_vol_size); 2024 return; 2025 } 2026 2027 hint = (resize->mref == FILE_MFTMirr) ? 1 : 0; 2028 if ((resize->mref == FILE_MFT) 2029 && (resize->ctx->attr->type == AT_DATA) 2030 && !run 2031 && resize->new_mft_start) { 2032 relocate_rl = resize->new_mft_start; 2033 } else 2034 if (!(relocate_rl = alloc_cluster(&resize->lcn_bitmap, 2035 lcn_length, new_vol_size, hint))) 2036 perr_exit("Cluster allocation failed for %llu:%lld", 2037 (unsigned long long)resize->mref, 2038 (long long)lcn_length); 2039 2040 /* FIXME: check $MFTMirr DATA isn't multi-run (or support it) */ 2041 ntfs_log_verbose("Relocate record %7llu:0x%x:%08lld:0x%08llx:0x%08llx " 2042 "--> 0x%08llx\n", (unsigned long long)resize->mref, 2043 (unsigned int)le32_to_cpu(resize->ctx->attr->type), 2044 (long long)lcn_length, 2045 (unsigned long long)(*rl + run)->vcn, 2046 (unsigned long long)lcn, 2047 (unsigned long long)relocate_rl->lcn); 2048 2049 relocate_clusters(resize, relocate_rl, lcn); 2050 rl_insert_at_run(rl, run, relocate_rl); 2051 2052 /* We don't release old clusters in the bitmap, that area isn't 2053 used by the allocator and will be truncated later on */ 2054 2055 /* Do not free the relocated MFT start */ 2056 if ((resize->mref != FILE_MFT) 2057 || (resize->ctx->attr->type != AT_DATA) 2058 || run 2059 || !resize->new_mft_start) 2060 free(relocate_rl); 2061 2062 resize->dirty_inode = DIRTY_ATTRIB; 2063} 2064 2065static void relocate_attribute(ntfs_resize_t *resize) 2066{ 2067 ATTR_RECORD *a; 2068 runlist *rl; 2069 int i; 2070 2071 a = resize->ctx->attr; 2072 2073 if (!a->non_resident) 2074 return; 2075 2076 if (!(rl = ntfs_mapping_pairs_decompress(resize->vol, a, NULL))) 2077 perr_exit("ntfs_decompress_mapping_pairs"); 2078 2079 for (i = 0; rl[i].length; i++) { 2080 s64 lcn = rl[i].lcn; 2081 s64 lcn_length = rl[i].length; 2082 2083 if (lcn == LCN_HOLE || lcn == LCN_RL_NOT_MAPPED) 2084 continue; 2085 2086 /* FIXME: ntfs_mapping_pairs_decompress should return error */ 2087 if (lcn < 0 || lcn_length <= 0) 2088 err_exit("Corrupt runlist in MTF %llu attr %x LCN " 2089 "%llx length %llx\n", 2090 (unsigned long long)resize->mref, 2091 (unsigned int)le32_to_cpu(a->type), 2092 (long long)lcn, (long long)lcn_length); 2093 2094 relocate_run(resize, &rl, i); 2095 } 2096 2097 if (resize->dirty_inode == DIRTY_ATTRIB) { 2098 if (!replace_attribute_runlist(resize, rl)) 2099 free(rl); 2100 resize->dirty_inode = DIRTY_INODE; 2101 } else 2102 free(rl); 2103} 2104 2105static int is_mftdata(ntfs_resize_t *resize) 2106{ 2107 /* 2108 * We must update the MFT own DATA record at the end of the second 2109 * step, because the old MFT must be kept available for processing 2110 * the other files. 2111 */ 2112 2113 if (resize->ctx->attr->type != AT_DATA) 2114 return 0; 2115 2116 if (resize->mref == 0) 2117 return 1; 2118 2119 if (MREF_LE(resize->mrec->base_mft_record) == 0 && 2120 MSEQNO_LE(resize->mrec->base_mft_record) != 0) 2121 return 1; 2122 2123 return 0; 2124} 2125 2126static int handle_mftdata(ntfs_resize_t *resize, int do_mftdata) 2127{ 2128 ATTR_RECORD *attr = resize->ctx->attr; 2129 VCN highest_vcn, lowest_vcn; 2130 2131 if (do_mftdata) { 2132 2133 if (!is_mftdata(resize)) 2134 return 0; 2135 2136 highest_vcn = sle64_to_cpu(attr->highest_vcn); 2137 lowest_vcn = sle64_to_cpu(attr->lowest_vcn); 2138 2139 if (resize->mft_highest_vcn != highest_vcn) 2140 return 0; 2141 2142 if (lowest_vcn == 0) 2143 resize->mft_highest_vcn = lowest_vcn; 2144 else 2145 resize->mft_highest_vcn = lowest_vcn - 1; 2146 2147 } else if (is_mftdata(resize)) { 2148 2149 highest_vcn = sle64_to_cpu(attr->highest_vcn); 2150 2151 if (resize->mft_highest_vcn < highest_vcn) 2152 resize->mft_highest_vcn = highest_vcn; 2153 2154 return 0; 2155 } 2156 2157 return 1; 2158} 2159 2160static void relocate_attributes(ntfs_resize_t *resize, int do_mftdata) 2161{ 2162 int ret; 2163 leMFT_REF lemref; 2164 MFT_REF base_mref; 2165 2166 if (!(resize->ctx = attr_get_search_ctx(NULL, resize->mrec))) 2167 exit(1); 2168 2169 lemref = resize->mrec->base_mft_record; 2170 if (lemref) 2171 base_mref = MREF(le64_to_cpu(lemref)); 2172 else 2173 base_mref = resize->mref; 2174 while (!ntfs_attrs_walk(resize->ctx)) { 2175 if (resize->ctx->attr->type == AT_END) 2176 break; 2177 2178 if (handle_mftdata(resize, do_mftdata) == 0) 2179 continue; 2180 2181 ret = ntfs_inode_badclus_bad(resize->mref, resize->ctx->attr); 2182 if (ret == -1) 2183 perr_exit("Bad sector list check failed"); 2184 else if (ret == 1) 2185 continue; 2186 2187 if (resize->mref == FILE_Bitmap && 2188 resize->ctx->attr->type == AT_DATA) 2189 continue; 2190 2191 /* Do not relocate bad clusters */ 2192 if ((base_mref == FILE_BadClus) 2193 && (resize->ctx->attr->type == AT_DATA)) 2194 continue; 2195 2196 relocate_attribute(resize); 2197 } 2198 2199 ntfs_attr_put_search_ctx(resize->ctx); 2200} 2201 2202static void relocate_inode(ntfs_resize_t *resize, MFT_REF mref, int do_mftdata) 2203{ 2204 ntfs_volume *vol = resize->vol; 2205 2206 if (ntfs_file_record_read(vol, mref, &resize->mrec, NULL)) { 2207 /* FIXME: continue only if it make sense, e.g. 2208 MFT record not in use based on $MFT bitmap */ 2209 if (errno == EIO || errno == ENOENT) 2210 return; 2211 perr_exit("ntfs_file_record_record"); 2212 } 2213 2214 if (!(resize->mrec->flags & MFT_RECORD_IN_USE)) 2215 return; 2216 2217 resize->mref = mref; 2218 resize->dirty_inode = DIRTY_NONE; 2219 2220 relocate_attributes(resize, do_mftdata); 2221 2222// if (vol->dev->d_ops->sync(vol->dev) == -1) 2223// perr_exit("Failed to sync device"); 2224 /* relocate MFT during second step, even if not dirty */ 2225 if ((mref == FILE_MFT) && do_mftdata && resize->new_mft_start) { 2226 s64 pos; 2227 2228 /* write the MFT own record at its new location */ 2229 pos = (resize->new_mft_start->lcn 2230 << vol->cluster_size_bits) 2231 + (FILE_MFT << vol->mft_record_size_bits); 2232 if (!opt.ro_flag 2233 && (ntfs_mst_pwrite(vol->dev, pos, 1, 2234 vol->mft_record_size, resize->mrec) != 1)) 2235 perr_exit("Couldn't update MFT own record"); 2236 } else { 2237 if ((resize->dirty_inode == DIRTY_INODE) 2238 && write_mft_record(vol, mref, resize->mrec)) { 2239 perr_exit("Couldn't update record %llu", 2240 (unsigned long long)mref); 2241 } 2242 } 2243} 2244 2245static void relocate_inodes(ntfs_resize_t *resize) 2246{ 2247 s64 nr_mft_records; 2248 MFT_REF mref; 2249 VCN highest_vcn; 2250 s64 length; 2251 2252 printf("Relocating needed data ...\n"); 2253 2254 progress_init(&resize->progress, 0, resize->relocations, resize->progress.flags); 2255 resize->relocations = 0; 2256 2257 resize->mrec = ntfs_malloc(resize->vol->mft_record_size); 2258 if (!resize->mrec) 2259 perr_exit("ntfs_malloc failed"); 2260 2261 nr_mft_records = resize->vol->mft_na->initialized_size >> 2262 resize->vol->mft_record_size_bits; 2263 2264 /* 2265 * If we need to relocate the first run of the MFT DATA, 2266 * do it now, to have a better chance of getting at least 2267 * 16 records in the first chunk. This is mandatory to be 2268 * later able to read an MFT extent in record 15. 2269 * Should this fail, we can stop with no damage, the volume 2270 * is still in its initial state. 2271 */ 2272 if (!resize->vol->mft_na->rl) 2273 err_exit("Internal error : no runlist for $MFT\n"); 2274 2275 if ((resize->vol->mft_na->rl->lcn + resize->vol->mft_na->rl->length) 2276 >= resize->new_volume_size) { 2277 /* 2278 * The length of the first run is normally found in 2279 * mft_na. However in some rare circumstance, this is 2280 * merged with the first run of an extent of MFT, 2281 * which implies there is a single run in the base record. 2282 * So we have to make sure not to overflow from the 2283 * runs present in the base extent. 2284 */ 2285 length = resize->vol->mft_na->rl->length; 2286 if (ntfs_file_record_read(resize->vol, FILE_MFT, 2287 &resize->mrec, NULL) 2288 || !(resize->ctx = attr_get_search_ctx(NULL, 2289 resize->mrec))) { 2290 err_exit("Could not read the base record of MFT\n"); 2291 } 2292 while (!ntfs_attrs_walk(resize->ctx) 2293 && (resize->ctx->attr->type != AT_DATA)) { } 2294 if (resize->ctx->attr->type == AT_DATA) { 2295 sle64 high_le; 2296 2297 high_le = resize->ctx->attr->highest_vcn; 2298 if (sle64_to_cpu(high_le) < length) 2299 length = sle64_to_cpu(high_le) + 1; 2300 } else { 2301 err_exit("Could not find the DATA of MFT\n"); 2302 } 2303 ntfs_attr_put_search_ctx(resize->ctx); 2304 resize->new_mft_start = alloc_cluster(&resize->lcn_bitmap, 2305 length, resize->new_volume_size, 0); 2306 if (!resize->new_mft_start 2307 || (((resize->new_mft_start->length 2308 << resize->vol->cluster_size_bits) 2309 >> resize->vol->mft_record_size_bits) < 16)) { 2310 err_exit("Could not allocate 16 records in" 2311 " the first MFT chunk\n"); 2312 } 2313 resize->mirr_from = MIRR_NEWMFT; 2314 } 2315 2316 for (mref = 0; mref < (MFT_REF)nr_mft_records; mref++) 2317 relocate_inode(resize, mref, 0); 2318 2319 while (1) { 2320 highest_vcn = resize->mft_highest_vcn; 2321 mref = nr_mft_records; 2322 do { 2323 relocate_inode(resize, --mref, 1); 2324 if (resize->mft_highest_vcn == 0) 2325 goto done; 2326 } while (mref); 2327 2328 if (highest_vcn == resize->mft_highest_vcn) 2329 err_exit("Sanity check failed! Highest_vcn = %lld. " 2330 "Please report!\n", (long long)highest_vcn); 2331 } 2332done: 2333 free(resize->mrec); 2334} 2335 2336static void print_hint(ntfs_volume *vol, const char *s, struct llcn_t llcn) 2337{ 2338 s64 runs_b, runs_mb; 2339 2340 if (llcn.lcn == 0) 2341 return; 2342 2343 runs_b = llcn.lcn * vol->cluster_size; 2344 runs_mb = rounded_up_division(runs_b, NTFS_MBYTE); 2345 printf("%-19s: %9lld MB %8lld\n", s, (long long)runs_mb, 2346 (long long)llcn.inode); 2347} 2348 2349/** 2350 * advise_on_resize 2351 * 2352 * The metadata file $Bitmap has one bit for each cluster on disk. This has 2353 * already been read into lcn_bitmap. By looking for the last used cluster on 2354 * the disk, we can work out by how much we can shrink the volume. 2355 */ 2356static void advise_on_resize(ntfs_resize_t *resize) 2357{ 2358 ntfs_volume *vol = resize->vol; 2359 2360 if (opt.verbose) { 2361 printf("Estimating smallest shrunken size supported ...\n"); 2362 printf("File feature Last used at By inode\n"); 2363 print_hint(vol, "$MFT", resize->last_mft); 2364 print_hint(vol, "Multi-Record", resize->last_multi_mft); 2365 print_hint(vol, "$MFTMirr", resize->last_mftmir); 2366 print_hint(vol, "Compressed", resize->last_compressed); 2367 print_hint(vol, "Sparse", resize->last_sparse); 2368 print_hint(vol, "Ordinary", resize->last_lcn); 2369 } 2370 2371 print_advise(vol, resize->last_unsupp); 2372} 2373 2374/** 2375 * bitmap_file_data_fixup 2376 * 2377 * $Bitmap can overlap the end of the volume. Any bits in this region 2378 * must be set. This region also encompasses the backup boot sector. 2379 */ 2380static void bitmap_file_data_fixup(s64 cluster, struct bitmap *bm) 2381{ 2382 for (; cluster < bm->size << 3; cluster++) 2383 ntfs_bit_set(bm->bm, (u64)cluster, 1); 2384} 2385 2386/* 2387 * Open the attribute $BadClust:$Bad and get its runlist 2388 */ 2389 2390static ntfs_attr *open_badclust_bad_attr(ntfs_attr_search_ctx *ctx) 2391{ 2392 ntfs_inode *base_ni; 2393 ntfs_attr *na; 2394 static ntfschar Bad[4] = { 2395 const_cpu_to_le16('$'), const_cpu_to_le16('B'), 2396 const_cpu_to_le16('a'), const_cpu_to_le16('d') 2397 } ; 2398 2399 base_ni = ctx->base_ntfs_ino; 2400 if (!base_ni) 2401 base_ni = ctx->ntfs_ino; 2402 2403 na = ntfs_attr_open(base_ni, AT_DATA, Bad, 4); 2404 if (!na) { 2405 err_printf("Could not access the bad sector list\n"); 2406 } else { 2407 if (ntfs_attr_map_whole_runlist(na) || !na->rl) { 2408 err_printf("Could not decode the bad sector list\n"); 2409 ntfs_attr_close(na); 2410 ntfs_inode_close(base_ni); 2411 na = (ntfs_attr*)NULL; 2412 } 2413 } 2414 return (na); 2415} 2416 2417/** 2418 * truncate_badclust_bad_attr 2419 * 2420 * The metadata file $BadClus needs to be shrunk. 2421 * 2422 * FIXME: this function should go away and instead using a generalized 2423 * "truncate_bitmap_data_attr()" 2424 */ 2425static void truncate_badclust_bad_attr(ntfs_resize_t *resize) 2426{ 2427 ntfs_inode *base_ni; 2428 ntfs_attr *na; 2429 ntfs_attr_search_ctx *ctx; 2430 s64 nr_clusters = resize->new_volume_size; 2431 ntfs_volume *vol = resize->vol; 2432 2433 na = open_badclust_bad_attr(resize->ctx); 2434 if (!na) { 2435 err_printf("Could not access the bad sector list\n"); 2436 exit(1); 2437 } 2438 base_ni = na->ni; 2439 if (ntfs_attr_truncate(na,nr_clusters << vol->cluster_size_bits)) { 2440 err_printf("Could not adjust the bad sector list\n"); 2441 exit(1); 2442 } 2443 /* Clear the sparse flags, even if there are bad clusters */ 2444 na->ni->flags &= ~FILE_ATTR_SPARSE_FILE; 2445 na->data_flags &= ~ATTR_IS_SPARSE; 2446 ctx = resize->ctx; 2447 ctx->attr->data_size = cpu_to_sle64(na->data_size); 2448 ctx->attr->initialized_size = cpu_to_sle64(na->initialized_size); 2449 ctx->attr->flags = na->data_flags; 2450 ctx->attr->compression_unit = 0; 2451 ntfs_inode_mark_dirty(ctx->ntfs_ino); 2452 NInoFileNameSetDirty(na->ni); 2453 NInoFileNameSetDirty(na->ni); 2454 2455 ntfs_attr_close(na); 2456 ntfs_inode_mark_dirty(base_ni); 2457} 2458 2459/** 2460 * realloc_bitmap_data_attr 2461 * 2462 * Reallocate the metadata file $Bitmap. It must be large enough for one bit 2463 * per cluster of the shrunken volume. Also it must be a of 8 bytes in size. 2464 */ 2465static void realloc_bitmap_data_attr(ntfs_resize_t *resize, 2466 runlist **rl, 2467 s64 nr_bm_clusters) 2468{ 2469 s64 i; 2470 ntfs_volume *vol = resize->vol; 2471 ATTR_RECORD *a = resize->ctx->attr; 2472 s64 new_size = resize->new_volume_size; 2473 struct bitmap *bm = &resize->lcn_bitmap; 2474 2475 if (!(*rl = ntfs_mapping_pairs_decompress(vol, a, NULL))) 2476 perr_exit("ntfs_mapping_pairs_decompress"); 2477 2478 release_bitmap_clusters(bm, *rl); 2479 free(*rl); 2480 2481 for (i = vol->nr_clusters; i < new_size; i++) 2482 ntfs_bit_set(bm->bm, i, 0); 2483 2484 if (!(*rl = alloc_cluster(bm, nr_bm_clusters, new_size, 0))) 2485 perr_exit("Couldn't allocate $Bitmap clusters"); 2486} 2487 2488static void realloc_lcn_bitmap(ntfs_resize_t *resize, s64 bm_bsize) 2489{ 2490 u8 *tmp; 2491 2492 if (!(tmp = realloc(resize->lcn_bitmap.bm, bm_bsize))) 2493 perr_exit("realloc"); 2494 2495 resize->lcn_bitmap.bm = tmp; 2496 resize->lcn_bitmap.size = bm_bsize; 2497 bitmap_file_data_fixup(resize->new_volume_size, &resize->lcn_bitmap); 2498} 2499 2500/** 2501 * truncate_bitmap_data_attr 2502 */ 2503static void truncate_bitmap_data_attr(ntfs_resize_t *resize) 2504{ 2505 ATTR_RECORD *a; 2506 runlist *rl; 2507 ntfs_attr *lcnbmp_na; 2508 s64 bm_bsize, size; 2509 s64 nr_bm_clusters; 2510 int truncated; 2511 ntfs_volume *vol = resize->vol; 2512 2513 a = resize->ctx->attr; 2514 if (!a->non_resident) 2515 /* FIXME: handle resident attribute value */ 2516 err_exit("Resident attribute in $Bitmap isn't supported!\n"); 2517 2518 bm_bsize = nr_clusters_to_bitmap_byte_size(resize->new_volume_size); 2519 nr_bm_clusters = rounded_up_division(bm_bsize, vol->cluster_size); 2520 2521 if (resize->shrink) { 2522 realloc_bitmap_data_attr(resize, &rl, nr_bm_clusters); 2523 realloc_lcn_bitmap(resize, bm_bsize); 2524 } else { 2525 realloc_lcn_bitmap(resize, bm_bsize); 2526 realloc_bitmap_data_attr(resize, &rl, nr_bm_clusters); 2527 } 2528 /* 2529 * Delayed relocations may require cluster allocations 2530 * through the library, to hold added attribute lists, 2531 * be sure they will be within the new limits. 2532 */ 2533 lcnbmp_na = resize->vol->lcnbmp_na; 2534 lcnbmp_na->data_size = bm_bsize; 2535 lcnbmp_na->initialized_size = bm_bsize; 2536 lcnbmp_na->allocated_size = nr_bm_clusters << vol->cluster_size_bits; 2537 vol->lcnbmp_ni->data_size = bm_bsize; 2538 vol->lcnbmp_ni->allocated_size = lcnbmp_na->allocated_size; 2539 a->highest_vcn = cpu_to_sle64(nr_bm_clusters - 1LL); 2540 a->allocated_size = cpu_to_sle64(nr_bm_clusters * vol->cluster_size); 2541 a->data_size = cpu_to_sle64(bm_bsize); 2542 a->initialized_size = cpu_to_sle64(bm_bsize); 2543 2544 truncated = !replace_attribute_runlist(resize, rl); 2545 2546 /* 2547 * FIXME: update allocated/data sizes and timestamps in $FILE_NAME 2548 * attribute too, for now chkdsk will do this for us. 2549 */ 2550 2551 size = ntfs_rl_pwrite(vol, rl, 0, 0, bm_bsize, resize->lcn_bitmap.bm); 2552 if (bm_bsize != size) { 2553 if (size == -1) 2554 perr_exit("Couldn't write $Bitmap"); 2555 err_exit("Couldn't write full $Bitmap file (%lld from %lld)\n", 2556 (long long)size, (long long)bm_bsize); 2557 } 2558 2559 if (truncated) { 2560 /* switch to the new bitmap runlist */ 2561 free(lcnbmp_na->rl); 2562 lcnbmp_na->rl = rl; 2563 } 2564} 2565 2566/** 2567 * lookup_data_attr 2568 * 2569 * Find the $DATA attribute (with or without a name) for the given MFT reference 2570 * (inode number). 2571 */ 2572static void lookup_data_attr(ntfs_volume *vol, 2573 MFT_REF mref, 2574 const char *aname, 2575 ntfs_attr_search_ctx **ctx) 2576{ 2577 ntfs_inode *ni; 2578 ntfschar *ustr; 2579 int len = 0; 2580 2581 if (!(ni = ntfs_inode_open(vol, mref))) 2582 perr_exit("ntfs_open_inode"); 2583 2584 if (!(*ctx = attr_get_search_ctx(ni, NULL))) 2585 exit(1); 2586 2587 if ((ustr = ntfs_str2ucs(aname, &len)) == NULL) { 2588 perr_printf("Couldn't convert '%s' to Unicode", aname); 2589 exit(1); 2590 } 2591 2592 if (ntfs_attr_lookup(AT_DATA, ustr, len, CASE_SENSITIVE, 2593 0, NULL, 0, *ctx)) 2594 perr_exit("ntfs_lookup_attr"); 2595 2596 ntfs_ucsfree(ustr); 2597} 2598 2599static void close_inode_and_context(ntfs_attr_search_ctx *ctx) 2600{ 2601 ntfs_inode *ni; 2602 2603 ni = ctx->base_ntfs_ino; 2604 if (!ni) 2605 ni = ctx->ntfs_ino; 2606 ntfs_attr_put_search_ctx(ctx); 2607 if (ni) 2608 ntfs_inode_close(ni); 2609} 2610 2611static int check_bad_sectors(ntfs_volume *vol) 2612{ 2613 ntfs_attr_search_ctx *ctx; 2614 ntfs_attr *na; 2615 runlist *rl; 2616 s64 i, badclusters = 0; 2617 2618 ntfs_log_verbose("Checking for bad sectors ...\n"); 2619 2620 lookup_data_attr(vol, FILE_BadClus, "$Bad", &ctx); 2621 2622 na = open_badclust_bad_attr(ctx); 2623 if (!na) { 2624 err_printf("Could not access the bad sector list\n"); 2625 exit(1); 2626 } 2627 rl = na->rl; 2628 for (i = 0; rl[i].length; i++) { 2629 /* CHECKME: LCN_RL_NOT_MAPPED check isn't needed */ 2630 if (rl[i].lcn == LCN_HOLE || rl[i].lcn == LCN_RL_NOT_MAPPED) 2631 continue; 2632 2633 badclusters += rl[i].length; 2634 ntfs_log_verbose("Bad cluster: %#8llx - %#llx (%lld)\n", 2635 (long long)rl[i].lcn, 2636 (long long)rl[i].lcn + rl[i].length - 1, 2637 (long long)rl[i].length); 2638 } 2639 2640 if (badclusters) { 2641 printf("%sThis software has detected that the disk has at least" 2642 " %lld bad sector%s.\n", 2643 !opt.badsectors ? NERR_PREFIX : "WARNING: ", 2644 (long long)badclusters, badclusters - 1 ? "s" : ""); 2645 if (!opt.badsectors) { 2646 printf("%s", bad_sectors_warning_msg); 2647 exit(1); 2648 } else 2649 printf("WARNING: Bad sectors can cause reliability " 2650 "problems and massive data loss!!!\n"); 2651 } 2652 2653 ntfs_attr_close(na); 2654#if CLEAN_EXIT 2655 close_inode_and_context(ctx); 2656#else 2657 ntfs_attr_put_search_ctx(ctx); 2658#endif 2659 2660 return badclusters; 2661} 2662 2663/** 2664 * truncate_badclust_file 2665 * 2666 * Shrink the $BadClus file to match the new volume size. 2667 */ 2668static void truncate_badclust_file(ntfs_resize_t *resize) 2669{ 2670 printf("Updating $BadClust file ...\n"); 2671 2672 lookup_data_attr(resize->vol, FILE_BadClus, "$Bad", &resize->ctx); 2673 /* FIXME: sanity_check_attr(ctx->attr); */ 2674 resize->mref = FILE_BadClus; 2675 truncate_badclust_bad_attr(resize); 2676 2677 close_inode_and_context(resize->ctx); 2678} 2679 2680/** 2681 * truncate_bitmap_file 2682 * 2683 * Shrink the $Bitmap file to match the new volume size. 2684 */ 2685static void truncate_bitmap_file(ntfs_resize_t *resize) 2686{ 2687 ntfs_volume *vol = resize->vol; 2688 2689 printf("Updating $Bitmap file ...\n"); 2690 2691 lookup_data_attr(resize->vol, FILE_Bitmap, NULL, &resize->ctx); 2692 resize->mref = FILE_Bitmap; 2693 truncate_bitmap_data_attr(resize); 2694 2695 if (resize->new_mft_start) { 2696 s64 pos; 2697 2698 /* write the MFT record at its new location */ 2699 pos = (resize->new_mft_start->lcn << vol->cluster_size_bits) 2700 + (FILE_Bitmap << vol->mft_record_size_bits); 2701 if (!opt.ro_flag 2702 && (ntfs_mst_pwrite(vol->dev, pos, 1, 2703 vol->mft_record_size, resize->ctx->mrec) != 1)) 2704 perr_exit("Couldn't update $Bitmap at new location"); 2705 } else { 2706 if (write_mft_record(vol, resize->ctx->ntfs_ino->mft_no, 2707 resize->ctx->mrec)) 2708 perr_exit("Couldn't update $Bitmap"); 2709 } 2710 2711 /* If successful, update cache and sync $Bitmap */ 2712 memcpy(vol->lcnbmp_ni->mrec,resize->ctx->mrec,vol->mft_record_size); 2713 ntfs_inode_mark_dirty(vol->lcnbmp_ni); 2714 NInoFileNameSetDirty(vol->lcnbmp_ni); 2715 ntfs_inode_sync(vol->lcnbmp_ni); 2716 2717#if CLEAN_EXIT 2718 close_inode_and_context(resize->ctx); 2719#else 2720 ntfs_attr_put_search_ctx(resize->ctx); 2721#endif 2722} 2723 2724/** 2725 * setup_lcn_bitmap 2726 * 2727 * Allocate a block of memory with one bit for each cluster of the disk. 2728 * All the bits are set to 0, except those representing the region beyond the 2729 * end of the disk. 2730 */ 2731static int setup_lcn_bitmap(struct bitmap *bm, s64 nr_clusters) 2732{ 2733 /* Determine lcn bitmap byte size and allocate it. */ 2734 bm->size = rounded_up_division(nr_clusters, 8); 2735 2736 bm->bm = ntfs_calloc(bm->size); 2737 if (!bm->bm) 2738 return -1; 2739 2740 bitmap_file_data_fixup(nr_clusters, bm); 2741 return 0; 2742} 2743 2744/** 2745 * update_bootsector 2746 * 2747 * FIXME: should be done using ntfs_* functions 2748 */ 2749static void update_bootsector(ntfs_resize_t *r) 2750{ 2751 NTFS_BOOT_SECTOR *bs; 2752 ntfs_volume *vol = r->vol; 2753 s64 bs_size = vol->sector_size; 2754 2755 printf("Updating Boot record ...\n"); 2756 2757 bs = (NTFS_BOOT_SECTOR*)ntfs_malloc(vol->sector_size); 2758 if (!bs) 2759 perr_exit("ntfs_malloc"); 2760 2761 if (vol->dev->d_ops->seek(vol->dev, 0, SEEK_SET) == (off_t)-1) 2762 perr_exit("lseek"); 2763 2764 if (vol->dev->d_ops->read(vol->dev, bs, bs_size) == -1) 2765 perr_exit("read() error"); 2766 2767 if (bs->bpb.sectors_per_cluster > 128) 2768 bs->number_of_sectors = cpu_to_sle64(r->new_volume_size 2769 << (256 - bs->bpb.sectors_per_cluster)); 2770 else 2771 bs->number_of_sectors = cpu_to_sle64(r->new_volume_size * 2772 bs->bpb.sectors_per_cluster); 2773 2774 if (r->mftmir_old || (r->mirr_from == MIRR_MFT)) { 2775 r->progress.flags |= NTFS_PROGBAR_SUPPRESS; 2776 /* Be sure the MFTMirr holds the updated MFT runlist */ 2777 switch (r->mirr_from) { 2778 case MIRR_MFT : 2779 /* The late updates of MFT have not been synced */ 2780 ntfs_inode_sync(vol->mft_ni); 2781 copy_clusters(r, r->mftmir_rl.lcn, 2782 vol->mft_na->rl->lcn, r->mftmir_rl.length); 2783 break; 2784 case MIRR_NEWMFT : 2785 copy_clusters(r, r->mftmir_rl.lcn, 2786 r->new_mft_start->lcn, r->mftmir_rl.length); 2787 break; 2788 default : 2789 copy_clusters(r, r->mftmir_rl.lcn, r->mftmir_old, 2790 r->mftmir_rl.length); 2791 break; 2792 } 2793 if (r->mftmir_old) 2794 bs->mftmirr_lcn = cpu_to_sle64(r->mftmir_rl.lcn); 2795 r->progress.flags &= ~NTFS_PROGBAR_SUPPRESS; 2796 } 2797 /* Set the start of the relocated MFT */ 2798 if (r->new_mft_start) { 2799 bs->mft_lcn = cpu_to_sle64(r->new_mft_start->lcn); 2800 /* no more need for the new MFT start */ 2801 free(r->new_mft_start); 2802 r->new_mft_start = (runlist_element*)NULL; 2803 } 2804 2805 if (vol->dev->d_ops->seek(vol->dev, 0, SEEK_SET) == (off_t)-1) 2806 perr_exit("lseek"); 2807 2808 if (!opt.ro_flag) 2809 if (vol->dev->d_ops->write(vol->dev, bs, bs_size) == -1) 2810 perr_exit("write() error"); 2811 /* 2812 * Set the backup boot sector, if the target size is 2813 * either not defined or is defined with no multiplier 2814 * suffix and is a multiple of the sector size. 2815 * With these conditions we can be confident enough that 2816 * the partition size is already defined or it will be 2817 * later defined with the same exact value. 2818 */ 2819 if (!opt.ro_flag && opt.reliable_size 2820 && !(opt.bytes % vol->sector_size)) { 2821 if (vol->dev->d_ops->seek(vol->dev, opt.bytes 2822 - vol->sector_size, SEEK_SET) == (off_t)-1) 2823 perr_exit("lseek"); 2824 if (vol->dev->d_ops->write(vol->dev, bs, bs_size) == -1) 2825 perr_exit("write() error"); 2826 } 2827 free(bs); 2828} 2829 2830/** 2831 * vol_size 2832 */ 2833static s64 vol_size(ntfs_volume *v, s64 nr_clusters) 2834{ 2835 /* add one sector_size for the backup boot sector */ 2836 return nr_clusters * v->cluster_size + v->sector_size; 2837} 2838 2839/** 2840 * print_vol_size 2841 * 2842 * Print the volume size in bytes and decimal megabytes. 2843 */ 2844static void print_vol_size(const char *str, s64 bytes) 2845{ 2846 printf("%s: %lld bytes (%lld MB)\n", str, (long long)bytes, 2847 (long long)rounded_up_division(bytes, NTFS_MBYTE)); 2848} 2849 2850/** 2851 * print_disk_usage 2852 * 2853 * Display the amount of disk space in use. 2854 */ 2855static void print_disk_usage(ntfs_volume *vol, s64 nr_used_clusters) 2856{ 2857 s64 total, used; 2858 2859 total = vol->nr_clusters * vol->cluster_size; 2860 used = nr_used_clusters * vol->cluster_size; 2861 2862 /* WARNING: don't modify the text, external tools grep for it */ 2863 if (!opt.infombonly) { 2864 printf("Space in use : %lld MB (%.1f%%)\n", 2865 (long long)rounded_up_division(used, NTFS_MBYTE), 2866 100.0 * ((float)used / total)); 2867 } 2868} 2869 2870static void print_num_of_relocations(ntfs_resize_t *resize) 2871{ 2872 s64 relocations = resize->relocations * resize->vol->cluster_size; 2873 2874 printf("Needed relocations : %lld (%lld MB)\n", 2875 (long long)resize->relocations, (long long) 2876 rounded_up_division(relocations, NTFS_MBYTE)); 2877} 2878 2879static ntfs_volume *check_volume(void) 2880{ 2881 ntfs_volume *myvol = NULL; 2882 2883 /* 2884 * Pass NTFS_MNT_FORENSIC so that the mount process does not modify the 2885 * volume at all. We will do the logfile emptying and dirty setting 2886 * later if needed. 2887 */ 2888 if (!(myvol = ntfs_mount(opt.volume, opt.ro_flag | NTFS_MNT_FORENSIC))) 2889 { 2890 int err = errno; 2891 2892 perr_printf("Opening '%s' as NTFS failed", opt.volume); 2893 switch (err) { 2894 case EINVAL : 2895 printf(invalid_ntfs_msg, opt.volume); 2896 break; 2897 case EIO : 2898 printf("%s", corrupt_volume_msg); 2899 break; 2900 case EPERM : 2901 printf("%s", hibernated_volume_msg); 2902 break; 2903 case EOPNOTSUPP : 2904 printf("%s", unclean_journal_msg); 2905 break; 2906 case EBUSY : 2907 printf("%s", opened_volume_msg); 2908 break; 2909 default : 2910 break; 2911 } 2912 exit(1); 2913 } 2914 return myvol; 2915} 2916 2917 2918/** 2919 * mount_volume 2920 * 2921 * First perform some checks to determine if the volume is already mounted, or 2922 * is dirty (Windows wasn't shutdown properly). If everything is OK, then mount 2923 * the volume (load the metadata into memory). 2924 */ 2925static ntfs_volume *mount_volume(void) 2926{ 2927 unsigned long mntflag; 2928 ntfs_volume *vol = NULL; 2929 2930 if (ntfs_check_if_mounted(opt.volume, &mntflag)) { 2931 perr_printf("Failed to check '%s' mount state", opt.volume); 2932 printf("Probably /etc/mtab is missing. It's too risky to " 2933 "continue. You might try\nan another Linux distro.\n"); 2934 exit(1); 2935 } 2936 if (mntflag & NTFS_MF_MOUNTED) { 2937 if (!(mntflag & NTFS_MF_READONLY)) 2938 err_exit("Device '%s' is mounted read-write. " 2939 "You must 'umount' it first.\n", opt.volume); 2940 if (!opt.ro_flag) 2941 err_exit("Device '%s' is mounted. " 2942 "You must 'umount' it first.\n", opt.volume); 2943 } 2944 vol = check_volume(); 2945 2946 if (vol->flags & VOLUME_IS_DIRTY) 2947 if (opt.force-- <= 0) 2948 err_exit("Volume is scheduled for check.\nRun chkdsk /f" 2949 " and please try again, or see option -f.\n"); 2950 2951 if (NTFS_MAX_CLUSTER_SIZE < vol->cluster_size) 2952 err_exit("Cluster size %u is too large!\n", 2953 (unsigned int)vol->cluster_size); 2954 2955 if (ntfs_volume_get_free_space(vol)) 2956 err_exit("Failed to update the free space\n"); 2957 2958 if (!opt.infombonly) { 2959 printf("Device name : %s\n", opt.volume); 2960 printf("NTFS volume version: %d.%d\n", 2961 vol->major_ver, vol->minor_ver); 2962 } 2963 if (ntfs_version_is_supported(vol)) 2964 perr_exit("Unknown NTFS version"); 2965 2966 if (!opt.infombonly) { 2967 printf("Cluster size : %u bytes\n", 2968 (unsigned int)vol->cluster_size); 2969 print_vol_size("Current volume size", 2970 vol_size(vol, vol->nr_clusters)); 2971 } 2972 2973 return vol; 2974} 2975 2976/** 2977 * prepare_volume_fixup 2978 * 2979 * Set the volume's dirty flag and wipe the filesystem journal. When Windows 2980 * boots it will automatically run chkdsk to check for any problems. If the 2981 * read-only command line option was given, this function will do nothing. 2982 */ 2983static void prepare_volume_fixup(ntfs_volume *vol) 2984{ 2985 printf("Schedule chkdsk for NTFS consistency check at Windows boot " 2986 "time ...\n"); 2987 vol->flags |= VOLUME_IS_DIRTY; 2988 if (ntfs_volume_write_flags(vol, vol->flags)) 2989 perr_exit("Failed to set the volume dirty"); 2990 2991 /* Porting note: This flag does not exist in libntfs-3g. The dirty flag 2992 * is never modified by libntfs-3g on unmount and we set it above. We 2993 * can safely comment out this statement. */ 2994 /* NVolSetWasDirty(vol); */ 2995 2996 if (vol->dev->d_ops->sync(vol->dev) == -1) 2997 perr_exit("Failed to sync device"); 2998 printf("Resetting $LogFile ... (this might take a while)\n"); 2999 if (ntfs_logfile_reset(vol)) 3000 perr_exit("Failed to reset $LogFile"); 3001 if (vol->dev->d_ops->sync(vol->dev) == -1) 3002 perr_exit("Failed to sync device"); 3003} 3004 3005static void set_disk_usage_constraint(ntfs_resize_t *resize) 3006{ 3007 /* last lcn for a filled up volume (no empty space) */ 3008 s64 last = resize->inuse - 1; 3009 3010 if (resize->last_unsupp < last) 3011 resize->last_unsupp = last; 3012} 3013 3014static void check_resize_constraints(ntfs_resize_t *resize) 3015{ 3016 s64 new_size = resize->new_volume_size; 3017 3018 /* FIXME: resize.shrink true also if only -i is used */ 3019 if (!resize->shrink) 3020 return; 3021 3022 if (resize->inuse == resize->vol->nr_clusters) 3023 err_exit("Volume is full. To shrink it, " 3024 "delete unused files.\n"); 3025 3026 if (opt.info || opt.infombonly) 3027 return; 3028 3029 /* FIXME: reserve some extra space so Windows can boot ... */ 3030 if (new_size < resize->inuse) 3031 err_exit("New size can't be less than the space already" 3032 " occupied by data.\nYou either need to delete unused" 3033 " files or see the -i option.\n"); 3034 3035 if (new_size <= resize->last_unsupp) 3036 err_exit("The fragmentation type, you have, isn't " 3037 "supported yet. Rerun ntfsresize\nwith " 3038 "the -i option to estimate the smallest " 3039 "shrunken volume size supported.\n"); 3040 3041 print_num_of_relocations(resize); 3042} 3043 3044static void check_cluster_allocation(ntfs_volume *vol, ntfsck_t *fsck) 3045{ 3046 memset(fsck, 0, sizeof(ntfsck_t)); 3047 3048 if (opt.show_progress) 3049 fsck->flags |= NTFSCK_PROGBAR; 3050 3051 if (setup_lcn_bitmap(&fsck->lcn_bitmap, vol->nr_clusters) != 0) 3052 perr_exit("Failed to setup allocation bitmap"); 3053 if (build_allocation_bitmap(vol, fsck) != 0) 3054 exit(1); 3055 if (fsck->outsider || fsck->multi_ref) { 3056 err_printf("Filesystem check failed!\n"); 3057 if (fsck->outsider) 3058 err_printf("%d clusters are referenced outside " 3059 "of the volume.\n", fsck->outsider); 3060 if (fsck->multi_ref) 3061 err_printf("%d clusters are referenced multiple" 3062 " times.\n", fsck->multi_ref); 3063 printf("%s", corrupt_volume_msg); 3064 exit(1); 3065 } 3066 3067 compare_bitmaps(vol, &fsck->lcn_bitmap); 3068} 3069 3070/* 3071 * Following are functions to expand an NTFS file system 3072 * to the beginning of a partition. The old metadata can be 3073 * located according to the backup bootsector, provided it can 3074 * still be found at the end of the partition. 3075 * 3076 * The data itself is kept in place, and this is only possible 3077 * if the expanded size is a multiple of cluster size, and big 3078 * enough to hold the new $Boot, $Bitmap and $MFT 3079 * 3080 * The volume cannot be mounted because the layout of data does 3081 * not match the volume parameters. The alignments of MFT entries 3082 * and index blocks may be different in the new volume and the old 3083 * one. The "ntfs_volume" structure is only partially usable, 3084 * "ntfs_inode" and "search_context" cannot be used until the 3085 * metadata has been moved and the volume is opened. 3086 * 3087 * Currently, no part of this new code is called from old code, 3088 * and the only change in old code is the processing of options. 3089 * Deduplication of code should be done later when the code is 3090 * proved safe. 3091 * 3092 */ 3093 3094typedef struct EXPAND { 3095 ntfs_volume *vol; 3096 u64 original_sectors; 3097 u64 new_sectors; 3098 u64 bitmap_allocated; 3099 u64 bitmap_size; 3100 u64 boot_size; 3101 u64 mft_size; 3102 LCN mft_lcn; 3103 s64 byte_increment; 3104 s64 sector_increment; 3105 s64 cluster_increment; 3106 u8 *bitmap; 3107 u8 *mft_bitmap; 3108 char *bootsector; 3109 MFT_RECORD *mrec; 3110 struct progress_bar *progress; 3111 struct DELAYED *delayed_runlists; /* runlists to process later */ 3112} expand_t; 3113 3114/* 3115 * Locate an attribute in an MFT record 3116 * 3117 * Returns NULL if not found (with no error message) 3118 */ 3119 3120static ATTR_RECORD *find_attr(MFT_RECORD *mrec, ATTR_TYPES type, 3121 ntfschar *name, int namelen) 3122{ 3123 ATTR_RECORD *a; 3124 u32 offset; 3125 ntfschar *attrname; 3126 3127 /* fetch the requested attribute */ 3128 offset = le16_to_cpu(mrec->attrs_offset); 3129 a = (ATTR_RECORD*)((char*)mrec + offset); 3130 attrname = (ntfschar*)((char*)a + le16_to_cpu(a->name_offset)); 3131 while ((a->type != AT_END) 3132 && ((a->type != type) 3133 || (a->name_length != namelen) 3134 || (namelen && memcmp(attrname,name,2*namelen))) 3135 && (offset < le32_to_cpu(mrec->bytes_in_use))) { 3136 offset += le32_to_cpu(a->length); 3137 a = (ATTR_RECORD*)((char*)mrec + offset); 3138 if (namelen) 3139 attrname = (ntfschar*)((char*)a 3140 + le16_to_cpu(a->name_offset)); 3141 } 3142 if ((a->type != type) 3143 || (a->name_length != namelen) 3144 || (namelen && memcmp(attrname,name,2*namelen))) 3145 a = (ATTR_RECORD*)NULL; 3146 return (a); 3147} 3148 3149/* 3150 * Read an MFT record and find an unnamed attribute 3151 * 3152 * Returns NULL if fails to read or attribute is not found 3153 */ 3154 3155static ATTR_RECORD *get_unnamed_attr(expand_t *expand, ATTR_TYPES type, 3156 s64 inum) 3157{ 3158 ntfs_volume *vol; 3159 ATTR_RECORD *a; 3160 MFT_RECORD *mrec; 3161 s64 pos; 3162 BOOL found; 3163 int got; 3164 3165 found = FALSE; 3166 a = (ATTR_RECORD*)NULL; 3167 mrec = expand->mrec; 3168 vol = expand->vol; 3169 pos = (vol->mft_lcn << vol->cluster_size_bits) 3170 + (inum << vol->mft_record_size_bits) 3171 + expand->byte_increment; 3172 got = ntfs_mst_pread(vol->dev, pos, 1, vol->mft_record_size, mrec); 3173 if ((got == 1) && (mrec->flags & MFT_RECORD_IN_USE)) { 3174 a = find_attr(expand->mrec, type, NULL, 0); 3175 found = a && (a->type == type) && !a->name_length; 3176 } 3177 /* not finding the attribute list is not an error */ 3178 if (!found && (type != AT_ATTRIBUTE_LIST)) { 3179 err_printf("Could not find attribute 0x%lx in inode %lld\n", 3180 (long)le32_to_cpu(type), (long long)inum); 3181 a = (ATTR_RECORD*)NULL; 3182 } 3183 return (a); 3184} 3185 3186/* 3187 * Read an MFT record and find an unnamed attribute 3188 * 3189 * Returns NULL if fails 3190 */ 3191 3192static ATTR_RECORD *read_and_get_attr(expand_t *expand, ATTR_TYPES type, 3193 s64 inum, ntfschar *name, int namelen) 3194{ 3195 ntfs_volume *vol; 3196 ATTR_RECORD *a; 3197 MFT_RECORD *mrec; 3198 s64 pos; 3199 int got; 3200 3201 a = (ATTR_RECORD*)NULL; 3202 mrec = expand->mrec; 3203 vol = expand->vol; 3204 pos = (vol->mft_lcn << vol->cluster_size_bits) 3205 + (inum << vol->mft_record_size_bits) 3206 + expand->byte_increment; 3207 got = ntfs_mst_pread(vol->dev, pos, 1, vol->mft_record_size, mrec); 3208 if ((got == 1) && (mrec->flags & MFT_RECORD_IN_USE)) { 3209 a = find_attr(expand->mrec, type, name, namelen); 3210 } 3211 if (!a) { 3212 err_printf("Could not find attribute 0x%lx in inode %lld\n", 3213 (long)le32_to_cpu(type), (long long)inum); 3214 } 3215 return (a); 3216} 3217 3218/* 3219 * Get the size allocated to the unnamed data of some inode 3220 * 3221 * Returns zero if fails. 3222 */ 3223 3224static s64 get_data_size(expand_t *expand, s64 inum) 3225{ 3226 ATTR_RECORD *a; 3227 s64 size; 3228 3229 size = 0; 3230 /* get the size of unnamed $DATA */ 3231 a = get_unnamed_attr(expand, AT_DATA, inum); 3232 if (a && a->non_resident) 3233 size = sle64_to_cpu(a->allocated_size); 3234 if (!size) { 3235 err_printf("Bad record %lld, could not get its size\n", 3236 (long long)inum); 3237 } 3238 return (size); 3239} 3240 3241/* 3242 * Get the MFT bitmap 3243 * 3244 * Returns NULL if fails. 3245 */ 3246 3247static u8 *get_mft_bitmap(expand_t *expand) 3248{ 3249 ATTR_RECORD *a; 3250 ntfs_volume *vol; 3251 runlist_element *rl; 3252 runlist_element *prl; 3253 u32 bitmap_size; 3254 BOOL ok; 3255 3256 expand->mft_bitmap = (u8*)NULL; 3257 vol = expand->vol; 3258 /* get the runlist of unnamed bitmap */ 3259 a = get_unnamed_attr(expand, AT_BITMAP, FILE_MFT); 3260 ok = TRUE; 3261 bitmap_size = sle64_to_cpu(a->allocated_size); 3262 if (a 3263 && a->non_resident 3264 && ((bitmap_size << (vol->mft_record_size_bits + 3)) 3265 >= expand->mft_size)) { 3266// rl in extent not implemented 3267 rl = ntfs_mapping_pairs_decompress(expand->vol, a, 3268 (runlist_element*)NULL); 3269 expand->mft_bitmap = (u8*)ntfs_calloc(bitmap_size); 3270 if (rl && expand->mft_bitmap) { 3271 for (prl=rl; prl->length && ok; prl++) { 3272 lseek_to_cluster(vol, 3273 prl->lcn + expand->cluster_increment); 3274 ok = !read_all(vol->dev, expand->mft_bitmap 3275 + (prl->vcn << vol->cluster_size_bits), 3276 prl->length << vol->cluster_size_bits); 3277 } 3278 if (!ok) { 3279 err_printf("Could not read the MFT bitmap\n"); 3280 free(expand->mft_bitmap); 3281 expand->mft_bitmap = (u8*)NULL; 3282 } 3283 free(rl); 3284 } else { 3285 err_printf("Could not get the MFT bitmap\n"); 3286 } 3287 } else 3288 err_printf("Invalid MFT bitmap\n"); 3289 return (expand->mft_bitmap); 3290} 3291 3292/* 3293 * Check for bad sectors 3294 * 3295 * Deduplication to be done when proved safe 3296 */ 3297 3298static int check_expand_bad_sectors(expand_t *expand, ATTR_RECORD *a) 3299{ 3300 runlist *rl; 3301 int res; 3302 s64 i, badclusters = 0; 3303 3304 res = 0; 3305 ntfs_log_verbose("Checking for bad sectors ...\n"); 3306 3307 if (find_attr(expand->mrec, AT_ATTRIBUTE_LIST, NULL, 0)) { 3308 err_printf("Hopelessly many bad sectors have been detected!\n"); 3309 err_printf("%s", many_bad_sectors_msg); 3310 res = -1; 3311 } else { 3312 3313 /* 3314 * FIXME: The below would be partial for non-base records in the 3315 * not yet supported multi-record case. Alternatively use audited 3316 * ntfs_attr_truncate after an umount & mount. 3317 */ 3318 rl = ntfs_mapping_pairs_decompress(expand->vol, a, NULL); 3319 if (!rl) { 3320 perr_printf("Decompressing $BadClust:" 3321 "$Bad mapping pairs failed"); 3322 res = -1; 3323 } else { 3324 for (i = 0; rl[i].length; i++) { 3325 /* CHECKME: LCN_RL_NOT_MAPPED check isn't needed */ 3326 if (rl[i].lcn == LCN_HOLE 3327 || rl[i].lcn == LCN_RL_NOT_MAPPED) 3328 continue; 3329 3330 badclusters += rl[i].length; 3331 ntfs_log_verbose("Bad cluster: %#8llx - %#llx" 3332 " (%lld)\n", 3333 (long long)rl[i].lcn, 3334 (long long)rl[i].lcn 3335 + rl[i].length - 1, 3336 (long long)rl[i].length); 3337 } 3338 3339 if (badclusters) { 3340 err_printf("%sThis software has detected that" 3341 " the disk has at least" 3342 " %lld bad sector%s.\n", 3343 !opt.badsectors ? NERR_PREFIX 3344 : "WARNING: ", 3345 (long long)badclusters, 3346 badclusters - 1 ? "s" : ""); 3347 if (!opt.badsectors) { 3348 err_printf("%s", bad_sectors_warning_msg); 3349 res = -1; 3350 } else 3351 err_printf("WARNING: Bad sectors can cause" 3352 " reliability problems" 3353 " and massive data loss!!!\n"); 3354 } 3355 free(rl); 3356 } 3357 } 3358 return (res); 3359} 3360 3361/* 3362 * Check miscellaneous expansion constraints 3363 */ 3364 3365static int check_expand_constraints(expand_t *expand) 3366{ 3367 static ntfschar bad[] = { 3368 const_cpu_to_le16('$'), const_cpu_to_le16('B'), 3369 const_cpu_to_le16('a'), const_cpu_to_le16('d') 3370 } ; 3371 ATTR_RECORD *a; 3372 runlist_element *rl; 3373 VOLUME_INFORMATION *volinfo; 3374 VOLUME_FLAGS flags; 3375 int res; 3376 3377 if (opt.verbose) 3378 ntfs_log_verbose("Checking for expansion constraints...\n"); 3379 res = 0; 3380 /* extents for $MFT are not supported */ 3381 if (get_unnamed_attr(expand, AT_ATTRIBUTE_LIST, FILE_MFT)) { 3382 err_printf("The $MFT is too much fragmented\n"); 3383 res = -1; 3384 } 3385 /* fragmented $MFTMirr is not supported */ 3386 a = get_unnamed_attr(expand, AT_DATA, FILE_MFTMirr); 3387 if (a) { 3388 rl = ntfs_mapping_pairs_decompress(expand->vol, a, NULL); 3389 if (!rl || !rl[0].length || rl[1].length) { 3390 err_printf("$MFTMirr is bad or fragmented\n"); 3391 res = -1; 3392 } 3393 free(rl); 3394 } 3395 /* fragmented $Boot is not supported */ 3396 a = get_unnamed_attr(expand, AT_DATA, FILE_Boot); 3397 if (a) { 3398 rl = ntfs_mapping_pairs_decompress(expand->vol, a, NULL); 3399 if (!rl || !rl[0].length || rl[1].length) { 3400 err_printf("$Boot is bad or fragmented\n"); 3401 res = -1; 3402 } 3403 free(rl); 3404 } 3405 /* Volume should not be marked dirty */ 3406 a = get_unnamed_attr(expand, AT_VOLUME_INFORMATION, FILE_Volume); 3407 if (a) { 3408 volinfo = (VOLUME_INFORMATION*) 3409 (le16_to_cpu(a->value_offset) + (char*)a); 3410 flags = volinfo->flags; 3411 if ((flags & VOLUME_IS_DIRTY) && (opt.force-- <= 0)) { 3412 err_printf("Volume is scheduled for check.\nRun chkdsk /f" 3413 " and please try again, or see option -f.\n"); 3414 res = -1; 3415 } 3416 } else { 3417 err_printf("Could not get Volume flags\n"); 3418 res = -1; 3419 } 3420 3421 /* There should not be too many bad clusters */ 3422 a = read_and_get_attr(expand, AT_DATA, FILE_BadClus, bad, 4); 3423 if (!a || !a->non_resident) { 3424 err_printf("Resident attribute in $BadClust! Please report to " 3425 "%s\n", NTFS_DEV_LIST); 3426 res = -1; 3427 } else 3428 if (check_expand_bad_sectors(expand,a)) 3429 res = -1; 3430 return (res); 3431} 3432 3433/* 3434 * Compute the new sizes and check whether the NTFS file 3435 * system can be expanded 3436 * 3437 * The partition has to have been expanded, 3438 * the extra space must be able to hold the $MFT, $Boot, and $Bitmap 3439 * the extra space must be a multiple of cluster size 3440 * 3441 * Returns TRUE if the partition can be expanded, 3442 * FALSE if it canno be expanded or option --info was set 3443 */ 3444 3445static BOOL can_expand(expand_t *expand, ntfs_volume *vol) 3446{ 3447 s64 old_sector_count; 3448 s64 sectors_needed; 3449 s64 clusters; 3450 s64 minimum_size; 3451 s64 got; 3452 s64 advice; 3453 s64 bitmap_bits; 3454 BOOL ok; 3455 3456 ok = TRUE; 3457 old_sector_count = vol->nr_clusters 3458 << (vol->cluster_size_bits - vol->sector_size_bits); 3459 /* do not include the space lost near the end */ 3460 expand->cluster_increment = (expand->new_sectors 3461 >> (vol->cluster_size_bits - vol->sector_size_bits)) 3462 - vol->nr_clusters; 3463 expand->byte_increment = expand->cluster_increment 3464 << vol->cluster_size_bits; 3465 expand->sector_increment = expand->byte_increment 3466 >> vol->sector_size_bits; 3467 printf("Sectors allocated to volume : old %lld current %lld difference %lld\n", 3468 (long long)old_sector_count, 3469 (long long)(old_sector_count + expand->sector_increment), 3470 (long long)expand->sector_increment); 3471 printf("Clusters allocated to volume : old %lld current %lld difference %lld\n", 3472 (long long)vol->nr_clusters, 3473 (long long)(vol->nr_clusters 3474 + expand->cluster_increment), 3475 (long long)expand->cluster_increment); 3476 /* the new size must be bigger */ 3477 if ((expand->sector_increment < 0) 3478 || (!expand->sector_increment && !opt.info)) { 3479 err_printf("Cannot expand volume : the partition has not been expanded\n"); 3480 ok = FALSE; 3481 } 3482 /* the old bootsector must match the backup */ 3483 got = ntfs_pread(expand->vol->dev, expand->byte_increment, 3484 vol->sector_size, expand->mrec); 3485 if ((got != vol->sector_size) 3486 || memcmp(expand->bootsector,expand->mrec,vol->sector_size)) { 3487 err_printf("The backup bootsector does not match the old bootsector\n"); 3488 ok = FALSE; 3489 } 3490 if (ok) { 3491 /* read the first MFT record, to get the MFT size */ 3492 expand->mft_size = get_data_size(expand, FILE_MFT); 3493 /* read the 6th MFT record, to get the $Boot size */ 3494 expand->boot_size = get_data_size(expand, FILE_Boot); 3495 if (!expand->mft_size || !expand->boot_size) { 3496 ok = FALSE; 3497 } else { 3498 /* 3499 * The bitmap is one bit per full cluster, 3500 * accounting for the backup bootsector. 3501 * When evaluating the minimal size, the bitmap 3502 * size must be adapted to the minimal size : 3503 * bits = clusters + ceil(clusters/clustersize) 3504 */ 3505 if (opt.info) { 3506 clusters = (((expand->original_sectors + 1) 3507 << vol->sector_size_bits) 3508 + expand->mft_size 3509 + expand->boot_size) 3510 >> vol->cluster_size_bits; 3511 bitmap_bits = ((clusters + 1) 3512 << vol->cluster_size_bits) 3513 / (vol->cluster_size + 1); 3514 } else { 3515 bitmap_bits = (expand->new_sectors + 1) 3516 >> (vol->cluster_size_bits 3517 - vol->sector_size_bits); 3518 } 3519 /* byte size must be a multiple of 8 */ 3520 expand->bitmap_size = ((bitmap_bits + 63) >> 3) & -8; 3521 expand->bitmap_allocated = ((expand->bitmap_size - 1) 3522 | (vol->cluster_size - 1)) + 1; 3523 expand->mft_lcn = (expand->boot_size 3524 + expand->bitmap_allocated) 3525 >> vol->cluster_size_bits; 3526 /* 3527 * Check whether $Boot, $Bitmap and $MFT can fit 3528 * into the expanded space. 3529 */ 3530 sectors_needed = (expand->boot_size + expand->mft_size 3531 + expand->bitmap_allocated) 3532 >> vol->sector_size_bits; 3533 if (!opt.info 3534 && (sectors_needed >= expand->sector_increment)) { 3535 err_printf("The expanded space cannot hold the new metadata\n"); 3536 err_printf(" expanded space %lld sectors\n", 3537 (long long)expand->sector_increment); 3538 err_printf(" needed space %lld sectors\n", 3539 (long long)sectors_needed); 3540 ok = FALSE; 3541 } 3542 } 3543 } 3544 if (ok) { 3545 advice = expand->byte_increment; 3546 /* the increment must be an integral number of clusters */ 3547 if (expand->byte_increment & (vol->cluster_size - 1)) { 3548 err_printf("Cannot expand volume without copying the data :\n"); 3549 err_printf("There are %d sectors in a cluster,\n", 3550 (int)(vol->cluster_size/vol->sector_size)); 3551 err_printf(" and the sector difference is not a multiple of %d\n", 3552 (int)(vol->cluster_size/vol->sector_size)); 3553 advice = expand->byte_increment & ~vol->cluster_size; 3554 ok = FALSE; 3555 } 3556 if (!ok) 3557 err_printf("You should increase the beginning of partition by %d sectors\n", 3558 (int)((expand->byte_increment - advice) 3559 >> vol->sector_size_bits)); 3560 } 3561 if (ok) 3562 ok = !check_expand_constraints(expand); 3563 if (ok && opt.info) { 3564 minimum_size = (expand->original_sectors 3565 << vol->sector_size_bits) 3566 + expand->boot_size 3567 + expand->mft_size 3568 + expand->bitmap_allocated; 3569 3570 printf("You must expand the partition to at least %lld bytes,\n", 3571 (long long)(minimum_size + vol->sector_size)); 3572 printf("and you may add a multiple of %ld bytes to this size.\n", 3573 (long)vol->cluster_size); 3574 printf("The minimum NTFS volume size is %lld bytes\n", 3575 (long long)minimum_size); 3576 ok = FALSE; 3577 } 3578 return (ok); 3579} 3580 3581static int set_bitmap(expand_t *expand, runlist_element *rl) 3582{ 3583 int res; 3584 s64 lcn; 3585 s64 lcn_end; 3586 BOOL reallocated; 3587 3588 res = -1; 3589 reallocated = FALSE; 3590 if ((rl->lcn >= 0) 3591 && (rl->length > 0) 3592 && ((rl->lcn + rl->length) 3593 <= (expand->vol->nr_clusters + expand->cluster_increment))) { 3594 lcn = rl->lcn; 3595 lcn_end = lcn + rl->length; 3596 while ((lcn & 7) && (lcn < lcn_end)) { 3597 if (expand->bitmap[lcn >> 3] & 1 << (lcn & 7)) 3598 reallocated = TRUE; 3599 expand->bitmap[lcn >> 3] |= 1 << (lcn & 7); 3600 lcn++; 3601 } 3602 while ((lcn_end - lcn) >= 8) { 3603 if (expand->bitmap[lcn >> 3]) 3604 reallocated = TRUE; 3605 expand->bitmap[lcn >> 3] = 255; 3606 lcn += 8; 3607 } 3608 while (lcn < lcn_end) { 3609 if (expand->bitmap[lcn >> 3] & 1 << (lcn & 7)) 3610 reallocated = TRUE; 3611 expand->bitmap[lcn >> 3] |= 1 << (lcn & 7); 3612 lcn++; 3613 } 3614 if (reallocated) 3615 err_printf("Reallocated cluster found in run" 3616 " lcn 0x%llx length %lld\n", 3617 (long long)rl->lcn,(long long)rl->length); 3618 else 3619 res = 0; 3620 } else { 3621 err_printf("Bad run : lcn 0x%llx length %lld\n", 3622 (long long)rl->lcn,(long long)rl->length); 3623 } 3624 return (res); 3625} 3626 3627/* 3628 * Write the backup bootsector 3629 * 3630 * When this has been done, the resizing cannot be done again 3631 */ 3632 3633static int write_bootsector(expand_t *expand) 3634{ 3635 ntfs_volume *vol; 3636 s64 bw; 3637 int res; 3638 3639 res = -1; 3640 vol = expand->vol; 3641 if (opt.verbose) 3642 ntfs_log_verbose("Rewriting the backup bootsector\n"); 3643 if (opt.ro_flag) 3644 bw = vol->sector_size; 3645 else 3646 bw = ntfs_pwrite(vol->dev, 3647 expand->new_sectors*vol->sector_size, 3648 vol->sector_size, expand->bootsector); 3649 if (bw == vol->sector_size) 3650 res = 0; 3651 else { 3652 if (bw != -1) 3653 errno = EINVAL; 3654 if (!bw) 3655 err_printf("Failed to rewrite the bootsector (size=0)\n"); 3656 else 3657 err_printf("Error rewriting the bootsector"); 3658 } 3659 return (res); 3660} 3661 3662/* 3663 * Write the new main bitmap 3664 */ 3665 3666static int write_bitmap(expand_t *expand) 3667{ 3668 ntfs_volume *vol; 3669 s64 bw; 3670 u64 cluster; 3671 int res; 3672 3673 res = -1; 3674 vol = expand->vol; 3675 cluster = vol->nr_clusters + expand->cluster_increment; 3676 while (cluster < (expand->bitmap_size << 3)) { 3677 expand->bitmap[cluster >> 3] |= 1 << (cluster & 7); 3678 cluster++; 3679 } 3680 if (opt.verbose) 3681 ntfs_log_verbose("Writing the new bitmap...\n"); 3682 /* write the full allocation (to avoid having to read) */ 3683 if (opt.ro_flag) 3684 bw = expand->bitmap_allocated; 3685 else 3686 bw = ntfs_pwrite(vol->dev, expand->boot_size, 3687 expand->bitmap_allocated, expand->bitmap); 3688 if (bw == (s64)expand->bitmap_allocated) 3689 res = 0; 3690 else { 3691 if (bw != -1) 3692 errno = EINVAL; 3693 if (!bw) 3694 err_printf("Failed to write the bitmap (size=0)\n"); 3695 else 3696 err_printf("Error rewriting the bitmap"); 3697 } 3698 return (res); 3699} 3700 3701/* 3702 * Copy the $MFT to $MFTMirr 3703 * 3704 * The $MFTMirr is not relocated as it should be kept away from $MFT. 3705 * Apart from the backup bootsector, this is the only part which is 3706 * overwritten. This has no effect on being able to redo the resizing 3707 * if something goes wrong, as the $MFTMirr is never read. However 3708 * this is done near the end of the resizing. 3709 */ 3710 3711static int copy_mftmirr(expand_t *expand) 3712{ 3713 ntfs_volume *vol; 3714 s64 pos; 3715 s64 inum; 3716 int res; 3717 u16 usa_ofs; 3718 le16 *pusn; 3719 u16 usn; 3720 3721 if (opt.verbose) 3722 ntfs_log_verbose("Copying $MFT to $MFTMirr...\n"); 3723 vol = expand->vol; 3724 res = 0; 3725 for (inum=FILE_MFT; !res && (inum<=FILE_Volume); inum++) { 3726 /* read the new $MFT */ 3727 pos = (expand->mft_lcn << vol->cluster_size_bits) 3728 + (inum << vol->mft_record_size_bits); 3729 if (ntfs_mst_pread(vol->dev, pos, 1, vol->mft_record_size, 3730 expand->mrec) == 1) { 3731 /* overwrite the old $MFTMirr */ 3732 pos = (vol->mftmirr_lcn << vol->cluster_size_bits) 3733 + (inum << vol->mft_record_size_bits) 3734 + expand->byte_increment; 3735 usa_ofs = le16_to_cpu(expand->mrec->usa_ofs); 3736 pusn = (le16*)((u8*)expand->mrec + usa_ofs); 3737 usn = le16_to_cpu(*pusn) - 1; 3738 if (!usn || (usn == 0xffff)) 3739 usn = -2; 3740 *pusn = cpu_to_le16(usn); 3741 if (!opt.ro_flag 3742 && (ntfs_mst_pwrite(vol->dev, pos, 1, 3743 vol->mft_record_size, expand->mrec) != 1)) { 3744 err_printf("Failed to overwrite the old $MFTMirr\n"); 3745 res = -1; 3746 } 3747 } else { 3748 err_printf("Failed to write the new $MFT\n"); 3749 res = -1; 3750 } 3751 } 3752 return (res); 3753} 3754 3755/* 3756 * Copy the $Boot, including the bootsector 3757 * 3758 * When the bootsector has been copied, repair tools are able to 3759 * fix things, but this is dangerous if the other metadata do 3760 * not point to actual user data. So this must be done near the end 3761 * of resizing. 3762 */ 3763 3764static int copy_boot(expand_t *expand) 3765{ 3766 NTFS_BOOT_SECTOR *bs; 3767 char *buf; 3768 ntfs_volume *vol; 3769 s64 mftmirr_lcn; 3770 s64 written; 3771 u32 boot_cnt; 3772 u32 hidden_sectors; 3773 le32 hidden_sectors_le; 3774 int res; 3775 3776 if (opt.verbose) 3777 ntfs_log_verbose("Copying $Boot...\n"); 3778 vol = expand->vol; 3779 res = 0; 3780 buf = (char*)ntfs_malloc(vol->cluster_size); 3781 if (buf) { 3782 /* set the new volume parameters in the bootsector */ 3783 bs = (NTFS_BOOT_SECTOR*)expand->bootsector; 3784 bs->number_of_sectors = cpu_to_sle64(expand->new_sectors); 3785 bs->mft_lcn = cpu_to_sle64(expand->mft_lcn); 3786 mftmirr_lcn = vol->mftmirr_lcn + expand->cluster_increment; 3787 bs->mftmirr_lcn = cpu_to_sle64(mftmirr_lcn); 3788 /* the hidden sectors are needed to boot into windows */ 3789 memcpy(&hidden_sectors_le,&bs->bpb.hidden_sectors,4); 3790 /* alignment messed up on the Sparc */ 3791 if (hidden_sectors_le) { 3792 hidden_sectors = le32_to_cpu(hidden_sectors_le); 3793 if (hidden_sectors >= expand->sector_increment) 3794 hidden_sectors -= expand->sector_increment; 3795 else 3796 hidden_sectors = 0; 3797 hidden_sectors_le = cpu_to_le32(hidden_sectors); 3798 memcpy(&bs->bpb.hidden_sectors,&hidden_sectors_le,4); 3799 } 3800 written = 0; 3801 boot_cnt = expand->boot_size >> vol->cluster_size_bits; 3802 while (!res && (written < boot_cnt)) { 3803 lseek_to_cluster(vol, expand->cluster_increment + written); 3804 if (!read_all(vol->dev, buf, vol->cluster_size)) { 3805 if (!written) 3806 memcpy(buf, expand->bootsector, vol->sector_size); 3807 lseek_to_cluster(vol, written); 3808 if (!opt.ro_flag 3809 && write_all(vol->dev, buf, vol->cluster_size)) { 3810 err_printf("Failed to write the new $Boot\n"); 3811 res = -1; 3812 } else 3813 written++; 3814 } else { 3815 err_printf("Failed to read the old $Boot\n"); 3816 res = -1; 3817 } 3818 } 3819 free(buf); 3820 } else { 3821 err_printf("Failed to allocate buffer\n"); 3822 res = -1; 3823 } 3824 return (res); 3825} 3826 3827/* 3828 * Process delayed runlist updates 3829 * 3830 * This is derived from delayed_updates() and they should 3831 * both be merged when the new code is considered safe. 3832 */ 3833 3834static void delayed_expand(ntfs_volume *vol, struct DELAYED *delayed, 3835 struct progress_bar *progress) 3836{ 3837 unsigned long count; 3838 struct DELAYED *current; 3839 int step = 100; 3840 3841 if (delayed) { 3842 if (opt.verbose) 3843 ntfs_log_verbose("Delayed updating of overflowing runlists...\n"); 3844 count = 0; 3845 /* count by steps because of inappropriate resolution */ 3846 for (current=delayed; current; current=current->next) 3847 count += step; 3848 progress_init(progress, 0, count, 3849 (opt.show_progress ? NTFS_PROGBAR : 0)); 3850 current = delayed; 3851 count = 0; 3852 while (current) { 3853 delayed = current; 3854 if (!opt.ro_flag) 3855 expand_attribute_runlist(vol, delayed); 3856 count += step; 3857 progress_update(progress, count); 3858 current = current->next; 3859 if (delayed->attr_name) 3860 free(delayed->attr_name); 3861 free(delayed->head_rl); 3862 free(delayed); 3863 } 3864 } 3865} 3866 3867/* 3868 * Expand the sizes in indexes for inodes which were expanded 3869 * 3870 * Only the new $Bitmap sizes are identified as needed to be 3871 * adjusted in index. The $BadClus is only expanded in an 3872 * alternate data stream, whose sizes are not present in the index. 3873 * 3874 * This is modifying the initial data, and can only be done when 3875 * the volume has been reopened after expanding. 3876 */ 3877 3878static int expand_index_sizes(expand_t *expand) 3879{ 3880 ntfs_inode *ni; 3881 int res; 3882 3883 res = -1; 3884 ni = ntfs_inode_open(expand->vol, FILE_Bitmap); 3885 if (ni) { 3886 NInoSetDirty(ni); 3887 NInoFileNameSetDirty(ni); 3888 ntfs_inode_close(ni); 3889 res = 0; 3890 } 3891 return (res); 3892} 3893 3894/* 3895 * Update a runlist into an attribute 3896 * 3897 * This is derived from replace_attribute_runlist() and they should 3898 * both be merged when the new code is considered safe. 3899 */ 3900 3901static int update_runlist(expand_t *expand, s64 inum, 3902 ATTR_RECORD *a, runlist_element *rl) 3903{ 3904 ntfs_resize_t resize; 3905 ntfs_attr_search_ctx ctx; 3906 ntfs_volume *vol; 3907 MFT_RECORD *mrec; 3908 runlist *head_rl; 3909 int mp_size; 3910 int l; 3911 int must_delay; 3912 void *mp; 3913 3914 vol = expand->vol; 3915 mrec = expand->mrec; 3916 head_rl = rl; 3917 rl_fixup(&rl); 3918 if ((mp_size = ntfs_get_size_for_mapping_pairs(vol, rl, 3919 0, INT_MAX)) == -1) 3920 perr_exit("ntfs_get_size_for_mapping_pairs"); 3921 3922 if (a->name_length) { 3923 u16 name_offs = le16_to_cpu(a->name_offset); 3924 u16 mp_offs = le16_to_cpu(a->mapping_pairs_offset); 3925 3926 if (name_offs >= mp_offs) 3927 err_exit("Attribute name is after mapping pairs! " 3928 "Please report!\n"); 3929 } 3930 3931 /* CHECKME: don't trust mapping_pairs is always the last item in the 3932 attribute, instead check for the real size/space */ 3933 l = (int)le32_to_cpu(a->length) - le16_to_cpu(a->mapping_pairs_offset); 3934 must_delay = 0; 3935 if (mp_size > l) { 3936 s32 remains_size; 3937 char *next_attr; 3938 3939 ntfs_log_verbose("Enlarging attribute header ...\n"); 3940 3941 mp_size = (mp_size + 7) & ~7; 3942 3943 ntfs_log_verbose("Old mp size : %d\n", l); 3944 ntfs_log_verbose("New mp size : %d\n", mp_size); 3945 ntfs_log_verbose("Bytes in use : %u\n", (unsigned int) 3946 le32_to_cpu(mrec->bytes_in_use)); 3947 3948 next_attr = (char *)a + le32_to_cpu(a->length); 3949 l = mp_size - l; 3950 3951 ntfs_log_verbose("Bytes in use new : %u\n", l + (unsigned int) 3952 le32_to_cpu(mrec->bytes_in_use)); 3953 ntfs_log_verbose("Bytes allocated : %u\n", (unsigned int) 3954 le32_to_cpu(mrec->bytes_allocated)); 3955 3956 remains_size = le32_to_cpu(mrec->bytes_in_use); 3957 remains_size -= (next_attr - (char *)mrec); 3958 3959 ntfs_log_verbose("increase : %d\n", l); 3960 ntfs_log_verbose("shift : %lld\n", 3961 (long long)remains_size); 3962 if (le32_to_cpu(mrec->bytes_in_use) + l > 3963 le32_to_cpu(mrec->bytes_allocated)) { 3964 ntfs_log_verbose("Queuing expansion for later processing\n"); 3965 /* hack for reusing unmodified old code ! */ 3966 resize.ctx = &ctx; 3967 ctx.attr = a; 3968 ctx.mrec = mrec; 3969 resize.mref = inum; 3970 resize.delayed_runlists = expand->delayed_runlists; 3971 resize.mirr_from = MIRR_OLD; 3972 must_delay = 1; 3973 replace_later(&resize,rl,head_rl); 3974 expand->delayed_runlists = resize.delayed_runlists; 3975 } else { 3976 memmove(next_attr + l, next_attr, remains_size); 3977 mrec->bytes_in_use = cpu_to_le32(l + 3978 le32_to_cpu(mrec->bytes_in_use)); 3979 a->length = cpu_to_le32(le32_to_cpu(a->length) + l); 3980 } 3981 } 3982 3983 if (!must_delay) { 3984 mp = ntfs_calloc(mp_size); 3985 if (!mp) 3986 perr_exit("ntfsc_calloc couldn't get memory"); 3987 3988 if (ntfs_mapping_pairs_build(vol, (u8*)mp, mp_size, rl, 0, NULL)) 3989 perr_exit("ntfs_mapping_pairs_build"); 3990 3991 memmove((u8*)a + le16_to_cpu(a->mapping_pairs_offset), mp, mp_size); 3992 3993 free(mp); 3994 } 3995 return (must_delay); 3996} 3997 3998/* 3999 * Create a minimal valid MFT record 4000 */ 4001 4002static int minimal_record(expand_t *expand, MFT_RECORD *mrec) 4003{ 4004 int usa_count; 4005 u32 bytes_in_use; 4006 4007 memset(mrec,0,expand->vol->mft_record_size); 4008 mrec->magic = magic_FILE; 4009 mrec->usa_ofs = const_cpu_to_le16(sizeof(MFT_RECORD)); 4010 usa_count = expand->vol->mft_record_size / NTFS_BLOCK_SIZE + 1; 4011 mrec->usa_count = cpu_to_le16(usa_count); 4012 bytes_in_use = (sizeof(MFT_RECORD) + 2*usa_count + 7) & -8; 4013 memset(((char*)mrec) + bytes_in_use, 255, 4); /* AT_END */ 4014 bytes_in_use += 8; 4015 mrec->bytes_in_use = cpu_to_le32(bytes_in_use); 4016 mrec->bytes_allocated = cpu_to_le32(expand->vol->mft_record_size); 4017 return (0); 4018} 4019 4020/* 4021 * Rebase all runlists of an MFT record 4022 * 4023 * Iterate through all its attributes and offset the non resident ones 4024 */ 4025 4026static int rebase_runlists(expand_t *expand, s64 inum) 4027{ 4028 MFT_RECORD *mrec; 4029 ATTR_RECORD *a; 4030 runlist_element *rl; 4031 runlist_element *prl; 4032 u32 offset; 4033 int res; 4034 4035 res = 0; 4036 mrec = expand->mrec; 4037 offset = le16_to_cpu(mrec->attrs_offset); 4038 a = (ATTR_RECORD*)((char*)mrec + offset); 4039 while (!res && (a->type != AT_END) 4040 && (offset < le32_to_cpu(mrec->bytes_in_use))) { 4041 if (a->non_resident) { 4042 rl = ntfs_mapping_pairs_decompress(expand->vol, a, 4043 (runlist_element*)NULL); 4044 if (rl) { 4045 for (prl=rl; prl->length; prl++) 4046 if (prl->lcn >= 0) { 4047 prl->lcn += expand->cluster_increment; 4048 if (set_bitmap(expand,prl)) 4049 res = -1; 4050 } 4051 if (update_runlist(expand,inum,a,rl)) { 4052 ntfs_log_verbose("Runlist updating has to be delayed\n"); 4053 } else 4054 free(rl); 4055 } else { 4056 err_printf("Could not get a runlist of inode %lld\n", 4057 (long long)inum); 4058 res = -1; 4059 } 4060 } 4061 offset += le32_to_cpu(a->length); 4062 a = (ATTR_RECORD*)((char*)mrec + offset); 4063 } 4064 return (res); 4065} 4066 4067/* 4068 * Rebase the runlists present in records with relocated $DATA 4069 * 4070 * The returned runlist is the old rebased runlist for $DATA, 4071 * which is generally different from the new computed runlist. 4072 */ 4073 4074static runlist_element *rebase_runlists_meta(expand_t *expand, s64 inum) 4075{ 4076 MFT_RECORD *mrec; 4077 ATTR_RECORD *a; 4078 ntfs_volume *vol; 4079 runlist_element *rl; 4080 runlist_element *old_rl; 4081 runlist_element *prl; 4082 runlist_element new_rl[2]; 4083 s64 data_size; 4084 s64 allocated_size; 4085 s64 lcn; 4086 u64 lth; 4087 u32 offset; 4088 BOOL keeprl; 4089 int res; 4090 4091 res = 0; 4092 old_rl = (runlist_element*)NULL; 4093 vol = expand->vol; 4094 mrec = expand->mrec; 4095 switch (inum) { 4096 case FILE_Boot : 4097 lcn = 0; 4098 lth = expand->boot_size >> vol->cluster_size_bits; 4099 data_size = expand->boot_size; 4100 break; 4101 case FILE_Bitmap : 4102 lcn = expand->boot_size >> vol->cluster_size_bits; 4103 lth = expand->bitmap_allocated >> vol->cluster_size_bits; 4104 data_size = expand->bitmap_size; 4105 break; 4106 case FILE_MFT : 4107 lcn = (expand->boot_size + expand->bitmap_allocated) 4108 >> vol->cluster_size_bits; 4109 lth = expand->mft_size >> vol->cluster_size_bits; 4110 data_size = expand->mft_size; 4111 break; 4112 case FILE_BadClus : 4113 lcn = 0; /* not used */ 4114 lth = vol->nr_clusters + expand->cluster_increment; 4115 data_size = lth << vol->cluster_size_bits; 4116 break; 4117 default : 4118 lcn = lth = data_size = 0; 4119 res = -1; 4120 } 4121 allocated_size = lth << vol->cluster_size_bits; 4122 offset = le16_to_cpu(mrec->attrs_offset); 4123 a = (ATTR_RECORD*)((char*)mrec + offset); 4124 while (!res && (a->type != AT_END) 4125 && (offset < le32_to_cpu(mrec->bytes_in_use))) { 4126 if (a->non_resident) { 4127 keeprl = FALSE; 4128 rl = ntfs_mapping_pairs_decompress(vol, a, 4129 (runlist_element*)NULL); 4130 if (rl) { 4131 /* rebase the old runlist */ 4132 for (prl=rl; prl->length; prl++) 4133 if (prl->lcn >= 0) { 4134 prl->lcn += expand->cluster_increment; 4135 if ((a->type != AT_DATA) 4136 && set_bitmap(expand,prl)) 4137 res = -1; 4138 } 4139 /* relocated unnamed data (not $BadClus) */ 4140 if ((a->type == AT_DATA) 4141 && !a->name_length 4142 && (inum != FILE_BadClus)) { 4143 old_rl = rl; 4144 rl = new_rl; 4145 keeprl = TRUE; 4146 rl[0].vcn = 0; 4147 rl[0].lcn = lcn; 4148 rl[0].length = lth; 4149 rl[1].vcn = lth; 4150 rl[1].lcn = LCN_ENOENT; 4151 rl[1].length = 0; 4152 if (set_bitmap(expand,rl)) 4153 res = -1; 4154 a->data_size = cpu_to_sle64(data_size); 4155 a->initialized_size = a->data_size; 4156 a->allocated_size 4157 = cpu_to_sle64(allocated_size); 4158 a->highest_vcn = cpu_to_sle64(lth - 1); 4159 } 4160 /* expand the named data for $BadClus */ 4161 if ((a->type == AT_DATA) 4162 && a->name_length 4163 && (inum == FILE_BadClus)) { 4164 old_rl = rl; 4165 keeprl = TRUE; 4166 prl = rl; 4167 if (prl->length) { 4168 while (prl[1].length) 4169 prl++; 4170 prl->length = lth - prl->vcn; 4171 prl[1].vcn = lth; 4172 } else 4173 prl->vcn = lth; 4174 a->data_size = cpu_to_sle64(data_size); 4175 /* do not change the initialized size */ 4176 a->allocated_size 4177 = cpu_to_sle64(allocated_size); 4178 a->highest_vcn = cpu_to_sle64(lth - 1); 4179 } 4180 if (!res && update_runlist(expand,inum,a,rl)) 4181 res = -1; 4182 if (!keeprl) 4183 free(rl); 4184 } else { 4185 err_printf("Could not get the data runlist of inode %lld\n", 4186 (long long)inum); 4187 res = -1; 4188 } 4189 } 4190 offset += le32_to_cpu(a->length); 4191 a = (ATTR_RECORD*)((char*)mrec + offset); 4192 } 4193 if (res && old_rl) { 4194 free(old_rl); 4195 old_rl = (runlist_element*)NULL; 4196 } 4197 return (old_rl); 4198} 4199 4200/* 4201 * Rebase all runlists in an MFT record 4202 * 4203 * Read from the old $MFT, rebase the runlists, 4204 * and write to the new $MFT 4205 */ 4206 4207static int rebase_inode(expand_t *expand, const runlist_element *prl, 4208 s64 inum, s64 jnum) 4209{ 4210 MFT_RECORD *mrec; 4211 runlist_element *rl; 4212 ntfs_volume *vol; 4213 s64 pos; 4214 int res; 4215 4216 res = 0; 4217 vol = expand->vol; 4218 mrec = expand->mrec; 4219 if (expand->mft_bitmap[inum >> 3] & (1 << (inum & 7))) { 4220 pos = (prl->lcn << vol->cluster_size_bits) 4221 + ((inum - jnum) << vol->mft_record_size_bits); 4222 if ((ntfs_mst_pread(vol->dev, pos, 1, 4223 vol->mft_record_size, mrec) == 1) 4224 && (mrec->flags & MFT_RECORD_IN_USE)) { 4225 switch (inum) { 4226 case FILE_Bitmap : 4227 case FILE_Boot : 4228 case FILE_BadClus : 4229 rl = rebase_runlists_meta(expand, inum); 4230 if (rl) 4231 free(rl); 4232 else 4233 res = -1; 4234 break; 4235 default : 4236 res = rebase_runlists(expand, inum); 4237 break; 4238 } 4239 } else { 4240 err_printf("Could not read the $MFT entry %lld\n", 4241 (long long)inum); 4242 res = -1; 4243 } 4244 } else { 4245 /* 4246 * Replace unused records (possibly uninitialized) 4247 * by minimal valid records, not marked in use 4248 */ 4249 res = minimal_record(expand,mrec); 4250 } 4251 if (!res) { 4252 pos = (expand->mft_lcn << vol->cluster_size_bits) 4253 + (inum << vol->mft_record_size_bits); 4254 if (opt.verbose) 4255 ntfs_log_verbose("Rebasing inode %lld cluster 0x%llx\n", 4256 (long long)inum, 4257 (long long)(pos >> vol->cluster_size_bits)); 4258 if (!opt.ro_flag 4259 && (ntfs_mst_pwrite(vol->dev, pos, 1, 4260 vol->mft_record_size, mrec) != 1)) { 4261 err_printf("Could not write the $MFT entry %lld\n", 4262 (long long)inum); 4263 res = -1; 4264 } 4265 } 4266 return (res); 4267} 4268 4269/* 4270 * Rebase all runlists 4271 * 4272 * First get the $MFT and define its location in the expanded space, 4273 * then rebase the other inodes and write them to the new $MFT 4274 */ 4275 4276static int rebase_all_inodes(expand_t *expand) 4277{ 4278 ntfs_volume *vol; 4279 MFT_RECORD *mrec; 4280 s64 inum; 4281 s64 jnum; 4282 s64 inodecnt; 4283 s64 pos; 4284 s64 got; 4285 int res; 4286 runlist_element *mft_rl; 4287 runlist_element *prl; 4288 4289 res = 0; 4290 mft_rl = (runlist_element*)NULL; 4291 vol = expand->vol; 4292 mrec = expand->mrec; 4293 inum = 0; 4294 pos = (vol->mft_lcn + expand->cluster_increment) 4295 << vol->cluster_size_bits; 4296 got = ntfs_mst_pread(vol->dev, pos, 1, 4297 vol->mft_record_size, mrec); 4298 if ((got == 1) && (mrec->flags & MFT_RECORD_IN_USE)) { 4299 pos = expand->mft_lcn << vol->cluster_size_bits; 4300 if (opt.verbose) 4301 ntfs_log_verbose("Rebasing inode %lld cluster 0x%llx\n", 4302 (long long)inum, 4303 (long long)(pos >> vol->cluster_size_bits)); 4304 mft_rl = rebase_runlists_meta(expand, FILE_MFT); 4305 if (!mft_rl 4306 || (!opt.ro_flag 4307 && (ntfs_mst_pwrite(vol->dev, pos, 1, 4308 vol->mft_record_size, mrec) != 1))) 4309 res = -1; 4310 else { 4311 for (prl=mft_rl; prl->length; prl++) { } 4312 inodecnt = (prl->vcn << vol->cluster_size_bits) 4313 >> vol->mft_record_size_bits; 4314 progress_init(expand->progress, 0, inodecnt, 4315 (opt.show_progress ? NTFS_PROGBAR : 0)); 4316 prl = mft_rl; 4317 jnum = 0; 4318 do { 4319 inum++; 4320 while (prl->length 4321 && ((inum << vol->mft_record_size_bits) 4322 >= ((prl->vcn + prl->length) 4323 << vol->cluster_size_bits))) { 4324 prl++; 4325 jnum = inum; 4326 } 4327 progress_update(expand->progress, inum); 4328 if (prl->length) { 4329 res = rebase_inode(expand, 4330 prl,inum,jnum); 4331 } 4332 } while (!res && prl->length); 4333 free(mft_rl); 4334 } 4335 } else { 4336 err_printf("Could not read the old $MFT\n"); 4337 res = -1; 4338 } 4339 return (res); 4340} 4341 4342 4343 4344/* 4345 * Get the old volume parameters from the backup bootsector 4346 * 4347 */ 4348 4349static ntfs_volume *get_volume_data(expand_t *expand, struct ntfs_device *dev, 4350 s32 sector_size) 4351{ 4352 s64 br; 4353 ntfs_volume *vol; 4354 le16 sector_size_le; 4355 NTFS_BOOT_SECTOR *bs; 4356 BOOL ok; 4357 4358 ok = FALSE; 4359 vol = (ntfs_volume*)ntfs_malloc(sizeof(ntfs_volume)); 4360 expand->bootsector = (char*)ntfs_malloc(sector_size); 4361 if (vol && expand->bootsector) { 4362 expand->vol = vol; 4363 vol->dev = dev; 4364 br = ntfs_pread(dev, expand->new_sectors*sector_size, 4365 sector_size, expand->bootsector); 4366 if (br != sector_size) { 4367 if (br != -1) 4368 errno = EINVAL; 4369 if (!br) 4370 err_printf("Failed to read the backup bootsector (size=0)\n"); 4371 else 4372 err_printf("Error reading the backup bootsector"); 4373 } else { 4374 bs = (NTFS_BOOT_SECTOR*)expand->bootsector; 4375 /* alignment problem on Sparc, even doing memcpy() */ 4376 sector_size_le = cpu_to_le16(sector_size); 4377 if (!memcmp(§or_size_le, 4378 &bs->bpb.bytes_per_sector,2) 4379 && ntfs_boot_sector_is_ntfs(bs) 4380 && !ntfs_boot_sector_parse(vol, bs)) { 4381 expand->original_sectors 4382 = sle64_to_cpu(bs->number_of_sectors); 4383 expand->mrec = (MFT_RECORD*) 4384 ntfs_malloc(vol->mft_record_size); 4385 if (expand->mrec 4386 && can_expand(expand,vol)) { 4387 ntfs_log_verbose("Resizing is possible\n"); 4388 ok = TRUE; 4389 } 4390 } else 4391 err_printf("Could not get the old volume parameters " 4392 "from the backup bootsector\n"); 4393 } 4394 if (!ok) { 4395 free(vol); 4396 free(expand->bootsector); 4397 } 4398 } 4399 return (ok ? vol : (ntfs_volume*)NULL); 4400} 4401 4402static int really_expand(expand_t *expand) 4403{ 4404 ntfs_volume *vol; 4405 struct ntfs_device *dev; 4406 int res; 4407 4408 res = -1; 4409 4410 expand->bitmap = (u8*)ntfs_calloc(expand->bitmap_allocated); 4411 if (expand->bitmap 4412 && get_mft_bitmap(expand)) { 4413 printf("\n*** WARNING ***\n\n"); 4414 printf("Expanding a volume is an experimental new feature\n"); 4415 if (!opt.ro_flag) 4416 printf("A first check with option -n is recommended\n"); 4417 printf("\nShould something go wrong during the actual" 4418 " resizing (power outage, etc.),\n"); 4419 printf("just restart the procedure, but DO NOT TRY to repair" 4420 " with chkdsk or similar,\n"); 4421 printf("until the resizing is over," 4422 " you would LOSE YOUR DATA !\n"); 4423 printf("\nYou have been warned !\n\n"); 4424 if (!opt.ro_flag && (opt.force-- <= 0)) 4425 proceed_question(); 4426 if (!rebase_all_inodes(expand) 4427 && !write_bitmap(expand) 4428 && !copy_mftmirr(expand) 4429 && !copy_boot(expand)) { 4430 free(expand->vol); 4431 expand->vol = (ntfs_volume*)NULL; 4432 free(expand->mft_bitmap); 4433 expand->mft_bitmap = (u8*)NULL; 4434 if (!opt.ro_flag) { 4435 /* the volume must be dirty, do not check */ 4436 opt.force++; 4437 vol = mount_volume(); 4438 if (vol) { 4439 dev = vol->dev; 4440 ntfs_log_verbose("Remounting the updated volume\n"); 4441 expand->vol = vol; 4442 ntfs_log_verbose("Delayed runlist updatings\n"); 4443 delayed_expand(vol, expand->delayed_runlists, 4444 expand->progress); 4445 expand->delayed_runlists 4446 = (struct DELAYED*)NULL; 4447 expand_index_sizes(expand); 4448 /* rewriting the backup bootsector, no return ticket now ! */ 4449 res = write_bootsector(expand); 4450 if (dev->d_ops->sync(dev) == -1) { 4451 printf("Could not sync\n"); 4452 res = -1; 4453 } 4454 ntfs_umount(vol,0); 4455 if (!res) 4456 printf("\nResizing completed successfully\n"); 4457 } 4458 } else { 4459 ntfs_log_verbose("Delayed runlist updatings\n"); 4460 delayed_expand(expand->vol, 4461 expand->delayed_runlists, 4462 expand->progress); 4463 expand->delayed_runlists 4464 = (struct DELAYED*)NULL; 4465 printf("\nAll checks have been completed successfully\n"); 4466 printf("Cannot check further in no-action mode\n"); 4467 } 4468 free(expand->bootsector); 4469 free(expand->mrec); 4470 } 4471 free(expand->bitmap); 4472 } else { 4473 err_printf("Failed to allocate memory\n"); 4474 } 4475 return (res); 4476} 4477 4478/* 4479 * Expand a volume to beginning of partition 4480 * 4481 * We rely on the backup bootsector to determine the original 4482 * volume size and metadata. 4483 */ 4484 4485static int expand_to_beginning(void) 4486{ 4487 expand_t expand; 4488 struct progress_bar progress; 4489 int ret; 4490 ntfs_volume *vol; 4491 struct ntfs_device *dev; 4492 int sector_size; 4493 s64 new_sectors; 4494 4495 ret = -1; 4496 dev = ntfs_device_alloc(opt.volume, 0, &ntfs_device_default_io_ops, 4497 NULL); 4498 if (dev) { 4499 if (!(*dev->d_ops->open)(dev, 4500 (opt.ro_flag ? O_RDONLY : O_RDWR))) { 4501 sector_size = ntfs_device_sector_size_get(dev); 4502 if (sector_size <= 0) { 4503 sector_size = 512; 4504 new_sectors = ntfs_device_size_get(dev, 4505 sector_size); 4506 if (!new_sectors) { 4507 sector_size = 4096; 4508 new_sectors = ntfs_device_size_get(dev, 4509 sector_size); 4510 } 4511 } else 4512 new_sectors = ntfs_device_size_get(dev, 4513 sector_size); 4514 if (new_sectors) { 4515 new_sectors--; /* last sector not counted */ 4516 expand.new_sectors = new_sectors; 4517 expand.progress = &progress; 4518 expand.delayed_runlists = (struct DELAYED*)NULL; 4519 vol = get_volume_data(&expand,dev,sector_size); 4520 if (vol) { 4521 expand.vol = vol; 4522 ret = really_expand(&expand); 4523 } 4524 } 4525 (*dev->d_ops->close)(dev); 4526 } else { 4527 err_exit("Couldn't open volume '%s'!\n", opt.volume); 4528 } 4529 ntfs_device_free(dev); 4530 } 4531 return (ret); 4532} 4533 4534 4535int main(int argc, char **argv) 4536{ 4537 ntfsck_t fsck; 4538 ntfs_resize_t resize; 4539 s64 new_size = 0; /* in clusters; 0 = --info w/o --size */ 4540 s64 device_size; /* in bytes */ 4541 ntfs_volume *vol = NULL; 4542 int res; 4543 4544 ntfs_log_set_handler(ntfs_log_handler_outerr); 4545 4546 printf("%s v%s (libntfs-3g)\n", EXEC_NAME, VERSION); 4547 4548 res = parse_options(argc, argv); 4549 if (res >= 0) 4550 return (res); 4551 4552 utils_set_locale(); 4553 4554 /* 4555 * If we're just checking the device, we'll do it first, 4556 * and exit out, no matter what we find. 4557 */ 4558 if (opt.check) { 4559 vol = check_volume(); 4560#if CLEAN_EXIT 4561 if (vol) 4562 ntfs_umount(vol,0); 4563#endif 4564 exit(0); 4565 } else { 4566 if (opt.expand) { 4567 /* 4568 * If we are to expand to beginning of partition, do 4569 * not try to mount : when merging two partitions, 4570 * the beginning of the partition would contain an 4571 * old filesystem which is not the one to expand. 4572 */ 4573 if (expand_to_beginning() && !opt.info) 4574 exit(1); 4575 return (0); 4576 } 4577 } 4578 4579 if (!(vol = mount_volume())) 4580 err_exit("Couldn't open volume '%s'!\n", opt.volume); 4581 4582 device_size = ntfs_device_size_get(vol->dev, vol->sector_size); 4583 device_size *= vol->sector_size; 4584 if (device_size <= 0) 4585 err_exit("Couldn't get device size (%lld)!\n", 4586 (long long)device_size); 4587 4588 if (!opt.infombonly) 4589 print_vol_size("Current device size", device_size); 4590 4591 if (device_size < vol->nr_clusters * vol->cluster_size) 4592 err_exit("Current NTFS volume size is bigger than the device " 4593 "size!\nCorrupt partition table or incorrect device " 4594 "partitioning?\n"); 4595 4596 if (!opt.bytes && !opt.info && !opt.infombonly) { 4597 opt.bytes = device_size; 4598 opt.reliable_size = 1; 4599 } 4600 4601 /* Backup boot sector at the end of device isn't counted in NTFS 4602 volume size thus we have to reserve space for it. */ 4603 if (opt.bytes > vol->sector_size) 4604 new_size = (opt.bytes - vol->sector_size) / vol->cluster_size; 4605 else 4606 new_size = 0; 4607 4608 if (!opt.info && !opt.infombonly) { 4609 print_vol_size("New volume size ", vol_size(vol, new_size)); 4610 if (device_size < opt.bytes) 4611 err_exit("New size can't be bigger than the device size" 4612 ".\nIf you want to enlarge NTFS then first " 4613 "enlarge the device size by e.g. fdisk.\n"); 4614 } 4615 4616 if (!opt.info && !opt.infombonly && (new_size == vol->nr_clusters || 4617 (opt.bytes == device_size && 4618 new_size == vol->nr_clusters - 1))) { 4619 printf("Nothing to do: NTFS volume size is already OK.\n"); 4620 exit(0); 4621 } 4622 4623 memset(&resize, 0, sizeof(resize)); 4624 resize.vol = vol; 4625 resize.new_volume_size = new_size; 4626 /* This is also true if --info was used w/o --size (new_size = 0) */ 4627 if (new_size < vol->nr_clusters) 4628 resize.shrink = 1; 4629 if (opt.show_progress) 4630 resize.progress.flags |= NTFS_PROGBAR; 4631 /* 4632 * Checking and __reporting__ of bad sectors must be done before cluster 4633 * allocation check because chkdsk doesn't fix $Bitmap's w/ bad sectors 4634 * thus users would (were) quite confused why chkdsk doesn't work. 4635 */ 4636 resize.badclusters = check_bad_sectors(vol); 4637 4638 NVolSetNoFixupWarn(vol); 4639 check_cluster_allocation(vol, &fsck); 4640 4641 print_disk_usage(vol, fsck.inuse); 4642 4643 resize.inuse = fsck.inuse; 4644 resize.lcn_bitmap = fsck.lcn_bitmap; 4645 resize.mirr_from = MIRR_OLD; 4646 4647 set_resize_constraints(&resize); 4648 set_disk_usage_constraint(&resize); 4649 check_resize_constraints(&resize); 4650 4651 if (opt.info || opt.infombonly) { 4652 advise_on_resize(&resize); 4653 exit(0); 4654 } 4655 4656 if (opt.force-- <= 0 && !opt.ro_flag) { 4657 printf("%s", resize_warning_msg); 4658 proceed_question(); 4659 } 4660 4661 /* FIXME: performance - relocate logfile here if it's needed */ 4662 prepare_volume_fixup(vol); 4663 4664 if (resize.relocations) 4665 relocate_inodes(&resize); 4666 4667 truncate_badclust_file(&resize); 4668 truncate_bitmap_file(&resize); 4669 delayed_updates(&resize); 4670 update_bootsector(&resize); 4671 4672 /* We don't create backup boot sector because we don't know where the 4673 partition will be split. The scheduled chkdsk will fix it */ 4674 4675 if (opt.ro_flag) { 4676 printf("The read-only test run ended successfully.\n"); 4677 exit(0); 4678 } 4679 4680 /* WARNING: don't modify the texts, external tools grep for them */ 4681 printf("Syncing device ...\n"); 4682 if (vol->dev->d_ops->sync(vol->dev) == -1) 4683 perr_exit("fsync"); 4684 4685 printf("Successfully resized NTFS on device '%s'.\n", vol->dev->d_name); 4686 if (resize.shrink) 4687 printf("%s", resize_important_msg); 4688 if (resize.lcn_bitmap.bm) 4689 free(resize.lcn_bitmap.bm); 4690 if (vol) 4691 ntfs_umount(vol,0); 4692 return 0; 4693} 4694