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(&sector_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