2 * mkntfs - Part of the Linux-NTFS project.
4 * Copyright (c) 2000-2011 Anton Altaparmakov
5 * Copyright (c) 2001-2005 Richard Russon
6 * Copyright (c) 2002-2006 Szabolcs Szakacsits
7 * Copyright (c) 2005 Erik Sornes
8 * Copyright (c) 2007 Yura Pakhuchiy
9 * Copyright (c) 2010-2014 Jean-Pierre Andre
11 * This utility will create an NTFS 1.2 or 3.1 volume on a user
12 * specified (block) device.
14 * Some things (option handling and determination of mount status) have been
15 * adapted from e2fsprogs-1.19 and lib/ext2fs/ismounted.c and misc/mke2fs.c in
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2 of the License, or
21 * (at your option) any later version.
23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
28 * You should have received a copy of the GNU General Public License
29 * along with this program (in the main directory of the Linux-NTFS source
30 * in the file COPYING); if not, write to the Free Software Foundation,
31 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
59 #ifdef HAVE_SYS_STAT_H
72 #include <uuid/uuid.h>
83 #ifdef HAVE_LINUX_MAJOR_H
84 # include <linux/major.h>
86 # define MAJOR(dev) ((dev) >> 8)
87 # define MINOR(dev) ((dev) & 0xff)
89 # ifndef IDE_DISK_MAJOR
92 # define IDE1_MAJOR 22
93 # define IDE2_MAJOR 33
94 # define IDE3_MAJOR 34
95 # define IDE4_MAJOR 56
96 # define IDE5_MAJOR 57
97 # define IDE6_MAJOR 88
98 # define IDE7_MAJOR 89
99 # define IDE8_MAJOR 90
100 # define IDE9_MAJOR 91
102 # define IDE_DISK_MAJOR(M) \
103 ((M) == IDE0_MAJOR || (M) == IDE1_MAJOR || \
104 (M) == IDE2_MAJOR || (M) == IDE3_MAJOR || \
105 (M) == IDE4_MAJOR || (M) == IDE5_MAJOR || \
106 (M) == IDE6_MAJOR || (M) == IDE7_MAJOR || \
107 (M) == IDE8_MAJOR || (M) == IDE9_MAJOR)
109 # ifndef SCSI_DISK_MAJOR
110 # ifndef SCSI_DISK0_MAJOR
111 # define SCSI_DISK0_MAJOR 8
112 # define SCSI_DISK1_MAJOR 65
113 # define SCSI_DISK7_MAJOR 71
115 # define SCSI_DISK_MAJOR(M) \
116 ((M) == SCSI_DISK0_MAJOR || \
117 ((M) >= SCSI_DISK1_MAJOR && \
118 (M) <= SCSI_DISK7_MAJOR))
122 #include "security.h"
126 #include "bootsect.h"
133 #include "ntfstime.h"
137 /* #include "version.h" */
143 #if defined(__sun) && defined (__SVR4)
145 #define basename(name) name
148 typedef enum { WRITE_STANDARD
, WRITE_BITMAP
, WRITE_LOGFILE
} WRITE_TYPE
;
150 #ifdef NO_NTFS_DEVICE_DEFAULT_IO_OPS
151 #error "No default device io operations! Cannot build mkntfs. \
152 You need to run ./configure without the --disable-default-device-io-ops \
153 switch if you want to be able to build the NTFS utilities."
156 /* Page size on ia32. Can change to 8192 on Alpha. */
157 #define NTFS_PAGE_SIZE 4096
159 static char EXEC_NAME
[] = "mkntfs";
161 struct BITMAP_ALLOCATION
{
162 struct BITMAP_ALLOCATION
*next
;
163 LCN lcn
; /* first allocated cluster */
164 s64 length
; /* count of consecutive clusters */
167 /* Upcase $Info, used since Windows 8 */
182 static u8
*g_buf
= NULL
;
183 static int g_mft_bitmap_byte_size
= 0;
184 static u8
*g_mft_bitmap
= NULL
;
185 static int g_lcn_bitmap_byte_size
= 0;
186 static int g_dynamic_buf_size
= 0;
187 static u8
*g_dynamic_buf
= NULL
;
188 static struct UPCASEINFO
*g_upcaseinfo
= NULL
;
189 static runlist
*g_rl_mft
= NULL
;
190 static runlist
*g_rl_mft_bmp
= NULL
;
191 static runlist
*g_rl_mftmirr
= NULL
;
192 static runlist
*g_rl_logfile
= NULL
;
193 static runlist
*g_rl_boot
= NULL
;
194 static runlist
*g_rl_bad
= NULL
;
195 static INDEX_ALLOCATION
*g_index_block
= NULL
;
196 static ntfs_volume
*g_vol
= NULL
;
197 static int g_mft_size
= 0;
198 static long long g_mft_lcn
= 0; /* lcn of $MFT, $DATA attribute */
199 static long long g_mftmirr_lcn
= 0; /* lcn of $MFTMirr, $DATA */
200 static long long g_logfile_lcn
= 0; /* lcn of $LogFile, $DATA */
201 static int g_logfile_size
= 0; /* in bytes, determined from volume_size */
202 static long long g_mft_zone_end
= 0; /* Determined from volume_size and mft_zone_multiplier, in clusters */
203 static long long g_num_bad_blocks
= 0; /* Number of bad clusters */
204 static long long *g_bad_blocks
= NULL
; /* Array of bad clusters */
206 static struct BITMAP_ALLOCATION
*g_allocation
= NULL
; /* Head of cluster allocations */
209 * struct mkntfs_options
211 static struct mkntfs_options
{
212 char *dev_name
; /* Name of the device, or file, to use */
213 BOOL enable_compression
; /* -C, enables compression of all files on the volume by default. */
214 BOOL quick_format
; /* -f or -Q, fast format, don't zero the volume first. */
215 BOOL force
; /* -F, force fs creation. */
216 long heads
; /* -H, number of heads on device */
217 BOOL disable_indexing
; /* -I, disables indexing of file contents on the volume by default. */
218 BOOL no_action
; /* -n, do not write to device, only display what would be done. */
219 long long part_start_sect
; /* -p, start sector of partition on parent device */
220 long sector_size
; /* -s, in bytes, power of 2, default is 512 bytes. */
221 long sectors_per_track
; /* -S, number of sectors per track on device */
222 BOOL use_epoch_time
; /* -T, fake the time to be 00:00:00 UTC, Jan 1, 1970. */
223 long mft_zone_multiplier
; /* -z, value from 1 to 4. Default is 1. */
224 long long num_sectors
; /* size of device in sectors */
225 long cluster_size
; /* -c, format with this cluster-size */
226 BOOL with_uuid
; /* -U, request setting an uuid */
227 char *label
; /* -L, volume label */
234 static void mkntfs_license(void)
236 ntfs_log_info("%s", ntfs_gpl
);
242 static void mkntfs_usage(void)
244 ntfs_log_info("\nUsage: %s [options] device [number-of-sectors]\n"
247 " -f, --fast Perform a quick format\n"
248 " -Q, --quick Perform a quick format\n"
249 " -L, --label STRING Set the volume label\n"
250 " -C, --enable-compression Enable compression on the volume\n"
251 " -I, --no-indexing Disable indexing on the volume\n"
252 " -n, --no-action Do not write to disk\n"
254 "Advanced options:\n"
255 " -c, --cluster-size BYTES Specify the cluster size for the volume\n"
256 " -s, --sector-size BYTES Specify the sector size for the device\n"
257 " -p, --partition-start SECTOR Specify the partition start sector\n"
258 " -H, --heads NUM Specify the number of heads\n"
259 " -S, --sectors-per-track NUM Specify the number of sectors per track\n"
260 " -z, --mft-zone-multiplier NUM Set the MFT zone multiplier\n"
261 " -T, --zero-time Fake the time to be 00:00 UTC, Jan 1, 1970\n"
262 " -F, --force Force execution despite errors\n"
265 " -q, --quiet Quiet execution\n"
266 " -v, --verbose Verbose execution\n"
267 " --debug Very verbose execution\n"
270 " -V, --version Display version\n"
271 " -l, --license Display licensing information\n"
272 " -h, --help Display this help\n"
273 "\n", basename(EXEC_NAME
));
274 ntfs_log_info("%s%s\n", ntfs_bugs
, ntfs_home
);
280 static void mkntfs_version(void)
282 ntfs_log_info("\n%s v%s (libntfs-3g)\n\n", EXEC_NAME
, VERSION
);
283 ntfs_log_info("Create an NTFS volume on a user specified (block) "
285 ntfs_log_info("Copyright (c) 2000-2007 Anton Altaparmakov\n");
286 ntfs_log_info("Copyright (c) 2001-2005 Richard Russon\n");
287 ntfs_log_info("Copyright (c) 2002-2006 Szabolcs Szakacsits\n");
288 ntfs_log_info("Copyright (c) 2005 Erik Sornes\n");
289 ntfs_log_info("Copyright (c) 2007 Yura Pakhuchiy\n");
290 ntfs_log_info("Copyright (c) 2010-2014 Jean-Pierre Andre\n");
291 ntfs_log_info("\n%s\n%s%s\n", ntfs_gpl
, ntfs_bugs
, ntfs_home
);
295 * crc64, adapted from http://rpm5.org/docs/api/digest_8c-source.html
296 * ECMA-182 polynomial, see
297 * http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-182.pdf
299 /* make sure the needed types are defined */
306 static uint64_t crc64(uint64_t crc
, const byte
* data
, size_t size
)
309 static uint64_t polynomial
= 0x9a6c9329ac4bc9b5ULL
;
310 static uint64_t xorout
= 0xffffffffffffffffULL
;
311 static uint64_t table
[256];
316 /* generate the table of CRC remainders for all possible bytes */
319 for (i
= 0; i
< 256; i
++) {
321 for (j
= 0; j
< 8; j
++) {
323 c
= polynomial
^ (c
>> 1);
331 crc
= table
[(crc
^ *data
) & 0xff] ^ (crc
>> 8);
342 * Mark a run of clusters as allocated
344 * Returns FALSE if unsuccessful
347 static BOOL
bitmap_allocate(LCN lcn
, s64 length
)
350 struct BITMAP_ALLOCATION
*p
;
351 struct BITMAP_ALLOCATION
*q
;
352 struct BITMAP_ALLOCATION
*newall
;
357 q
= (struct BITMAP_ALLOCATION
*)NULL
;
358 /* locate the first run which starts beyond the requested lcn */
359 while (p
&& (p
->lcn
<= lcn
)) {
363 /* make sure the requested lcns were not allocated */
364 if ((q
&& ((q
->lcn
+ q
->length
) > lcn
))
365 || (p
&& ((lcn
+ length
) > p
->lcn
))) {
366 ntfs_log_error("Bitmap allocation error\n");
369 if (q
&& ((q
->lcn
+ q
->length
) == lcn
)) {
370 /* extend current run, no overlapping possible */
373 newall
= (struct BITMAP_ALLOCATION
*)
374 ntfs_malloc(sizeof(struct BITMAP_ALLOCATION
));
377 newall
->length
= length
;
379 if (q
) q
->next
= newall
;
380 else g_allocation
= newall
;
383 ntfs_log_perror("Not enough memory");
391 * Mark a run of cluster as not allocated
393 * Returns FALSE if unsuccessful
394 * (freeing free clusters is not considered as an error)
397 static BOOL
bitmap_deallocate(LCN lcn
, s64 length
)
400 struct BITMAP_ALLOCATION
*p
;
401 struct BITMAP_ALLOCATION
*q
;
403 s64 begin_length
, end_length
;
408 q
= (struct BITMAP_ALLOCATION
*)NULL
;
409 /* locate a run which has a common portion */
411 first
= (p
->lcn
> lcn
? p
->lcn
: lcn
);
412 last
= ((p
->lcn
+ p
->length
) < (lcn
+ length
)
413 ? p
->lcn
+ p
->length
: lcn
+ length
);
415 /* get the parts which must be kept */
416 begin_length
= first
- p
->lcn
;
417 end_length
= p
->lcn
+ p
->length
- last
;
418 /* delete the entry */
422 g_allocation
= p
->next
;
424 /* reallocate the beginning and the end */
426 && !bitmap_allocate(first
- begin_length
,
430 && !bitmap_allocate(last
, end_length
))
432 /* restart a full search */
434 q
= (struct BITMAP_ALLOCATION
*)NULL
;
445 * Get the allocation status of a single cluster
446 * and mark as allocated
448 * Returns 1 if the cluster was previously allocated
451 static int bitmap_get_and_set(LCN lcn
, unsigned long length
)
453 struct BITMAP_ALLOCATION
*p
;
454 struct BITMAP_ALLOCATION
*q
;
459 q
= (struct BITMAP_ALLOCATION
*)NULL
;
460 /* locate the first run which starts beyond the requested lcn */
461 while (p
&& (p
->lcn
<= lcn
)) {
465 if (q
&& (q
->lcn
<= lcn
) && ((q
->lcn
+ q
->length
) > lcn
))
466 bit
= 1; /* was allocated */
468 bitmap_allocate(lcn
, length
);
472 ntfs_log_error("Can only allocate a single cluster at a time\n");
479 * Build a section of the bitmap according to allocation
482 static void bitmap_build(u8
*buf
, LCN lcn
, s64 length
)
484 struct BITMAP_ALLOCATION
*p
;
486 int j
; /* byte number */
487 int bn
; /* bit number */
489 for (j
=0; (8*j
)<length
; j
++)
491 for (p
=g_allocation
; p
; p
=p
->next
) {
492 first
= (p
->lcn
> lcn
? p
->lcn
: lcn
);
493 last
= ((p
->lcn
+ p
->length
) < (lcn
+ length
)
494 ? p
->lcn
+ p
->length
: lcn
+ length
);
497 /* initial partial byte, if any */
498 while ((bn
< (last
- lcn
)) && (bn
& 7)) {
499 buf
[bn
>> 3] |= 1 << (bn
& 7);
503 while (bn
< (last
- lcn
- 7)) {
507 /* final partial byte, if any */
508 while (bn
< (last
- lcn
)) {
509 buf
[bn
>> 3] |= 1 << (bn
& 7);
519 static BOOL
mkntfs_parse_long(const char *string
, const char *name
, long *num
)
524 if (!string
|| !name
|| !num
)
528 ntfs_log_error("You may only specify the %s once.\n", name
);
532 tmp
= strtol(string
, &end
, 0);
534 ntfs_log_error("Cannot understand the %s '%s'.\n", name
, string
);
545 static BOOL
mkntfs_parse_llong(const char *string
, const char *name
,
551 if (!string
|| !name
|| !num
)
555 ntfs_log_error("You may only specify the %s once.\n", name
);
559 tmp
= strtoll(string
, &end
, 0);
561 ntfs_log_error("Cannot understand the %s '%s'.\n", name
,
571 * mkntfs_init_options
573 static void mkntfs_init_options(struct mkntfs_options
*opts2
)
578 memset(opts2
, 0, sizeof(*opts2
));
580 /* Mark all the numeric options as "unset". */
581 opts2
->cluster_size
= -1;
583 opts2
->mft_zone_multiplier
= -1;
584 opts2
->num_sectors
= -1;
585 opts2
->part_start_sect
= -1;
586 opts2
->sector_size
= -1;
587 opts2
->sectors_per_track
= -1;
591 * mkntfs_parse_options
593 static int mkntfs_parse_options(int argc
, char *argv
[], struct mkntfs_options
*opts2
)
595 static const char *sopt
= "-c:CfFhH:IlL:np:qQs:S:TUvVz:";
596 static const struct option lopt
[] = {
597 { "cluster-size", required_argument
, NULL
, 'c' },
598 { "debug", no_argument
, NULL
, 'Z' },
599 { "enable-compression", no_argument
, NULL
, 'C' },
600 { "fast", no_argument
, NULL
, 'f' },
601 { "force", no_argument
, NULL
, 'F' },
602 { "heads", required_argument
, NULL
, 'H' },
603 { "help", no_argument
, NULL
, 'h' },
604 { "label", required_argument
, NULL
, 'L' },
605 { "license", no_argument
, NULL
, 'l' },
606 { "mft-zone-multiplier",required_argument
, NULL
, 'z' },
607 { "no-action", no_argument
, NULL
, 'n' },
608 { "no-indexing", no_argument
, NULL
, 'I' },
609 { "partition-start", required_argument
, NULL
, 'p' },
610 { "quick", no_argument
, NULL
, 'Q' },
611 { "quiet", no_argument
, NULL
, 'q' },
612 { "sector-size", required_argument
, NULL
, 's' },
613 { "sectors-per-track", required_argument
, NULL
, 'S' },
614 { "with-uuid", no_argument
, NULL
, 'U' },
615 { "verbose", no_argument
, NULL
, 'v' },
616 { "version", no_argument
, NULL
, 'V' },
617 { "zero-time", no_argument
, NULL
, 'T' },
627 if (!argv
|| !opts2
) {
628 ntfs_log_error("Internal error: invalid parameters to "
629 "mkntfs_options.\n");
633 opterr
= 0; /* We'll handle the errors, thank you. */
635 while ((c
= getopt_long(argc
, argv
, sopt
, lopt
, NULL
)) != -1) {
637 case 1: /* A device, or a number of sectors */
638 if (!opts2
->dev_name
)
639 opts2
->dev_name
= argv
[optind
- 1];
640 else if (!mkntfs_parse_llong(optarg
,
642 &opts2
->num_sectors
))
646 opts2
->enable_compression
= TRUE
;
649 if (!mkntfs_parse_long(optarg
, "cluster size",
650 &opts2
->cluster_size
))
657 case 'Q': /* quick */
658 opts2
->quick_format
= TRUE
;
661 if (!mkntfs_parse_long(optarg
, "heads", &opts2
->heads
))
665 help
++; /* display help */
668 opts2
->disable_indexing
= TRUE
;
672 opts2
->label
= argv
[optind
-1];
674 ntfs_log_error("You may only specify the label "
680 lic
++; /* display the license */
683 opts2
->no_action
= TRUE
;
686 if (!mkntfs_parse_llong(optarg
, "partition start",
687 &opts2
->part_start_sect
))
691 ntfs_log_clear_levels(NTFS_LOG_LEVEL_QUIET
|
692 NTFS_LOG_LEVEL_VERBOSE
|
693 NTFS_LOG_LEVEL_PROGRESS
);
696 if (!mkntfs_parse_long(optarg
, "sector size",
697 &opts2
->sector_size
))
701 if (!mkntfs_parse_long(optarg
, "sectors per track",
702 &opts2
->sectors_per_track
))
706 opts2
->use_epoch_time
= TRUE
;
709 opts2
->with_uuid
= TRUE
;
712 ntfs_log_set_levels(NTFS_LOG_LEVEL_QUIET
|
713 NTFS_LOG_LEVEL_VERBOSE
|
714 NTFS_LOG_LEVEL_PROGRESS
);
717 ver
++; /* display version info */
719 case 'Z': /* debug - turn on everything */
720 ntfs_log_set_levels(NTFS_LOG_LEVEL_DEBUG
|
721 NTFS_LOG_LEVEL_TRACE
|
722 NTFS_LOG_LEVEL_VERBOSE
|
723 NTFS_LOG_LEVEL_QUIET
);
726 if (!mkntfs_parse_long(optarg
, "mft zone multiplier",
727 &opts2
->mft_zone_multiplier
))
731 if (ntfs_log_parse_option (argv
[optind
-1]))
733 if (((optopt
== 'c') || (optopt
== 'H') ||
734 (optopt
== 'L') || (optopt
== 'p') ||
735 (optopt
== 's') || (optopt
== 'S') ||
736 (optopt
== 'N') || (optopt
== 'z')) &&
738 ntfs_log_error("Option '%s' requires an "
739 "argument.\n", argv
[optind
-1]);
740 } else if (optopt
!= '?') {
741 ntfs_log_error("Unknown option '%s'.\n",
749 if (!err
&& !help
&& !ver
&& !lic
) {
750 if (opts2
->dev_name
== NULL
) {
752 ntfs_log_error("You must specify a device.\n");
764 /* tri-state 0 : done, 1 : error, -1 : proceed */
765 return (err
? 1 : (help
|| ver
|| lic
? 0 : -1));
772 static ntfs_time
mkntfs_time(void)
778 if (!opts
.use_epoch_time
)
779 ts
.tv_sec
= time(NULL
);
780 return timespec2ntfs(ts
);
784 * append_to_bad_blocks
786 static BOOL
append_to_bad_blocks(unsigned long long block
)
790 if (!(g_num_bad_blocks
& 15)) {
791 new_buf
= realloc(g_bad_blocks
, (g_num_bad_blocks
+ 16) *
794 ntfs_log_perror("Reallocating memory for bad blocks "
798 g_bad_blocks
= new_buf
;
800 g_bad_blocks
[g_num_bad_blocks
++] = block
;
807 static long long mkntfs_write(struct ntfs_device
*dev
,
808 const void *b
, long long count
)
810 long long bytes_written
, total
;
818 bytes_written
= dev
->d_ops
->write(dev
, b
, count
);
819 if (bytes_written
== -1LL) {
821 ntfs_log_perror("Error writing to %s", dev
->d_name
);
823 return bytes_written
;
824 } else if (!bytes_written
) {
827 count
-= bytes_written
;
828 total
+= bytes_written
;
830 } while (count
&& retry
< 3);
832 ntfs_log_error("Failed to complete writing to %s after three retries."
838 * Build and write a part of the global bitmap
839 * without overflowing from the allocated buffer
841 * mkntfs_bitmap_write
843 static s64
mkntfs_bitmap_write(struct ntfs_device
*dev
,
844 s64 offset
, s64 length
)
849 partial_length
= length
;
850 if (partial_length
> g_dynamic_buf_size
)
851 partial_length
= g_dynamic_buf_size
;
852 /* create a partial bitmap section, and write it */
853 bitmap_build(g_dynamic_buf
,offset
<< 3,partial_length
<< 3);
854 written
= dev
->d_ops
->write(dev
, g_dynamic_buf
, partial_length
);
859 * Build and write a part of the log file
860 * without overflowing from the allocated buffer
862 * mkntfs_logfile_write
864 static s64
mkntfs_logfile_write(struct ntfs_device
*dev
,
865 s64 offset
__attribute__((unused
)), s64 length
)
870 partial_length
= length
;
871 if (partial_length
> g_dynamic_buf_size
)
872 partial_length
= g_dynamic_buf_size
;
873 /* create a partial bad cluster section, and write it */
874 memset(g_dynamic_buf
, -1, partial_length
);
875 written
= dev
->d_ops
->write(dev
, g_dynamic_buf
, partial_length
);
880 * ntfs_rlwrite - Write to disk the clusters contained in the runlist @rl
881 * taking the data from @val. Take @val_len bytes from @val and pad the
884 * If the @rl specifies a completely sparse file, @val is allowed to be NULL.
886 * @inited_size if not NULL points to an output variable which will contain
887 * the actual number of bytes written to disk. I.e. this will not include
888 * sparse bytes for example.
890 * Return the number of bytes written (minus padding) or -1 on error. Errno
891 * will be set to the error code.
893 static s64
ntfs_rlwrite(struct ntfs_device
*dev
, const runlist
*rl
,
894 const u8
*val
, const s64 val_len
, s64
*inited_size
,
895 WRITE_TYPE write_type
)
897 s64 bytes_written
, total
, length
, delta
;
906 for (i
= 0; rl
[i
].length
; i
++) {
907 length
= rl
[i
].length
* g_vol
->cluster_size
;
908 /* Don't write sparse runs. */
909 if (rl
[i
].lcn
== -1) {
913 /* TODO: Check that *val is really zero at pos and len. */
917 * Break up the write into the real data write and then a write
918 * of zeroes between the end of the real data and the end of
921 if (total
+ length
> val_len
) {
923 length
= val_len
- total
;
926 if (dev
->d_ops
->seek(dev
, rl
[i
].lcn
* g_vol
->cluster_size
,
927 SEEK_SET
) == (off_t
)-1)
931 /* use specific functions if buffer is not prefilled */
932 switch (write_type
) {
934 bytes_written
= mkntfs_bitmap_write(dev
,
938 bytes_written
= mkntfs_logfile_write(dev
,
942 bytes_written
= dev
->d_ops
->write(dev
,
943 val
+ total
, length
);
946 if (bytes_written
== -1LL) {
948 ntfs_log_perror("Error writing to %s",
951 return bytes_written
;
954 length
-= bytes_written
;
955 total
+= bytes_written
;
957 *inited_size
+= bytes_written
;
961 } while (length
&& retry
< 3);
963 ntfs_log_error("Failed to complete writing to %s after three "
964 "retries.\n", dev
->d_name
);
970 char *b
= ntfs_calloc(delta
);
973 bytes_written
= mkntfs_write(dev
, b
, delta
);
977 if (bytes_written
== -1LL)
978 return bytes_written
;
984 * make_room_for_attribute - make room for an attribute inside an mft record
986 * @pos: position at which to make space
987 * @size: byte size to make available at this position
989 * @pos points to the attribute in front of which we want to make space.
991 * Return 0 on success or -errno on error. Possible error codes are:
993 * -ENOSPC There is not enough space available to complete
994 * operation. The caller has to make space before calling
996 * -EINVAL Can only occur if mkntfs was compiled with -DDEBUG. Means
997 * the input parameters were faulty.
999 static int make_room_for_attribute(MFT_RECORD
*m
, char *pos
, const u32 size
)
1007 * Rigorous consistency checks. Always return -EINVAL even if more
1008 * appropriate codes exist for simplicity of parsing the return value.
1010 if (size
!= ((size
+ 7) & ~7)) {
1011 ntfs_log_error("make_room_for_attribute() received non 8-byte aligned "
1017 if (pos
< (char*)m
|| pos
+ size
< (char*)m
||
1018 pos
> (char*)m
+ le32_to_cpu(m
->bytes_allocated
) ||
1019 pos
+ size
> (char*)m
+ le32_to_cpu(m
->bytes_allocated
))
1021 /* The -8 is for the attribute terminator. */
1022 if (pos
- (char*)m
> (int)le32_to_cpu(m
->bytes_in_use
) - 8)
1025 biu
= le32_to_cpu(m
->bytes_in_use
);
1026 /* Do we have enough space? */
1027 if (biu
+ size
> le32_to_cpu(m
->bytes_allocated
))
1029 /* Move everything after pos to pos + size. */
1030 memmove(pos
+ size
, pos
, biu
- (pos
- (char*)m
));
1031 /* Update mft record. */
1032 m
->bytes_in_use
= cpu_to_le32(biu
+ size
);
1037 * deallocate_scattered_clusters
1039 static void deallocate_scattered_clusters(const runlist
*rl
)
1045 /* Iterate over all runs in the runlist @rl. */
1046 for (i
= 0; rl
[i
].length
; i
++) {
1047 /* Skip sparse runs. */
1048 if (rl
[i
].lcn
== -1LL)
1050 /* Deallocate the current run. */
1051 bitmap_deallocate(rl
[i
].lcn
, rl
[i
].length
);
1056 * allocate_scattered_clusters
1057 * @clusters: Amount of clusters to allocate.
1059 * Allocate @clusters and create a runlist of the allocated clusters.
1061 * Return the allocated runlist. Caller has to free the runlist when finished
1064 * On error return NULL and errno is set to the error code.
1066 * TODO: We should be returning the size as well, but for mkntfs this is not
1069 static runlist
* allocate_scattered_clusters(s64 clusters
)
1071 runlist
*rl
= NULL
, *rlt
;
1073 LCN lcn
, end
, prev_lcn
= 0LL;
1076 s64 prev_run_len
= 0LL;
1079 end
= g_vol
->nr_clusters
;
1080 /* Loop until all clusters are allocated. */
1082 /* Loop in current zone until we run out of free clusters. */
1083 for (lcn
= g_mft_zone_end
; lcn
< end
; lcn
++) {
1084 bit
= bitmap_get_and_set(lcn
,1);
1088 * Reallocate memory if necessary. Make sure we have
1089 * enough for the terminator entry as well.
1091 if ((rlpos
+ 2) * (int)sizeof(runlist
) >= rlsize
) {
1092 rlsize
+= 4096; /* PAGE_SIZE */
1093 rlt
= realloc(rl
, rlsize
);
1098 /* Coalesce with previous run if adjacent LCNs. */
1099 if (prev_lcn
== lcn
- prev_run_len
) {
1100 rl
[rlpos
- 1].length
= ++prev_run_len
;
1103 rl
[rlpos
].vcn
= vcn
++;
1104 rl
[rlpos
].lcn
= lcn
;
1106 rl
[rlpos
].length
= 1LL;
1112 /* Add terminator element and return. */
1113 rl
[rlpos
].vcn
= vcn
;
1114 rl
[rlpos
].lcn
= 0LL;
1115 rl
[rlpos
].length
= 0LL;
1120 /* Switch to next zone, decreasing mft zone by factor 2. */
1121 end
= g_mft_zone_end
;
1122 g_mft_zone_end
>>= 1;
1123 /* Have we run out of space on the volume? */
1124 if (g_mft_zone_end
<= 0)
1130 /* Add terminator element. */
1131 rl
[rlpos
].vcn
= vcn
;
1132 rl
[rlpos
].lcn
= -1LL;
1133 rl
[rlpos
].length
= 0LL;
1134 /* Deallocate all allocated clusters. */
1135 deallocate_scattered_clusters(rl
);
1136 /* Free the runlist. */
1143 * ntfs_attr_find - find (next) attribute in mft record
1144 * @type: attribute type to find
1145 * @name: attribute name to find (optional, i.e. NULL means don't care)
1146 * @name_len: attribute name length (only needed if @name present)
1147 * @ic: IGNORE_CASE or CASE_SENSITIVE (ignored if @name not present)
1148 * @val: attribute value to find (optional, resident attributes only)
1149 * @val_len: attribute value length
1150 * @ctx: search context with mft record and attribute to search from
1152 * You shouldn't need to call this function directly. Use lookup_attr() instead.
1154 * ntfs_attr_find() takes a search context @ctx as parameter and searches the
1155 * mft record specified by @ctx->mrec, beginning at @ctx->attr, for an
1156 * attribute of @type, optionally @name and @val. If found, ntfs_attr_find()
1157 * returns 0 and @ctx->attr will point to the found attribute.
1159 * If not found, ntfs_attr_find() returns -1, with errno set to ENOENT and
1160 * @ctx->attr will point to the attribute before which the attribute being
1161 * searched for would need to be inserted if such an action were to be desired.
1163 * On actual error, ntfs_attr_find() returns -1 with errno set to the error
1164 * code but not to ENOENT. In this case @ctx->attr is undefined and in
1165 * particular do not rely on it not changing.
1167 * If @ctx->is_first is TRUE, the search begins with @ctx->attr itself. If it
1168 * is FALSE, the search begins after @ctx->attr.
1170 * If @type is AT_UNUSED, return the first found attribute, i.e. one can
1171 * enumerate all attributes by setting @type to AT_UNUSED and then calling
1172 * ntfs_attr_find() repeatedly until it returns -1 with errno set to ENOENT to
1173 * indicate that there are no more entries. During the enumeration, each
1174 * successful call of ntfs_attr_find() will return the next attribute in the
1175 * mft record @ctx->mrec.
1177 * If @type is AT_END, seek to the end and return -1 with errno set to ENOENT.
1178 * AT_END is not a valid attribute, its length is zero for example, thus it is
1179 * safer to return error instead of success in this case. This also allows us
1180 * to interoperate cleanly with ntfs_external_attr_find().
1182 * If @name is AT_UNNAMED search for an unnamed attribute. If @name is present
1183 * but not AT_UNNAMED search for a named attribute matching @name. Otherwise,
1184 * match both named and unnamed attributes.
1186 * If @ic is IGNORE_CASE, the @name comparison is not case sensitive and
1187 * @ctx->ntfs_ino must be set to the ntfs inode to which the mft record
1188 * @ctx->mrec belongs. This is so we can get at the ntfs volume and hence at
1189 * the upcase table. If @ic is CASE_SENSITIVE, the comparison is case
1190 * sensitive. When @name is present, @name_len is the @name length in Unicode
1193 * If @name is not present (NULL), we assume that the unnamed attribute is
1194 * being searched for.
1196 * Finally, the resident attribute value @val is looked for, if present.
1197 * If @val is not present (NULL), @val_len is ignored.
1199 * ntfs_attr_find() only searches the specified mft record and it ignores the
1200 * presence of an attribute list attribute (unless it is the one being searched
1201 * for, obviously). If you need to take attribute lists into consideration, use
1202 * ntfs_attr_lookup() instead (see below). This also means that you cannot use
1203 * ntfs_attr_find() to search for extent records of non-resident attributes, as
1204 * extents with lowest_vcn != 0 are usually described by the attribute list
1205 * attribute only. - Note that it is possible that the first extent is only in
1206 * the attribute list while the last extent is in the base mft record, so don't
1207 * rely on being able to find the first extent in the base mft record.
1209 * Warning: Never use @val when looking for attribute types which can be
1210 * non-resident as this most likely will result in a crash!
1212 static int mkntfs_attr_find(const ATTR_TYPES type
, const ntfschar
*name
,
1213 const u32 name_len
, const IGNORE_CASE_BOOL ic
,
1214 const u8
*val
, const u32 val_len
, ntfs_attr_search_ctx
*ctx
)
1217 ntfschar
*upcase
= g_vol
->upcase
;
1218 u32 upcase_len
= g_vol
->upcase_len
;
1221 * Iterate over attributes in mft record starting at @ctx->attr, or the
1222 * attribute following that, if @ctx->is_first is TRUE.
1224 if (ctx
->is_first
) {
1226 ctx
->is_first
= FALSE
;
1228 a
= (ATTR_RECORD
*)((char*)ctx
->attr
+
1229 le32_to_cpu(ctx
->attr
->length
));
1231 for (;; a
= (ATTR_RECORD
*)((char*)a
+ le32_to_cpu(a
->length
))) {
1232 if (p2n(a
) < p2n(ctx
->mrec
) || (char*)a
> (char*)ctx
->mrec
+
1233 le32_to_cpu(ctx
->mrec
->bytes_allocated
))
1236 if (((type
!= AT_UNUSED
) && (le32_to_cpu(a
->type
) >
1237 le32_to_cpu(type
))) ||
1238 (a
->type
== AT_END
)) {
1244 /* If this is an enumeration return this attribute. */
1245 if (type
== AT_UNUSED
)
1247 if (a
->type
!= type
)
1250 * If @name is AT_UNNAMED we want an unnamed attribute.
1251 * If @name is present, compare the two names.
1252 * Otherwise, match any attribute.
1254 if (name
== AT_UNNAMED
) {
1255 /* The search failed if the found attribute is named. */
1256 if (a
->name_length
) {
1260 } else if (name
&& !ntfs_names_are_equal(name
, name_len
,
1261 (ntfschar
*)((char*)a
+ le16_to_cpu(a
->name_offset
)),
1262 a
->name_length
, ic
, upcase
, upcase_len
)) {
1265 rc
= ntfs_names_full_collate(name
, name_len
,
1266 (ntfschar
*)((char*)a
+
1267 le16_to_cpu(a
->name_offset
)),
1268 a
->name_length
, IGNORE_CASE
,
1269 upcase
, upcase_len
);
1271 * If @name collates before a->name, there is no
1272 * matching attribute.
1278 /* If the strings are not equal, continue search. */
1281 rc
= ntfs_names_full_collate(name
, name_len
,
1282 (ntfschar
*)((char*)a
+
1283 le16_to_cpu(a
->name_offset
)),
1284 a
->name_length
, CASE_SENSITIVE
,
1285 upcase
, upcase_len
);
1294 * The names match or @name not present and attribute is
1295 * unnamed. If no @val specified, we have found the attribute
1300 /* @val is present; compare values. */
1304 rc
= memcmp(val
, (char*)a
+le16_to_cpu(a
->value_offset
),
1306 le32_to_cpu(a
->value_length
)));
1308 * If @val collates before the current attribute's
1309 * value, there is no matching attribute.
1313 avl
= le32_to_cpu(a
->value_length
);
1316 if (val_len
< avl
) {
1320 } else if (rc
< 0) {
1326 ntfs_log_trace("File is corrupt. Run chkdsk.\n");
1332 * ntfs_attr_lookup - find an attribute in an ntfs inode
1333 * @type: attribute type to find
1334 * @name: attribute name to find (optional, i.e. NULL means don't care)
1335 * @name_len: attribute name length (only needed if @name present)
1336 * @ic: IGNORE_CASE or CASE_SENSITIVE (ignored if @name not present)
1337 * @lowest_vcn: lowest vcn to find (optional, non-resident attributes only)
1338 * @val: attribute value to find (optional, resident attributes only)
1339 * @val_len: attribute value length
1340 * @ctx: search context with mft record and attribute to search from
1342 * Find an attribute in an ntfs inode. On first search @ctx->ntfs_ino must
1343 * be the base mft record and @ctx must have been obtained from a call to
1344 * ntfs_attr_get_search_ctx().
1346 * This function transparently handles attribute lists and @ctx is used to
1347 * continue searches where they were left off at.
1349 * If @type is AT_UNUSED, return the first found attribute, i.e. one can
1350 * enumerate all attributes by setting @type to AT_UNUSED and then calling
1351 * ntfs_attr_lookup() repeatedly until it returns -1 with errno set to ENOENT
1352 * to indicate that there are no more entries. During the enumeration, each
1353 * successful call of ntfs_attr_lookup() will return the next attribute, with
1354 * the current attribute being described by the search context @ctx.
1356 * If @type is AT_END, seek to the end of the base mft record ignoring the
1357 * attribute list completely and return -1 with errno set to ENOENT. AT_END is
1358 * not a valid attribute, its length is zero for example, thus it is safer to
1359 * return error instead of success in this case. It should never be needed to
1360 * do this, but we implement the functionality because it allows for simpler
1361 * code inside ntfs_external_attr_find().
1363 * If @name is AT_UNNAMED search for an unnamed attribute. If @name is present
1364 * but not AT_UNNAMED search for a named attribute matching @name. Otherwise,
1365 * match both named and unnamed attributes.
1367 * After finishing with the attribute/mft record you need to call
1368 * ntfs_attr_put_search_ctx() to cleanup the search context (unmapping any
1369 * mapped extent inodes, etc).
1371 * Return 0 if the search was successful and -1 if not, with errno set to the
1374 * On success, @ctx->attr is the found attribute, it is in mft record
1375 * @ctx->mrec, and @ctx->al_entry is the attribute list entry for this
1376 * attribute with @ctx->base_* being the base mft record to which @ctx->attr
1377 * belongs. If no attribute list attribute is present @ctx->al_entry and
1378 * @ctx->base_* are NULL.
1380 * On error ENOENT, i.e. attribute not found, @ctx->attr is set to the
1381 * attribute which collates just after the attribute being searched for in the
1382 * base ntfs inode, i.e. if one wants to add the attribute to the mft record
1383 * this is the correct place to insert it into, and if there is not enough
1384 * space, the attribute should be placed in an extent mft record.
1385 * @ctx->al_entry points to the position within @ctx->base_ntfs_ino->attr_list
1386 * at which the new attribute's attribute list entry should be inserted. The
1387 * other @ctx fields, base_ntfs_ino, base_mrec, and base_attr are set to NULL.
1388 * The only exception to this is when @type is AT_END, in which case
1389 * @ctx->al_entry is set to NULL also (see above).
1391 * The following error codes are defined:
1392 * ENOENT Attribute not found, not an error as such.
1393 * EINVAL Invalid arguments.
1394 * EIO I/O error or corrupt data structures found.
1395 * ENOMEM Not enough memory to allocate necessary buffers.
1397 static int mkntfs_attr_lookup(const ATTR_TYPES type
, const ntfschar
*name
,
1398 const u32 name_len
, const IGNORE_CASE_BOOL ic
,
1399 const VCN lowest_vcn
__attribute__((unused
)), const u8
*val
,
1400 const u32 val_len
, ntfs_attr_search_ctx
*ctx
)
1402 ntfs_inode
*base_ni
;
1404 if (!ctx
|| !ctx
->mrec
|| !ctx
->attr
) {
1408 if (ctx
->base_ntfs_ino
)
1409 base_ni
= ctx
->base_ntfs_ino
;
1411 base_ni
= ctx
->ntfs_ino
;
1412 if (!base_ni
|| !NInoAttrList(base_ni
) || type
== AT_ATTRIBUTE_LIST
)
1413 return mkntfs_attr_find(type
, name
, name_len
, ic
, val
, val_len
,
1420 * insert_positioned_attr_in_mft_record
1422 * Create a non-resident attribute with a predefined on disk location
1423 * specified by the runlist @rl. The clusters specified by @rl are assumed to
1424 * be allocated already.
1426 * Return 0 on success and -errno on error.
1428 static int insert_positioned_attr_in_mft_record(MFT_RECORD
*m
,
1429 const ATTR_TYPES type
, const char *name
, u32 name_len
,
1430 const IGNORE_CASE_BOOL ic
, const ATTR_FLAGS flags
,
1431 const runlist
*rl
, const u8
*val
, const s64 val_len
)
1433 ntfs_attr_search_ctx
*ctx
;
1436 int asize
, mpa_size
, err
, i
;
1437 s64 bw
= 0, inited_size
;
1439 ntfschar
*uname
= NULL
;
1447 uname
= ntfs_str2ucs(name
, &uname_len
);
1451 /* Check if the attribute is already there. */
1452 ctx
= ntfs_attr_get_search_ctx(NULL
, m
);
1454 ntfs_log_error("Failed to allocate attribute search context.\n");
1458 if (ic
== IGNORE_CASE
) {
1459 ntfs_log_error("FIXME: Hit unimplemented code path #1.\n");
1463 if (!mkntfs_attr_lookup(type
, uname
, uname_len
, ic
, 0, NULL
, 0, ctx
)) {
1467 if (errno
!= ENOENT
) {
1468 ntfs_log_error("Corrupt inode.\n");
1473 if (flags
& ATTR_COMPRESSION_MASK
) {
1474 ntfs_log_error("Compressed attributes not supported yet.\n");
1475 /* FIXME: Compress attribute into a temporary buffer, set */
1476 /* val accordingly and save the compressed size. */
1480 if (flags
& (ATTR_IS_ENCRYPTED
| ATTR_IS_SPARSE
)) {
1481 ntfs_log_error("Encrypted/sparse attributes not supported.\n");
1485 if (flags
& ATTR_COMPRESSION_MASK
) {
1487 /* FIXME: This compression stuff is all wrong. Never mind for */
1490 mpa_size
= 0; /* get_size_for_compressed_mapping_pairs(rl); */
1496 mpa_size
= ntfs_get_size_for_mapping_pairs(g_vol
, rl
, 0, INT_MAX
);
1499 ntfs_log_error("Failed to get size for mapping "
1507 /* Mapping pairs array and next attribute must be 8-byte aligned. */
1508 asize
= (((int)hdr_size
+ ((name_len
+ 7) & ~7) + mpa_size
) + 7) & ~7;
1509 /* Get the highest vcn. */
1510 for (i
= 0, highest_vcn
= 0LL; rl
[i
].length
; i
++)
1511 highest_vcn
+= rl
[i
].length
;
1512 /* Does the value fit inside the allocated size? */
1513 if (highest_vcn
* g_vol
->cluster_size
< val_len
) {
1514 ntfs_log_error("BUG: Allocated size is smaller than data size!\n");
1518 err
= make_room_for_attribute(m
, (char*)a
, asize
);
1519 if (err
== -ENOSPC
) {
1521 * FIXME: Make space! (AIA)
1522 * can we make it non-resident? if yes, do that.
1523 * does it fit now? yes -> do it.
1524 * m's $DATA or $BITMAP+$INDEX_ALLOCATION resident?
1525 * yes -> make non-resident
1526 * does it fit now? yes -> do it.
1527 * make all attributes non-resident
1528 * does it fit now? yes -> do it.
1529 * m is a base record? yes -> allocate extension record
1530 * does the new attribute fit in there? yes -> do it.
1531 * split up runlist into extents and place each in an extension
1533 * FIXME: the check for needing extension records should be
1534 * earlier on as it is very quick: asize > m->bytes_allocated?
1539 } else if (err
== -EINVAL
) {
1540 ntfs_log_error("BUG(): in insert_positioned_attribute_in_mft_"
1541 "record(): make_room_for_attribute() returned "
1542 "error: EINVAL!\n");
1547 a
->length
= cpu_to_le32(asize
);
1548 a
->non_resident
= 1;
1549 a
->name_length
= name_len
;
1550 a
->name_offset
= cpu_to_le16(hdr_size
);
1552 a
->instance
= m
->next_attr_instance
;
1553 m
->next_attr_instance
= cpu_to_le16((le16_to_cpu(m
->next_attr_instance
)
1555 a
->lowest_vcn
= const_cpu_to_sle64(0);
1556 a
->highest_vcn
= cpu_to_sle64(highest_vcn
- 1LL);
1557 a
->mapping_pairs_offset
= cpu_to_le16(hdr_size
+ ((name_len
+ 7) & ~7));
1558 memset(a
->reserved1
, 0, sizeof(a
->reserved1
));
1559 /* FIXME: Allocated size depends on compression. */
1560 a
->allocated_size
= cpu_to_sle64(highest_vcn
* g_vol
->cluster_size
);
1561 a
->data_size
= cpu_to_sle64(val_len
);
1563 memcpy((char*)a
+ hdr_size
, uname
, name_len
<< 1);
1564 if (flags
& ATTR_COMPRESSION_MASK
) {
1565 if (flags
& ATTR_COMPRESSION_MASK
& ~ATTR_IS_COMPRESSED
) {
1566 ntfs_log_error("Unknown compression format. Reverting "
1567 "to standard compression.\n");
1568 a
->flags
&= ~ATTR_COMPRESSION_MASK
;
1569 a
->flags
|= ATTR_IS_COMPRESSED
;
1571 a
->compression_unit
= 4;
1572 inited_size
= val_len
;
1573 /* FIXME: Set the compressed size. */
1574 a
->compressed_size
= const_cpu_to_sle64(0);
1575 /* FIXME: Write out the compressed data. */
1576 /* FIXME: err = build_mapping_pairs_compressed(); */
1579 a
->compression_unit
= 0;
1580 if ((type
== AT_DATA
)
1581 && (m
->mft_record_number
1582 == const_cpu_to_le32(FILE_LogFile
)))
1583 bw
= ntfs_rlwrite(g_vol
->dev
, rl
, val
, val_len
,
1584 &inited_size
, WRITE_LOGFILE
);
1586 bw
= ntfs_rlwrite(g_vol
->dev
, rl
, val
, val_len
,
1587 &inited_size
, WRITE_STANDARD
);
1588 if (bw
!= val_len
) {
1589 ntfs_log_error("Error writing non-resident attribute "
1593 err
= ntfs_mapping_pairs_build(g_vol
, (u8
*)a
+ hdr_size
+
1594 ((name_len
+ 7) & ~7), mpa_size
, rl
, 0, NULL
);
1596 a
->initialized_size
= cpu_to_sle64(inited_size
);
1597 if (err
< 0 || bw
!= val_len
) {
1598 /* FIXME: Handle error. */
1599 /* deallocate clusters */
1600 /* remove attribute */
1603 ntfs_log_error("insert_positioned_attr_in_mft_record failed "
1604 "with error %i.\n", err
< 0 ? err
: (int)bw
);
1608 ntfs_attr_put_search_ctx(ctx
);
1609 ntfs_ucsfree(uname
);
1614 * insert_non_resident_attr_in_mft_record
1616 * Return 0 on success and -errno on error.
1618 static int insert_non_resident_attr_in_mft_record(MFT_RECORD
*m
,
1619 const ATTR_TYPES type
, const char *name
, u32 name_len
,
1620 const IGNORE_CASE_BOOL ic
, const ATTR_FLAGS flags
,
1621 const u8
*val
, const s64 val_len
,
1622 WRITE_TYPE write_type
)
1624 ntfs_attr_search_ctx
*ctx
;
1627 int asize
, mpa_size
, err
, i
;
1630 ntfschar
*uname
= NULL
;
1638 uname
= ntfs_str2ucs(name
, &uname_len
);
1642 /* Check if the attribute is already there. */
1643 ctx
= ntfs_attr_get_search_ctx(NULL
, m
);
1645 ntfs_log_error("Failed to allocate attribute search context.\n");
1649 if (ic
== IGNORE_CASE
) {
1650 ntfs_log_error("FIXME: Hit unimplemented code path #2.\n");
1654 if (!mkntfs_attr_lookup(type
, uname
, uname_len
, ic
, 0, NULL
, 0, ctx
)) {
1658 if (errno
!= ENOENT
) {
1659 ntfs_log_error("Corrupt inode.\n");
1664 if (flags
& ATTR_COMPRESSION_MASK
) {
1665 ntfs_log_error("Compressed attributes not supported yet.\n");
1666 /* FIXME: Compress attribute into a temporary buffer, set */
1667 /* val accordingly and save the compressed size. */
1671 if (flags
& (ATTR_IS_ENCRYPTED
| ATTR_IS_SPARSE
)) {
1672 ntfs_log_error("Encrypted/sparse attributes not supported.\n");
1677 rl
= allocate_scattered_clusters((val_len
+
1678 g_vol
->cluster_size
- 1) / g_vol
->cluster_size
);
1681 ntfs_log_perror("Failed to allocate scattered clusters");
1687 if (flags
& ATTR_COMPRESSION_MASK
) {
1689 /* FIXME: This compression stuff is all wrong. Never mind for */
1692 mpa_size
= 0; /* get_size_for_compressed_mapping_pairs(rl); */
1698 mpa_size
= ntfs_get_size_for_mapping_pairs(g_vol
, rl
, 0, INT_MAX
);
1701 ntfs_log_error("Failed to get size for mapping "
1709 /* Mapping pairs array and next attribute must be 8-byte aligned. */
1710 asize
= (((int)hdr_size
+ ((name_len
+ 7) & ~7) + mpa_size
) + 7) & ~7;
1711 err
= make_room_for_attribute(m
, (char*)a
, asize
);
1712 if (err
== -ENOSPC
) {
1714 * FIXME: Make space! (AIA)
1715 * can we make it non-resident? if yes, do that.
1716 * does it fit now? yes -> do it.
1717 * m's $DATA or $BITMAP+$INDEX_ALLOCATION resident?
1718 * yes -> make non-resident
1719 * does it fit now? yes -> do it.
1720 * make all attributes non-resident
1721 * does it fit now? yes -> do it.
1722 * m is a base record? yes -> allocate extension record
1723 * does the new attribute fit in there? yes -> do it.
1724 * split up runlist into extents and place each in an extension
1726 * FIXME: the check for needing extension records should be
1727 * earlier on as it is very quick: asize > m->bytes_allocated?
1732 } else if (err
== -EINVAL
) {
1733 ntfs_log_error("BUG(): in insert_non_resident_attribute_in_"
1734 "mft_record(): make_room_for_attribute() "
1735 "returned error: EINVAL!\n");
1740 a
->length
= cpu_to_le32(asize
);
1741 a
->non_resident
= 1;
1742 a
->name_length
= name_len
;
1743 a
->name_offset
= cpu_to_le16(hdr_size
);
1745 a
->instance
= m
->next_attr_instance
;
1746 m
->next_attr_instance
= cpu_to_le16((le16_to_cpu(m
->next_attr_instance
)
1748 a
->lowest_vcn
= const_cpu_to_sle64(0);
1749 for (i
= 0; rl
[i
].length
; i
++)
1751 a
->highest_vcn
= cpu_to_sle64(rl
[i
].vcn
- 1);
1752 a
->mapping_pairs_offset
= cpu_to_le16(hdr_size
+ ((name_len
+ 7) & ~7));
1753 memset(a
->reserved1
, 0, sizeof(a
->reserved1
));
1754 /* FIXME: Allocated size depends on compression. */
1755 a
->allocated_size
= cpu_to_sle64((val_len
+ (g_vol
->cluster_size
- 1)) &
1756 ~(g_vol
->cluster_size
- 1));
1757 a
->data_size
= cpu_to_sle64(val_len
);
1758 a
->initialized_size
= cpu_to_sle64(val_len
);
1760 memcpy((char*)a
+ hdr_size
, uname
, name_len
<< 1);
1761 if (flags
& ATTR_COMPRESSION_MASK
) {
1762 if (flags
& ATTR_COMPRESSION_MASK
& ~ATTR_IS_COMPRESSED
) {
1763 ntfs_log_error("Unknown compression format. Reverting "
1764 "to standard compression.\n");
1765 a
->flags
&= ~ATTR_COMPRESSION_MASK
;
1766 a
->flags
|= ATTR_IS_COMPRESSED
;
1768 a
->compression_unit
= 4;
1769 /* FIXME: Set the compressed size. */
1770 a
->compressed_size
= const_cpu_to_sle64(0);
1771 /* FIXME: Write out the compressed data. */
1772 /* FIXME: err = build_mapping_pairs_compressed(); */
1775 a
->compression_unit
= 0;
1776 bw
= ntfs_rlwrite(g_vol
->dev
, rl
, val
, val_len
, NULL
,
1778 if (bw
!= val_len
) {
1779 ntfs_log_error("Error writing non-resident attribute "
1783 err
= ntfs_mapping_pairs_build(g_vol
, (u8
*)a
+ hdr_size
+
1784 ((name_len
+ 7) & ~7), mpa_size
, rl
, 0, NULL
);
1786 if (err
< 0 || bw
!= val_len
) {
1787 /* FIXME: Handle error. */
1788 /* deallocate clusters */
1789 /* remove attribute */
1792 ntfs_log_error("insert_non_resident_attr_in_mft_record failed with "
1793 "error %lld.\n", (long long) (err
< 0 ? err
: bw
));
1797 ntfs_attr_put_search_ctx(ctx
);
1798 ntfs_ucsfree(uname
);
1804 * insert_resident_attr_in_mft_record
1806 * Return 0 on success and -errno on error.
1808 static int insert_resident_attr_in_mft_record(MFT_RECORD
*m
,
1809 const ATTR_TYPES type
, const char *name
, u32 name_len
,
1810 const IGNORE_CASE_BOOL ic
, const ATTR_FLAGS flags
,
1811 const RESIDENT_ATTR_FLAGS res_flags
,
1812 const u8
*val
, const u32 val_len
)
1814 ntfs_attr_search_ctx
*ctx
;
1817 ntfschar
*uname
= NULL
;
1821 mkntfs_attr_lookup();
1825 uname
= ntfs_str2ucs(name
, &uname_len
);
1829 /* Check if the attribute is already there. */
1830 ctx
= ntfs_attr_get_search_ctx(NULL
, m
);
1832 ntfs_log_error("Failed to allocate attribute search context.\n");
1836 if (ic
== IGNORE_CASE
) {
1837 ntfs_log_error("FIXME: Hit unimplemented code path #3.\n");
1841 if (!mkntfs_attr_lookup(type
, uname
, uname_len
, ic
, 0, val
, val_len
,
1846 if (errno
!= ENOENT
) {
1847 ntfs_log_error("Corrupt inode.\n");
1852 /* sizeof(resident attribute record header) == 24 */
1853 asize
= ((24 + ((name_len
*2 + 7) & ~7) + val_len
) + 7) & ~7;
1854 err
= make_room_for_attribute(m
, (char*)a
, asize
);
1855 if (err
== -ENOSPC
) {
1857 * FIXME: Make space! (AIA)
1858 * can we make it non-resident? if yes, do that.
1859 * does it fit now? yes -> do it.
1860 * m's $DATA or $BITMAP+$INDEX_ALLOCATION resident?
1861 * yes -> make non-resident
1862 * does it fit now? yes -> do it.
1863 * make all attributes non-resident
1864 * does it fit now? yes -> do it.
1865 * m is a base record? yes -> allocate extension record
1866 * does the new attribute fit in there? yes -> do it.
1867 * split up runlist into extents and place each in an extension
1869 * FIXME: the check for needing extension records should be
1870 * earlier on as it is very quick: asize > m->bytes_allocated?
1876 if (err
== -EINVAL
) {
1877 ntfs_log_error("BUG(): in insert_resident_attribute_in_mft_"
1878 "record(): make_room_for_attribute() returned "
1879 "error: EINVAL!\n");
1884 a
->length
= cpu_to_le32(asize
);
1885 a
->non_resident
= 0;
1886 a
->name_length
= name_len
;
1887 if (type
== AT_OBJECT_ID
)
1888 a
->name_offset
= const_cpu_to_le16(0);
1890 a
->name_offset
= const_cpu_to_le16(24);
1892 a
->instance
= m
->next_attr_instance
;
1893 m
->next_attr_instance
= cpu_to_le16((le16_to_cpu(m
->next_attr_instance
)
1895 a
->value_length
= cpu_to_le32(val_len
);
1896 a
->value_offset
= cpu_to_le16(24 + ((name_len
*2 + 7) & ~7));
1897 a
->resident_flags
= res_flags
;
1900 memcpy((char*)a
+ 24, uname
, name_len
<< 1);
1902 memcpy((char*)a
+ le16_to_cpu(a
->value_offset
), val
, val_len
);
1905 ntfs_attr_put_search_ctx(ctx
);
1906 ntfs_ucsfree(uname
);
1914 * Return 0 on success or -errno on error.
1916 static int add_attr_std_info(MFT_RECORD
*m
, const FILE_ATTR_FLAGS flags
,
1919 STANDARD_INFORMATION si
;
1924 si
.creation_time
= mkntfs_time();
1925 si
.last_data_change_time
= si
.creation_time
;
1926 si
.last_mft_change_time
= si
.creation_time
;
1927 si
.last_access_time
= si
.creation_time
;
1928 si
.file_attributes
= flags
; /* already LE */
1929 si
.maximum_versions
= const_cpu_to_le32(0);
1930 si
.version_number
= const_cpu_to_le32(0);
1931 si
.class_id
= const_cpu_to_le32(0);
1932 si
.security_id
= security_id
;
1933 if (si
.security_id
!= const_cpu_to_le32(0))
1935 /* FIXME: $Quota support... */
1936 si
.owner_id
= const_cpu_to_le32(0);
1937 si
.quota_charged
= const_cpu_to_le64(0ULL);
1938 /* FIXME: $UsnJrnl support... Not needed on fresh w2k3-volume */
1939 si
.usn
= const_cpu_to_le64(0ULL);
1940 /* NTFS 1.2: size of si = 48, NTFS 3.[01]: size of si = 72 */
1941 err
= insert_resident_attr_in_mft_record(m
, AT_STANDARD_INFORMATION
,
1942 NULL
, 0, CASE_SENSITIVE
, const_cpu_to_le16(0),
1943 0, (u8
*)&si
, sd_size
);
1945 ntfs_log_perror("add_attr_std_info failed");
1950 * Tell whether the unnamed data is non resident
1953 static BOOL
non_resident_unnamed_data(MFT_RECORD
*m
)
1956 ntfs_attr_search_ctx
*ctx
;
1959 ctx
= ntfs_attr_get_search_ctx(NULL
, m
);
1960 if (ctx
&& !mkntfs_attr_find(AT_DATA
,
1961 (const ntfschar
*)NULL
, 0, CASE_SENSITIVE
,
1962 (u8
*)NULL
, 0, ctx
)) {
1964 nonres
= a
->non_resident
!= 0;
1966 ntfs_log_error("BUG: Unnamed data not found\n");
1970 ntfs_attr_put_search_ctx(ctx
);
1975 * Get the time stored in the standard information attribute
1978 static ntfs_time
stdinfo_time(MFT_RECORD
*m
)
1980 STANDARD_INFORMATION
*si
;
1981 ntfs_attr_search_ctx
*ctx
;
1982 ntfs_time info_time
;
1984 ctx
= ntfs_attr_get_search_ctx(NULL
, m
);
1985 if (ctx
&& !mkntfs_attr_find(AT_STANDARD_INFORMATION
,
1986 (const ntfschar
*)NULL
, 0, CASE_SENSITIVE
,
1987 (u8
*)NULL
, 0, ctx
)) {
1988 si
= (STANDARD_INFORMATION
*)((char*)ctx
->attr
+
1989 le16_to_cpu(ctx
->attr
->value_offset
));
1990 info_time
= si
->creation_time
;
1992 ntfs_log_error("BUG: Standard information not found\n");
1993 info_time
= mkntfs_time();
1996 ntfs_attr_put_search_ctx(ctx
);
2001 * add_attr_file_name
2003 * Return 0 on success or -errno on error.
2005 static int add_attr_file_name(MFT_RECORD
*m
, const leMFT_REF parent_dir
,
2006 const s64 allocated_size
, const s64 data_size
,
2007 const FILE_ATTR_FLAGS flags
, const u16 packed_ea_size
,
2008 const u32 reparse_point_tag
, const char *file_name
,
2009 const FILE_NAME_TYPE_FLAGS file_name_type
)
2011 ntfs_attr_search_ctx
*ctx
;
2012 STANDARD_INFORMATION
*si
;
2017 /* Check if the attribute is already there. */
2018 ctx
= ntfs_attr_get_search_ctx(NULL
, m
);
2020 ntfs_log_error("Failed to get attribute search context.\n");
2023 if (mkntfs_attr_lookup(AT_STANDARD_INFORMATION
, AT_UNNAMED
, 0,
2024 CASE_SENSITIVE
, 0, NULL
, 0, ctx
)) {
2026 ntfs_log_error("BUG: Standard information attribute not "
2027 "present in file record.\n");
2028 ntfs_attr_put_search_ctx(ctx
);
2031 si
= (STANDARD_INFORMATION
*)((char*)ctx
->attr
+
2032 le16_to_cpu(ctx
->attr
->value_offset
));
2033 i
= (strlen(file_name
) + 1) * sizeof(ntfschar
);
2034 fn_size
= sizeof(FILE_NAME_ATTR
) + i
;
2035 fn
= ntfs_malloc(fn_size
);
2037 ntfs_attr_put_search_ctx(ctx
);
2040 fn
->parent_directory
= parent_dir
;
2042 fn
->creation_time
= si
->creation_time
;
2043 fn
->last_data_change_time
= si
->last_data_change_time
;
2044 fn
->last_mft_change_time
= si
->last_mft_change_time
;
2045 fn
->last_access_time
= si
->last_access_time
;
2046 ntfs_attr_put_search_ctx(ctx
);
2048 fn
->allocated_size
= cpu_to_sle64(allocated_size
);
2049 fn
->data_size
= cpu_to_sle64(data_size
);
2050 fn
->file_attributes
= flags
;
2051 /* These are in a union so can't have both. */
2052 if (packed_ea_size
&& reparse_point_tag
) {
2056 if (packed_ea_size
) {
2057 fn
->packed_ea_size
= cpu_to_le16(packed_ea_size
);
2058 fn
->reserved
= const_cpu_to_le16(0);
2060 fn
->reparse_point_tag
= cpu_to_le32(reparse_point_tag
);
2062 fn
->file_name_type
= file_name_type
;
2063 uname
= fn
->file_name
;
2064 i
= ntfs_mbstoucs_libntfscompat(file_name
, &uname
, i
);
2071 return -ENAMETOOLONG
;
2073 /* No terminating null in file names. */
2074 fn
->file_name_length
= i
;
2075 fn_size
= sizeof(FILE_NAME_ATTR
) + i
* sizeof(ntfschar
);
2076 i
= insert_resident_attr_in_mft_record(m
, AT_FILE_NAME
, NULL
, 0,
2077 CASE_SENSITIVE
, const_cpu_to_le16(0),
2078 RESIDENT_ATTR_IS_INDEXED
, (u8
*)fn
, fn_size
);
2081 ntfs_log_error("add_attr_file_name failed: %s\n", strerror(-i
));
2086 * add_attr_object_id -
2088 * Note we insert only a basic object id which only has the GUID and none of
2089 * the extended fields. This is because we currently only use this function
2090 * when creating the object id for the volume.
2092 * Return 0 on success or -errno on error.
2094 static int add_attr_object_id(MFT_RECORD
*m
, const GUID
*object_id
)
2099 oi
= (OBJECT_ID_ATTR
) {
2100 .object_id
= *object_id
,
2102 err
= insert_resident_attr_in_mft_record(m
, AT_OBJECT_ID
, NULL
,
2103 0, CASE_SENSITIVE
, const_cpu_to_le16(0),
2104 0, (u8
*)&oi
, sizeof(oi
.object_id
));
2106 ntfs_log_error("add_attr_vol_info failed: %s\n", strerror(-err
));
2113 * Create the security descriptor attribute adding the security descriptor @sd
2114 * of length @sd_len to the mft record @m.
2116 * Return 0 on success or -errno on error.
2118 static int add_attr_sd(MFT_RECORD
*m
, const u8
*sd
, const s64 sd_len
)
2122 /* Does it fit? NO: create non-resident. YES: create resident. */
2123 if (le32_to_cpu(m
->bytes_in_use
) + 24 + sd_len
>
2124 le32_to_cpu(m
->bytes_allocated
))
2125 err
= insert_non_resident_attr_in_mft_record(m
,
2126 AT_SECURITY_DESCRIPTOR
, NULL
, 0,
2127 CASE_SENSITIVE
, const_cpu_to_le16(0), sd
,
2128 sd_len
, WRITE_STANDARD
);
2130 err
= insert_resident_attr_in_mft_record(m
,
2131 AT_SECURITY_DESCRIPTOR
, NULL
, 0,
2132 CASE_SENSITIVE
, const_cpu_to_le16(0), 0, sd
,
2135 ntfs_log_error("add_attr_sd failed: %s\n", strerror(-err
));
2142 * Return 0 on success or -errno on error.
2144 static int add_attr_data(MFT_RECORD
*m
, const char *name
, const u32 name_len
,
2145 const IGNORE_CASE_BOOL ic
, const ATTR_FLAGS flags
,
2146 const u8
*val
, const s64 val_len
)
2151 * Does it fit? NO: create non-resident. YES: create resident.
2153 * FIXME: Introduced arbitrary limit of mft record allocated size - 512.
2154 * This is to get around the problem that if $Bitmap/$DATA becomes too
2155 * big, but is just small enough to be resident, we would make it
2156 * resident, and later run out of space when creating the other
2157 * attributes and this would cause us to abort as making resident
2158 * attributes non-resident is not supported yet.
2159 * The proper fix is to support making resident attribute non-resident.
2161 if (le32_to_cpu(m
->bytes_in_use
) + 24 + val_len
>
2162 min(le32_to_cpu(m
->bytes_allocated
),
2163 le32_to_cpu(m
->bytes_allocated
) - 512))
2164 err
= insert_non_resident_attr_in_mft_record(m
, AT_DATA
, name
,
2165 name_len
, ic
, flags
, val
, val_len
,
2168 err
= insert_resident_attr_in_mft_record(m
, AT_DATA
, name
,
2169 name_len
, ic
, flags
, 0, val
, val_len
);
2172 ntfs_log_error("add_attr_data failed: %s\n", strerror(-err
));
2177 * add_attr_data_positioned
2179 * Create a non-resident data attribute with a predefined on disk location
2180 * specified by the runlist @rl. The clusters specified by @rl are assumed to
2181 * be allocated already.
2183 * Return 0 on success or -errno on error.
2185 static int add_attr_data_positioned(MFT_RECORD
*m
, const char *name
,
2186 const u32 name_len
, const IGNORE_CASE_BOOL ic
,
2187 const ATTR_FLAGS flags
, const runlist
*rl
,
2188 const u8
*val
, const s64 val_len
)
2192 err
= insert_positioned_attr_in_mft_record(m
, AT_DATA
, name
, name_len
,
2193 ic
, flags
, rl
, val
, val_len
);
2195 ntfs_log_error("add_attr_data_positioned failed: %s\n",
2203 * Create volume name attribute specifying the volume name @vol_name as a null
2204 * terminated char string of length @vol_name_len (number of characters not
2205 * including the terminating null), which is converted internally to a little
2206 * endian ntfschar string. The name is at least 1 character long (though
2207 * Windows accepts zero characters), and at most 128 characters long (not
2208 * counting the terminating null).
2210 * Return 0 on success or -errno on error.
2212 static int add_attr_vol_name(MFT_RECORD
*m
, const char *vol_name
,
2213 const int vol_name_len
__attribute__((unused
)))
2215 ntfschar
*uname
= NULL
;
2220 uname_len
= ntfs_mbstoucs(vol_name
, &uname
);
2223 if (uname_len
> 128) {
2225 return -ENAMETOOLONG
;
2228 i
= insert_resident_attr_in_mft_record(m
, AT_VOLUME_NAME
, NULL
, 0,
2229 CASE_SENSITIVE
, const_cpu_to_le16(0),
2230 0, (u8
*)uname
, uname_len
*sizeof(ntfschar
));
2233 ntfs_log_error("add_attr_vol_name failed: %s\n", strerror(-i
));
2240 * Return 0 on success or -errno on error.
2242 static int add_attr_vol_info(MFT_RECORD
*m
, const VOLUME_FLAGS flags
,
2243 const u8 major_ver
, const u8 minor_ver
)
2245 VOLUME_INFORMATION vi
;
2248 memset(&vi
, 0, sizeof(vi
));
2249 vi
.major_ver
= major_ver
;
2250 vi
.minor_ver
= minor_ver
;
2251 vi
.flags
= flags
& VOLUME_FLAGS_MASK
;
2252 err
= insert_resident_attr_in_mft_record(m
, AT_VOLUME_INFORMATION
, NULL
,
2253 0, CASE_SENSITIVE
, const_cpu_to_le16(0),
2254 0, (u8
*)&vi
, sizeof(vi
));
2256 ntfs_log_error("add_attr_vol_info failed: %s\n", strerror(-err
));
2261 * add_attr_index_root
2263 * Return 0 on success or -errno on error.
2265 static int add_attr_index_root(MFT_RECORD
*m
, const char *name
,
2266 const u32 name_len
, const IGNORE_CASE_BOOL ic
,
2267 const ATTR_TYPES indexed_attr_type
,
2268 const COLLATION_RULES collation_rule
,
2269 const u32 index_block_size
)
2272 INDEX_ENTRY_HEADER
*e
;
2275 val_len
= sizeof(INDEX_ROOT
) + sizeof(INDEX_ENTRY_HEADER
);
2276 r
= ntfs_malloc(val_len
);
2279 r
->type
= (indexed_attr_type
== AT_FILE_NAME
)
2280 ? AT_FILE_NAME
: const_cpu_to_le32(0);
2281 if (indexed_attr_type
== AT_FILE_NAME
&&
2282 collation_rule
!= COLLATION_FILE_NAME
) {
2284 ntfs_log_error("add_attr_index_root: indexed attribute is $FILE_NAME "
2285 "but collation rule is not COLLATION_FILE_NAME.\n");
2288 r
->collation_rule
= collation_rule
;
2289 r
->index_block_size
= cpu_to_le32(index_block_size
);
2290 if (index_block_size
>= g_vol
->cluster_size
) {
2291 if (index_block_size
% g_vol
->cluster_size
) {
2292 ntfs_log_error("add_attr_index_root: index block size is not "
2293 "a multiple of the cluster size.\n");
2297 r
->clusters_per_index_block
= index_block_size
/
2298 g_vol
->cluster_size
;
2299 } else { /* if (g_vol->cluster_size > index_block_size) */
2300 if (index_block_size
& (index_block_size
- 1)) {
2301 ntfs_log_error("add_attr_index_root: index block size is not "
2306 if (index_block_size
< (u32
)opts
.sector_size
) {
2307 ntfs_log_error("add_attr_index_root: index block size "
2308 "is smaller than the sector size.\n");
2312 r
->clusters_per_index_block
= index_block_size
2313 >> NTFS_BLOCK_SIZE_BITS
;
2315 memset(&r
->reserved
, 0, sizeof(r
->reserved
));
2316 r
->index
.entries_offset
= const_cpu_to_le32(sizeof(INDEX_HEADER
));
2317 r
->index
.index_length
= const_cpu_to_le32(sizeof(INDEX_HEADER
) +
2318 sizeof(INDEX_ENTRY_HEADER
));
2319 r
->index
.allocated_size
= r
->index
.index_length
;
2320 r
->index
.ih_flags
= SMALL_INDEX
;
2321 memset(&r
->index
.reserved
, 0, sizeof(r
->index
.reserved
));
2322 e
= (INDEX_ENTRY_HEADER
*)((u8
*)&r
->index
+
2323 le32_to_cpu(r
->index
.entries_offset
));
2325 * No matter whether this is a file index or a view as this is a
2326 * termination entry, hence no key value / data is associated with it
2327 * at all. Thus, we just need the union to be all zero.
2329 e
->indexed_file
= const_cpu_to_le64(0LL);
2330 e
->length
= const_cpu_to_le16(sizeof(INDEX_ENTRY_HEADER
));
2331 e
->key_length
= const_cpu_to_le16(0);
2332 e
->flags
= INDEX_ENTRY_END
;
2333 e
->reserved
= const_cpu_to_le16(0);
2334 err
= insert_resident_attr_in_mft_record(m
, AT_INDEX_ROOT
, name
,
2335 name_len
, ic
, const_cpu_to_le16(0), 0,
2339 ntfs_log_error("add_attr_index_root failed: %s\n", strerror(-err
));
2344 * add_attr_index_alloc
2346 * Return 0 on success or -errno on error.
2348 static int add_attr_index_alloc(MFT_RECORD
*m
, const char *name
,
2349 const u32 name_len
, const IGNORE_CASE_BOOL ic
,
2350 const u8
*index_alloc_val
, const u32 index_alloc_val_len
)
2354 err
= insert_non_resident_attr_in_mft_record(m
, AT_INDEX_ALLOCATION
,
2355 name
, name_len
, ic
, const_cpu_to_le16(0),
2356 index_alloc_val
, index_alloc_val_len
, WRITE_STANDARD
);
2358 ntfs_log_error("add_attr_index_alloc failed: %s\n", strerror(-err
));
2365 * Return 0 on success or -errno on error.
2367 static int add_attr_bitmap(MFT_RECORD
*m
, const char *name
, const u32 name_len
,
2368 const IGNORE_CASE_BOOL ic
, const u8
*bitmap
,
2369 const u32 bitmap_len
)
2373 /* Does it fit? NO: create non-resident. YES: create resident. */
2374 if (le32_to_cpu(m
->bytes_in_use
) + 24 + bitmap_len
>
2375 le32_to_cpu(m
->bytes_allocated
))
2376 err
= insert_non_resident_attr_in_mft_record(m
, AT_BITMAP
, name
,
2377 name_len
, ic
, const_cpu_to_le16(0), bitmap
,
2378 bitmap_len
, WRITE_STANDARD
);
2380 err
= insert_resident_attr_in_mft_record(m
, AT_BITMAP
, name
,
2381 name_len
, ic
, const_cpu_to_le16(0), 0,
2382 bitmap
, bitmap_len
);
2385 ntfs_log_error("add_attr_bitmap failed: %s\n", strerror(-err
));
2390 * add_attr_bitmap_positioned
2392 * Create a non-resident bitmap attribute with a predefined on disk location
2393 * specified by the runlist @rl. The clusters specified by @rl are assumed to
2394 * be allocated already.
2396 * Return 0 on success or -errno on error.
2398 static int add_attr_bitmap_positioned(MFT_RECORD
*m
, const char *name
,
2399 const u32 name_len
, const IGNORE_CASE_BOOL ic
,
2400 const runlist
*rl
, const u8
*bitmap
, const u32 bitmap_len
)
2404 err
= insert_positioned_attr_in_mft_record(m
, AT_BITMAP
, name
, name_len
,
2405 ic
, const_cpu_to_le16(0), rl
, bitmap
, bitmap_len
);
2407 ntfs_log_error("add_attr_bitmap_positioned failed: %s\n",
2414 * upgrade_to_large_index
2416 * Create bitmap and index allocation attributes, modify index root
2417 * attribute accordingly and move all of the index entries from the index root
2418 * into the index allocation.
2420 * Return 0 on success or -errno on error.
2422 static int upgrade_to_large_index(MFT_RECORD
*m
, const char *name
,
2423 u32 name_len
, const IGNORE_CASE_BOOL ic
,
2424 INDEX_ALLOCATION
**idx
)
2426 ntfs_attr_search_ctx
*ctx
;
2430 INDEX_ALLOCATION
*ia_val
= NULL
;
2431 ntfschar
*uname
= NULL
;
2434 char *re_start
, *re_end
;
2435 int i
, err
, index_block_size
;
2437 uname
= ntfs_str2ucs(name
, &uname_len
);
2441 /* Find the index root attribute. */
2442 ctx
= ntfs_attr_get_search_ctx(NULL
, m
);
2444 ntfs_log_error("Failed to allocate attribute search context.\n");
2445 ntfs_ucsfree(uname
);
2448 if (ic
== IGNORE_CASE
) {
2449 ntfs_log_error("FIXME: Hit unimplemented code path #4.\n");
2451 ntfs_ucsfree(uname
);
2454 err
= mkntfs_attr_lookup(AT_INDEX_ROOT
, uname
, uname_len
, ic
, 0, NULL
, 0,
2456 ntfs_ucsfree(uname
);
2462 if (a
->non_resident
|| a
->flags
) {
2466 r
= (INDEX_ROOT
*)((char*)a
+ le16_to_cpu(a
->value_offset
));
2467 re_end
= (char*)r
+ le32_to_cpu(a
->value_length
);
2468 re_start
= (char*)&r
->index
+ le32_to_cpu(r
->index
.entries_offset
);
2469 re
= (INDEX_ENTRY
*)re_start
;
2470 index_block_size
= le32_to_cpu(r
->index_block_size
);
2471 memset(bmp
, 0, sizeof(bmp
));
2472 ntfs_bit_set(bmp
, 0ULL, 1);
2473 /* Bitmap has to be at least 8 bytes in size. */
2474 err
= add_attr_bitmap(m
, name
, name_len
, ic
, bmp
, sizeof(bmp
));
2477 ia_val
= ntfs_calloc(index_block_size
);
2483 ia_val
->magic
= magic_INDX
;
2484 ia_val
->usa_ofs
= const_cpu_to_le16(sizeof(INDEX_ALLOCATION
));
2485 if (index_block_size
>= NTFS_BLOCK_SIZE
) {
2486 ia_val
->usa_count
= cpu_to_le16(index_block_size
/
2487 NTFS_BLOCK_SIZE
+ 1);
2489 ia_val
->usa_count
= const_cpu_to_le16(1);
2490 ntfs_log_error("Sector size is bigger than index block size. "
2491 "Setting usa_count to 1. If Windows chkdsk "
2492 "reports this as corruption, please email %s "
2493 "stating that you saw this message and that "
2494 "the filesystem created was corrupt. "
2495 "Thank you.", NTFS_DEV_LIST
);
2498 *(le16
*)((char*)ia_val
+ le16_to_cpu(ia_val
->usa_ofs
)) =
2499 const_cpu_to_le16(1);
2500 ia_val
->lsn
= const_cpu_to_sle64(0);
2501 ia_val
->index_block_vcn
= const_cpu_to_sle64(0);
2502 ia_val
->index
.ih_flags
= LEAF_NODE
;
2503 /* Align to 8-byte boundary. */
2504 ia_val
->index
.entries_offset
= cpu_to_le32((sizeof(INDEX_HEADER
) +
2505 le16_to_cpu(ia_val
->usa_count
) * 2 + 7) & ~7);
2506 ia_val
->index
.allocated_size
= cpu_to_le32(index_block_size
-
2507 (sizeof(INDEX_ALLOCATION
) - sizeof(INDEX_HEADER
)));
2508 /* Find the last entry in the index root and save it in re. */
2509 while ((char*)re
< re_end
&& !(re
->ie_flags
& INDEX_ENTRY_END
)) {
2510 /* Next entry in index root. */
2511 re
= (INDEX_ENTRY
*)((char*)re
+ le16_to_cpu(re
->length
));
2513 /* Copy all the entries including the termination entry. */
2514 i
= (char*)re
- re_start
+ le16_to_cpu(re
->length
);
2515 memcpy((char*)&ia_val
->index
+
2516 le32_to_cpu(ia_val
->index
.entries_offset
), re_start
, i
);
2517 /* Finish setting up index allocation. */
2518 ia_val
->index
.index_length
= cpu_to_le32(i
+
2519 le32_to_cpu(ia_val
->index
.entries_offset
));
2520 /* Move the termination entry forward to the beginning if necessary. */
2521 if ((char*)re
> re_start
) {
2522 memmove(re_start
, (char*)re
, le16_to_cpu(re
->length
));
2523 re
= (INDEX_ENTRY
*)re_start
;
2525 /* Now fixup empty index root with pointer to index allocation VCN 0. */
2526 r
->index
.ih_flags
= LARGE_INDEX
;
2527 re
->ie_flags
|= INDEX_ENTRY_NODE
;
2528 if (le16_to_cpu(re
->length
) < sizeof(INDEX_ENTRY_HEADER
) + sizeof(VCN
))
2529 re
->length
= cpu_to_le16(le16_to_cpu(re
->length
) + sizeof(VCN
));
2530 r
->index
.index_length
= cpu_to_le32(le32_to_cpu(r
->index
.entries_offset
)
2531 + le16_to_cpu(re
->length
));
2532 r
->index
.allocated_size
= r
->index
.index_length
;
2533 /* Resize index root attribute. */
2534 if (ntfs_resident_attr_value_resize(m
, a
, sizeof(INDEX_ROOT
) -
2535 sizeof(INDEX_HEADER
) +
2536 le32_to_cpu(r
->index
.allocated_size
))) {
2537 /* TODO: Remove the added bitmap! */
2538 /* Revert index root from index allocation. */
2542 /* Set VCN pointer to 0LL. */
2543 *(leVCN
*)((char*)re
+ le16_to_cpu(re
->length
) - sizeof(VCN
)) =
2544 const_cpu_to_sle64(0);
2545 err
= ntfs_mst_pre_write_fixup((NTFS_RECORD
*)ia_val
, index_block_size
);
2548 ntfs_log_error("ntfs_mst_pre_write_fixup() failed in "
2549 "upgrade_to_large_index.\n");
2552 err
= add_attr_index_alloc(m
, name
, name_len
, ic
, (u8
*)ia_val
,
2554 ntfs_mst_post_write_fixup((NTFS_RECORD
*)ia_val
);
2556 /* TODO: Remove the added bitmap! */
2557 /* Revert index root from index allocation. */
2561 ntfs_attr_put_search_ctx(ctx
);
2564 ntfs_attr_put_search_ctx(ctx
);
2570 * make_room_for_index_entry_in_index_block
2572 * Create space of @size bytes at position @pos inside the index block @idx.
2574 * Return 0 on success or -errno on error.
2576 static int make_room_for_index_entry_in_index_block(INDEX_BLOCK
*idx
,
2577 INDEX_ENTRY
*pos
, u32 size
)
2585 * Rigorous consistency checks. Always return -EINVAL even if more
2586 * appropriate codes exist for simplicity of parsing the return value.
2588 if (size
!= ((size
+ 7) & ~7)) {
2589 ntfs_log_error("make_room_for_index_entry_in_index_block() received "
2590 "non 8-byte aligned size.\n");
2595 if ((char*)pos
< (char*)idx
|| (char*)pos
+ size
< (char*)idx
||
2596 (char*)pos
> (char*)idx
+ sizeof(INDEX_BLOCK
) -
2597 sizeof(INDEX_HEADER
) +
2598 le32_to_cpu(idx
->index
.allocated_size
) ||
2599 (char*)pos
+ size
> (char*)idx
+ sizeof(INDEX_BLOCK
) -
2600 sizeof(INDEX_HEADER
) +
2601 le32_to_cpu(idx
->index
.allocated_size
))
2603 /* The - sizeof(INDEX_ENTRY_HEADER) is for the index terminator. */
2604 if ((char*)pos
- (char*)&idx
->index
>
2605 (int)le32_to_cpu(idx
->index
.index_length
)
2606 - (int)sizeof(INDEX_ENTRY_HEADER
))
2609 biu
= le32_to_cpu(idx
->index
.index_length
);
2610 /* Do we have enough space? */
2611 if (biu
+ size
> le32_to_cpu(idx
->index
.allocated_size
))
2613 /* Move everything after pos to pos + size. */
2614 memmove((char*)pos
+ size
, (char*)pos
, biu
- ((char*)pos
-
2615 (char*)&idx
->index
));
2616 /* Update index block. */
2617 idx
->index
.index_length
= cpu_to_le32(biu
+ size
);
2622 * ntfs_index_keys_compare
2624 * not all types of COLLATION_RULES supported yet...
2625 * added as needed.. (remove this comment when all are added)
2627 static int ntfs_index_keys_compare(u8
*key1
, u8
*key2
, int key1_length
,
2628 int key2_length
, COLLATION_RULES collation_rule
)
2633 if (collation_rule
== COLLATION_NTOFS_ULONG
) {
2634 /* i.e. $SII or $QUOTA-$Q */
2635 u1
= le32_to_cpup((const le32
*)key1
);
2636 u2
= le32_to_cpup((const le32
*)key2
);
2644 if (collation_rule
== COLLATION_NTOFS_ULONGS
) {
2647 while (i
< min(key1_length
, key2_length
)) {
2648 u1
= le32_to_cpup((const le32
*)(key1
+ i
));
2649 u2
= le32_to_cpup((const le32
*)(key2
+ i
));
2657 if (key1_length
< key2_length
)
2659 if (key1_length
> key2_length
)
2663 if (collation_rule
== COLLATION_NTOFS_SECURITY_HASH
) {
2665 u1
= le32_to_cpu(((SDH_INDEX_KEY
*)key1
)->hash
);
2666 u2
= le32_to_cpu(((SDH_INDEX_KEY
*)key2
)->hash
);
2672 u1
= le32_to_cpu(((SDH_INDEX_KEY
*)key1
)->security_id
);
2673 u2
= le32_to_cpu(((SDH_INDEX_KEY
*)key2
)->security_id
);
2680 if (collation_rule
== COLLATION_NTOFS_SID
) {
2682 i
= memcmp(key1
, key2
, min(key1_length
, key2_length
));
2684 if (key1_length
< key2_length
)
2686 if (key1_length
> key2_length
)
2691 ntfs_log_critical("ntfs_index_keys_compare called without supported "
2692 "collation rule.\n");
2693 return 0; /* Claim they're equal. What else can we do? */
2697 * insert_index_entry_in_res_dir_index
2699 * i.e. insert an index_entry in some named index_root
2700 * simplified search method, works for mkntfs
2702 static int insert_index_entry_in_res_dir_index(INDEX_ENTRY
*idx
, u32 idx_size
,
2703 MFT_RECORD
*m
, ntfschar
*name
, u32 name_size
, ATTR_TYPES type
)
2705 ntfs_attr_search_ctx
*ctx
;
2706 INDEX_HEADER
*idx_header
;
2707 INDEX_ENTRY
*idx_entry
, *idx_end
;
2709 COLLATION_RULES collation_rule
;
2714 if (g_vol
->mft_record_size
> idx_size
+ le32_to_cpu(m
->bytes_allocated
))
2716 /* find the INDEX_ROOT attribute:*/
2717 ctx
= ntfs_attr_get_search_ctx(NULL
, m
);
2719 ntfs_log_error("Failed to allocate attribute search "
2724 if (mkntfs_attr_lookup(AT_INDEX_ROOT
, name
, name_size
,
2725 CASE_SENSITIVE
, 0, NULL
, 0, ctx
)) {
2729 /* found attribute */
2730 a
= (ATTR_RECORD
*)ctx
->attr
;
2731 collation_rule
= ((INDEX_ROOT
*)((u8
*)a
+
2732 le16_to_cpu(a
->value_offset
)))->collation_rule
;
2733 idx_header
= (INDEX_HEADER
*)((u8
*)a
+ le16_to_cpu(a
->value_offset
)
2735 idx_entry
= (INDEX_ENTRY
*)((u8
*)idx_header
+
2736 le32_to_cpu(idx_header
->entries_offset
));
2737 idx_end
= (INDEX_ENTRY
*)((u8
*)idx_entry
+
2738 le32_to_cpu(idx_header
->index_length
));
2740 * Loop until we exceed valid memory (corruption case) or until we
2741 * reach the last entry.
2743 if (type
== AT_FILE_NAME
) {
2744 while (((u8
*)idx_entry
< (u8
*)idx_end
) &&
2745 !(idx_entry
->ie_flags
& INDEX_ENTRY_END
)) {
2747 i = ntfs_file_values_compare(&idx->key.file_name,
2748 &idx_entry->key.file_name, 1,
2749 IGNORE_CASE, g_vol->upcase,
2752 i
= ntfs_names_full_collate(idx
->key
.file_name
.file_name
, idx
->key
.file_name
.file_name_length
,
2753 idx_entry
->key
.file_name
.file_name
, idx_entry
->key
.file_name
.file_name_length
,
2754 IGNORE_CASE
, g_vol
->upcase
,
2757 * If @file_name collates before ie->key.file_name,
2758 * there is no matching index entry.
2762 /* If file names are not equal, continue search. */
2765 if (idx
->key
.file_name
.file_name_type
!=
2767 idx_entry
->key
.file_name
.file_name_type
2771 i = ntfs_file_values_compare(&idx->key.file_name,
2772 &idx_entry->key.file_name, 1,
2773 CASE_SENSITIVE, g_vol->upcase,
2776 i
= ntfs_names_full_collate(idx
->key
.file_name
.file_name
, idx
->key
.file_name
.file_name_length
,
2777 idx_entry
->key
.file_name
.file_name
, idx_entry
->key
.file_name
.file_name_length
,
2778 CASE_SENSITIVE
, g_vol
->upcase
,
2785 idx_entry
= (INDEX_ENTRY
*)((u8
*)idx_entry
+
2786 le16_to_cpu(idx_entry
->length
));
2788 } else if (type
== AT_UNUSED
) { /* case view */
2789 while (((u8
*)idx_entry
< (u8
*)idx_end
) &&
2790 !(idx_entry
->ie_flags
& INDEX_ENTRY_END
)) {
2791 i
= ntfs_index_keys_compare((u8
*)idx
+ 0x10,
2792 (u8
*)idx_entry
+ 0x10,
2793 le16_to_cpu(idx
->key_length
),
2794 le16_to_cpu(idx_entry
->key_length
),
2800 idx_entry
= (INDEX_ENTRY
*)((u8
*)idx_entry
+
2801 le16_to_cpu(idx_entry
->length
));
2805 memmove((u8
*)idx_entry
+ idx_size
, (u8
*)idx_entry
,
2806 le32_to_cpu(m
->bytes_in_use
) -
2807 ((u8
*)idx_entry
- (u8
*)m
));
2808 memcpy((u8
*)idx_entry
, (u8
*)idx
, idx_size
);
2809 /* Adjust various offsets, etc... */
2810 m
->bytes_in_use
= cpu_to_le32(le32_to_cpu(m
->bytes_in_use
) + idx_size
);
2811 a
->length
= cpu_to_le32(le32_to_cpu(a
->length
) + idx_size
);
2812 a
->value_length
= cpu_to_le32(le32_to_cpu(a
->value_length
) + idx_size
);
2813 idx_header
->index_length
= cpu_to_le32(
2814 le32_to_cpu(idx_header
->index_length
) + idx_size
);
2815 idx_header
->allocated_size
= cpu_to_le32(
2816 le32_to_cpu(idx_header
->allocated_size
) + idx_size
);
2819 ntfs_attr_put_search_ctx(ctx
);
2826 * initializes $Secure's $SDH and $SII indexes from $SDS datastream
2828 static int initialize_secure(char *sds
, u32 sds_size
, MFT_RECORD
*m
)
2830 int err
, sdh_size
, sii_size
;
2831 SECURITY_DESCRIPTOR_HEADER
*sds_header
;
2832 INDEX_ENTRY
*idx_entry_sdh
, *idx_entry_sii
;
2833 SDH_INDEX_DATA
*sdh_data
;
2834 SII_INDEX_DATA
*sii_data
;
2836 sds_header
= (SECURITY_DESCRIPTOR_HEADER
*)sds
;
2837 sdh_size
= sizeof(INDEX_ENTRY_HEADER
);
2838 sdh_size
+= sizeof(SDH_INDEX_KEY
) + sizeof(SDH_INDEX_DATA
);
2839 sii_size
= sizeof(INDEX_ENTRY_HEADER
);
2840 sii_size
+= sizeof(SII_INDEX_KEY
) + sizeof(SII_INDEX_DATA
);
2841 idx_entry_sdh
= ntfs_calloc(sizeof(INDEX_ENTRY
));
2844 idx_entry_sii
= ntfs_calloc(sizeof(INDEX_ENTRY
));
2845 if (!idx_entry_sii
) {
2846 free(idx_entry_sdh
);
2851 while ((char*)sds_header
< (char*)sds
+ sds_size
) {
2852 if (!sds_header
->length
)
2854 /* SDH index entry */
2855 idx_entry_sdh
->data_offset
= const_cpu_to_le16(0x18);
2856 idx_entry_sdh
->data_length
= const_cpu_to_le16(0x14);
2857 idx_entry_sdh
->reservedV
= const_cpu_to_le32(0x00);
2858 idx_entry_sdh
->length
= const_cpu_to_le16(0x30);
2859 idx_entry_sdh
->key_length
= const_cpu_to_le16(0x08);
2860 idx_entry_sdh
->ie_flags
= const_cpu_to_le16(0x00);
2861 idx_entry_sdh
->reserved
= const_cpu_to_le16(0x00);
2862 idx_entry_sdh
->key
.sdh
.hash
= sds_header
->hash
;
2863 idx_entry_sdh
->key
.sdh
.security_id
= sds_header
->security_id
;
2864 sdh_data
= (SDH_INDEX_DATA
*)((u8
*)idx_entry_sdh
+
2865 le16_to_cpu(idx_entry_sdh
->data_offset
));
2866 sdh_data
->hash
= sds_header
->hash
;
2867 sdh_data
->security_id
= sds_header
->security_id
;
2868 sdh_data
->offset
= sds_header
->offset
;
2869 sdh_data
->length
= sds_header
->length
;
2870 sdh_data
->reserved_II
= const_cpu_to_le32(0x00490049);
2872 /* SII index entry */
2873 idx_entry_sii
->data_offset
= const_cpu_to_le16(0x14);
2874 idx_entry_sii
->data_length
= const_cpu_to_le16(0x14);
2875 idx_entry_sii
->reservedV
= const_cpu_to_le32(0x00);
2876 idx_entry_sii
->length
= const_cpu_to_le16(0x28);
2877 idx_entry_sii
->key_length
= const_cpu_to_le16(0x04);
2878 idx_entry_sii
->ie_flags
= const_cpu_to_le16(0x00);
2879 idx_entry_sii
->reserved
= const_cpu_to_le16(0x00);
2880 idx_entry_sii
->key
.sii
.security_id
= sds_header
->security_id
;
2881 sii_data
= (SII_INDEX_DATA
*)((u8
*)idx_entry_sii
+
2882 le16_to_cpu(idx_entry_sii
->data_offset
));
2883 sii_data
->hash
= sds_header
->hash
;
2884 sii_data
->security_id
= sds_header
->security_id
;
2885 sii_data
->offset
= sds_header
->offset
;
2886 sii_data
->length
= sds_header
->length
;
2887 if ((err
= insert_index_entry_in_res_dir_index(idx_entry_sdh
,
2888 sdh_size
, m
, NTFS_INDEX_SDH
, 4, AT_UNUSED
)))
2890 if ((err
= insert_index_entry_in_res_dir_index(idx_entry_sii
,
2891 sii_size
, m
, NTFS_INDEX_SII
, 4, AT_UNUSED
)))
2893 sds_header
= (SECURITY_DESCRIPTOR_HEADER
*)((u8
*)sds_header
+
2894 ((le32_to_cpu(sds_header
->length
) + 15) & ~15));
2896 free(idx_entry_sdh
);
2897 free(idx_entry_sii
);
2904 * initialize $Quota with the default quota index-entries.
2906 static int initialize_quota(MFT_RECORD
*m
)
2908 int o_size
, q1_size
, q2_size
, err
, i
;
2909 INDEX_ENTRY
*idx_entry_o
, *idx_entry_q1
, *idx_entry_q2
;
2910 QUOTA_O_INDEX_DATA
*idx_entry_o_data
;
2911 QUOTA_CONTROL_ENTRY
*idx_entry_q1_data
, *idx_entry_q2_data
;
2914 /* q index entry num 1 */
2916 idx_entry_q1
= ntfs_calloc(q1_size
);
2919 idx_entry_q1
->data_offset
= const_cpu_to_le16(0x14);
2920 idx_entry_q1
->data_length
= const_cpu_to_le16(0x30);
2921 idx_entry_q1
->reservedV
= const_cpu_to_le32(0x00);
2922 idx_entry_q1
->length
= const_cpu_to_le16(0x48);
2923 idx_entry_q1
->key_length
= const_cpu_to_le16(0x04);
2924 idx_entry_q1
->ie_flags
= const_cpu_to_le16(0x00);
2925 idx_entry_q1
->reserved
= const_cpu_to_le16(0x00);
2926 idx_entry_q1
->key
.owner_id
= const_cpu_to_le32(0x01);
2927 idx_entry_q1_data
= (QUOTA_CONTROL_ENTRY
*)((char*)idx_entry_q1
2928 + le16_to_cpu(idx_entry_q1
->data_offset
));
2929 idx_entry_q1_data
->version
= const_cpu_to_le32(0x02);
2930 idx_entry_q1_data
->flags
= QUOTA_FLAG_DEFAULT_LIMITS
;
2931 idx_entry_q1_data
->bytes_used
= const_cpu_to_le64(0x00);
2932 idx_entry_q1_data
->change_time
= mkntfs_time();
2933 idx_entry_q1_data
->threshold
= const_cpu_to_sle64(-1);
2934 idx_entry_q1_data
->limit
= const_cpu_to_sle64(-1);
2935 idx_entry_q1_data
->exceeded_time
= const_cpu_to_sle64(0);
2936 err
= insert_index_entry_in_res_dir_index(idx_entry_q1
, q1_size
, m
,
2937 NTFS_INDEX_Q
, 2, AT_UNUSED
);
2941 /* q index entry num 2 */
2943 idx_entry_q2
= ntfs_calloc(q2_size
);
2946 idx_entry_q2
->data_offset
= const_cpu_to_le16(0x14);
2947 idx_entry_q2
->data_length
= const_cpu_to_le16(0x40);
2948 idx_entry_q2
->reservedV
= const_cpu_to_le32(0x00);
2949 idx_entry_q2
->length
= const_cpu_to_le16(0x58);
2950 idx_entry_q2
->key_length
= const_cpu_to_le16(0x04);
2951 idx_entry_q2
->ie_flags
= const_cpu_to_le16(0x00);
2952 idx_entry_q2
->reserved
= const_cpu_to_le16(0x00);
2953 idx_entry_q2
->key
.owner_id
= QUOTA_FIRST_USER_ID
;
2954 idx_entry_q2_data
= (QUOTA_CONTROL_ENTRY
*)((char*)idx_entry_q2
2955 + le16_to_cpu(idx_entry_q2
->data_offset
));
2956 idx_entry_q2_data
->version
= const_cpu_to_le32(0x02);
2957 idx_entry_q2_data
->flags
= QUOTA_FLAG_DEFAULT_LIMITS
;
2958 idx_entry_q2_data
->bytes_used
= const_cpu_to_le64(0x00);
2959 idx_entry_q2_data
->change_time
= mkntfs_time();
2960 idx_entry_q2_data
->threshold
= const_cpu_to_sle64(-1);
2961 idx_entry_q2_data
->limit
= const_cpu_to_sle64(-1);
2962 idx_entry_q2_data
->exceeded_time
= const_cpu_to_sle64(0);
2963 idx_entry_q2_data
->sid
.revision
= 1;
2964 idx_entry_q2_data
->sid
.sub_authority_count
= 2;
2965 for (i
= 0; i
< 5; i
++)
2966 idx_entry_q2_data
->sid
.identifier_authority
.value
[i
] = 0;
2967 idx_entry_q2_data
->sid
.identifier_authority
.value
[5] = 0x05;
2968 idx_entry_q2_data
->sid
.sub_authority
[0] =
2969 const_cpu_to_le32(SECURITY_BUILTIN_DOMAIN_RID
);
2970 idx_entry_q2_data
->sid
.sub_authority
[1] =
2971 const_cpu_to_le32(DOMAIN_ALIAS_RID_ADMINS
);
2972 err
= insert_index_entry_in_res_dir_index(idx_entry_q2
, q2_size
, m
,
2973 NTFS_INDEX_Q
, 2, AT_UNUSED
);
2978 idx_entry_o
= ntfs_calloc(o_size
);
2981 idx_entry_o
->data_offset
= const_cpu_to_le16(0x20);
2982 idx_entry_o
->data_length
= const_cpu_to_le16(0x04);
2983 idx_entry_o
->reservedV
= const_cpu_to_le32(0x00);
2984 idx_entry_o
->length
= const_cpu_to_le16(0x28);
2985 idx_entry_o
->key_length
= const_cpu_to_le16(0x10);
2986 idx_entry_o
->ie_flags
= const_cpu_to_le16(0x00);
2987 idx_entry_o
->reserved
= const_cpu_to_le16(0x00);
2988 idx_entry_o
->key
.sid
.revision
= 0x01;
2989 idx_entry_o
->key
.sid
.sub_authority_count
= 0x02;
2990 for (i
= 0; i
< 5; i
++)
2991 idx_entry_o
->key
.sid
.identifier_authority
.value
[i
] = 0;
2992 idx_entry_o
->key
.sid
.identifier_authority
.value
[5] = 0x05;
2993 idx_entry_o
->key
.sid
.sub_authority
[0] =
2994 const_cpu_to_le32(SECURITY_BUILTIN_DOMAIN_RID
);
2995 idx_entry_o
->key
.sid
.sub_authority
[1] =
2996 const_cpu_to_le32(DOMAIN_ALIAS_RID_ADMINS
);
2997 idx_entry_o_data
= (QUOTA_O_INDEX_DATA
*)((char*)idx_entry_o
2998 + le16_to_cpu(idx_entry_o
->data_offset
));
2999 idx_entry_o_data
->owner_id
= QUOTA_FIRST_USER_ID
;
3000 /* 20 00 00 00 padding after here on ntfs 3.1. 3.0 is unchecked. */
3001 idx_entry_o_data
->unknown
= const_cpu_to_le32(32);
3002 err
= insert_index_entry_in_res_dir_index(idx_entry_o
, o_size
, m
,
3003 NTFS_INDEX_O
, 2, AT_UNUSED
);
3010 * insert_file_link_in_dir_index
3012 * Insert the fully completed FILE_NAME_ATTR @file_name which is inside
3013 * the file with mft reference @file_ref into the index (allocation) block
3014 * @idx (which belongs to @file_ref's parent directory).
3016 * Return 0 on success or -errno on error.
3018 static int insert_file_link_in_dir_index(INDEX_BLOCK
*idx
, leMFT_REF file_ref
,
3019 FILE_NAME_ATTR
*file_name
, u32 file_name_size
)
3026 * Lookup dir entry @file_name in dir @idx to determine correct
3027 * insertion location. FIXME: Using a very oversimplified lookup
3028 * method which is sufficient for mkntfs but no good whatsoever in
3029 * real world scenario. (AIA)
3032 index_end
= (char*)&idx
->index
+ le32_to_cpu(idx
->index
.index_length
);
3033 ie
= (INDEX_ENTRY
*)((char*)&idx
->index
+
3034 le32_to_cpu(idx
->index
.entries_offset
));
3036 * Loop until we exceed valid memory (corruption case) or until we
3037 * reach the last entry.
3039 while ((char*)ie
< index_end
&& !(ie
->ie_flags
& INDEX_ENTRY_END
)) {
3042 ntfs_log_debug("file_name_attr1->file_name_length = %i\n",
3043 file_name
->file_name_length
);
3044 if (file_name
->file_name_length
) {
3046 i
= ntfs_ucstombs((ntfschar
*)&file_name
->file_name
,
3047 file_name
->file_name_length
, &__buf
, 0);
3049 ntfs_log_debug("Name contains non-displayable "
3050 "Unicode characters.\n");
3051 ntfs_log_debug("file_name_attr1->file_name = %s\n",
3055 ntfs_log_debug("file_name_attr2->file_name_length = %i\n",
3056 ie
->key
.file_name
.file_name_length
);
3057 if (ie
->key
.file_name
.file_name_length
) {
3059 i
= ntfs_ucstombs(ie
->key
.file_name
.file_name
,
3060 ie
->key
.file_name
.file_name_length
+ 1, &__buf
,
3063 ntfs_log_debug("Name contains non-displayable "
3064 "Unicode characters.\n");
3065 ntfs_log_debug("file_name_attr2->file_name = %s\n",
3072 i = ntfs_file_values_compare(file_name,
3073 (FILE_NAME_ATTR*)&ie->key.file_name, 1,
3074 IGNORE_CASE, g_vol->upcase, g_vol->upcase_len);
3076 i
= ntfs_names_full_collate(file_name
->file_name
, file_name
->file_name_length
,
3077 ((FILE_NAME_ATTR
*)&ie
->key
.file_name
)->file_name
, ((FILE_NAME_ATTR
*)&ie
->key
.file_name
)->file_name_length
,
3078 IGNORE_CASE
, g_vol
->upcase
, g_vol
->upcase_len
);
3080 * If @file_name collates before ie->key.file_name, there is no
3081 * matching index entry.
3085 /* If file names are not equal, continue search. */
3088 /* File names are equal when compared ignoring case. */
3090 * If BOTH file names are in the POSIX namespace, do a case
3091 * sensitive comparison as well. Otherwise the names match so
3092 * we return -EEXIST. FIXME: There are problems with this in a
3093 * real world scenario, when one is POSIX and one isn't, but
3094 * fine for mkntfs where we don't use POSIX namespace at all
3095 * and hence this following code is luxury. (AIA)
3097 if (file_name
->file_name_type
!= FILE_NAME_POSIX
||
3098 ie
->key
.file_name
.file_name_type
!= FILE_NAME_POSIX
)
3101 i = ntfs_file_values_compare(file_name,
3102 (FILE_NAME_ATTR*)&ie->key.file_name, 1,
3103 CASE_SENSITIVE, g_vol->upcase,
3106 i
= ntfs_names_full_collate(file_name
->file_name
, file_name
->file_name_length
,
3107 ((FILE_NAME_ATTR
*)&ie
->key
.file_name
)->file_name
, ((FILE_NAME_ATTR
*)&ie
->key
.file_name
)->file_name_length
,
3108 CASE_SENSITIVE
, g_vol
->upcase
, g_vol
->upcase_len
);
3111 /* Complete match. Bugger. Can't insert. */
3118 ntfs_log_debug("BUG: ie->length is zero, breaking out "
3123 ie
= (INDEX_ENTRY
*)((char*)ie
+ le16_to_cpu(ie
->length
));
3125 i
= (sizeof(INDEX_ENTRY_HEADER
) + file_name_size
+ 7) & ~7;
3126 err
= make_room_for_index_entry_in_index_block(idx
, ie
, i
);
3128 ntfs_log_error("make_room_for_index_entry_in_index_block "
3129 "failed: %s\n", strerror(-err
));
3132 /* Create entry in place and copy file name attribute value. */
3133 ie
->indexed_file
= file_ref
;
3134 ie
->length
= cpu_to_le16(i
);
3135 ie
->key_length
= cpu_to_le16(file_name_size
);
3136 ie
->ie_flags
= const_cpu_to_le16(0);
3137 ie
->reserved
= const_cpu_to_le16(0);
3138 memcpy((char*)&ie
->key
.file_name
, (char*)file_name
, file_name_size
);
3143 * create_hardlink_res
3145 * Create a file_name_attribute in the mft record @m_file which points to the
3146 * parent directory with mft reference @ref_parent.
3148 * Then, insert an index entry with this file_name_attribute in the index
3149 * root @idx of the index_root attribute of the parent directory.
3151 * @ref_file is the mft reference of @m_file.
3153 * Return 0 on success or -errno on error.
3155 static int create_hardlink_res(MFT_RECORD
*m_parent
, const leMFT_REF ref_parent
,
3156 MFT_RECORD
*m_file
, const leMFT_REF ref_file
,
3157 const s64 allocated_size
, const s64 data_size
,
3158 const FILE_ATTR_FLAGS flags
, const u16 packed_ea_size
,
3159 const u32 reparse_point_tag
, const char *file_name
,
3160 const FILE_NAME_TYPE_FLAGS file_name_type
)
3163 int i
, fn_size
, idx_size
;
3164 INDEX_ENTRY
*idx_entry_new
;
3167 /* Create the file_name attribute. */
3168 i
= (strlen(file_name
) + 1) * sizeof(ntfschar
);
3169 fn_size
= sizeof(FILE_NAME_ATTR
) + i
;
3170 fn
= ntfs_malloc(fn_size
);
3173 fn
->parent_directory
= ref_parent
;
3174 fn
->creation_time
= stdinfo_time(m_file
);
3175 fn
->last_data_change_time
= fn
->creation_time
;
3176 fn
->last_mft_change_time
= fn
->creation_time
;
3177 fn
->last_access_time
= fn
->creation_time
;
3178 fn
->allocated_size
= cpu_to_sle64(allocated_size
);
3179 fn
->data_size
= cpu_to_sle64(data_size
);
3180 fn
->file_attributes
= flags
;
3181 /* These are in a union so can't have both. */
3182 if (packed_ea_size
&& reparse_point_tag
) {
3186 if (packed_ea_size
) {
3190 if (packed_ea_size
) {
3191 fn
->packed_ea_size
= cpu_to_le16(packed_ea_size
);
3192 fn
->reserved
= const_cpu_to_le16(0);
3194 fn
->reparse_point_tag
= cpu_to_le32(reparse_point_tag
);
3196 fn
->file_name_type
= file_name_type
;
3197 uname
= fn
->file_name
;
3198 i
= ntfs_mbstoucs_libntfscompat(file_name
, &uname
, i
);
3205 return -ENAMETOOLONG
;
3207 /* No terminating null in file names. */
3208 fn
->file_name_length
= i
;
3209 fn_size
= sizeof(FILE_NAME_ATTR
) + i
* sizeof(ntfschar
);
3210 /* Increment the link count of @m_file. */
3211 i
= le16_to_cpu(m_file
->link_count
);
3213 ntfs_log_error("Too many hardlinks present already.\n");
3217 m_file
->link_count
= cpu_to_le16(i
+ 1);
3218 /* Add the file_name to @m_file. */
3219 i
= insert_resident_attr_in_mft_record(m_file
, AT_FILE_NAME
, NULL
, 0,
3220 CASE_SENSITIVE
, const_cpu_to_le16(0),
3221 RESIDENT_ATTR_IS_INDEXED
, (u8
*)fn
, fn_size
);
3223 ntfs_log_error("create_hardlink failed adding file name "
3224 "attribute: %s\n", strerror(-i
));
3226 /* Undo link count increment. */
3227 m_file
->link_count
= cpu_to_le16(
3228 le16_to_cpu(m_file
->link_count
) - 1);
3231 /* Insert the index entry for file_name in @idx. */
3232 idx_size
= (fn_size
+ 7) & ~7;
3233 idx_entry_new
= ntfs_calloc(idx_size
+ 0x10);
3236 idx_entry_new
->indexed_file
= ref_file
;
3237 idx_entry_new
->length
= cpu_to_le16(idx_size
+ 0x10);
3238 idx_entry_new
->key_length
= cpu_to_le16(fn_size
);
3239 memcpy((u8
*)idx_entry_new
+ 0x10, (u8
*)fn
, fn_size
);
3240 i
= insert_index_entry_in_res_dir_index(idx_entry_new
, idx_size
+ 0x10,
3241 m_parent
, NTFS_INDEX_I30
, 4, AT_FILE_NAME
);
3243 ntfs_log_error("create_hardlink failed inserting index entry: "
3244 "%s\n", strerror(-i
));
3245 /* FIXME: Remove the file name attribute from @m_file. */
3246 free(idx_entry_new
);
3248 /* Undo link count increment. */
3249 m_file
->link_count
= cpu_to_le16(
3250 le16_to_cpu(m_file
->link_count
) - 1);
3253 free(idx_entry_new
);
3261 * Create a file_name_attribute in the mft record @m_file which points to the
3262 * parent directory with mft reference @ref_parent.
3264 * Then, insert an index entry with this file_name_attribute in the index
3265 * block @idx of the index allocation attribute of the parent directory.
3267 * @ref_file is the mft reference of @m_file.
3269 * Return 0 on success or -errno on error.
3271 static int create_hardlink(INDEX_BLOCK
*idx
, const leMFT_REF ref_parent
,
3272 MFT_RECORD
*m_file
, const leMFT_REF ref_file
,
3273 const s64 allocated_size
, const s64 data_size
,
3274 const FILE_ATTR_FLAGS flags
, const u16 packed_ea_size
,
3275 const u32 reparse_point_tag
, const char *file_name
,
3276 const FILE_NAME_TYPE_FLAGS file_name_type
)
3282 /* Create the file_name attribute. */
3283 i
= (strlen(file_name
) + 1) * sizeof(ntfschar
);
3284 fn_size
= sizeof(FILE_NAME_ATTR
) + i
;
3285 fn
= ntfs_malloc(fn_size
);
3288 fn
->parent_directory
= ref_parent
;
3289 fn
->creation_time
= stdinfo_time(m_file
);
3290 fn
->last_data_change_time
= fn
->creation_time
;
3291 fn
->last_mft_change_time
= fn
->creation_time
;
3292 fn
->last_access_time
= fn
->creation_time
;
3293 /* allocated size depends on unnamed data being resident */
3294 if (allocated_size
&& non_resident_unnamed_data(m_file
))
3295 fn
->allocated_size
= cpu_to_sle64(allocated_size
);
3297 fn
->allocated_size
= cpu_to_sle64((data_size
+ 7) & -8);
3298 fn
->data_size
= cpu_to_sle64(data_size
);
3299 fn
->file_attributes
= flags
;
3300 /* These are in a union so can't have both. */
3301 if (packed_ea_size
&& reparse_point_tag
) {
3305 if (packed_ea_size
) {
3306 fn
->packed_ea_size
= cpu_to_le16(packed_ea_size
);
3307 fn
->reserved
= const_cpu_to_le16(0);
3309 fn
->reparse_point_tag
= cpu_to_le32(reparse_point_tag
);
3311 fn
->file_name_type
= file_name_type
;
3312 uname
= fn
->file_name
;
3313 i
= ntfs_mbstoucs_libntfscompat(file_name
, &uname
, i
);
3320 return -ENAMETOOLONG
;
3322 /* No terminating null in file names. */
3323 fn
->file_name_length
= i
;
3324 fn_size
= sizeof(FILE_NAME_ATTR
) + i
* sizeof(ntfschar
);
3325 /* Increment the link count of @m_file. */
3326 i
= le16_to_cpu(m_file
->link_count
);
3328 ntfs_log_error("Too many hardlinks present already.\n");
3332 m_file
->link_count
= cpu_to_le16(i
+ 1);
3333 /* Add the file_name to @m_file. */
3334 i
= insert_resident_attr_in_mft_record(m_file
, AT_FILE_NAME
, NULL
, 0,
3335 CASE_SENSITIVE
, const_cpu_to_le16(0),
3336 RESIDENT_ATTR_IS_INDEXED
, (u8
*)fn
, fn_size
);
3338 ntfs_log_error("create_hardlink failed adding file name attribute: "
3339 "%s\n", strerror(-i
));
3341 /* Undo link count increment. */
3342 m_file
->link_count
= cpu_to_le16(
3343 le16_to_cpu(m_file
->link_count
) - 1);
3346 /* Insert the index entry for file_name in @idx. */
3347 i
= insert_file_link_in_dir_index(idx
, ref_file
, fn
, fn_size
);
3349 ntfs_log_error("create_hardlink failed inserting index entry: %s\n",
3351 /* FIXME: Remove the file name attribute from @m_file. */
3353 /* Undo link count increment. */
3354 m_file
->link_count
= cpu_to_le16(
3355 le16_to_cpu(m_file
->link_count
) - 1);
3363 * index_obj_id_insert
3365 * Insert an index entry with the key @guid and data pointing to the mft record
3366 * @ref in the $O index root of the mft record @m (which must be the mft record
3369 * Return 0 on success or -errno on error.
3371 static int index_obj_id_insert(MFT_RECORD
*m
, const GUID
*guid
,
3372 const leMFT_REF ref
)
3374 INDEX_ENTRY
*idx_entry_new
;
3375 int data_ofs
, idx_size
, err
;
3376 OBJ_ID_INDEX_DATA
*oi
;
3379 * Insert the index entry for the object id in the index.
3381 * First determine the size of the index entry to be inserted. This
3382 * consists of the index entry header, followed by the index key, i.e.
3383 * the GUID, followed by the index data, i.e. OBJ_ID_INDEX_DATA.
3385 data_ofs
= (sizeof(INDEX_ENTRY_HEADER
) + sizeof(GUID
) + 7) & ~7;
3386 idx_size
= (data_ofs
+ sizeof(OBJ_ID_INDEX_DATA
) + 7) & ~7;
3387 idx_entry_new
= ntfs_calloc(idx_size
);
3390 idx_entry_new
->data_offset
= cpu_to_le16(data_ofs
);
3391 idx_entry_new
->data_length
=
3392 const_cpu_to_le16(sizeof(OBJ_ID_INDEX_DATA
));
3393 idx_entry_new
->length
= cpu_to_le16(idx_size
);
3394 idx_entry_new
->key_length
= const_cpu_to_le16(sizeof(GUID
));
3395 idx_entry_new
->key
.object_id
= *guid
;
3396 oi
= (OBJ_ID_INDEX_DATA
*)((u8
*)idx_entry_new
+ data_ofs
);
3397 oi
->mft_reference
= ref
;
3398 err
= insert_index_entry_in_res_dir_index(idx_entry_new
, idx_size
, m
,
3399 NTFS_INDEX_O
, 2, AT_UNUSED
);
3400 free(idx_entry_new
);
3402 ntfs_log_error("index_obj_id_insert failed inserting index "
3403 "entry: %s\n", strerror(-err
));
3412 static void mkntfs_cleanup(void)
3414 struct BITMAP_ALLOCATION
*p
, *q
;
3416 /* Close the volume */
3419 if (NDevOpen(g_vol
->dev
) && g_vol
->dev
->d_ops
->close(g_vol
->dev
))
3420 ntfs_log_perror("Warning: Could not close %s", g_vol
->dev
->d_name
);
3421 ntfs_device_free(g_vol
->dev
);
3423 free(g_vol
->vol_name
);
3424 free(g_vol
->attrdef
);
3425 free(g_vol
->upcase
);
3430 /* Free any memory we've used */
3431 free(g_bad_blocks
); g_bad_blocks
= NULL
;
3432 free(g_buf
); g_buf
= NULL
;
3433 free(g_index_block
); g_index_block
= NULL
;
3434 free(g_dynamic_buf
); g_dynamic_buf
= NULL
;
3435 free(g_mft_bitmap
); g_mft_bitmap
= NULL
;
3436 free(g_rl_bad
); g_rl_bad
= NULL
;
3437 free(g_rl_boot
); g_rl_boot
= NULL
;
3438 free(g_rl_logfile
); g_rl_logfile
= NULL
;
3439 free(g_rl_mft
); g_rl_mft
= NULL
;
3440 free(g_rl_mft_bmp
); g_rl_mft_bmp
= NULL
;
3441 free(g_rl_mftmirr
); g_rl_mftmirr
= NULL
;
3453 * mkntfs_open_partition -
3455 static BOOL
mkntfs_open_partition(ntfs_volume
*vol
)
3457 BOOL result
= FALSE
;
3460 unsigned long mnt_flags
;
3463 * Allocate and initialize an ntfs device structure and attach it to
3466 vol
->dev
= ntfs_device_alloc(opts
.dev_name
, 0, &ntfs_device_default_io_ops
, NULL
);
3468 ntfs_log_perror("Could not create device");
3472 /* Open the device for reading or reading and writing. */
3473 if (opts
.no_action
) {
3474 ntfs_log_quiet("Running in READ-ONLY mode!\n");
3479 if (vol
->dev
->d_ops
->open(vol
->dev
, i
)) {
3480 if (errno
== ENOENT
)
3481 ntfs_log_error("The device doesn't exist; did you specify it correctly?\n");
3483 ntfs_log_perror("Could not open %s", vol
->dev
->d_name
);
3486 /* Verify we are dealing with a block device. */
3487 if (vol
->dev
->d_ops
->stat(vol
->dev
, &sbuf
)) {
3488 ntfs_log_perror("Error getting information about %s", vol
->dev
->d_name
);
3492 if (!S_ISBLK(sbuf
.st_mode
)) {
3493 ntfs_log_error("%s is not a block device.\n", vol
->dev
->d_name
);
3495 ntfs_log_error("Refusing to make a filesystem here!\n");
3498 if (!opts
.num_sectors
) {
3499 if (!sbuf
.st_size
&& !sbuf
.st_blocks
) {
3500 ntfs_log_error("You must specify the number of sectors.\n");
3503 if (opts
.sector_size
) {
3505 opts
.num_sectors
= sbuf
.st_size
/ opts
.sector_size
;
3507 opts
.num_sectors
= ((s64
)sbuf
.st_blocks
<< 9) / opts
.sector_size
;
3510 opts
.num_sectors
= sbuf
.st_size
/ 512;
3512 opts
.num_sectors
= sbuf
.st_blocks
;
3513 opts
.sector_size
= 512;
3516 ntfs_log_warning("mkntfs forced anyway.\n");
3517 #ifdef HAVE_LINUX_MAJOR_H
3518 } else if ((IDE_DISK_MAJOR(MAJOR(sbuf
.st_rdev
)) &&
3519 MINOR(sbuf
.st_rdev
) % 64 == 0) ||
3520 (SCSI_DISK_MAJOR(MAJOR(sbuf
.st_rdev
)) &&
3521 MINOR(sbuf
.st_rdev
) % 16 == 0)) {
3522 ntfs_log_error("%s is entire device, not just one partition.\n", vol
->dev
->d_name
);
3524 ntfs_log_error("Refusing to make a filesystem here!\n");
3527 ntfs_log_warning("mkntfs forced anyway.\n");
3530 /* Make sure the file system is not mounted. */
3531 if (ntfs_check_if_mounted(vol
->dev
->d_name
, &mnt_flags
)) {
3532 ntfs_log_perror("Failed to determine whether %s is mounted", vol
->dev
->d_name
);
3533 } else if (mnt_flags
& NTFS_MF_MOUNTED
) {
3534 ntfs_log_error("%s is mounted.\n", vol
->dev
->d_name
);
3536 ntfs_log_error("Refusing to make a filesystem here!\n");
3539 ntfs_log_warning("mkntfs forced anyway. Hope /etc/mtab is incorrect.\n");
3547 * mkntfs_get_page_size - detect the system's memory page size.
3549 static long mkntfs_get_page_size(void)
3553 page_size
= sysconf(_SC_PAGESIZE
);
3557 ntfs_log_warning("Failed to determine system page size. "
3558 "Assuming safe default of 4096 bytes.\n");
3561 ntfs_log_debug("System page size is %li bytes.\n", page_size
);
3566 * mkntfs_override_vol_params -
3568 static BOOL
mkntfs_override_vol_params(ntfs_volume
*vol
)
3573 BOOL winboot
= TRUE
;
3575 /* If user didn't specify the sector size, determine it now. */
3576 if (opts
.sector_size
< 0) {
3577 opts
.sector_size
= ntfs_device_sector_size_get(vol
->dev
);
3578 if (opts
.sector_size
< 0) {
3579 ntfs_log_warning("The sector size was not specified "
3580 "for %s and it could not be obtained "
3581 "automatically. It has been set to 512 "
3582 "bytes.\n", vol
->dev
->d_name
);
3583 opts
.sector_size
= 512;
3586 /* Validate sector size. */
3587 if ((opts
.sector_size
- 1) & opts
.sector_size
) {
3588 ntfs_log_error("The sector size is invalid. It must be a "
3589 "power of two, e.g. 512, 1024.\n");
3592 if (opts
.sector_size
< 256 || opts
.sector_size
> 4096) {
3593 ntfs_log_error("The sector size is invalid. The minimum size "
3594 "is 256 bytes and the maximum is 4096 bytes.\n");
3597 ntfs_log_debug("sector size = %ld bytes\n", opts
.sector_size
);
3598 /* Now set the device block size to the sector size. */
3599 if (ntfs_device_block_size_set(vol
->dev
, opts
.sector_size
))
3600 ntfs_log_debug("Failed to set the device block size to the "
3601 "sector size. This may cause problems when "
3602 "creating the backup boot sector and also may "
3603 "affect performance but should be harmless "
3604 "otherwise. Error: %s\n", strerror(errno
));
3605 /* If user didn't specify the number of sectors, determine it now. */
3606 if (opts
.num_sectors
< 0) {
3607 opts
.num_sectors
= ntfs_device_size_get(vol
->dev
,
3609 if (opts
.num_sectors
<= 0) {
3610 ntfs_log_error("Couldn't determine the size of %s. "
3611 "Please specify the number of sectors "
3612 "manually.\n", vol
->dev
->d_name
);
3616 ntfs_log_debug("number of sectors = %lld (0x%llx)\n", opts
.num_sectors
,
3619 * Reserve the last sector for the backup boot sector unless the
3620 * sector size is less than 512 bytes in which case reserve 512 bytes
3624 if (opts
.sector_size
< 512)
3625 i
= 512 / opts
.sector_size
;
3626 opts
.num_sectors
-= i
;
3627 /* If user didn't specify the partition start sector, determine it. */
3628 if (opts
.part_start_sect
< 0) {
3629 opts
.part_start_sect
= ntfs_device_partition_start_sector_get(
3631 if (opts
.part_start_sect
< 0) {
3632 ntfs_log_warning("The partition start sector was not "
3633 "specified for %s and it could not be obtained "
3634 "automatically. It has been set to 0.\n",
3636 opts
.part_start_sect
= 0;
3638 } else if (opts
.part_start_sect
>> 32) {
3639 ntfs_log_warning("The partition start sector specified "
3640 "for %s and the automatically determined value "
3641 "is too large. It has been set to 0.\n",
3643 opts
.part_start_sect
= 0;
3646 } else if (opts
.part_start_sect
>> 32) {
3647 ntfs_log_error("Invalid partition start sector. Maximum is "
3648 "4294967295 (2^32-1).\n");
3651 /* If user didn't specify the sectors per track, determine it now. */
3652 if (opts
.sectors_per_track
< 0) {
3653 opts
.sectors_per_track
= ntfs_device_sectors_per_track_get(
3655 if (opts
.sectors_per_track
< 0) {
3656 ntfs_log_warning("The number of sectors per track was "
3657 "not specified for %s and it could not be "
3658 "obtained automatically. It has been set to "
3659 "0.\n", vol
->dev
->d_name
);
3660 opts
.sectors_per_track
= 0;
3662 } else if (opts
.sectors_per_track
> 65535) {
3663 ntfs_log_warning("The number of sectors per track was "
3664 "not specified for %s and the automatically "
3665 "determined value is too large. It has been "
3666 "set to 0.\n", vol
->dev
->d_name
);
3667 opts
.sectors_per_track
= 0;
3670 } else if (opts
.sectors_per_track
> 65535) {
3671 ntfs_log_error("Invalid number of sectors per track. Maximum "
3675 /* If user didn't specify the number of heads, determine it now. */
3676 if (opts
.heads
< 0) {
3677 opts
.heads
= ntfs_device_heads_get(vol
->dev
);
3678 if (opts
.heads
< 0) {
3679 ntfs_log_warning("The number of heads was not "
3680 "specified for %s and it could not be obtained "
3681 "automatically. It has been set to 0.\n",
3685 } else if (opts
.heads
> 65535) {
3686 ntfs_log_warning("The number of heads was not "
3687 "specified for %s and the automatically "
3688 "determined value is too large. It has been "
3689 "set to 0.\n", vol
->dev
->d_name
);
3693 } else if (opts
.heads
> 65535) {
3694 ntfs_log_error("Invalid number of heads. Maximum is 65535.\n");
3697 volume_size
= opts
.num_sectors
* opts
.sector_size
;
3698 /* Validate volume size. */
3699 if (volume_size
< (1 << 20)) { /* 1MiB */
3700 ntfs_log_error("Device is too small (%llikiB). Minimum NTFS "
3701 "volume size is 1MiB.\n",
3702 (long long)(volume_size
/ 1024));
3705 ntfs_log_debug("volume size = %llikiB\n", volume_size
/ 1024);
3706 /* If user didn't specify the cluster size, determine it now. */
3707 if (!vol
->cluster_size
) {
3709 * Windows Vista always uses 4096 bytes as the default cluster
3710 * size regardless of the volume size so we do it, too.
3712 vol
->cluster_size
= 4096;
3713 /* For small volumes on devices with large sector sizes. */
3714 if (vol
->cluster_size
< (u32
)opts
.sector_size
)
3715 vol
->cluster_size
= opts
.sector_size
;
3717 * For huge volumes, grow the cluster size until the number of
3718 * clusters fits into 32 bits or the cluster size exceeds the
3719 * maximum limit of 64kiB.
3721 while (volume_size
>> (ffs(vol
->cluster_size
) - 1 + 32)) {
3722 vol
->cluster_size
<<= 1;
3723 if (vol
->cluster_size
> 65535) {
3724 ntfs_log_error("Device is too large to hold an "
3725 "NTFS volume (maximum size is "
3730 ntfs_log_quiet("Cluster size has been automatically set to %u "
3731 "bytes.\n", (unsigned)vol
->cluster_size
);
3733 /* Validate cluster size. */
3734 if (vol
->cluster_size
& (vol
->cluster_size
- 1)) {
3735 ntfs_log_error("The cluster size is invalid. It must be a "
3736 "power of two, e.g. 1024, 4096.\n");
3739 if (vol
->cluster_size
< (u32
)opts
.sector_size
) {
3740 ntfs_log_error("The cluster size is invalid. It must be equal "
3741 "to, or larger than, the sector size.\n");
3744 if (vol
->cluster_size
> 128 * (u32
)opts
.sector_size
) {
3745 ntfs_log_error("The cluster size is invalid. It cannot be "
3746 "more that 128 times the size of the sector "
3750 if (vol
->cluster_size
> 65536) {
3751 ntfs_log_error("The cluster size is invalid. The maximum "
3752 "cluster size is 65536 bytes (64kiB).\n");
3755 vol
->cluster_size_bits
= ffs(vol
->cluster_size
) - 1;
3756 ntfs_log_debug("cluster size = %u bytes\n",
3757 (unsigned int)vol
->cluster_size
);
3758 if (vol
->cluster_size
> 4096) {
3759 if (opts
.enable_compression
) {
3761 ntfs_log_error("Windows cannot use compression "
3762 "when the cluster size is "
3763 "larger than 4096 bytes.\n");
3766 opts
.enable_compression
= 0;
3768 ntfs_log_warning("Windows cannot use compression when the "
3769 "cluster size is larger than 4096 bytes. "
3770 "Compression has been disabled for this "
3773 vol
->nr_clusters
= volume_size
/ vol
->cluster_size
;
3775 * Check the cluster_size and num_sectors for consistency with
3776 * sector_size and num_sectors. And check both of these for consistency
3779 if ((vol
->nr_clusters
!= ((opts
.num_sectors
* opts
.sector_size
) /
3780 vol
->cluster_size
) ||
3781 (volume_size
/ opts
.sector_size
) != opts
.num_sectors
||
3782 (volume_size
/ vol
->cluster_size
) !=
3783 vol
->nr_clusters
)) {
3784 /* XXX is this code reachable? */
3785 ntfs_log_error("Illegal combination of volume/cluster/sector "
3786 "size and/or cluster/sector number.\n");
3789 ntfs_log_debug("number of clusters = %llu (0x%llx)\n",
3790 vol
->nr_clusters
, vol
->nr_clusters
);
3791 /* Number of clusters must fit within 32 bits (Win2k limitation). */
3792 if (vol
->nr_clusters
>> 32) {
3793 if (vol
->cluster_size
>= 65536) {
3794 ntfs_log_error("Device is too large to hold an NTFS "
3795 "volume (maximum size is 256TiB).\n");
3798 ntfs_log_error("Number of clusters exceeds 32 bits. Please "
3799 "try again with a larger\ncluster size or "
3800 "leave the cluster size unspecified and the "
3801 "smallest possible cluster size for the size "
3802 "of the device will be used.\n");
3805 page_size
= mkntfs_get_page_size();
3807 * Set the mft record size. By default this is 1024 but it has to be
3808 * at least as big as a sector and not bigger than a page on the system
3809 * or the NTFS kernel driver will not be able to mount the volume.
3810 * TODO: The mft record size should be user specifiable just like the
3811 * "inode size" can be specified on other Linux/Unix file systems.
3813 vol
->mft_record_size
= 1024;
3814 if (vol
->mft_record_size
< (u32
)opts
.sector_size
)
3815 vol
->mft_record_size
= opts
.sector_size
;
3816 if (vol
->mft_record_size
> (unsigned long)page_size
)
3817 ntfs_log_warning("Mft record size (%u bytes) exceeds system "
3818 "page size (%li bytes). You will not be able "
3819 "to mount this volume using the NTFS kernel "
3820 "driver.\n", (unsigned)vol
->mft_record_size
,
3822 vol
->mft_record_size_bits
= ffs(vol
->mft_record_size
) - 1;
3823 ntfs_log_debug("mft record size = %u bytes\n",
3824 (unsigned)vol
->mft_record_size
);
3826 * Set the index record size. By default this is 4096 but it has to be
3827 * at least as big as a sector and not bigger than a page on the system
3828 * or the NTFS kernel driver will not be able to mount the volume.
3829 * FIXME: Should we make the index record size to be user specifiable?
3831 vol
->indx_record_size
= 4096;
3832 if (vol
->indx_record_size
< (u32
)opts
.sector_size
)
3833 vol
->indx_record_size
= opts
.sector_size
;
3834 if (vol
->indx_record_size
> (unsigned long)page_size
)
3835 ntfs_log_warning("Index record size (%u bytes) exceeds system "
3836 "page size (%li bytes). You will not be able "
3837 "to mount this volume using the NTFS kernel "
3838 "driver.\n", (unsigned)vol
->indx_record_size
,
3840 vol
->indx_record_size_bits
= ffs(vol
->indx_record_size
) - 1;
3841 ntfs_log_debug("index record size = %u bytes\n",
3842 (unsigned)vol
->indx_record_size
);
3844 ntfs_log_warning("To boot from a device, Windows needs the "
3845 "'partition start sector', the 'sectors per "
3846 "track' and the 'number of heads' to be "
3848 ntfs_log_warning("Windows will not be able to boot from this "
3855 * mkntfs_initialize_bitmaps -
3857 static BOOL
mkntfs_initialize_bitmaps(void)
3860 int mft_bitmap_size
;
3862 /* Determine lcn bitmap byte size and allocate it. */
3863 g_lcn_bitmap_byte_size
= (g_vol
->nr_clusters
+ 7) >> 3;
3864 /* Needs to be multiple of 8 bytes. */
3865 g_lcn_bitmap_byte_size
= (g_lcn_bitmap_byte_size
+ 7) & ~7;
3866 i
= (g_lcn_bitmap_byte_size
+ g_vol
->cluster_size
- 1) &
3867 ~(g_vol
->cluster_size
- 1);
3868 ntfs_log_debug("g_lcn_bitmap_byte_size = %i, allocated = %llu\n",
3869 g_lcn_bitmap_byte_size
, i
);
3870 g_dynamic_buf_size
= mkntfs_get_page_size();
3871 g_dynamic_buf
= (u8
*)ntfs_calloc(g_dynamic_buf_size
);
3875 * $Bitmap can overlap the end of the volume. Any bits in this region
3876 * must be set. This region also encompasses the backup boot sector.
3878 if (!bitmap_allocate(g_vol
->nr_clusters
,
3879 ((s64
)g_lcn_bitmap_byte_size
<< 3) - g_vol
->nr_clusters
))
3882 * Mft size is 27 (NTFS 3.0+) mft records or one cluster, whichever is
3886 g_mft_size
*= g_vol
->mft_record_size
;
3887 if (g_mft_size
< (s32
)g_vol
->cluster_size
)
3888 g_mft_size
= g_vol
->cluster_size
;
3889 ntfs_log_debug("MFT size = %i (0x%x) bytes\n", g_mft_size
, g_mft_size
);
3890 /* Determine mft bitmap size and allocate it. */
3891 mft_bitmap_size
= g_mft_size
/ g_vol
->mft_record_size
;
3892 /* Convert to bytes, at least one. */
3893 g_mft_bitmap_byte_size
= (mft_bitmap_size
+ 7) >> 3;
3894 /* Mft bitmap is allocated in multiples of 8 bytes. */
3895 g_mft_bitmap_byte_size
= (g_mft_bitmap_byte_size
+ 7) & ~7;
3896 ntfs_log_debug("mft_bitmap_size = %i, g_mft_bitmap_byte_size = %i\n",
3897 mft_bitmap_size
, g_mft_bitmap_byte_size
);
3898 g_mft_bitmap
= ntfs_calloc(g_mft_bitmap_byte_size
);
3901 /* Create runlist for mft bitmap. */
3902 g_rl_mft_bmp
= ntfs_malloc(2 * sizeof(runlist
));
3906 g_rl_mft_bmp
[0].vcn
= 0LL;
3907 /* Mft bitmap is right after $Boot's data. */
3908 i
= (8192 + g_vol
->cluster_size
- 1) / g_vol
->cluster_size
;
3909 g_rl_mft_bmp
[0].lcn
= i
;
3911 * Size is always one cluster, even though valid data size and
3912 * initialized data size are only 8 bytes.
3914 g_rl_mft_bmp
[1].vcn
= 1LL;
3915 g_rl_mft_bmp
[0].length
= 1LL;
3916 g_rl_mft_bmp
[1].lcn
= -1LL;
3917 g_rl_mft_bmp
[1].length
= 0LL;
3918 /* Allocate cluster for mft bitmap. */
3919 return (bitmap_allocate(i
,1));
3923 * mkntfs_initialize_rl_mft -
3925 static BOOL
mkntfs_initialize_rl_mft(void)
3930 /* If user didn't specify the mft lcn, determine it now. */
3933 * We start at the higher value out of 16kiB and just after the
3936 g_mft_lcn
= g_rl_mft_bmp
[0].lcn
+ g_rl_mft_bmp
[0].length
;
3937 if (g_mft_lcn
* g_vol
->cluster_size
< 16 * 1024)
3938 g_mft_lcn
= (16 * 1024 + g_vol
->cluster_size
- 1) /
3939 g_vol
->cluster_size
;
3941 ntfs_log_debug("$MFT logical cluster number = 0x%llx\n", g_mft_lcn
);
3942 /* Determine MFT zone size. */
3943 g_mft_zone_end
= g_vol
->nr_clusters
;
3944 switch (opts
.mft_zone_multiplier
) { /* % of volume size in clusters */
3946 g_mft_zone_end
= g_mft_zone_end
>> 1; /* 50% */
3949 g_mft_zone_end
= g_mft_zone_end
* 3 >> 3;/* 37.5% */
3952 g_mft_zone_end
= g_mft_zone_end
>> 2; /* 25% */
3956 g_mft_zone_end
= g_mft_zone_end
>> 3; /* 12.5% */
3959 ntfs_log_debug("MFT zone size = %lldkiB\n", g_mft_zone_end
<<
3960 g_vol
->cluster_size_bits
>> 10 /* >> 10 == / 1024 */);
3962 * The mft zone begins with the mft data attribute, not at the beginning
3965 g_mft_zone_end
+= g_mft_lcn
;
3966 /* Create runlist for mft. */
3967 g_rl_mft
= ntfs_malloc(2 * sizeof(runlist
));
3971 g_rl_mft
[0].vcn
= 0LL;
3972 g_rl_mft
[0].lcn
= g_mft_lcn
;
3973 /* rounded up division by cluster size */
3974 j
= (g_mft_size
+ g_vol
->cluster_size
- 1) / g_vol
->cluster_size
;
3975 g_rl_mft
[1].vcn
= j
;
3976 g_rl_mft
[0].length
= j
;
3977 g_rl_mft
[1].lcn
= -1LL;
3978 g_rl_mft
[1].length
= 0LL;
3979 /* Allocate clusters for mft. */
3980 bitmap_allocate(g_mft_lcn
,j
);
3981 /* Determine mftmirr_lcn (middle of volume). */
3982 g_mftmirr_lcn
= (opts
.num_sectors
* opts
.sector_size
>> 1)
3983 / g_vol
->cluster_size
;
3984 ntfs_log_debug("$MFTMirr logical cluster number = 0x%llx\n",
3986 /* Create runlist for mft mirror. */
3987 g_rl_mftmirr
= ntfs_malloc(2 * sizeof(runlist
));
3991 g_rl_mftmirr
[0].vcn
= 0LL;
3992 g_rl_mftmirr
[0].lcn
= g_mftmirr_lcn
;
3994 * The mft mirror is either 4kb (the first four records) or one cluster
3995 * in size, which ever is bigger. In either case, it contains a
3996 * byte-for-byte identical copy of the beginning of the mft (i.e. either
3997 * the first four records (4kb) or the first cluster worth of records,
3998 * whichever is bigger).
4000 j
= (4 * g_vol
->mft_record_size
+ g_vol
->cluster_size
- 1) / g_vol
->cluster_size
;
4001 g_rl_mftmirr
[1].vcn
= j
;
4002 g_rl_mftmirr
[0].length
= j
;
4003 g_rl_mftmirr
[1].lcn
= -1LL;
4004 g_rl_mftmirr
[1].length
= 0LL;
4005 /* Allocate clusters for mft mirror. */
4006 done
= bitmap_allocate(g_mftmirr_lcn
,j
);
4007 g_logfile_lcn
= g_mftmirr_lcn
+ j
;
4008 ntfs_log_debug("$LogFile logical cluster number = 0x%llx\n",
4014 * mkntfs_initialize_rl_logfile -
4016 static BOOL
mkntfs_initialize_rl_logfile(void)
4021 /* Create runlist for log file. */
4022 g_rl_logfile
= ntfs_malloc(2 * sizeof(runlist
));
4027 volume_size
= g_vol
->nr_clusters
<< g_vol
->cluster_size_bits
;
4029 g_rl_logfile
[0].vcn
= 0LL;
4030 g_rl_logfile
[0].lcn
= g_logfile_lcn
;
4032 * Determine logfile_size from volume_size (rounded up to a cluster),
4033 * making sure it does not overflow the end of the volume.
4035 if (volume_size
< 2048LL * 1024) /* < 2MiB */
4036 g_logfile_size
= 256LL * 1024; /* -> 256kiB */
4037 else if (volume_size
< 4000000LL) /* < 4MB */
4038 g_logfile_size
= 512LL * 1024; /* -> 512kiB */
4039 else if (volume_size
<= 200LL * 1024 * 1024) /* < 200MiB */
4040 g_logfile_size
= 2048LL * 1024; /* -> 2MiB */
4043 * FIXME: The $LogFile size is 64 MiB upwards from 12GiB but
4044 * the "200" divider below apparently approximates "100" or
4045 * some other value as the volume size decreases. For example:
4046 * Volume size LogFile size Ratio
4047 * 8799808 46048 191.100
4048 * 8603248 45072 190.877
4049 * 7341704 38768 189.375
4050 * 6144828 32784 187.433
4051 * 4192932 23024 182.111
4053 if (volume_size
>= 12LL << 30) /* > 12GiB */
4054 g_logfile_size
= 64 << 20; /* -> 64MiB */
4056 g_logfile_size
= (volume_size
/ 200) &
4057 ~(g_vol
->cluster_size
- 1);
4059 j
= g_logfile_size
/ g_vol
->cluster_size
;
4060 while (g_rl_logfile
[0].lcn
+ j
>= g_vol
->nr_clusters
) {
4062 * $Logfile would overflow volume. Need to make it smaller than
4063 * the standard size. It's ok as we are creating a non-standard
4064 * volume anyway if it is that small.
4066 g_logfile_size
>>= 1;
4067 j
= g_logfile_size
/ g_vol
->cluster_size
;
4069 g_logfile_size
= (g_logfile_size
+ g_vol
->cluster_size
- 1) &
4070 ~(g_vol
->cluster_size
- 1);
4071 ntfs_log_debug("$LogFile (journal) size = %ikiB\n",
4072 g_logfile_size
/ 1024);
4074 * FIXME: The 256kiB limit is arbitrary. Should find out what the real
4075 * minimum requirement for Windows is so it doesn't blue screen.
4077 if (g_logfile_size
< 256 << 10) {
4078 ntfs_log_error("$LogFile would be created with invalid size. "
4079 "This is not allowed as it would cause Windows "
4080 "to blue screen and during boot.\n");
4083 g_rl_logfile
[1].vcn
= j
;
4084 g_rl_logfile
[0].length
= j
;
4085 g_rl_logfile
[1].lcn
= -1LL;
4086 g_rl_logfile
[1].length
= 0LL;
4087 /* Allocate clusters for log file. */
4088 return (bitmap_allocate(g_logfile_lcn
,j
));
4092 * mkntfs_initialize_rl_boot -
4094 static BOOL
mkntfs_initialize_rl_boot(void)
4097 /* Create runlist for $Boot. */
4098 g_rl_boot
= ntfs_malloc(2 * sizeof(runlist
));
4102 g_rl_boot
[0].vcn
= 0LL;
4103 g_rl_boot
[0].lcn
= 0LL;
4105 * $Boot is always 8192 (0x2000) bytes or 1 cluster, whichever is
4108 j
= (8192 + g_vol
->cluster_size
- 1) / g_vol
->cluster_size
;
4109 g_rl_boot
[1].vcn
= j
;
4110 g_rl_boot
[0].length
= j
;
4111 g_rl_boot
[1].lcn
= -1LL;
4112 g_rl_boot
[1].length
= 0LL;
4113 /* Allocate clusters for $Boot. */
4114 return (bitmap_allocate(0,j
));
4118 * mkntfs_initialize_rl_bad -
4120 static BOOL
mkntfs_initialize_rl_bad(void)
4122 /* Create runlist for $BadClus, $DATA named stream $Bad. */
4123 g_rl_bad
= ntfs_malloc(2 * sizeof(runlist
));
4127 g_rl_bad
[0].vcn
= 0LL;
4128 g_rl_bad
[0].lcn
= -1LL;
4130 * $BadClus named stream $Bad contains the whole volume as a single
4131 * sparse runlist entry.
4133 g_rl_bad
[1].vcn
= g_vol
->nr_clusters
;
4134 g_rl_bad
[0].length
= g_vol
->nr_clusters
;
4135 g_rl_bad
[1].lcn
= -1LL;
4136 g_rl_bad
[1].length
= 0LL;
4138 /* TODO: Mark bad blocks as such. */
4143 * mkntfs_fill_device_with_zeroes -
4145 static BOOL
mkntfs_fill_device_with_zeroes(void)
4148 * If not quick format, fill the device with 0s.
4149 * FIXME: Except bad blocks! (AIA)
4153 unsigned long long position
;
4154 float progress_inc
= (float)g_vol
->nr_clusters
/ 100;
4157 volume_size
= g_vol
->nr_clusters
<< g_vol
->cluster_size_bits
;
4159 ntfs_log_progress("Initializing device with zeroes: 0%%");
4160 for (position
= 0; position
< (unsigned long long)g_vol
->nr_clusters
;
4162 if (!(position
% (int)(progress_inc
+1))) {
4163 ntfs_log_progress("\b\b\b\b%3.0f%%", position
/
4166 bw
= mkntfs_write(g_vol
->dev
, g_buf
, g_vol
->cluster_size
);
4167 if (bw
!= (ssize_t
)g_vol
->cluster_size
) {
4168 if (bw
!= -1 || errno
!= EIO
) {
4169 ntfs_log_error("This should not happen.\n");
4173 ntfs_log_error("Error: Cluster zero is bad. "
4174 "Cannot create NTFS file "
4178 /* Add the baddie to our bad blocks list. */
4179 if (!append_to_bad_blocks(position
))
4181 ntfs_log_quiet("\nFound bad cluster (%lld). Adding to "
4182 "list of bad blocks.\nInitializing "
4183 "device with zeroes: %3.0f%%", position
,
4184 position
/ progress_inc
);
4185 /* Seek to next cluster. */
4186 g_vol
->dev
->d_ops
->seek(g_vol
->dev
,
4187 ((off_t
)position
+ 1) *
4188 g_vol
->cluster_size
, SEEK_SET
);
4191 ntfs_log_progress("\b\b\b\b100%%");
4192 position
= (volume_size
& (g_vol
->cluster_size
- 1)) /
4194 for (i
= 0; (unsigned long)i
< position
; i
++) {
4195 bw
= mkntfs_write(g_vol
->dev
, g_buf
, opts
.sector_size
);
4196 if (bw
!= opts
.sector_size
) {
4197 if (bw
!= -1 || errno
!= EIO
) {
4198 ntfs_log_error("This should not happen.\n");
4200 } else if (i
+ 1ull == position
) {
4201 ntfs_log_error("Error: Bad cluster found in "
4202 "location reserved for system "
4206 /* Seek to next sector. */
4207 g_vol
->dev
->d_ops
->seek(g_vol
->dev
,
4208 opts
.sector_size
, SEEK_CUR
);
4211 ntfs_log_progress(" - Done.\n");
4216 * mkntfs_sync_index_record
4218 * (ERSO) made a function out of this, but the reason for doing that
4219 * disappeared during coding....
4221 static BOOL
mkntfs_sync_index_record(INDEX_ALLOCATION
* idx
, MFT_RECORD
* m
,
4222 ntfschar
* name
, u32 name_len
)
4225 ntfs_attr_search_ctx
*ctx
;
4228 runlist
*rl_index
= NULL
;
4230 i
= 5 * sizeof(ntfschar
);
4231 ctx
= ntfs_attr_get_search_ctx(NULL
, m
);
4233 ntfs_log_perror("Failed to allocate attribute search context");
4236 /* FIXME: This should be IGNORE_CASE! */
4237 if (mkntfs_attr_lookup(AT_INDEX_ALLOCATION
, name
, name_len
,
4238 CASE_SENSITIVE
, 0, NULL
, 0, ctx
)) {
4239 ntfs_attr_put_search_ctx(ctx
);
4240 ntfs_log_error("BUG: $INDEX_ALLOCATION attribute not found.\n");
4244 rl_index
= ntfs_mapping_pairs_decompress(g_vol
, a
, NULL
);
4246 ntfs_attr_put_search_ctx(ctx
);
4247 ntfs_log_error("Failed to decompress runlist of $INDEX_ALLOCATION "
4251 if (sle64_to_cpu(a
->initialized_size
) < i
) {
4252 ntfs_attr_put_search_ctx(ctx
);
4254 ntfs_log_error("BUG: $INDEX_ALLOCATION attribute too short.\n");
4257 ntfs_attr_put_search_ctx(ctx
);
4258 i
= sizeof(INDEX_BLOCK
) - sizeof(INDEX_HEADER
) +
4259 le32_to_cpu(idx
->index
.allocated_size
);
4260 err
= ntfs_mst_pre_write_fixup((NTFS_RECORD
*)idx
, i
);
4263 ntfs_log_error("ntfs_mst_pre_write_fixup() failed while "
4264 "syncing index block.\n");
4267 lw
= ntfs_rlwrite(g_vol
->dev
, rl_index
, (u8
*)idx
, i
, NULL
,
4271 ntfs_log_error("Error writing $INDEX_ALLOCATION.\n");
4274 /* No more changes to @idx below here so no need for fixup: */
4275 /* ntfs_mst_post_write_fixup((NTFS_RECORD*)idx); */
4280 * create_file_volume -
4282 static BOOL
create_file_volume(MFT_RECORD
*m
, leMFT_REF root_ref
,
4283 VOLUME_FLAGS fl
, const GUID
*volume_guid
)
4288 ntfs_log_verbose("Creating $Volume (mft record 3)\n");
4289 m
= (MFT_RECORD
*)(g_buf
+ 3 * g_vol
->mft_record_size
);
4290 err
= create_hardlink(g_index_block
, root_ref
, m
,
4291 MK_LE_MREF(FILE_Volume
, FILE_Volume
), 0LL, 0LL,
4292 FILE_ATTR_HIDDEN
| FILE_ATTR_SYSTEM
, 0, 0,
4293 "$Volume", FILE_NAME_WIN32_AND_DOS
);
4295 init_system_file_sd(FILE_Volume
, &sd
, &i
);
4296 err
= add_attr_sd(m
, sd
, i
);
4299 err
= add_attr_data(m
, NULL
, 0, CASE_SENSITIVE
,
4300 const_cpu_to_le16(0), NULL
, 0);
4302 err
= add_attr_vol_name(m
, g_vol
->vol_name
, g_vol
->vol_name
?
4303 strlen(g_vol
->vol_name
) : 0);
4305 if (fl
& VOLUME_IS_DIRTY
)
4306 ntfs_log_quiet("Setting the volume dirty so check "
4307 "disk runs on next reboot into "
4309 err
= add_attr_vol_info(m
, fl
, g_vol
->major_ver
,
4312 if (!err
&& opts
.with_uuid
)
4313 err
= add_attr_object_id(m
, volume_guid
);
4315 ntfs_log_error("Couldn't create $Volume: %s\n",
4323 * create_backup_boot_sector
4325 * Return 0 on success or -1 if it couldn't be created.
4327 static int create_backup_boot_sector(u8
*buff
)
4333 ntfs_log_verbose("Creating backup boot sector.\n");
4335 * Write the first max(512, opts.sector_size) bytes from buf to the
4336 * last sector, but limit that to 8192 bytes of written data since that
4337 * is how big $Boot is (and how big our buffer is)..
4340 if (size
< opts
.sector_size
)
4341 size
= opts
.sector_size
;
4342 if (g_vol
->dev
->d_ops
->seek(g_vol
->dev
, (opts
.num_sectors
+ 1) *
4343 opts
.sector_size
- size
, SEEK_SET
) == (off_t
)-1) {
4344 ntfs_log_perror("Seek failed");
4349 bw
= mkntfs_write(g_vol
->dev
, buff
, size
);
4356 s
= "unknown error";
4357 /* At least some 2.4 kernels return EIO instead of ENOSPC. */
4358 if (bw
!= -1LL || (bw
== -1LL && e
!= ENOSPC
&& e
!= EIO
)) {
4359 ntfs_log_critical("Couldn't write backup boot sector: %s\n", s
);
4363 ntfs_log_error("Couldn't write backup boot sector. This is due to a "
4364 "limitation in the\nLinux kernel. This is not a major "
4365 "problem as Windows check disk will create the\n"
4366 "backup boot sector when it is run on your next boot "
4372 * mkntfs_create_root_structures -
4374 static BOOL
mkntfs_create_root_structures(void)
4376 NTFS_BOOT_SECTOR
*bs
;
4379 leMFT_REF extend_ref
;
4384 FILE_ATTR_FLAGS extend_flags
;
4385 VOLUME_FLAGS volume_flags
= const_cpu_to_le16(0);
4387 int buf_sds_first_size
;
4391 ntfs_log_quiet("Creating NTFS volume structures.\n");
4394 * Setup an empty mft record. Note, we can just give 0 as the mft
4395 * reference as we are creating an NTFS 1.2 volume for which the mft
4396 * reference is ignored by ntfs_mft_record_layout().
4398 * Copy the mft record onto all 16 records in the buffer and setup the
4399 * sequence numbers of each system file to equal the mft record number
4400 * of that file (only for $MFT is the sequence number 1 rather than 0).
4402 for (i
= 0; i
< nr_sysfiles
; i
++) {
4403 if (ntfs_mft_record_layout(g_vol
, 0, m
= (MFT_RECORD
*)(g_buf
+
4404 i
* g_vol
->mft_record_size
))) {
4405 ntfs_log_error("Failed to layout system mft records."
4409 if (i
== 0 || i
> 23)
4410 m
->sequence_number
= const_cpu_to_le16(1);
4412 m
->sequence_number
= cpu_to_le16(i
);
4415 * If only one cluster contains all system files then
4416 * fill the rest of it with empty, formatted records.
4418 if (nr_sysfiles
* (s32
)g_vol
->mft_record_size
< g_mft_size
) {
4419 for (i
= nr_sysfiles
;
4420 i
* (s32
)g_vol
->mft_record_size
< g_mft_size
; i
++) {
4421 m
= (MFT_RECORD
*)(g_buf
+ i
* g_vol
->mft_record_size
);
4422 if (ntfs_mft_record_layout(g_vol
, 0, m
)) {
4423 ntfs_log_error("Failed to layout mft record."
4427 m
->flags
= const_cpu_to_le16(0);
4428 m
->sequence_number
= cpu_to_le16(i
);
4432 * Create the 16 system files, adding the system information attribute
4433 * to each as well as marking them in use in the mft bitmap.
4435 for (i
= 0; i
< nr_sysfiles
; i
++) {
4438 m
= (MFT_RECORD
*)(g_buf
+ i
* g_vol
->mft_record_size
);
4439 if (i
< 16 || i
> 23) {
4440 m
->mft_record_number
= cpu_to_le32(i
);
4441 m
->flags
|= MFT_RECORD_IN_USE
;
4442 ntfs_bit_set(g_mft_bitmap
, 0LL + i
, 1);
4444 file_attrs
= FILE_ATTR_HIDDEN
| FILE_ATTR_SYSTEM
;
4445 if (i
== FILE_root
) {
4446 file_attrs
|= FILE_ATTR_ARCHIVE
;
4447 if (opts
.disable_indexing
)
4448 file_attrs
|= FILE_ATTR_NOT_CONTENT_INDEXED
;
4449 if (opts
.enable_compression
)
4450 file_attrs
|= FILE_ATTR_COMPRESSED
;
4452 /* setting specific security_id flag and */
4453 /* file permissions for ntfs 3.x */
4454 if (i
== 0 || i
== 1 || i
== 2 || i
== 6 || i
== 8 ||
4456 add_attr_std_info(m
, file_attrs
,
4457 const_cpu_to_le32(0x0100));
4458 } else if (i
== 9) {
4459 file_attrs
|= FILE_ATTR_VIEW_INDEX_PRESENT
;
4460 add_attr_std_info(m
, file_attrs
,
4461 const_cpu_to_le32(0x0101));
4462 } else if (i
== 11) {
4463 add_attr_std_info(m
, file_attrs
,
4464 const_cpu_to_le32(0x0101));
4465 } else if (i
== 24 || i
== 25 || i
== 26) {
4466 file_attrs
|= FILE_ATTR_ARCHIVE
;
4467 file_attrs
|= FILE_ATTR_VIEW_INDEX_PRESENT
;
4468 add_attr_std_info(m
, file_attrs
,
4469 const_cpu_to_le32(0x0101));
4471 add_attr_std_info(m
, file_attrs
,
4472 const_cpu_to_le32(0x00));
4475 /* The root directory mft reference. */
4476 root_ref
= MK_LE_MREF(FILE_root
, FILE_root
);
4477 extend_ref
= MK_LE_MREF(11,11);
4478 ntfs_log_verbose("Creating root directory (mft record 5)\n");
4479 m
= (MFT_RECORD
*)(g_buf
+ 5 * g_vol
->mft_record_size
);
4480 m
->flags
|= MFT_RECORD_IS_DIRECTORY
;
4481 m
->link_count
= cpu_to_le16(le16_to_cpu(m
->link_count
) + 1);
4482 err
= add_attr_file_name(m
, root_ref
, 0LL, 0LL,
4483 FILE_ATTR_HIDDEN
| FILE_ATTR_SYSTEM
|
4484 FILE_ATTR_I30_INDEX_PRESENT
, 0, 0, ".",
4485 FILE_NAME_WIN32_AND_DOS
);
4487 init_root_sd(&sd
, &i
);
4488 err
= add_attr_sd(m
, sd
, i
);
4490 /* FIXME: This should be IGNORE_CASE */
4492 err
= add_attr_index_root(m
, "$I30", 4, CASE_SENSITIVE
,
4493 AT_FILE_NAME
, COLLATION_FILE_NAME
,
4494 g_vol
->indx_record_size
);
4495 /* FIXME: This should be IGNORE_CASE */
4497 err
= upgrade_to_large_index(m
, "$I30", 4, CASE_SENSITIVE
,
4500 ntfs_attr_search_ctx
*ctx
;
4502 ctx
= ntfs_attr_get_search_ctx(NULL
, m
);
4504 ntfs_log_perror("Failed to allocate attribute search "
4508 /* There is exactly one file name so this is ok. */
4509 if (mkntfs_attr_lookup(AT_FILE_NAME
, AT_UNNAMED
, 0,
4510 CASE_SENSITIVE
, 0, NULL
, 0, ctx
)) {
4511 ntfs_attr_put_search_ctx(ctx
);
4512 ntfs_log_error("BUG: $FILE_NAME attribute not found."
4517 err
= insert_file_link_in_dir_index(g_index_block
, root_ref
,
4518 (FILE_NAME_ATTR
*)((char*)a
+
4519 le16_to_cpu(a
->value_offset
)),
4520 le32_to_cpu(a
->value_length
));
4521 ntfs_attr_put_search_ctx(ctx
);
4524 ntfs_log_error("Couldn't create root directory: %s\n",
4528 /* Add all other attributes, on a per-file basis for clarity. */
4529 ntfs_log_verbose("Creating $MFT (mft record 0)\n");
4530 m
= (MFT_RECORD
*)g_buf
;
4531 err
= add_attr_data_positioned(m
, NULL
, 0, CASE_SENSITIVE
,
4532 const_cpu_to_le16(0), g_rl_mft
, g_buf
, g_mft_size
);
4534 err
= create_hardlink(g_index_block
, root_ref
, m
,
4535 MK_LE_MREF(FILE_MFT
, 1),
4537 | (g_vol
->cluster_size
- 1)) + 1,
4538 g_mft_size
, FILE_ATTR_HIDDEN
|
4539 FILE_ATTR_SYSTEM
, 0, 0, "$MFT",
4540 FILE_NAME_WIN32_AND_DOS
);
4541 /* mft_bitmap is not modified in mkntfs; no need to sync it later. */
4543 err
= add_attr_bitmap_positioned(m
, NULL
, 0, CASE_SENSITIVE
,
4545 g_mft_bitmap
, g_mft_bitmap_byte_size
);
4547 ntfs_log_error("Couldn't create $MFT: %s\n", strerror(-err
));
4550 ntfs_log_verbose("Creating $MFTMirr (mft record 1)\n");
4551 m
= (MFT_RECORD
*)(g_buf
+ 1 * g_vol
->mft_record_size
);
4552 err
= add_attr_data_positioned(m
, NULL
, 0, CASE_SENSITIVE
,
4553 const_cpu_to_le16(0), g_rl_mftmirr
, g_buf
,
4554 g_rl_mftmirr
[0].length
* g_vol
->cluster_size
);
4556 err
= create_hardlink(g_index_block
, root_ref
, m
,
4557 MK_LE_MREF(FILE_MFTMirr
, FILE_MFTMirr
),
4558 g_rl_mftmirr
[0].length
* g_vol
->cluster_size
,
4559 g_rl_mftmirr
[0].length
* g_vol
->cluster_size
,
4560 FILE_ATTR_HIDDEN
| FILE_ATTR_SYSTEM
, 0, 0,
4561 "$MFTMirr", FILE_NAME_WIN32_AND_DOS
);
4563 ntfs_log_error("Couldn't create $MFTMirr: %s\n",
4567 ntfs_log_verbose("Creating $LogFile (mft record 2)\n");
4568 m
= (MFT_RECORD
*)(g_buf
+ 2 * g_vol
->mft_record_size
);
4569 err
= add_attr_data_positioned(m
, NULL
, 0, CASE_SENSITIVE
,
4570 const_cpu_to_le16(0), g_rl_logfile
,
4571 (const u8
*)NULL
, g_logfile_size
);
4573 err
= create_hardlink(g_index_block
, root_ref
, m
,
4574 MK_LE_MREF(FILE_LogFile
, FILE_LogFile
),
4575 g_logfile_size
, g_logfile_size
,
4576 FILE_ATTR_HIDDEN
| FILE_ATTR_SYSTEM
, 0, 0,
4577 "$LogFile", FILE_NAME_WIN32_AND_DOS
);
4579 ntfs_log_error("Couldn't create $LogFile: %s\n",
4583 ntfs_log_verbose("Creating $AttrDef (mft record 4)\n");
4584 m
= (MFT_RECORD
*)(g_buf
+ 4 * g_vol
->mft_record_size
);
4585 err
= add_attr_data(m
, NULL
, 0, CASE_SENSITIVE
, const_cpu_to_le16(0),
4586 (u8
*)g_vol
->attrdef
, g_vol
->attrdef_len
);
4588 err
= create_hardlink(g_index_block
, root_ref
, m
,
4589 MK_LE_MREF(FILE_AttrDef
, FILE_AttrDef
),
4590 (g_vol
->attrdef_len
+ g_vol
->cluster_size
- 1) &
4591 ~(g_vol
->cluster_size
- 1), g_vol
->attrdef_len
,
4592 FILE_ATTR_HIDDEN
| FILE_ATTR_SYSTEM
, 0, 0,
4593 "$AttrDef", FILE_NAME_WIN32_AND_DOS
);
4595 init_system_file_sd(FILE_AttrDef
, &sd
, &i
);
4596 err
= add_attr_sd(m
, sd
, i
);
4599 ntfs_log_error("Couldn't create $AttrDef: %s\n",
4603 ntfs_log_verbose("Creating $Bitmap (mft record 6)\n");
4604 m
= (MFT_RECORD
*)(g_buf
+ 6 * g_vol
->mft_record_size
);
4605 /* the data attribute of $Bitmap must be non-resident or otherwise */
4606 /* windows 2003 will regard the volume as corrupt (ERSO) */
4608 err
= insert_non_resident_attr_in_mft_record(m
,
4609 AT_DATA
, NULL
, 0, CASE_SENSITIVE
,
4610 const_cpu_to_le16(0), (const u8
*)NULL
,
4611 g_lcn_bitmap_byte_size
, WRITE_BITMAP
);
4615 err
= create_hardlink(g_index_block
, root_ref
, m
,
4616 MK_LE_MREF(FILE_Bitmap
, FILE_Bitmap
),
4617 (g_lcn_bitmap_byte_size
+ g_vol
->cluster_size
-
4618 1) & ~(g_vol
->cluster_size
- 1),
4619 g_lcn_bitmap_byte_size
,
4620 FILE_ATTR_HIDDEN
| FILE_ATTR_SYSTEM
, 0, 0,
4621 "$Bitmap", FILE_NAME_WIN32_AND_DOS
);
4623 ntfs_log_error("Couldn't create $Bitmap: %s\n", strerror(-err
));
4626 ntfs_log_verbose("Creating $Boot (mft record 7)\n");
4627 m
= (MFT_RECORD
*)(g_buf
+ 7 * g_vol
->mft_record_size
);
4628 bs
= ntfs_calloc(8192);
4631 memcpy(bs
, boot_array
, sizeof(boot_array
));
4633 * Create the boot sector in bs. Note, that bs is already zeroed
4634 * in the boot sector section and that it has the NTFS OEM id/magic
4635 * already inserted, so no need to worry about these things.
4637 bs
->bpb
.bytes_per_sector
= cpu_to_le16(opts
.sector_size
);
4638 bs
->bpb
.sectors_per_cluster
= (u8
)(g_vol
->cluster_size
/
4640 bs
->bpb
.media_type
= 0xf8; /* hard disk */
4641 bs
->bpb
.sectors_per_track
= cpu_to_le16(opts
.sectors_per_track
);
4642 ntfs_log_debug("sectors per track = %ld (0x%lx)\n",
4643 opts
.sectors_per_track
, opts
.sectors_per_track
);
4644 bs
->bpb
.heads
= cpu_to_le16(opts
.heads
);
4645 ntfs_log_debug("heads = %ld (0x%lx)\n", opts
.heads
, opts
.heads
);
4646 bs
->bpb
.hidden_sectors
= cpu_to_le32(opts
.part_start_sect
);
4647 ntfs_log_debug("hidden sectors = %llu (0x%llx)\n", opts
.part_start_sect
,
4648 opts
.part_start_sect
);
4649 bs
->physical_drive
= 0x80; /* boot from hard disk */
4650 bs
->extended_boot_signature
= 0x80; /* everybody sets this, so we do */
4651 bs
->number_of_sectors
= cpu_to_sle64(opts
.num_sectors
);
4652 bs
->mft_lcn
= cpu_to_sle64(g_mft_lcn
);
4653 bs
->mftmirr_lcn
= cpu_to_sle64(g_mftmirr_lcn
);
4654 if (g_vol
->mft_record_size
>= g_vol
->cluster_size
) {
4655 bs
->clusters_per_mft_record
= g_vol
->mft_record_size
/
4656 g_vol
->cluster_size
;
4658 bs
->clusters_per_mft_record
= -(ffs(g_vol
->mft_record_size
) -
4660 if ((u32
)(1 << -bs
->clusters_per_mft_record
) !=
4661 g_vol
->mft_record_size
) {
4663 ntfs_log_error("BUG: calculated clusters_per_mft_record"
4664 " is wrong (= 0x%x)\n",
4665 bs
->clusters_per_mft_record
);
4669 ntfs_log_debug("clusters per mft record = %i (0x%x)\n",
4670 bs
->clusters_per_mft_record
,
4671 bs
->clusters_per_mft_record
);
4672 if (g_vol
->indx_record_size
>= g_vol
->cluster_size
) {
4673 bs
->clusters_per_index_record
= g_vol
->indx_record_size
/
4674 g_vol
->cluster_size
;
4676 bs
->clusters_per_index_record
= -g_vol
->indx_record_size_bits
;
4677 if ((1 << -bs
->clusters_per_index_record
) !=
4678 (s32
)g_vol
->indx_record_size
) {
4680 ntfs_log_error("BUG: calculated "
4681 "clusters_per_index_record is wrong "
4683 bs
->clusters_per_index_record
);
4687 ntfs_log_debug("clusters per index block = %i (0x%x)\n",
4688 bs
->clusters_per_index_record
,
4689 bs
->clusters_per_index_record
);
4690 /* Generate a 64-bit random number for the serial number. */
4691 bs
->volume_serial_number
= cpu_to_le64(((u64
)random() << 32) |
4692 ((u64
)random() & 0xffffffff));
4694 * Leave zero for now as NT4 leaves it zero, too. If want it later, see
4695 * ../libntfs/bootsect.c for how to calculate it.
4697 bs
->checksum
= const_cpu_to_le32(0);
4698 /* Make sure the bootsector is ok. */
4699 if (!ntfs_boot_sector_is_ntfs(bs
)) {
4701 ntfs_log_error("FATAL: Generated boot sector is invalid!\n");
4704 err
= add_attr_data_positioned(m
, NULL
, 0, CASE_SENSITIVE
,
4705 const_cpu_to_le16(0), g_rl_boot
, (u8
*)bs
, 8192);
4707 err
= create_hardlink(g_index_block
, root_ref
, m
,
4708 MK_LE_MREF(FILE_Boot
, FILE_Boot
),
4709 (8192 + g_vol
->cluster_size
- 1) &
4710 ~(g_vol
->cluster_size
- 1), 8192,
4711 FILE_ATTR_HIDDEN
| FILE_ATTR_SYSTEM
, 0, 0,
4712 "$Boot", FILE_NAME_WIN32_AND_DOS
);
4714 init_system_file_sd(FILE_Boot
, &sd
, &i
);
4715 err
= add_attr_sd(m
, sd
, i
);
4719 ntfs_log_error("Couldn't create $Boot: %s\n", strerror(-err
));
4722 if (create_backup_boot_sector((u8
*)bs
)) {
4724 * Pre-2.6 kernels couldn't access the last sector if it was
4725 * odd and we failed to set the device block size to the sector
4726 * size, hence we schedule chkdsk to create it.
4728 volume_flags
|= VOLUME_IS_DIRTY
;
4732 * We cheat a little here and if the user has requested all times to be
4733 * set to zero then we set the GUID to zero as well. This options is
4734 * only used for development purposes so that should be fine.
4736 if (!opts
.use_epoch_time
) {
4737 /* Generate a GUID for the volume. */
4739 uuid_generate((void*)&vol_guid
);
4741 ntfs_generate_guid(&vol_guid
);
4744 memset(&vol_guid
, 0, sizeof(vol_guid
));
4745 if (!create_file_volume(m
, root_ref
, volume_flags
, &vol_guid
))
4747 ntfs_log_verbose("Creating $BadClus (mft record 8)\n");
4748 m
= (MFT_RECORD
*)(g_buf
+ 8 * g_vol
->mft_record_size
);
4749 /* FIXME: This should be IGNORE_CASE */
4750 /* Create a sparse named stream of size equal to the volume size. */
4751 err
= add_attr_data_positioned(m
, "$Bad", 4, CASE_SENSITIVE
,
4752 const_cpu_to_le16(0), g_rl_bad
, NULL
,
4753 g_vol
->nr_clusters
* g_vol
->cluster_size
);
4755 err
= add_attr_data(m
, NULL
, 0, CASE_SENSITIVE
,
4756 const_cpu_to_le16(0), NULL
, 0);
4759 err
= create_hardlink(g_index_block
, root_ref
, m
,
4760 MK_LE_MREF(FILE_BadClus
, FILE_BadClus
),
4761 0LL, 0LL, FILE_ATTR_HIDDEN
| FILE_ATTR_SYSTEM
,
4762 0, 0, "$BadClus", FILE_NAME_WIN32_AND_DOS
);
4765 ntfs_log_error("Couldn't create $BadClus: %s\n",
4769 /* create $Secure (NTFS 3.0+) */
4770 ntfs_log_verbose("Creating $Secure (mft record 9)\n");
4771 m
= (MFT_RECORD
*)(g_buf
+ 9 * g_vol
->mft_record_size
);
4772 m
->flags
|= MFT_RECORD_IS_VIEW_INDEX
;
4774 err
= create_hardlink(g_index_block
, root_ref
, m
,
4775 MK_LE_MREF(9, 9), 0LL, 0LL,
4776 FILE_ATTR_HIDDEN
| FILE_ATTR_SYSTEM
|
4777 FILE_ATTR_VIEW_INDEX_PRESENT
, 0, 0,
4778 "$Secure", FILE_NAME_WIN32_AND_DOS
);
4780 buf_sds_first_size
= 0;
4784 buf_sds_first_size
= 0xfc;
4785 buf_sds_size
= 0x40000 + buf_sds_first_size
;
4786 buf_sds
= ntfs_calloc(buf_sds_size
);
4789 init_secure_sds(buf_sds
);
4790 memcpy(buf_sds
+ 0x40000, buf_sds
, buf_sds_first_size
);
4791 err
= add_attr_data(m
, "$SDS", 4, CASE_SENSITIVE
,
4792 const_cpu_to_le16(0), (u8
*)buf_sds
,
4795 /* FIXME: This should be IGNORE_CASE */
4797 err
= add_attr_index_root(m
, "$SDH", 4, CASE_SENSITIVE
,
4798 AT_UNUSED
, COLLATION_NTOFS_SECURITY_HASH
,
4799 g_vol
->indx_record_size
);
4800 /* FIXME: This should be IGNORE_CASE */
4802 err
= add_attr_index_root(m
, "$SII", 4, CASE_SENSITIVE
,
4803 AT_UNUSED
, COLLATION_NTOFS_ULONG
,
4804 g_vol
->indx_record_size
);
4806 err
= initialize_secure(buf_sds
, buf_sds_first_size
, m
);
4809 ntfs_log_error("Couldn't create $Secure: %s\n",
4813 ntfs_log_verbose("Creating $UpCase (mft record 0xa)\n");
4814 m
= (MFT_RECORD
*)(g_buf
+ 0xa * g_vol
->mft_record_size
);
4815 err
= add_attr_data(m
, NULL
, 0, CASE_SENSITIVE
, const_cpu_to_le16(0),
4816 (u8
*)g_vol
->upcase
, g_vol
->upcase_len
<< 1);
4818 * The $Info only exists since Windows 8, but it apparently
4819 * does not disturb chkdsk from earlier versions.
4822 err
= add_attr_data(m
, "$Info", 5, CASE_SENSITIVE
,
4823 const_cpu_to_le16(0),
4824 (u8
*)g_upcaseinfo
, sizeof(struct UPCASEINFO
));
4826 err
= create_hardlink(g_index_block
, root_ref
, m
,
4827 MK_LE_MREF(FILE_UpCase
, FILE_UpCase
),
4828 ((g_vol
->upcase_len
<< 1) +
4829 g_vol
->cluster_size
- 1) &
4830 ~(g_vol
->cluster_size
- 1),
4831 g_vol
->upcase_len
<< 1,
4832 FILE_ATTR_HIDDEN
| FILE_ATTR_SYSTEM
, 0, 0,
4833 "$UpCase", FILE_NAME_WIN32_AND_DOS
);
4835 ntfs_log_error("Couldn't create $UpCase: %s\n", strerror(-err
));
4838 ntfs_log_verbose("Creating $Extend (mft record 11)\n");
4840 * $Extend index must be resident. Otherwise, w2k3 will regard the
4841 * volume as corrupt. (ERSO)
4843 m
= (MFT_RECORD
*)(g_buf
+ 11 * g_vol
->mft_record_size
);
4844 m
->flags
|= MFT_RECORD_IS_DIRECTORY
;
4846 err
= create_hardlink(g_index_block
, root_ref
, m
,
4847 MK_LE_MREF(11, 11), 0LL, 0LL,
4848 FILE_ATTR_HIDDEN
| FILE_ATTR_SYSTEM
|
4849 FILE_ATTR_I30_INDEX_PRESENT
, 0, 0,
4850 "$Extend", FILE_NAME_WIN32_AND_DOS
);
4851 /* FIXME: This should be IGNORE_CASE */
4853 err
= add_attr_index_root(m
, "$I30", 4, CASE_SENSITIVE
,
4854 AT_FILE_NAME
, COLLATION_FILE_NAME
,
4855 g_vol
->indx_record_size
);
4857 ntfs_log_error("Couldn't create $Extend: %s\n",
4861 /* NTFS reserved system files (mft records 0xc-0xf) */
4862 for (i
= 0xc; i
< 0x10; i
++) {
4863 ntfs_log_verbose("Creating system file (mft record 0x%x)\n", i
);
4864 m
= (MFT_RECORD
*)(g_buf
+ i
* g_vol
->mft_record_size
);
4865 err
= add_attr_data(m
, NULL
, 0, CASE_SENSITIVE
,
4866 const_cpu_to_le16(0), NULL
, 0);
4868 init_system_file_sd(i
, &sd
, &j
);
4869 err
= add_attr_sd(m
, sd
, j
);
4872 ntfs_log_error("Couldn't create system file %i (0x%x): "
4873 "%s\n", i
, i
, strerror(-err
));
4877 /* create systemfiles for ntfs volumes (3.1) */
4878 /* starting with file 24 (ignoring file 16-23) */
4879 extend_flags
= FILE_ATTR_HIDDEN
| FILE_ATTR_SYSTEM
|
4880 FILE_ATTR_ARCHIVE
| FILE_ATTR_VIEW_INDEX_PRESENT
;
4881 ntfs_log_verbose("Creating $Quota (mft record 24)\n");
4882 m
= (MFT_RECORD
*)(g_buf
+ 24 * g_vol
->mft_record_size
);
4883 m
->flags
|= MFT_RECORD_IS_4
;
4884 m
->flags
|= MFT_RECORD_IS_VIEW_INDEX
;
4886 err
= create_hardlink_res((MFT_RECORD
*)(g_buf
+
4887 11 * g_vol
->mft_record_size
), extend_ref
, m
,
4888 MK_LE_MREF(24, 1), 0LL, 0LL, extend_flags
,
4889 0, 0, "$Quota", FILE_NAME_WIN32_AND_DOS
);
4890 /* FIXME: This should be IGNORE_CASE */
4892 err
= add_attr_index_root(m
, "$Q", 2, CASE_SENSITIVE
, AT_UNUSED
,
4893 COLLATION_NTOFS_ULONG
, g_vol
->indx_record_size
);
4894 /* FIXME: This should be IGNORE_CASE */
4896 err
= add_attr_index_root(m
, "$O", 2, CASE_SENSITIVE
, AT_UNUSED
,
4897 COLLATION_NTOFS_SID
, g_vol
->indx_record_size
);
4899 err
= initialize_quota(m
);
4901 ntfs_log_error("Couldn't create $Quota: %s\n", strerror(-err
));
4904 ntfs_log_verbose("Creating $ObjId (mft record 25)\n");
4905 m
= (MFT_RECORD
*)(g_buf
+ 25 * g_vol
->mft_record_size
);
4906 m
->flags
|= MFT_RECORD_IS_4
;
4907 m
->flags
|= MFT_RECORD_IS_VIEW_INDEX
;
4909 err
= create_hardlink_res((MFT_RECORD
*)(g_buf
+
4910 11 * g_vol
->mft_record_size
), extend_ref
,
4911 m
, MK_LE_MREF(25, 1), 0LL, 0LL,
4912 extend_flags
, 0, 0, "$ObjId",
4913 FILE_NAME_WIN32_AND_DOS
);
4915 /* FIXME: This should be IGNORE_CASE */
4917 err
= add_attr_index_root(m
, "$O", 2, CASE_SENSITIVE
, AT_UNUSED
,
4918 COLLATION_NTOFS_ULONGS
,
4919 g_vol
->indx_record_size
);
4920 if (!err
&& opts
.with_uuid
)
4921 err
= index_obj_id_insert(m
, &vol_guid
,
4922 MK_LE_MREF(FILE_Volume
, FILE_Volume
));
4924 ntfs_log_error("Couldn't create $ObjId: %s\n",
4928 ntfs_log_verbose("Creating $Reparse (mft record 26)\n");
4929 m
= (MFT_RECORD
*)(g_buf
+ 26 * g_vol
->mft_record_size
);
4930 m
->flags
|= MFT_RECORD_IS_4
;
4931 m
->flags
|= MFT_RECORD_IS_VIEW_INDEX
;
4933 err
= create_hardlink_res((MFT_RECORD
*)(g_buf
+
4934 11 * g_vol
->mft_record_size
),
4935 extend_ref
, m
, MK_LE_MREF(26, 1),
4936 0LL, 0LL, extend_flags
, 0, 0,
4937 "$Reparse", FILE_NAME_WIN32_AND_DOS
);
4938 /* FIXME: This should be IGNORE_CASE */
4940 err
= add_attr_index_root(m
, "$R", 2, CASE_SENSITIVE
, AT_UNUSED
,
4941 COLLATION_NTOFS_ULONGS
, g_vol
->indx_record_size
);
4943 ntfs_log_error("Couldn't create $Reparse: %s\n",
4953 static int mkntfs_redirect(struct mkntfs_options
*opts2
)
4957 ntfs_attr_search_ctx
*ctx
= NULL
;
4964 ntfs_log_error("Internal error: invalid parameters to mkntfs_options.\n");
4967 /* Initialize the random number generator with the current time. */
4968 srandom(sle64_to_cpu(mkntfs_time())/10000000);
4969 /* Allocate and initialize ntfs_volume structure g_vol. */
4970 g_vol
= ntfs_volume_alloc();
4972 ntfs_log_perror("Could not create volume");
4975 /* Create NTFS 3.1 (Windows XP/Vista) volumes. */
4976 g_vol
->major_ver
= 3;
4977 g_vol
->minor_ver
= 1;
4978 /* Transfer some options to the volume. */
4980 g_vol
->vol_name
= strdup(opts
.label
);
4981 if (!g_vol
->vol_name
) {
4982 ntfs_log_perror("Could not copy volume name");
4986 if (opts
.cluster_size
>= 0)
4987 g_vol
->cluster_size
= opts
.cluster_size
;
4988 /* Length is in unicode characters. */
4989 g_vol
->upcase_len
= ntfs_upcase_build_default(&g_vol
->upcase
);
4990 /* Since Windows 8, there is a $Info stream in $UpCase */
4992 (struct UPCASEINFO
*)ntfs_malloc(sizeof(struct UPCASEINFO
));
4993 if (!g_vol
->upcase_len
|| !g_upcaseinfo
)
4995 /* If the CRC is correct, chkdsk does not warn about obsolete table */
4996 crc64(0,(byte
*)NULL
,0); /* initialize the crc computation */
4997 upcase_crc
= crc64(0,(byte
*)g_vol
->upcase
,
4998 g_vol
->upcase_len
* sizeof(ntfschar
));
4999 /* keep the version fields as zero */
5000 memset(g_upcaseinfo
, 0, sizeof(struct UPCASEINFO
));
5001 g_upcaseinfo
->len
= const_cpu_to_le32(sizeof(struct UPCASEINFO
));
5002 g_upcaseinfo
->crc
= cpu_to_le64(upcase_crc
);
5003 g_vol
->attrdef
= ntfs_malloc(sizeof(attrdef_ntfs3x_array
));
5004 if (!g_vol
->attrdef
) {
5005 ntfs_log_perror("Could not create attrdef structure");
5008 memcpy(g_vol
->attrdef
, attrdef_ntfs3x_array
,
5009 sizeof(attrdef_ntfs3x_array
));
5010 g_vol
->attrdef_len
= sizeof(attrdef_ntfs3x_array
);
5011 /* Open the partition. */
5012 if (!mkntfs_open_partition(g_vol
))
5015 * Decide on the sector size, cluster size, mft record and index record
5016 * sizes as well as the number of sectors/tracks/heads/size, etc.
5018 if (!mkntfs_override_vol_params(g_vol
))
5020 /* Initialize $Bitmap and $MFT/$BITMAP related stuff. */
5021 if (!mkntfs_initialize_bitmaps())
5023 /* Initialize MFT & set g_logfile_lcn. */
5024 if (!mkntfs_initialize_rl_mft())
5026 /* Initialize $LogFile. */
5027 if (!mkntfs_initialize_rl_logfile())
5029 /* Initialize $Boot. */
5030 if (!mkntfs_initialize_rl_boot())
5032 /* Allocate a buffer large enough to hold the mft. */
5033 g_buf
= ntfs_calloc(g_mft_size
);
5036 /* Create runlist for $BadClus, $DATA named stream $Bad. */
5037 if (!mkntfs_initialize_rl_bad())
5039 /* If not quick format, fill the device with 0s. */
5040 if (!opts
.quick_format
) {
5041 if (!mkntfs_fill_device_with_zeroes())
5044 /* Create NTFS volume structures. */
5045 if (!mkntfs_create_root_structures())
5048 * - Do not step onto bad blocks!!!
5049 * - If any bad blocks were specified or found, modify $BadClus,
5050 * allocating the bad clusters in $Bitmap.
5051 * - C&w bootsector backup bootsector (backup in last sector of the
5053 * - If NTFS 3.0+, c&w $Secure file and $Extend directory with the
5054 * corresponding special files in it, i.e. $ObjId, $Quota, $Reparse,
5055 * and $UsnJrnl. And others? Or not all necessary?
5056 * - RE: Populate $root with the system files (and $Extend directory if
5057 * applicable). Possibly should move this as far to the top as
5058 * possible and update during each subsequent c&w of each system file.
5060 ntfs_log_verbose("Syncing root directory index record.\n");
5061 if (!mkntfs_sync_index_record(g_index_block
, (MFT_RECORD
*)(g_buf
+ 5 *
5062 g_vol
->mft_record_size
), NTFS_INDEX_I30
, 4))
5065 ntfs_log_verbose("Syncing $Bitmap.\n");
5066 m
= (MFT_RECORD
*)(g_buf
+ 6 * g_vol
->mft_record_size
);
5068 ctx
= ntfs_attr_get_search_ctx(NULL
, m
);
5070 ntfs_log_perror("Could not create an attribute search context");
5074 if (mkntfs_attr_lookup(AT_DATA
, AT_UNNAMED
, 0, CASE_SENSITIVE
,
5076 ntfs_log_error("BUG: $DATA attribute not found.\n");
5081 if (a
->non_resident
) {
5082 runlist
*rl
= ntfs_mapping_pairs_decompress(g_vol
, a
, NULL
);
5084 ntfs_log_error("ntfs_mapping_pairs_decompress() failed\n");
5087 lw
= ntfs_rlwrite(g_vol
->dev
, rl
, (const u8
*)NULL
,
5088 g_lcn_bitmap_byte_size
, NULL
, WRITE_BITMAP
);
5091 if (lw
!= g_lcn_bitmap_byte_size
) {
5092 ntfs_log_error("ntfs_rlwrite: %s\n", lw
== -1 ?
5093 strerror(err
) : "unknown error");
5097 /* Error : the bitmap must be created non resident */
5098 ntfs_log_error("Error : the global bitmap is resident\n");
5103 * No need to sync $MFT/$BITMAP as that has never been modified since
5106 ntfs_log_verbose("Syncing $MFT.\n");
5107 pos
= g_mft_lcn
* g_vol
->cluster_size
;
5109 for (i
= 0; i
< g_mft_size
/ (s32
)g_vol
->mft_record_size
; i
++) {
5110 if (!opts
.no_action
)
5111 lw
= ntfs_mst_pwrite(g_vol
->dev
, pos
, 1, g_vol
->mft_record_size
, g_buf
+ i
* g_vol
->mft_record_size
);
5113 ntfs_log_error("ntfs_mst_pwrite: %s\n", lw
== -1 ?
5114 strerror(errno
) : "unknown error");
5117 pos
+= g_vol
->mft_record_size
;
5119 ntfs_log_verbose("Updating $MFTMirr.\n");
5120 pos
= g_mftmirr_lcn
* g_vol
->cluster_size
;
5122 for (i
= 0; i
< g_rl_mftmirr
[0].length
* g_vol
->cluster_size
/ g_vol
->mft_record_size
; i
++) {
5123 m
= (MFT_RECORD
*)(g_buf
+ i
* g_vol
->mft_record_size
);
5125 * Decrement the usn by one, so it becomes the same as the one
5126 * in $MFT once it is mst protected. - This is as we need the
5127 * $MFTMirr to have the exact same byte by byte content as
5128 * $MFT, rather than just equivalent meaning content.
5130 if (ntfs_mft_usn_dec(m
)) {
5131 ntfs_log_error("ntfs_mft_usn_dec");
5134 if (!opts
.no_action
)
5135 lw
= ntfs_mst_pwrite(g_vol
->dev
, pos
, 1, g_vol
->mft_record_size
, g_buf
+ i
* g_vol
->mft_record_size
);
5137 ntfs_log_error("ntfs_mst_pwrite: %s\n", lw
== -1 ?
5138 strerror(errno
) : "unknown error");
5141 pos
+= g_vol
->mft_record_size
;
5143 ntfs_log_verbose("Syncing device.\n");
5144 if (g_vol
->dev
->d_ops
->sync(g_vol
->dev
)) {
5145 ntfs_log_error("Syncing device. FAILED");
5148 ntfs_log_quiet("mkntfs completed successfully. Have a nice day.\n");
5151 ntfs_attr_put_search_ctx(ctx
);
5152 mkntfs_cleanup(); /* Device is unlocked and closed here */
5162 * Return: 0 Success, the program worked
5163 * 1 Error, something went wrong
5165 int main(int argc
, char *argv
[])
5169 ntfs_log_set_handler(ntfs_log_handler_outerr
);
5172 mkntfs_init_options(&opts
); /* Set up the options */
5174 /* Read the command line options */
5175 result
= mkntfs_parse_options(argc
, argv
, &opts
);
5178 result
= mkntfs_redirect(&opts
);