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 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-2012 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 BOOL
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' },
626 if (!argv
|| !opts2
) {
627 ntfs_log_error("Internal error: invalid parameters to "
628 "mkntfs_options.\n");
632 opterr
= 0; /* We'll handle the errors, thank you. */
634 while ((c
= getopt_long(argc
, argv
, sopt
, lopt
, NULL
)) != -1) {
636 case 1: /* A device, or a number of sectors */
637 if (!opts2
->dev_name
)
638 opts2
->dev_name
= argv
[optind
- 1];
639 else if (!mkntfs_parse_llong(optarg
,
641 &opts2
->num_sectors
))
645 opts2
->enable_compression
= TRUE
;
648 if (!mkntfs_parse_long(optarg
, "cluster size",
649 &opts2
->cluster_size
))
656 case 'Q': /* quick */
657 opts2
->quick_format
= TRUE
;
660 if (!mkntfs_parse_long(optarg
, "heads", &opts2
->heads
))
664 err
++; /* display help */
667 opts2
->disable_indexing
= TRUE
;
671 opts2
->label
= argv
[optind
-1];
673 ntfs_log_error("You may only specify the label "
679 lic
++; /* display the license */
682 opts2
->no_action
= TRUE
;
685 if (!mkntfs_parse_llong(optarg
, "partition start",
686 &opts2
->part_start_sect
))
690 ntfs_log_clear_levels(NTFS_LOG_LEVEL_QUIET
|
691 NTFS_LOG_LEVEL_VERBOSE
|
692 NTFS_LOG_LEVEL_PROGRESS
);
695 if (!mkntfs_parse_long(optarg
, "sector size",
696 &opts2
->sector_size
))
700 if (!mkntfs_parse_long(optarg
, "sectors per track",
701 &opts2
->sectors_per_track
))
705 opts2
->use_epoch_time
= TRUE
;
708 opts2
->with_uuid
= TRUE
;
711 ntfs_log_set_levels(NTFS_LOG_LEVEL_QUIET
|
712 NTFS_LOG_LEVEL_VERBOSE
|
713 NTFS_LOG_LEVEL_PROGRESS
);
716 ver
++; /* display version info */
718 case 'Z': /* debug - turn on everything */
719 ntfs_log_set_levels(NTFS_LOG_LEVEL_DEBUG
|
720 NTFS_LOG_LEVEL_TRACE
|
721 NTFS_LOG_LEVEL_VERBOSE
|
722 NTFS_LOG_LEVEL_QUIET
);
725 if (!mkntfs_parse_long(optarg
, "mft zone multiplier",
726 &opts2
->mft_zone_multiplier
))
730 if (ntfs_log_parse_option (argv
[optind
-1]))
732 if (((optopt
== 'c') || (optopt
== 'H') ||
733 (optopt
== 'L') || (optopt
== 'p') ||
734 (optopt
== 's') || (optopt
== 'S') ||
735 (optopt
== 'N') || (optopt
== 'z')) &&
737 ntfs_log_error("Option '%s' requires an "
738 "argument.\n", argv
[optind
-1]);
739 } else if (optopt
!= '?') {
740 ntfs_log_error("Unknown option '%s'.\n",
748 if (!err
&& !ver
&& !lic
) {
749 if (opts2
->dev_name
== NULL
) {
751 ntfs_log_error("You must specify a device.\n");
763 return (!err
&& !ver
&& !lic
);
770 static ntfs_time
mkntfs_time(void)
776 if (!opts
.use_epoch_time
)
777 ts
.tv_sec
= time(NULL
);
778 return timespec2ntfs(ts
);
782 * append_to_bad_blocks
784 static BOOL
append_to_bad_blocks(unsigned long long block
)
788 if (!(g_num_bad_blocks
& 15)) {
789 new_buf
= realloc(g_bad_blocks
, (g_num_bad_blocks
+ 16) *
792 ntfs_log_perror("Reallocating memory for bad blocks "
796 g_bad_blocks
= new_buf
;
798 g_bad_blocks
[g_num_bad_blocks
++] = block
;
805 static long long mkntfs_write(struct ntfs_device
*dev
,
806 const void *b
, long long count
)
808 long long bytes_written
, total
;
816 bytes_written
= dev
->d_ops
->write(dev
, b
, count
);
817 if (bytes_written
== -1LL) {
819 ntfs_log_perror("Error writing to %s", dev
->d_name
);
821 return bytes_written
;
822 } else if (!bytes_written
) {
825 count
-= bytes_written
;
826 total
+= bytes_written
;
828 } while (count
&& retry
< 3);
830 ntfs_log_error("Failed to complete writing to %s after three retries."
836 * Build and write a part of the global bitmap
837 * without overflowing from the allocated buffer
839 * mkntfs_bitmap_write
841 static s64
mkntfs_bitmap_write(struct ntfs_device
*dev
,
842 s64 offset
, s64 length
)
847 partial_length
= length
;
848 if (partial_length
> g_dynamic_buf_size
)
849 partial_length
= g_dynamic_buf_size
;
850 /* create a partial bitmap section, and write it */
851 bitmap_build(g_dynamic_buf
,offset
<< 3,partial_length
<< 3);
852 written
= dev
->d_ops
->write(dev
, g_dynamic_buf
, partial_length
);
857 * Build and write a part of the log file
858 * without overflowing from the allocated buffer
860 * mkntfs_logfile_write
862 static s64
mkntfs_logfile_write(struct ntfs_device
*dev
,
863 s64 offset
__attribute__((unused
)), s64 length
)
868 partial_length
= length
;
869 if (partial_length
> g_dynamic_buf_size
)
870 partial_length
= g_dynamic_buf_size
;
871 /* create a partial bad cluster section, and write it */
872 memset(g_dynamic_buf
, -1, partial_length
);
873 written
= dev
->d_ops
->write(dev
, g_dynamic_buf
, partial_length
);
878 * ntfs_rlwrite - Write to disk the clusters contained in the runlist @rl
879 * taking the data from @val. Take @val_len bytes from @val and pad the
882 * If the @rl specifies a completely sparse file, @val is allowed to be NULL.
884 * @inited_size if not NULL points to an output variable which will contain
885 * the actual number of bytes written to disk. I.e. this will not include
886 * sparse bytes for example.
888 * Return the number of bytes written (minus padding) or -1 on error. Errno
889 * will be set to the error code.
891 static s64
ntfs_rlwrite(struct ntfs_device
*dev
, const runlist
*rl
,
892 const u8
*val
, const s64 val_len
, s64
*inited_size
,
893 WRITE_TYPE write_type
)
895 s64 bytes_written
, total
, length
, delta
;
904 for (i
= 0; rl
[i
].length
; i
++) {
905 length
= rl
[i
].length
* g_vol
->cluster_size
;
906 /* Don't write sparse runs. */
907 if (rl
[i
].lcn
== -1) {
911 /* TODO: Check that *val is really zero at pos and len. */
915 * Break up the write into the real data write and then a write
916 * of zeroes between the end of the real data and the end of
919 if (total
+ length
> val_len
) {
921 length
= val_len
- total
;
924 if (dev
->d_ops
->seek(dev
, rl
[i
].lcn
* g_vol
->cluster_size
,
925 SEEK_SET
) == (off_t
)-1)
929 /* use specific functions if buffer is not prefilled */
930 switch (write_type
) {
932 bytes_written
= mkntfs_bitmap_write(dev
,
936 bytes_written
= mkntfs_logfile_write(dev
,
940 bytes_written
= dev
->d_ops
->write(dev
,
941 val
+ total
, length
);
944 if (bytes_written
== -1LL) {
946 ntfs_log_perror("Error writing to %s",
949 return bytes_written
;
952 length
-= bytes_written
;
953 total
+= bytes_written
;
955 *inited_size
+= bytes_written
;
959 } while (length
&& retry
< 3);
961 ntfs_log_error("Failed to complete writing to %s after three "
962 "retries.\n", dev
->d_name
);
968 char *b
= ntfs_calloc(delta
);
971 bytes_written
= mkntfs_write(dev
, b
, delta
);
975 if (bytes_written
== -1LL)
976 return bytes_written
;
982 * make_room_for_attribute - make room for an attribute inside an mft record
984 * @pos: position at which to make space
985 * @size: byte size to make available at this position
987 * @pos points to the attribute in front of which we want to make space.
989 * Return 0 on success or -errno on error. Possible error codes are:
991 * -ENOSPC There is not enough space available to complete
992 * operation. The caller has to make space before calling
994 * -EINVAL Can only occur if mkntfs was compiled with -DDEBUG. Means
995 * the input parameters were faulty.
997 static int make_room_for_attribute(MFT_RECORD
*m
, char *pos
, const u32 size
)
1005 * Rigorous consistency checks. Always return -EINVAL even if more
1006 * appropriate codes exist for simplicity of parsing the return value.
1008 if (size
!= ((size
+ 7) & ~7)) {
1009 ntfs_log_error("make_room_for_attribute() received non 8-byte aligned "
1015 if (pos
< (char*)m
|| pos
+ size
< (char*)m
||
1016 pos
> (char*)m
+ le32_to_cpu(m
->bytes_allocated
) ||
1017 pos
+ size
> (char*)m
+ le32_to_cpu(m
->bytes_allocated
))
1019 /* The -8 is for the attribute terminator. */
1020 if (pos
- (char*)m
> (int)le32_to_cpu(m
->bytes_in_use
) - 8)
1023 biu
= le32_to_cpu(m
->bytes_in_use
);
1024 /* Do we have enough space? */
1025 if (biu
+ size
> le32_to_cpu(m
->bytes_allocated
))
1027 /* Move everything after pos to pos + size. */
1028 memmove(pos
+ size
, pos
, biu
- (pos
- (char*)m
));
1029 /* Update mft record. */
1030 m
->bytes_in_use
= cpu_to_le32(biu
+ size
);
1035 * deallocate_scattered_clusters
1037 static void deallocate_scattered_clusters(const runlist
*rl
)
1043 /* Iterate over all runs in the runlist @rl. */
1044 for (i
= 0; rl
[i
].length
; i
++) {
1045 /* Skip sparse runs. */
1046 if (rl
[i
].lcn
== -1LL)
1048 /* Deallocate the current run. */
1049 bitmap_deallocate(rl
[i
].lcn
, rl
[i
].length
);
1054 * allocate_scattered_clusters
1055 * @clusters: Amount of clusters to allocate.
1057 * Allocate @clusters and create a runlist of the allocated clusters.
1059 * Return the allocated runlist. Caller has to free the runlist when finished
1062 * On error return NULL and errno is set to the error code.
1064 * TODO: We should be returning the size as well, but for mkntfs this is not
1067 static runlist
* allocate_scattered_clusters(s64 clusters
)
1069 runlist
*rl
= NULL
, *rlt
;
1071 LCN lcn
, end
, prev_lcn
= 0LL;
1074 s64 prev_run_len
= 0LL;
1077 end
= g_vol
->nr_clusters
;
1078 /* Loop until all clusters are allocated. */
1080 /* Loop in current zone until we run out of free clusters. */
1081 for (lcn
= g_mft_zone_end
; lcn
< end
; lcn
++) {
1082 bit
= bitmap_get_and_set(lcn
,1);
1086 * Reallocate memory if necessary. Make sure we have
1087 * enough for the terminator entry as well.
1089 if ((rlpos
+ 2) * (int)sizeof(runlist
) >= rlsize
) {
1090 rlsize
+= 4096; /* PAGE_SIZE */
1091 rlt
= realloc(rl
, rlsize
);
1096 /* Coalesce with previous run if adjacent LCNs. */
1097 if (prev_lcn
== lcn
- prev_run_len
) {
1098 rl
[rlpos
- 1].length
= ++prev_run_len
;
1101 rl
[rlpos
].vcn
= vcn
++;
1102 rl
[rlpos
].lcn
= lcn
;
1104 rl
[rlpos
].length
= 1LL;
1110 /* Add terminator element and return. */
1111 rl
[rlpos
].vcn
= vcn
;
1112 rl
[rlpos
].lcn
= 0LL;
1113 rl
[rlpos
].length
= 0LL;
1118 /* Switch to next zone, decreasing mft zone by factor 2. */
1119 end
= g_mft_zone_end
;
1120 g_mft_zone_end
>>= 1;
1121 /* Have we run out of space on the volume? */
1122 if (g_mft_zone_end
<= 0)
1128 /* Add terminator element. */
1129 rl
[rlpos
].vcn
= vcn
;
1130 rl
[rlpos
].lcn
= -1LL;
1131 rl
[rlpos
].length
= 0LL;
1132 /* Deallocate all allocated clusters. */
1133 deallocate_scattered_clusters(rl
);
1134 /* Free the runlist. */
1141 * ntfs_attr_find - find (next) attribute in mft record
1142 * @type: attribute type to find
1143 * @name: attribute name to find (optional, i.e. NULL means don't care)
1144 * @name_len: attribute name length (only needed if @name present)
1145 * @ic: IGNORE_CASE or CASE_SENSITIVE (ignored if @name not present)
1146 * @val: attribute value to find (optional, resident attributes only)
1147 * @val_len: attribute value length
1148 * @ctx: search context with mft record and attribute to search from
1150 * You shouldn't need to call this function directly. Use lookup_attr() instead.
1152 * ntfs_attr_find() takes a search context @ctx as parameter and searches the
1153 * mft record specified by @ctx->mrec, beginning at @ctx->attr, for an
1154 * attribute of @type, optionally @name and @val. If found, ntfs_attr_find()
1155 * returns 0 and @ctx->attr will point to the found attribute.
1157 * If not found, ntfs_attr_find() returns -1, with errno set to ENOENT and
1158 * @ctx->attr will point to the attribute before which the attribute being
1159 * searched for would need to be inserted if such an action were to be desired.
1161 * On actual error, ntfs_attr_find() returns -1 with errno set to the error
1162 * code but not to ENOENT. In this case @ctx->attr is undefined and in
1163 * particular do not rely on it not changing.
1165 * If @ctx->is_first is TRUE, the search begins with @ctx->attr itself. If it
1166 * is FALSE, the search begins after @ctx->attr.
1168 * If @type is AT_UNUSED, return the first found attribute, i.e. one can
1169 * enumerate all attributes by setting @type to AT_UNUSED and then calling
1170 * ntfs_attr_find() repeatedly until it returns -1 with errno set to ENOENT to
1171 * indicate that there are no more entries. During the enumeration, each
1172 * successful call of ntfs_attr_find() will return the next attribute in the
1173 * mft record @ctx->mrec.
1175 * If @type is AT_END, seek to the end and return -1 with errno set to ENOENT.
1176 * AT_END is not a valid attribute, its length is zero for example, thus it is
1177 * safer to return error instead of success in this case. This also allows us
1178 * to interoperate cleanly with ntfs_external_attr_find().
1180 * If @name is AT_UNNAMED search for an unnamed attribute. If @name is present
1181 * but not AT_UNNAMED search for a named attribute matching @name. Otherwise,
1182 * match both named and unnamed attributes.
1184 * If @ic is IGNORE_CASE, the @name comparison is not case sensitive and
1185 * @ctx->ntfs_ino must be set to the ntfs inode to which the mft record
1186 * @ctx->mrec belongs. This is so we can get at the ntfs volume and hence at
1187 * the upcase table. If @ic is CASE_SENSITIVE, the comparison is case
1188 * sensitive. When @name is present, @name_len is the @name length in Unicode
1191 * If @name is not present (NULL), we assume that the unnamed attribute is
1192 * being searched for.
1194 * Finally, the resident attribute value @val is looked for, if present.
1195 * If @val is not present (NULL), @val_len is ignored.
1197 * ntfs_attr_find() only searches the specified mft record and it ignores the
1198 * presence of an attribute list attribute (unless it is the one being searched
1199 * for, obviously). If you need to take attribute lists into consideration, use
1200 * ntfs_attr_lookup() instead (see below). This also means that you cannot use
1201 * ntfs_attr_find() to search for extent records of non-resident attributes, as
1202 * extents with lowest_vcn != 0 are usually described by the attribute list
1203 * attribute only. - Note that it is possible that the first extent is only in
1204 * the attribute list while the last extent is in the base mft record, so don't
1205 * rely on being able to find the first extent in the base mft record.
1207 * Warning: Never use @val when looking for attribute types which can be
1208 * non-resident as this most likely will result in a crash!
1210 static int mkntfs_attr_find(const ATTR_TYPES type
, const ntfschar
*name
,
1211 const u32 name_len
, const IGNORE_CASE_BOOL ic
,
1212 const u8
*val
, const u32 val_len
, ntfs_attr_search_ctx
*ctx
)
1215 ntfschar
*upcase
= g_vol
->upcase
;
1216 u32 upcase_len
= g_vol
->upcase_len
;
1219 * Iterate over attributes in mft record starting at @ctx->attr, or the
1220 * attribute following that, if @ctx->is_first is TRUE.
1222 if (ctx
->is_first
) {
1224 ctx
->is_first
= FALSE
;
1226 a
= (ATTR_RECORD
*)((char*)ctx
->attr
+
1227 le32_to_cpu(ctx
->attr
->length
));
1229 for (;; a
= (ATTR_RECORD
*)((char*)a
+ le32_to_cpu(a
->length
))) {
1230 if (p2n(a
) < p2n(ctx
->mrec
) || (char*)a
> (char*)ctx
->mrec
+
1231 le32_to_cpu(ctx
->mrec
->bytes_allocated
))
1234 if (((type
!= AT_UNUSED
) && (le32_to_cpu(a
->type
) >
1235 le32_to_cpu(type
))) ||
1236 (a
->type
== AT_END
)) {
1242 /* If this is an enumeration return this attribute. */
1243 if (type
== AT_UNUSED
)
1245 if (a
->type
!= type
)
1248 * If @name is AT_UNNAMED we want an unnamed attribute.
1249 * If @name is present, compare the two names.
1250 * Otherwise, match any attribute.
1252 if (name
== AT_UNNAMED
) {
1253 /* The search failed if the found attribute is named. */
1254 if (a
->name_length
) {
1258 } else if (name
&& !ntfs_names_are_equal(name
, name_len
,
1259 (ntfschar
*)((char*)a
+ le16_to_cpu(a
->name_offset
)),
1260 a
->name_length
, ic
, upcase
, upcase_len
)) {
1263 rc
= ntfs_names_full_collate(name
, name_len
,
1264 (ntfschar
*)((char*)a
+
1265 le16_to_cpu(a
->name_offset
)),
1266 a
->name_length
, IGNORE_CASE
,
1267 upcase
, upcase_len
);
1269 * If @name collates before a->name, there is no
1270 * matching attribute.
1276 /* If the strings are not equal, continue search. */
1279 rc
= ntfs_names_full_collate(name
, name_len
,
1280 (ntfschar
*)((char*)a
+
1281 le16_to_cpu(a
->name_offset
)),
1282 a
->name_length
, CASE_SENSITIVE
,
1283 upcase
, upcase_len
);
1292 * The names match or @name not present and attribute is
1293 * unnamed. If no @val specified, we have found the attribute
1298 /* @val is present; compare values. */
1302 rc
= memcmp(val
, (char*)a
+le16_to_cpu(a
->value_offset
),
1304 le32_to_cpu(a
->value_length
)));
1306 * If @val collates before the current attribute's
1307 * value, there is no matching attribute.
1311 avl
= le32_to_cpu(a
->value_length
);
1314 if (val_len
< avl
) {
1318 } else if (rc
< 0) {
1324 ntfs_log_trace("File is corrupt. Run chkdsk.\n");
1330 * ntfs_attr_lookup - find an attribute in an ntfs inode
1331 * @type: attribute type to find
1332 * @name: attribute name to find (optional, i.e. NULL means don't care)
1333 * @name_len: attribute name length (only needed if @name present)
1334 * @ic: IGNORE_CASE or CASE_SENSITIVE (ignored if @name not present)
1335 * @lowest_vcn: lowest vcn to find (optional, non-resident attributes only)
1336 * @val: attribute value to find (optional, resident attributes only)
1337 * @val_len: attribute value length
1338 * @ctx: search context with mft record and attribute to search from
1340 * Find an attribute in an ntfs inode. On first search @ctx->ntfs_ino must
1341 * be the base mft record and @ctx must have been obtained from a call to
1342 * ntfs_attr_get_search_ctx().
1344 * This function transparently handles attribute lists and @ctx is used to
1345 * continue searches where they were left off at.
1347 * If @type is AT_UNUSED, return the first found attribute, i.e. one can
1348 * enumerate all attributes by setting @type to AT_UNUSED and then calling
1349 * ntfs_attr_lookup() repeatedly until it returns -1 with errno set to ENOENT
1350 * to indicate that there are no more entries. During the enumeration, each
1351 * successful call of ntfs_attr_lookup() will return the next attribute, with
1352 * the current attribute being described by the search context @ctx.
1354 * If @type is AT_END, seek to the end of the base mft record ignoring the
1355 * attribute list completely and return -1 with errno set to ENOENT. AT_END is
1356 * not a valid attribute, its length is zero for example, thus it is safer to
1357 * return error instead of success in this case. It should never be needed to
1358 * do this, but we implement the functionality because it allows for simpler
1359 * code inside ntfs_external_attr_find().
1361 * If @name is AT_UNNAMED search for an unnamed attribute. If @name is present
1362 * but not AT_UNNAMED search for a named attribute matching @name. Otherwise,
1363 * match both named and unnamed attributes.
1365 * After finishing with the attribute/mft record you need to call
1366 * ntfs_attr_put_search_ctx() to cleanup the search context (unmapping any
1367 * mapped extent inodes, etc).
1369 * Return 0 if the search was successful and -1 if not, with errno set to the
1372 * On success, @ctx->attr is the found attribute, it is in mft record
1373 * @ctx->mrec, and @ctx->al_entry is the attribute list entry for this
1374 * attribute with @ctx->base_* being the base mft record to which @ctx->attr
1375 * belongs. If no attribute list attribute is present @ctx->al_entry and
1376 * @ctx->base_* are NULL.
1378 * On error ENOENT, i.e. attribute not found, @ctx->attr is set to the
1379 * attribute which collates just after the attribute being searched for in the
1380 * base ntfs inode, i.e. if one wants to add the attribute to the mft record
1381 * this is the correct place to insert it into, and if there is not enough
1382 * space, the attribute should be placed in an extent mft record.
1383 * @ctx->al_entry points to the position within @ctx->base_ntfs_ino->attr_list
1384 * at which the new attribute's attribute list entry should be inserted. The
1385 * other @ctx fields, base_ntfs_ino, base_mrec, and base_attr are set to NULL.
1386 * The only exception to this is when @type is AT_END, in which case
1387 * @ctx->al_entry is set to NULL also (see above).
1389 * The following error codes are defined:
1390 * ENOENT Attribute not found, not an error as such.
1391 * EINVAL Invalid arguments.
1392 * EIO I/O error or corrupt data structures found.
1393 * ENOMEM Not enough memory to allocate necessary buffers.
1395 static int mkntfs_attr_lookup(const ATTR_TYPES type
, const ntfschar
*name
,
1396 const u32 name_len
, const IGNORE_CASE_BOOL ic
,
1397 const VCN lowest_vcn
__attribute__((unused
)), const u8
*val
,
1398 const u32 val_len
, ntfs_attr_search_ctx
*ctx
)
1400 ntfs_inode
*base_ni
;
1402 if (!ctx
|| !ctx
->mrec
|| !ctx
->attr
) {
1406 if (ctx
->base_ntfs_ino
)
1407 base_ni
= ctx
->base_ntfs_ino
;
1409 base_ni
= ctx
->ntfs_ino
;
1410 if (!base_ni
|| !NInoAttrList(base_ni
) || type
== AT_ATTRIBUTE_LIST
)
1411 return mkntfs_attr_find(type
, name
, name_len
, ic
, val
, val_len
,
1418 * insert_positioned_attr_in_mft_record
1420 * Create a non-resident attribute with a predefined on disk location
1421 * specified by the runlist @rl. The clusters specified by @rl are assumed to
1422 * be allocated already.
1424 * Return 0 on success and -errno on error.
1426 static int insert_positioned_attr_in_mft_record(MFT_RECORD
*m
,
1427 const ATTR_TYPES type
, const char *name
, u32 name_len
,
1428 const IGNORE_CASE_BOOL ic
, const ATTR_FLAGS flags
,
1429 const runlist
*rl
, const u8
*val
, const s64 val_len
)
1431 ntfs_attr_search_ctx
*ctx
;
1434 int asize
, mpa_size
, err
, i
;
1435 s64 bw
= 0, inited_size
;
1437 ntfschar
*uname
= NULL
;
1445 uname
= ntfs_str2ucs(name
, &uname_len
);
1449 /* Check if the attribute is already there. */
1450 ctx
= ntfs_attr_get_search_ctx(NULL
, m
);
1452 ntfs_log_error("Failed to allocate attribute search context.\n");
1456 if (ic
== IGNORE_CASE
) {
1457 ntfs_log_error("FIXME: Hit unimplemented code path #1.\n");
1461 if (!mkntfs_attr_lookup(type
, uname
, uname_len
, ic
, 0, NULL
, 0, ctx
)) {
1465 if (errno
!= ENOENT
) {
1466 ntfs_log_error("Corrupt inode.\n");
1471 if (flags
& ATTR_COMPRESSION_MASK
) {
1472 ntfs_log_error("Compressed attributes not supported yet.\n");
1473 /* FIXME: Compress attribute into a temporary buffer, set */
1474 /* val accordingly and save the compressed size. */
1478 if (flags
& (ATTR_IS_ENCRYPTED
| ATTR_IS_SPARSE
)) {
1479 ntfs_log_error("Encrypted/sparse attributes not supported.\n");
1483 if (flags
& ATTR_COMPRESSION_MASK
) {
1485 /* FIXME: This compression stuff is all wrong. Never mind for */
1488 mpa_size
= 0; /* get_size_for_compressed_mapping_pairs(rl); */
1494 mpa_size
= ntfs_get_size_for_mapping_pairs(g_vol
, rl
, 0, INT_MAX
);
1497 ntfs_log_error("Failed to get size for mapping "
1505 /* Mapping pairs array and next attribute must be 8-byte aligned. */
1506 asize
= (((int)hdr_size
+ ((name_len
+ 7) & ~7) + mpa_size
) + 7) & ~7;
1507 /* Get the highest vcn. */
1508 for (i
= 0, highest_vcn
= 0LL; rl
[i
].length
; i
++)
1509 highest_vcn
+= rl
[i
].length
;
1510 /* Does the value fit inside the allocated size? */
1511 if (highest_vcn
* g_vol
->cluster_size
< val_len
) {
1512 ntfs_log_error("BUG: Allocated size is smaller than data size!\n");
1516 err
= make_room_for_attribute(m
, (char*)a
, asize
);
1517 if (err
== -ENOSPC
) {
1519 * FIXME: Make space! (AIA)
1520 * can we make it non-resident? if yes, do that.
1521 * does it fit now? yes -> do it.
1522 * m's $DATA or $BITMAP+$INDEX_ALLOCATION resident?
1523 * yes -> make non-resident
1524 * does it fit now? yes -> do it.
1525 * make all attributes non-resident
1526 * does it fit now? yes -> do it.
1527 * m is a base record? yes -> allocate extension record
1528 * does the new attribute fit in there? yes -> do it.
1529 * split up runlist into extents and place each in an extension
1531 * FIXME: the check for needing extension records should be
1532 * earlier on as it is very quick: asize > m->bytes_allocated?
1537 } else if (err
== -EINVAL
) {
1538 ntfs_log_error("BUG(): in insert_positioned_attribute_in_mft_"
1539 "record(): make_room_for_attribute() returned "
1540 "error: EINVAL!\n");
1545 a
->length
= cpu_to_le32(asize
);
1546 a
->non_resident
= 1;
1547 a
->name_length
= name_len
;
1548 a
->name_offset
= cpu_to_le16(hdr_size
);
1550 a
->instance
= m
->next_attr_instance
;
1551 m
->next_attr_instance
= cpu_to_le16((le16_to_cpu(m
->next_attr_instance
)
1553 a
->lowest_vcn
= cpu_to_le64(0);
1554 a
->highest_vcn
= cpu_to_sle64(highest_vcn
- 1LL);
1555 a
->mapping_pairs_offset
= cpu_to_le16(hdr_size
+ ((name_len
+ 7) & ~7));
1556 memset(a
->reserved1
, 0, sizeof(a
->reserved1
));
1557 /* FIXME: Allocated size depends on compression. */
1558 a
->allocated_size
= cpu_to_sle64(highest_vcn
* g_vol
->cluster_size
);
1559 a
->data_size
= cpu_to_sle64(val_len
);
1561 memcpy((char*)a
+ hdr_size
, uname
, name_len
<< 1);
1562 if (flags
& ATTR_COMPRESSION_MASK
) {
1563 if (flags
& ATTR_COMPRESSION_MASK
& ~ATTR_IS_COMPRESSED
) {
1564 ntfs_log_error("Unknown compression format. Reverting "
1565 "to standard compression.\n");
1566 a
->flags
&= ~ATTR_COMPRESSION_MASK
;
1567 a
->flags
|= ATTR_IS_COMPRESSED
;
1569 a
->compression_unit
= 4;
1570 inited_size
= val_len
;
1571 /* FIXME: Set the compressed size. */
1572 a
->compressed_size
= cpu_to_le64(0);
1573 /* FIXME: Write out the compressed data. */
1574 /* FIXME: err = build_mapping_pairs_compressed(); */
1577 a
->compression_unit
= 0;
1578 if ((type
== AT_DATA
)
1579 && (m
->mft_record_number
1580 == const_cpu_to_le32(FILE_LogFile
)))
1581 bw
= ntfs_rlwrite(g_vol
->dev
, rl
, val
, val_len
,
1582 &inited_size
, WRITE_LOGFILE
);
1584 bw
= ntfs_rlwrite(g_vol
->dev
, rl
, val
, val_len
,
1585 &inited_size
, WRITE_STANDARD
);
1586 if (bw
!= val_len
) {
1587 ntfs_log_error("Error writing non-resident attribute "
1591 err
= ntfs_mapping_pairs_build(g_vol
, (u8
*)a
+ hdr_size
+
1592 ((name_len
+ 7) & ~7), mpa_size
, rl
, 0, NULL
);
1594 a
->initialized_size
= cpu_to_sle64(inited_size
);
1595 if (err
< 0 || bw
!= val_len
) {
1596 /* FIXME: Handle error. */
1597 /* deallocate clusters */
1598 /* remove attribute */
1601 ntfs_log_error("insert_positioned_attr_in_mft_record failed "
1602 "with error %i.\n", err
< 0 ? err
: (int)bw
);
1606 ntfs_attr_put_search_ctx(ctx
);
1607 ntfs_ucsfree(uname
);
1612 * insert_non_resident_attr_in_mft_record
1614 * Return 0 on success and -errno on error.
1616 static int insert_non_resident_attr_in_mft_record(MFT_RECORD
*m
,
1617 const ATTR_TYPES type
, const char *name
, u32 name_len
,
1618 const IGNORE_CASE_BOOL ic
, const ATTR_FLAGS flags
,
1619 const u8
*val
, const s64 val_len
,
1620 WRITE_TYPE write_type
)
1622 ntfs_attr_search_ctx
*ctx
;
1625 int asize
, mpa_size
, err
, i
;
1628 ntfschar
*uname
= NULL
;
1636 uname
= ntfs_str2ucs(name
, &uname_len
);
1640 /* Check if the attribute is already there. */
1641 ctx
= ntfs_attr_get_search_ctx(NULL
, m
);
1643 ntfs_log_error("Failed to allocate attribute search context.\n");
1647 if (ic
== IGNORE_CASE
) {
1648 ntfs_log_error("FIXME: Hit unimplemented code path #2.\n");
1652 if (!mkntfs_attr_lookup(type
, uname
, uname_len
, ic
, 0, NULL
, 0, ctx
)) {
1656 if (errno
!= ENOENT
) {
1657 ntfs_log_error("Corrupt inode.\n");
1662 if (flags
& ATTR_COMPRESSION_MASK
) {
1663 ntfs_log_error("Compressed attributes not supported yet.\n");
1664 /* FIXME: Compress attribute into a temporary buffer, set */
1665 /* val accordingly and save the compressed size. */
1669 if (flags
& (ATTR_IS_ENCRYPTED
| ATTR_IS_SPARSE
)) {
1670 ntfs_log_error("Encrypted/sparse attributes not supported.\n");
1675 rl
= allocate_scattered_clusters((val_len
+
1676 g_vol
->cluster_size
- 1) / g_vol
->cluster_size
);
1679 ntfs_log_perror("Failed to allocate scattered clusters");
1685 if (flags
& ATTR_COMPRESSION_MASK
) {
1687 /* FIXME: This compression stuff is all wrong. Never mind for */
1690 mpa_size
= 0; /* get_size_for_compressed_mapping_pairs(rl); */
1696 mpa_size
= ntfs_get_size_for_mapping_pairs(g_vol
, rl
, 0, INT_MAX
);
1699 ntfs_log_error("Failed to get size for mapping "
1707 /* Mapping pairs array and next attribute must be 8-byte aligned. */
1708 asize
= (((int)hdr_size
+ ((name_len
+ 7) & ~7) + mpa_size
) + 7) & ~7;
1709 err
= make_room_for_attribute(m
, (char*)a
, asize
);
1710 if (err
== -ENOSPC
) {
1712 * FIXME: Make space! (AIA)
1713 * can we make it non-resident? if yes, do that.
1714 * does it fit now? yes -> do it.
1715 * m's $DATA or $BITMAP+$INDEX_ALLOCATION resident?
1716 * yes -> make non-resident
1717 * does it fit now? yes -> do it.
1718 * make all attributes non-resident
1719 * does it fit now? yes -> do it.
1720 * m is a base record? yes -> allocate extension record
1721 * does the new attribute fit in there? yes -> do it.
1722 * split up runlist into extents and place each in an extension
1724 * FIXME: the check for needing extension records should be
1725 * earlier on as it is very quick: asize > m->bytes_allocated?
1730 } else if (err
== -EINVAL
) {
1731 ntfs_log_error("BUG(): in insert_non_resident_attribute_in_"
1732 "mft_record(): make_room_for_attribute() "
1733 "returned error: EINVAL!\n");
1738 a
->length
= cpu_to_le32(asize
);
1739 a
->non_resident
= 1;
1740 a
->name_length
= name_len
;
1741 a
->name_offset
= cpu_to_le16(hdr_size
);
1743 a
->instance
= m
->next_attr_instance
;
1744 m
->next_attr_instance
= cpu_to_le16((le16_to_cpu(m
->next_attr_instance
)
1746 a
->lowest_vcn
= cpu_to_le64(0);
1747 for (i
= 0; rl
[i
].length
; i
++)
1749 a
->highest_vcn
= cpu_to_sle64(rl
[i
].vcn
- 1);
1750 a
->mapping_pairs_offset
= cpu_to_le16(hdr_size
+ ((name_len
+ 7) & ~7));
1751 memset(a
->reserved1
, 0, sizeof(a
->reserved1
));
1752 /* FIXME: Allocated size depends on compression. */
1753 a
->allocated_size
= cpu_to_sle64((val_len
+ (g_vol
->cluster_size
- 1)) &
1754 ~(g_vol
->cluster_size
- 1));
1755 a
->data_size
= cpu_to_sle64(val_len
);
1756 a
->initialized_size
= cpu_to_sle64(val_len
);
1758 memcpy((char*)a
+ hdr_size
, uname
, name_len
<< 1);
1759 if (flags
& ATTR_COMPRESSION_MASK
) {
1760 if (flags
& ATTR_COMPRESSION_MASK
& ~ATTR_IS_COMPRESSED
) {
1761 ntfs_log_error("Unknown compression format. Reverting "
1762 "to standard compression.\n");
1763 a
->flags
&= ~ATTR_COMPRESSION_MASK
;
1764 a
->flags
|= ATTR_IS_COMPRESSED
;
1766 a
->compression_unit
= 4;
1767 /* FIXME: Set the compressed size. */
1768 a
->compressed_size
= cpu_to_le64(0);
1769 /* FIXME: Write out the compressed data. */
1770 /* FIXME: err = build_mapping_pairs_compressed(); */
1773 a
->compression_unit
= 0;
1774 bw
= ntfs_rlwrite(g_vol
->dev
, rl
, val
, val_len
, NULL
,
1776 if (bw
!= val_len
) {
1777 ntfs_log_error("Error writing non-resident attribute "
1781 err
= ntfs_mapping_pairs_build(g_vol
, (u8
*)a
+ hdr_size
+
1782 ((name_len
+ 7) & ~7), mpa_size
, rl
, 0, NULL
);
1784 if (err
< 0 || bw
!= val_len
) {
1785 /* FIXME: Handle error. */
1786 /* deallocate clusters */
1787 /* remove attribute */
1790 ntfs_log_error("insert_non_resident_attr_in_mft_record failed with "
1791 "error %lld.\n", (long long) (err
< 0 ? err
: bw
));
1795 ntfs_attr_put_search_ctx(ctx
);
1796 ntfs_ucsfree(uname
);
1802 * insert_resident_attr_in_mft_record
1804 * Return 0 on success and -errno on error.
1806 static int insert_resident_attr_in_mft_record(MFT_RECORD
*m
,
1807 const ATTR_TYPES type
, const char *name
, u32 name_len
,
1808 const IGNORE_CASE_BOOL ic
, const ATTR_FLAGS flags
,
1809 const RESIDENT_ATTR_FLAGS res_flags
,
1810 const u8
*val
, const u32 val_len
)
1812 ntfs_attr_search_ctx
*ctx
;
1815 ntfschar
*uname
= NULL
;
1819 mkntfs_attr_lookup();
1823 uname
= ntfs_str2ucs(name
, &uname_len
);
1827 /* Check if the attribute is already there. */
1828 ctx
= ntfs_attr_get_search_ctx(NULL
, m
);
1830 ntfs_log_error("Failed to allocate attribute search context.\n");
1834 if (ic
== IGNORE_CASE
) {
1835 ntfs_log_error("FIXME: Hit unimplemented code path #3.\n");
1839 if (!mkntfs_attr_lookup(type
, uname
, uname_len
, ic
, 0, val
, val_len
,
1844 if (errno
!= ENOENT
) {
1845 ntfs_log_error("Corrupt inode.\n");
1850 /* sizeof(resident attribute record header) == 24 */
1851 asize
= ((24 + ((name_len
*2 + 7) & ~7) + val_len
) + 7) & ~7;
1852 err
= make_room_for_attribute(m
, (char*)a
, asize
);
1853 if (err
== -ENOSPC
) {
1855 * FIXME: Make space! (AIA)
1856 * can we make it non-resident? if yes, do that.
1857 * does it fit now? yes -> do it.
1858 * m's $DATA or $BITMAP+$INDEX_ALLOCATION resident?
1859 * yes -> make non-resident
1860 * does it fit now? yes -> do it.
1861 * make all attributes non-resident
1862 * does it fit now? yes -> do it.
1863 * m is a base record? yes -> allocate extension record
1864 * does the new attribute fit in there? yes -> do it.
1865 * split up runlist into extents and place each in an extension
1867 * FIXME: the check for needing extension records should be
1868 * earlier on as it is very quick: asize > m->bytes_allocated?
1874 if (err
== -EINVAL
) {
1875 ntfs_log_error("BUG(): in insert_resident_attribute_in_mft_"
1876 "record(): make_room_for_attribute() returned "
1877 "error: EINVAL!\n");
1882 a
->length
= cpu_to_le32(asize
);
1883 a
->non_resident
= 0;
1884 a
->name_length
= name_len
;
1885 if (type
== AT_OBJECT_ID
)
1886 a
->name_offset
= const_cpu_to_le16(0);
1888 a
->name_offset
= const_cpu_to_le16(24);
1890 a
->instance
= m
->next_attr_instance
;
1891 m
->next_attr_instance
= cpu_to_le16((le16_to_cpu(m
->next_attr_instance
)
1893 a
->value_length
= cpu_to_le32(val_len
);
1894 a
->value_offset
= cpu_to_le16(24 + ((name_len
*2 + 7) & ~7));
1895 a
->resident_flags
= res_flags
;
1898 memcpy((char*)a
+ 24, uname
, name_len
<< 1);
1900 memcpy((char*)a
+ le16_to_cpu(a
->value_offset
), val
, val_len
);
1903 ntfs_attr_put_search_ctx(ctx
);
1904 ntfs_ucsfree(uname
);
1912 * Return 0 on success or -errno on error.
1914 static int add_attr_std_info(MFT_RECORD
*m
, const FILE_ATTR_FLAGS flags
,
1917 STANDARD_INFORMATION si
;
1922 si
.creation_time
= mkntfs_time();
1923 si
.last_data_change_time
= si
.creation_time
;
1924 si
.last_mft_change_time
= si
.creation_time
;
1925 si
.last_access_time
= si
.creation_time
;
1926 si
.file_attributes
= flags
; /* already LE */
1927 si
.maximum_versions
= cpu_to_le32(0);
1928 si
.version_number
= cpu_to_le32(0);
1929 si
.class_id
= cpu_to_le32(0);
1930 si
.security_id
= security_id
;
1931 if (si
.security_id
!= const_cpu_to_le32(0))
1933 /* FIXME: $Quota support... */
1934 si
.owner_id
= cpu_to_le32(0);
1935 si
.quota_charged
= cpu_to_le64(0ULL);
1936 /* FIXME: $UsnJrnl support... Not needed on fresh w2k3-volume */
1937 si
.usn
= cpu_to_le64(0ULL);
1938 /* NTFS 1.2: size of si = 48, NTFS 3.[01]: size of si = 72 */
1939 err
= insert_resident_attr_in_mft_record(m
, AT_STANDARD_INFORMATION
,
1940 NULL
, 0, CASE_SENSITIVE
, const_cpu_to_le16(0),
1941 0, (u8
*)&si
, sd_size
);
1943 ntfs_log_perror("add_attr_std_info failed");
1948 * Tell whether the unnamed data is non resident
1951 static BOOL
non_resident_unnamed_data(MFT_RECORD
*m
)
1954 ntfs_attr_search_ctx
*ctx
;
1957 ctx
= ntfs_attr_get_search_ctx(NULL
, m
);
1958 if (ctx
&& !mkntfs_attr_find(AT_DATA
,
1959 (const ntfschar
*)NULL
, 0, CASE_SENSITIVE
,
1960 (u8
*)NULL
, 0, ctx
)) {
1962 nonres
= a
->non_resident
!= 0;
1964 ntfs_log_error("BUG: Unnamed data not found\n");
1968 ntfs_attr_put_search_ctx(ctx
);
1973 * Get the time stored in the standard information attribute
1976 static ntfs_time
stdinfo_time(MFT_RECORD
*m
)
1978 STANDARD_INFORMATION
*si
;
1979 ntfs_attr_search_ctx
*ctx
;
1980 ntfs_time info_time
;
1982 ctx
= ntfs_attr_get_search_ctx(NULL
, m
);
1983 if (ctx
&& !mkntfs_attr_find(AT_STANDARD_INFORMATION
,
1984 (const ntfschar
*)NULL
, 0, CASE_SENSITIVE
,
1985 (u8
*)NULL
, 0, ctx
)) {
1986 si
= (STANDARD_INFORMATION
*)((char*)ctx
->attr
+
1987 le16_to_cpu(ctx
->attr
->value_offset
));
1988 info_time
= si
->creation_time
;
1990 ntfs_log_error("BUG: Standard information not found\n");
1991 info_time
= mkntfs_time();
1994 ntfs_attr_put_search_ctx(ctx
);
1999 * add_attr_file_name
2001 * Return 0 on success or -errno on error.
2003 static int add_attr_file_name(MFT_RECORD
*m
, const leMFT_REF parent_dir
,
2004 const s64 allocated_size
, const s64 data_size
,
2005 const FILE_ATTR_FLAGS flags
, const u16 packed_ea_size
,
2006 const u32 reparse_point_tag
, const char *file_name
,
2007 const FILE_NAME_TYPE_FLAGS file_name_type
)
2009 ntfs_attr_search_ctx
*ctx
;
2010 STANDARD_INFORMATION
*si
;
2015 /* Check if the attribute is already there. */
2016 ctx
= ntfs_attr_get_search_ctx(NULL
, m
);
2018 ntfs_log_error("Failed to get attribute search context.\n");
2021 if (mkntfs_attr_lookup(AT_STANDARD_INFORMATION
, AT_UNNAMED
, 0,
2022 CASE_SENSITIVE
, 0, NULL
, 0, ctx
)) {
2024 ntfs_log_error("BUG: Standard information attribute not "
2025 "present in file record.\n");
2026 ntfs_attr_put_search_ctx(ctx
);
2029 si
= (STANDARD_INFORMATION
*)((char*)ctx
->attr
+
2030 le16_to_cpu(ctx
->attr
->value_offset
));
2031 i
= (strlen(file_name
) + 1) * sizeof(ntfschar
);
2032 fn_size
= sizeof(FILE_NAME_ATTR
) + i
;
2033 fn
= ntfs_malloc(fn_size
);
2035 ntfs_attr_put_search_ctx(ctx
);
2038 fn
->parent_directory
= parent_dir
;
2040 fn
->creation_time
= si
->creation_time
;
2041 fn
->last_data_change_time
= si
->last_data_change_time
;
2042 fn
->last_mft_change_time
= si
->last_mft_change_time
;
2043 fn
->last_access_time
= si
->last_access_time
;
2044 ntfs_attr_put_search_ctx(ctx
);
2046 fn
->allocated_size
= cpu_to_sle64(allocated_size
);
2047 fn
->data_size
= cpu_to_sle64(data_size
);
2048 fn
->file_attributes
= flags
;
2049 /* These are in a union so can't have both. */
2050 if (packed_ea_size
&& reparse_point_tag
) {
2054 if (packed_ea_size
) {
2055 fn
->packed_ea_size
= cpu_to_le16(packed_ea_size
);
2056 fn
->reserved
= cpu_to_le16(0);
2058 fn
->reparse_point_tag
= cpu_to_le32(reparse_point_tag
);
2060 fn
->file_name_type
= file_name_type
;
2061 uname
= fn
->file_name
;
2062 i
= ntfs_mbstoucs_libntfscompat(file_name
, &uname
, i
);
2069 return -ENAMETOOLONG
;
2071 /* No terminating null in file names. */
2072 fn
->file_name_length
= i
;
2073 fn_size
= sizeof(FILE_NAME_ATTR
) + i
* sizeof(ntfschar
);
2074 i
= insert_resident_attr_in_mft_record(m
, AT_FILE_NAME
, NULL
, 0,
2075 CASE_SENSITIVE
, const_cpu_to_le16(0),
2076 RESIDENT_ATTR_IS_INDEXED
, (u8
*)fn
, fn_size
);
2079 ntfs_log_error("add_attr_file_name failed: %s\n", strerror(-i
));
2084 * add_attr_object_id -
2086 * Note we insert only a basic object id which only has the GUID and none of
2087 * the extended fields. This is because we currently only use this function
2088 * when creating the object id for the volume.
2090 * Return 0 on success or -errno on error.
2092 static int add_attr_object_id(MFT_RECORD
*m
, const GUID
*object_id
)
2097 oi
= (OBJECT_ID_ATTR
) {
2098 .object_id
= *object_id
,
2100 err
= insert_resident_attr_in_mft_record(m
, AT_OBJECT_ID
, NULL
,
2101 0, CASE_SENSITIVE
, const_cpu_to_le16(0),
2102 0, (u8
*)&oi
, sizeof(oi
.object_id
));
2104 ntfs_log_error("add_attr_vol_info failed: %s\n", strerror(-err
));
2111 * Create the security descriptor attribute adding the security descriptor @sd
2112 * of length @sd_len to the mft record @m.
2114 * Return 0 on success or -errno on error.
2116 static int add_attr_sd(MFT_RECORD
*m
, const u8
*sd
, const s64 sd_len
)
2120 /* Does it fit? NO: create non-resident. YES: create resident. */
2121 if (le32_to_cpu(m
->bytes_in_use
) + 24 + sd_len
>
2122 le32_to_cpu(m
->bytes_allocated
))
2123 err
= insert_non_resident_attr_in_mft_record(m
,
2124 AT_SECURITY_DESCRIPTOR
, NULL
, 0,
2125 CASE_SENSITIVE
, const_cpu_to_le16(0), sd
,
2126 sd_len
, WRITE_STANDARD
);
2128 err
= insert_resident_attr_in_mft_record(m
,
2129 AT_SECURITY_DESCRIPTOR
, NULL
, 0,
2130 CASE_SENSITIVE
, const_cpu_to_le16(0), 0, sd
,
2133 ntfs_log_error("add_attr_sd failed: %s\n", strerror(-err
));
2140 * Return 0 on success or -errno on error.
2142 static int add_attr_data(MFT_RECORD
*m
, const char *name
, const u32 name_len
,
2143 const IGNORE_CASE_BOOL ic
, const ATTR_FLAGS flags
,
2144 const u8
*val
, const s64 val_len
)
2149 * Does it fit? NO: create non-resident. YES: create resident.
2151 * FIXME: Introduced arbitrary limit of mft record allocated size - 512.
2152 * This is to get around the problem that if $Bitmap/$DATA becomes too
2153 * big, but is just small enough to be resident, we would make it
2154 * resident, and later run out of space when creating the other
2155 * attributes and this would cause us to abort as making resident
2156 * attributes non-resident is not supported yet.
2157 * The proper fix is to support making resident attribute non-resident.
2159 if (le32_to_cpu(m
->bytes_in_use
) + 24 + val_len
>
2160 min(le32_to_cpu(m
->bytes_allocated
),
2161 le32_to_cpu(m
->bytes_allocated
) - 512))
2162 err
= insert_non_resident_attr_in_mft_record(m
, AT_DATA
, name
,
2163 name_len
, ic
, flags
, val
, val_len
,
2166 err
= insert_resident_attr_in_mft_record(m
, AT_DATA
, name
,
2167 name_len
, ic
, flags
, 0, val
, val_len
);
2170 ntfs_log_error("add_attr_data failed: %s\n", strerror(-err
));
2175 * add_attr_data_positioned
2177 * Create a non-resident data attribute with a predefined on disk location
2178 * specified by the runlist @rl. The clusters specified by @rl are assumed to
2179 * be allocated already.
2181 * Return 0 on success or -errno on error.
2183 static int add_attr_data_positioned(MFT_RECORD
*m
, const char *name
,
2184 const u32 name_len
, const IGNORE_CASE_BOOL ic
,
2185 const ATTR_FLAGS flags
, const runlist
*rl
,
2186 const u8
*val
, const s64 val_len
)
2190 err
= insert_positioned_attr_in_mft_record(m
, AT_DATA
, name
, name_len
,
2191 ic
, flags
, rl
, val
, val_len
);
2193 ntfs_log_error("add_attr_data_positioned failed: %s\n",
2201 * Create volume name attribute specifying the volume name @vol_name as a null
2202 * terminated char string of length @vol_name_len (number of characters not
2203 * including the terminating null), which is converted internally to a little
2204 * endian ntfschar string. The name is at least 1 character long (though
2205 * Windows accepts zero characters), and at most 128 characters long (not
2206 * counting the terminating null).
2208 * Return 0 on success or -errno on error.
2210 static int add_attr_vol_name(MFT_RECORD
*m
, const char *vol_name
,
2211 const int vol_name_len
__attribute__((unused
)))
2213 ntfschar
*uname
= NULL
;
2218 uname_len
= ntfs_mbstoucs(vol_name
, &uname
);
2221 if (uname_len
> 128) {
2223 return -ENAMETOOLONG
;
2226 i
= insert_resident_attr_in_mft_record(m
, AT_VOLUME_NAME
, NULL
, 0,
2227 CASE_SENSITIVE
, const_cpu_to_le16(0),
2228 0, (u8
*)uname
, uname_len
*sizeof(ntfschar
));
2231 ntfs_log_error("add_attr_vol_name failed: %s\n", strerror(-i
));
2238 * Return 0 on success or -errno on error.
2240 static int add_attr_vol_info(MFT_RECORD
*m
, const VOLUME_FLAGS flags
,
2241 const u8 major_ver
, const u8 minor_ver
)
2243 VOLUME_INFORMATION vi
;
2246 memset(&vi
, 0, sizeof(vi
));
2247 vi
.major_ver
= major_ver
;
2248 vi
.minor_ver
= minor_ver
;
2249 vi
.flags
= flags
& VOLUME_FLAGS_MASK
;
2250 err
= insert_resident_attr_in_mft_record(m
, AT_VOLUME_INFORMATION
, NULL
,
2251 0, CASE_SENSITIVE
, const_cpu_to_le16(0),
2252 0, (u8
*)&vi
, sizeof(vi
));
2254 ntfs_log_error("add_attr_vol_info failed: %s\n", strerror(-err
));
2259 * add_attr_index_root
2261 * Return 0 on success or -errno on error.
2263 static int add_attr_index_root(MFT_RECORD
*m
, const char *name
,
2264 const u32 name_len
, const IGNORE_CASE_BOOL ic
,
2265 const ATTR_TYPES indexed_attr_type
,
2266 const COLLATION_RULES collation_rule
,
2267 const u32 index_block_size
)
2270 INDEX_ENTRY_HEADER
*e
;
2273 val_len
= sizeof(INDEX_ROOT
) + sizeof(INDEX_ENTRY_HEADER
);
2274 r
= ntfs_malloc(val_len
);
2277 r
->type
= (indexed_attr_type
== AT_FILE_NAME
)
2278 ? AT_FILE_NAME
: const_cpu_to_le32(0);
2279 if (indexed_attr_type
== AT_FILE_NAME
&&
2280 collation_rule
!= COLLATION_FILE_NAME
) {
2282 ntfs_log_error("add_attr_index_root: indexed attribute is $FILE_NAME "
2283 "but collation rule is not COLLATION_FILE_NAME.\n");
2286 r
->collation_rule
= collation_rule
;
2287 r
->index_block_size
= cpu_to_le32(index_block_size
);
2288 if (index_block_size
>= g_vol
->cluster_size
) {
2289 if (index_block_size
% g_vol
->cluster_size
) {
2290 ntfs_log_error("add_attr_index_root: index block size is not "
2291 "a multiple of the cluster size.\n");
2295 r
->clusters_per_index_block
= index_block_size
/
2296 g_vol
->cluster_size
;
2297 } else { /* if (g_vol->cluster_size > index_block_size) */
2298 if (index_block_size
& (index_block_size
- 1)) {
2299 ntfs_log_error("add_attr_index_root: index block size is not "
2304 if (index_block_size
< (u32
)opts
.sector_size
) {
2305 ntfs_log_error("add_attr_index_root: index block size "
2306 "is smaller than the sector size.\n");
2310 r
->clusters_per_index_block
= index_block_size
2311 >> NTFS_BLOCK_SIZE_BITS
;
2313 memset(&r
->reserved
, 0, sizeof(r
->reserved
));
2314 r
->index
.entries_offset
= const_cpu_to_le32(sizeof(INDEX_HEADER
));
2315 r
->index
.index_length
= const_cpu_to_le32(sizeof(INDEX_HEADER
) +
2316 sizeof(INDEX_ENTRY_HEADER
));
2317 r
->index
.allocated_size
= r
->index
.index_length
;
2318 r
->index
.ih_flags
= SMALL_INDEX
;
2319 memset(&r
->index
.reserved
, 0, sizeof(r
->index
.reserved
));
2320 e
= (INDEX_ENTRY_HEADER
*)((u8
*)&r
->index
+
2321 le32_to_cpu(r
->index
.entries_offset
));
2323 * No matter whether this is a file index or a view as this is a
2324 * termination entry, hence no key value / data is associated with it
2325 * at all. Thus, we just need the union to be all zero.
2327 e
->indexed_file
= const_cpu_to_le64(0LL);
2328 e
->length
= const_cpu_to_le16(sizeof(INDEX_ENTRY_HEADER
));
2329 e
->key_length
= const_cpu_to_le16(0);
2330 e
->flags
= INDEX_ENTRY_END
;
2331 e
->reserved
= const_cpu_to_le16(0);
2332 err
= insert_resident_attr_in_mft_record(m
, AT_INDEX_ROOT
, name
,
2333 name_len
, ic
, const_cpu_to_le16(0), 0,
2337 ntfs_log_error("add_attr_index_root failed: %s\n", strerror(-err
));
2342 * add_attr_index_alloc
2344 * Return 0 on success or -errno on error.
2346 static int add_attr_index_alloc(MFT_RECORD
*m
, const char *name
,
2347 const u32 name_len
, const IGNORE_CASE_BOOL ic
,
2348 const u8
*index_alloc_val
, const u32 index_alloc_val_len
)
2352 err
= insert_non_resident_attr_in_mft_record(m
, AT_INDEX_ALLOCATION
,
2353 name
, name_len
, ic
, const_cpu_to_le16(0),
2354 index_alloc_val
, index_alloc_val_len
, WRITE_STANDARD
);
2356 ntfs_log_error("add_attr_index_alloc failed: %s\n", strerror(-err
));
2363 * Return 0 on success or -errno on error.
2365 static int add_attr_bitmap(MFT_RECORD
*m
, const char *name
, const u32 name_len
,
2366 const IGNORE_CASE_BOOL ic
, const u8
*bitmap
,
2367 const u32 bitmap_len
)
2371 /* Does it fit? NO: create non-resident. YES: create resident. */
2372 if (le32_to_cpu(m
->bytes_in_use
) + 24 + bitmap_len
>
2373 le32_to_cpu(m
->bytes_allocated
))
2374 err
= insert_non_resident_attr_in_mft_record(m
, AT_BITMAP
, name
,
2375 name_len
, ic
, const_cpu_to_le16(0), bitmap
,
2376 bitmap_len
, WRITE_STANDARD
);
2378 err
= insert_resident_attr_in_mft_record(m
, AT_BITMAP
, name
,
2379 name_len
, ic
, const_cpu_to_le16(0), 0,
2380 bitmap
, bitmap_len
);
2383 ntfs_log_error("add_attr_bitmap failed: %s\n", strerror(-err
));
2388 * add_attr_bitmap_positioned
2390 * Create a non-resident bitmap attribute with a predefined on disk location
2391 * specified by the runlist @rl. The clusters specified by @rl are assumed to
2392 * be allocated already.
2394 * Return 0 on success or -errno on error.
2396 static int add_attr_bitmap_positioned(MFT_RECORD
*m
, const char *name
,
2397 const u32 name_len
, const IGNORE_CASE_BOOL ic
,
2398 const runlist
*rl
, const u8
*bitmap
, const u32 bitmap_len
)
2402 err
= insert_positioned_attr_in_mft_record(m
, AT_BITMAP
, name
, name_len
,
2403 ic
, const_cpu_to_le16(0), rl
, bitmap
, bitmap_len
);
2405 ntfs_log_error("add_attr_bitmap_positioned failed: %s\n",
2412 * upgrade_to_large_index
2414 * Create bitmap and index allocation attributes, modify index root
2415 * attribute accordingly and move all of the index entries from the index root
2416 * into the index allocation.
2418 * Return 0 on success or -errno on error.
2420 static int upgrade_to_large_index(MFT_RECORD
*m
, const char *name
,
2421 u32 name_len
, const IGNORE_CASE_BOOL ic
,
2422 INDEX_ALLOCATION
**idx
)
2424 ntfs_attr_search_ctx
*ctx
;
2428 INDEX_ALLOCATION
*ia_val
= NULL
;
2429 ntfschar
*uname
= NULL
;
2432 char *re_start
, *re_end
;
2433 int i
, err
, index_block_size
;
2435 uname
= ntfs_str2ucs(name
, &uname_len
);
2439 /* Find the index root attribute. */
2440 ctx
= ntfs_attr_get_search_ctx(NULL
, m
);
2442 ntfs_log_error("Failed to allocate attribute search context.\n");
2443 ntfs_ucsfree(uname
);
2446 if (ic
== IGNORE_CASE
) {
2447 ntfs_log_error("FIXME: Hit unimplemented code path #4.\n");
2449 ntfs_ucsfree(uname
);
2452 err
= mkntfs_attr_lookup(AT_INDEX_ROOT
, uname
, uname_len
, ic
, 0, NULL
, 0,
2454 ntfs_ucsfree(uname
);
2460 if (a
->non_resident
|| a
->flags
) {
2464 r
= (INDEX_ROOT
*)((char*)a
+ le16_to_cpu(a
->value_offset
));
2465 re_end
= (char*)r
+ le32_to_cpu(a
->value_length
);
2466 re_start
= (char*)&r
->index
+ le32_to_cpu(r
->index
.entries_offset
);
2467 re
= (INDEX_ENTRY
*)re_start
;
2468 index_block_size
= le32_to_cpu(r
->index_block_size
);
2469 memset(bmp
, 0, sizeof(bmp
));
2470 ntfs_bit_set(bmp
, 0ULL, 1);
2471 /* Bitmap has to be at least 8 bytes in size. */
2472 err
= add_attr_bitmap(m
, name
, name_len
, ic
, bmp
, sizeof(bmp
));
2475 ia_val
= ntfs_calloc(index_block_size
);
2481 ia_val
->magic
= magic_INDX
;
2482 ia_val
->usa_ofs
= cpu_to_le16(sizeof(INDEX_ALLOCATION
));
2483 if (index_block_size
>= NTFS_BLOCK_SIZE
) {
2484 ia_val
->usa_count
= cpu_to_le16(index_block_size
/
2485 NTFS_BLOCK_SIZE
+ 1);
2487 ia_val
->usa_count
= cpu_to_le16(1);
2488 ntfs_log_error("Sector size is bigger than index block size. "
2489 "Setting usa_count to 1. If Windows chkdsk "
2490 "reports this as corruption, please email %s "
2491 "stating that you saw this message and that "
2492 "the filesystem created was corrupt. "
2493 "Thank you.", NTFS_DEV_LIST
);
2496 *(le16
*)((char*)ia_val
+ le16_to_cpu(ia_val
->usa_ofs
)) =
2498 ia_val
->lsn
= cpu_to_le64(0);
2499 ia_val
->index_block_vcn
= cpu_to_le64(0);
2500 ia_val
->index
.ih_flags
= LEAF_NODE
;
2501 /* Align to 8-byte boundary. */
2502 ia_val
->index
.entries_offset
= cpu_to_le32((sizeof(INDEX_HEADER
) +
2503 le16_to_cpu(ia_val
->usa_count
) * 2 + 7) & ~7);
2504 ia_val
->index
.allocated_size
= cpu_to_le32(index_block_size
-
2505 (sizeof(INDEX_ALLOCATION
) - sizeof(INDEX_HEADER
)));
2506 /* Find the last entry in the index root and save it in re. */
2507 while ((char*)re
< re_end
&& !(re
->ie_flags
& INDEX_ENTRY_END
)) {
2508 /* Next entry in index root. */
2509 re
= (INDEX_ENTRY
*)((char*)re
+ le16_to_cpu(re
->length
));
2511 /* Copy all the entries including the termination entry. */
2512 i
= (char*)re
- re_start
+ le16_to_cpu(re
->length
);
2513 memcpy((char*)&ia_val
->index
+
2514 le32_to_cpu(ia_val
->index
.entries_offset
), re_start
, i
);
2515 /* Finish setting up index allocation. */
2516 ia_val
->index
.index_length
= cpu_to_le32(i
+
2517 le32_to_cpu(ia_val
->index
.entries_offset
));
2518 /* Move the termination entry forward to the beginning if necessary. */
2519 if ((char*)re
> re_start
) {
2520 memmove(re_start
, (char*)re
, le16_to_cpu(re
->length
));
2521 re
= (INDEX_ENTRY
*)re_start
;
2523 /* Now fixup empty index root with pointer to index allocation VCN 0. */
2524 r
->index
.ih_flags
= LARGE_INDEX
;
2525 re
->ie_flags
|= INDEX_ENTRY_NODE
;
2526 if (le16_to_cpu(re
->length
) < sizeof(INDEX_ENTRY_HEADER
) + sizeof(VCN
))
2527 re
->length
= cpu_to_le16(le16_to_cpu(re
->length
) + sizeof(VCN
));
2528 r
->index
.index_length
= cpu_to_le32(le32_to_cpu(r
->index
.entries_offset
)
2529 + le16_to_cpu(re
->length
));
2530 r
->index
.allocated_size
= r
->index
.index_length
;
2531 /* Resize index root attribute. */
2532 if (ntfs_resident_attr_value_resize(m
, a
, sizeof(INDEX_ROOT
) -
2533 sizeof(INDEX_HEADER
) +
2534 le32_to_cpu(r
->index
.allocated_size
))) {
2535 /* TODO: Remove the added bitmap! */
2536 /* Revert index root from index allocation. */
2540 /* Set VCN pointer to 0LL. */
2541 *(leVCN
*)((char*)re
+ cpu_to_le16(re
->length
) - sizeof(VCN
)) =
2543 err
= ntfs_mst_pre_write_fixup((NTFS_RECORD
*)ia_val
, index_block_size
);
2546 ntfs_log_error("ntfs_mst_pre_write_fixup() failed in "
2547 "upgrade_to_large_index.\n");
2550 err
= add_attr_index_alloc(m
, name
, name_len
, ic
, (u8
*)ia_val
,
2552 ntfs_mst_post_write_fixup((NTFS_RECORD
*)ia_val
);
2554 /* TODO: Remove the added bitmap! */
2555 /* Revert index root from index allocation. */
2559 ntfs_attr_put_search_ctx(ctx
);
2562 ntfs_attr_put_search_ctx(ctx
);
2568 * make_room_for_index_entry_in_index_block
2570 * Create space of @size bytes at position @pos inside the index block @idx.
2572 * Return 0 on success or -errno on error.
2574 static int make_room_for_index_entry_in_index_block(INDEX_BLOCK
*idx
,
2575 INDEX_ENTRY
*pos
, u32 size
)
2583 * Rigorous consistency checks. Always return -EINVAL even if more
2584 * appropriate codes exist for simplicity of parsing the return value.
2586 if (size
!= ((size
+ 7) & ~7)) {
2587 ntfs_log_error("make_room_for_index_entry_in_index_block() received "
2588 "non 8-byte aligned size.\n");
2593 if ((char*)pos
< (char*)idx
|| (char*)pos
+ size
< (char*)idx
||
2594 (char*)pos
> (char*)idx
+ sizeof(INDEX_BLOCK
) -
2595 sizeof(INDEX_HEADER
) +
2596 le32_to_cpu(idx
->index
.allocated_size
) ||
2597 (char*)pos
+ size
> (char*)idx
+ sizeof(INDEX_BLOCK
) -
2598 sizeof(INDEX_HEADER
) +
2599 le32_to_cpu(idx
->index
.allocated_size
))
2601 /* The - sizeof(INDEX_ENTRY_HEADER) is for the index terminator. */
2602 if ((char*)pos
- (char*)&idx
->index
>
2603 (int)le32_to_cpu(idx
->index
.index_length
)
2604 - (int)sizeof(INDEX_ENTRY_HEADER
))
2607 biu
= le32_to_cpu(idx
->index
.index_length
);
2608 /* Do we have enough space? */
2609 if (biu
+ size
> le32_to_cpu(idx
->index
.allocated_size
))
2611 /* Move everything after pos to pos + size. */
2612 memmove((char*)pos
+ size
, (char*)pos
, biu
- ((char*)pos
-
2613 (char*)&idx
->index
));
2614 /* Update index block. */
2615 idx
->index
.index_length
= cpu_to_le32(biu
+ size
);
2620 * ntfs_index_keys_compare
2622 * not all types of COLLATION_RULES supported yet...
2623 * added as needed.. (remove this comment when all are added)
2625 static int ntfs_index_keys_compare(u8
*key1
, u8
*key2
, int key1_length
,
2626 int key2_length
, COLLATION_RULES collation_rule
)
2631 if (collation_rule
== COLLATION_NTOFS_ULONG
) {
2632 /* i.e. $SII or $QUOTA-$Q */
2633 u1
= le32_to_cpup((const le32
*)key1
);
2634 u2
= le32_to_cpup((const le32
*)key2
);
2642 if (collation_rule
== COLLATION_NTOFS_ULONGS
) {
2645 while (i
< min(key1_length
, key2_length
)) {
2646 u1
= le32_to_cpup((const le32
*)(key1
+ i
));
2647 u2
= le32_to_cpup((const le32
*)(key2
+ i
));
2655 if (key1_length
< key2_length
)
2657 if (key1_length
> key2_length
)
2661 if (collation_rule
== COLLATION_NTOFS_SECURITY_HASH
) {
2663 u1
= le32_to_cpu(((SDH_INDEX_KEY
*)key1
)->hash
);
2664 u2
= le32_to_cpu(((SDH_INDEX_KEY
*)key2
)->hash
);
2670 u1
= le32_to_cpu(((SDH_INDEX_KEY
*)key1
)->security_id
);
2671 u2
= le32_to_cpu(((SDH_INDEX_KEY
*)key2
)->security_id
);
2678 if (collation_rule
== COLLATION_NTOFS_SID
) {
2680 i
= memcmp(key1
, key2
, min(key1_length
, key2_length
));
2682 if (key1_length
< key2_length
)
2684 if (key1_length
> key2_length
)
2689 ntfs_log_critical("ntfs_index_keys_compare called without supported "
2690 "collation rule.\n");
2691 return 0; /* Claim they're equal. What else can we do? */
2695 * insert_index_entry_in_res_dir_index
2697 * i.e. insert an index_entry in some named index_root
2698 * simplified search method, works for mkntfs
2700 static int insert_index_entry_in_res_dir_index(INDEX_ENTRY
*idx
, u32 idx_size
,
2701 MFT_RECORD
*m
, ntfschar
*name
, u32 name_size
, ATTR_TYPES type
)
2703 ntfs_attr_search_ctx
*ctx
;
2704 INDEX_HEADER
*idx_header
;
2705 INDEX_ENTRY
*idx_entry
, *idx_end
;
2707 COLLATION_RULES collation_rule
;
2712 if (g_vol
->mft_record_size
> idx_size
+ le32_to_cpu(m
->bytes_allocated
))
2714 /* find the INDEX_ROOT attribute:*/
2715 ctx
= ntfs_attr_get_search_ctx(NULL
, m
);
2717 ntfs_log_error("Failed to allocate attribute search "
2722 if (mkntfs_attr_lookup(AT_INDEX_ROOT
, name
, name_size
,
2723 CASE_SENSITIVE
, 0, NULL
, 0, ctx
)) {
2727 /* found attribute */
2728 a
= (ATTR_RECORD
*)ctx
->attr
;
2729 collation_rule
= ((INDEX_ROOT
*)((u8
*)a
+
2730 le16_to_cpu(a
->value_offset
)))->collation_rule
;
2731 idx_header
= (INDEX_HEADER
*)((u8
*)a
+ le16_to_cpu(a
->value_offset
)
2733 idx_entry
= (INDEX_ENTRY
*)((u8
*)idx_header
+
2734 le32_to_cpu(idx_header
->entries_offset
));
2735 idx_end
= (INDEX_ENTRY
*)((u8
*)idx_entry
+
2736 le32_to_cpu(idx_header
->index_length
));
2738 * Loop until we exceed valid memory (corruption case) or until we
2739 * reach the last entry.
2741 if (type
== AT_FILE_NAME
) {
2742 while (((u8
*)idx_entry
< (u8
*)idx_end
) &&
2743 !(idx_entry
->ie_flags
& INDEX_ENTRY_END
)) {
2745 i = ntfs_file_values_compare(&idx->key.file_name,
2746 &idx_entry->key.file_name, 1,
2747 IGNORE_CASE, g_vol->upcase,
2750 i
= ntfs_names_full_collate(idx
->key
.file_name
.file_name
, idx
->key
.file_name
.file_name_length
,
2751 idx_entry
->key
.file_name
.file_name
, idx_entry
->key
.file_name
.file_name_length
,
2752 IGNORE_CASE
, g_vol
->upcase
,
2755 * If @file_name collates before ie->key.file_name,
2756 * there is no matching index entry.
2760 /* If file names are not equal, continue search. */
2763 if (idx
->key
.file_name
.file_name_type
!=
2765 idx_entry
->key
.file_name
.file_name_type
2769 i = ntfs_file_values_compare(&idx->key.file_name,
2770 &idx_entry->key.file_name, 1,
2771 CASE_SENSITIVE, g_vol->upcase,
2774 i
= ntfs_names_full_collate(idx
->key
.file_name
.file_name
, idx
->key
.file_name
.file_name_length
,
2775 idx_entry
->key
.file_name
.file_name
, idx_entry
->key
.file_name
.file_name_length
,
2776 CASE_SENSITIVE
, g_vol
->upcase
,
2783 idx_entry
= (INDEX_ENTRY
*)((u8
*)idx_entry
+
2784 le16_to_cpu(idx_entry
->length
));
2786 } else if (type
== AT_UNUSED
) { /* case view */
2787 while (((u8
*)idx_entry
< (u8
*)idx_end
) &&
2788 !(idx_entry
->ie_flags
& INDEX_ENTRY_END
)) {
2789 i
= ntfs_index_keys_compare((u8
*)idx
+ 0x10,
2790 (u8
*)idx_entry
+ 0x10,
2791 le16_to_cpu(idx
->key_length
),
2792 le16_to_cpu(idx_entry
->key_length
),
2798 idx_entry
= (INDEX_ENTRY
*)((u8
*)idx_entry
+
2799 le16_to_cpu(idx_entry
->length
));
2803 memmove((u8
*)idx_entry
+ idx_size
, (u8
*)idx_entry
,
2804 le32_to_cpu(m
->bytes_in_use
) -
2805 ((u8
*)idx_entry
- (u8
*)m
));
2806 memcpy((u8
*)idx_entry
, (u8
*)idx
, idx_size
);
2807 /* Adjust various offsets, etc... */
2808 m
->bytes_in_use
= cpu_to_le32(le32_to_cpu(m
->bytes_in_use
) + idx_size
);
2809 a
->length
= cpu_to_le32(le32_to_cpu(a
->length
) + idx_size
);
2810 a
->value_length
= cpu_to_le32(le32_to_cpu(a
->value_length
) + idx_size
);
2811 idx_header
->index_length
= cpu_to_le32(
2812 le32_to_cpu(idx_header
->index_length
) + idx_size
);
2813 idx_header
->allocated_size
= cpu_to_le32(
2814 le32_to_cpu(idx_header
->allocated_size
) + idx_size
);
2817 ntfs_attr_put_search_ctx(ctx
);
2824 * initializes $Secure's $SDH and $SII indexes from $SDS datastream
2826 static int initialize_secure(char *sds
, u32 sds_size
, MFT_RECORD
*m
)
2828 int err
, sdh_size
, sii_size
;
2829 SECURITY_DESCRIPTOR_HEADER
*sds_header
;
2830 INDEX_ENTRY
*idx_entry_sdh
, *idx_entry_sii
;
2831 SDH_INDEX_DATA
*sdh_data
;
2832 SII_INDEX_DATA
*sii_data
;
2834 sds_header
= (SECURITY_DESCRIPTOR_HEADER
*)sds
;
2835 sdh_size
= sizeof(INDEX_ENTRY_HEADER
);
2836 sdh_size
+= sizeof(SDH_INDEX_KEY
) + sizeof(SDH_INDEX_DATA
);
2837 sii_size
= sizeof(INDEX_ENTRY_HEADER
);
2838 sii_size
+= sizeof(SII_INDEX_KEY
) + sizeof(SII_INDEX_DATA
);
2839 idx_entry_sdh
= ntfs_calloc(sizeof(INDEX_ENTRY
));
2842 idx_entry_sii
= ntfs_calloc(sizeof(INDEX_ENTRY
));
2843 if (!idx_entry_sii
) {
2844 free(idx_entry_sdh
);
2849 while ((char*)sds_header
< (char*)sds
+ sds_size
) {
2850 if (!sds_header
->length
)
2852 /* SDH index entry */
2853 idx_entry_sdh
->data_offset
= const_cpu_to_le16(0x18);
2854 idx_entry_sdh
->data_length
= const_cpu_to_le16(0x14);
2855 idx_entry_sdh
->reservedV
= const_cpu_to_le32(0x00);
2856 idx_entry_sdh
->length
= const_cpu_to_le16(0x30);
2857 idx_entry_sdh
->key_length
= const_cpu_to_le16(0x08);
2858 idx_entry_sdh
->ie_flags
= const_cpu_to_le16(0x00);
2859 idx_entry_sdh
->reserved
= const_cpu_to_le16(0x00);
2860 idx_entry_sdh
->key
.sdh
.hash
= sds_header
->hash
;
2861 idx_entry_sdh
->key
.sdh
.security_id
= sds_header
->security_id
;
2862 sdh_data
= (SDH_INDEX_DATA
*)((u8
*)idx_entry_sdh
+
2863 le16_to_cpu(idx_entry_sdh
->data_offset
));
2864 sdh_data
->hash
= sds_header
->hash
;
2865 sdh_data
->security_id
= sds_header
->security_id
;
2866 sdh_data
->offset
= sds_header
->offset
;
2867 sdh_data
->length
= sds_header
->length
;
2868 sdh_data
->reserved_II
= const_cpu_to_le32(0x00490049);
2870 /* SII index entry */
2871 idx_entry_sii
->data_offset
= const_cpu_to_le16(0x14);
2872 idx_entry_sii
->data_length
= const_cpu_to_le16(0x14);
2873 idx_entry_sii
->reservedV
= const_cpu_to_le32(0x00);
2874 idx_entry_sii
->length
= const_cpu_to_le16(0x28);
2875 idx_entry_sii
->key_length
= const_cpu_to_le16(0x04);
2876 idx_entry_sii
->ie_flags
= const_cpu_to_le16(0x00);
2877 idx_entry_sii
->reserved
= const_cpu_to_le16(0x00);
2878 idx_entry_sii
->key
.sii
.security_id
= sds_header
->security_id
;
2879 sii_data
= (SII_INDEX_DATA
*)((u8
*)idx_entry_sii
+
2880 le16_to_cpu(idx_entry_sii
->data_offset
));
2881 sii_data
->hash
= sds_header
->hash
;
2882 sii_data
->security_id
= sds_header
->security_id
;
2883 sii_data
->offset
= sds_header
->offset
;
2884 sii_data
->length
= sds_header
->length
;
2885 if ((err
= insert_index_entry_in_res_dir_index(idx_entry_sdh
,
2886 sdh_size
, m
, NTFS_INDEX_SDH
, 4, AT_UNUSED
)))
2888 if ((err
= insert_index_entry_in_res_dir_index(idx_entry_sii
,
2889 sii_size
, m
, NTFS_INDEX_SII
, 4, AT_UNUSED
)))
2891 sds_header
= (SECURITY_DESCRIPTOR_HEADER
*)((u8
*)sds_header
+
2892 ((le32_to_cpu(sds_header
->length
) + 15) & ~15));
2894 free(idx_entry_sdh
);
2895 free(idx_entry_sii
);
2902 * initialize $Quota with the default quota index-entries.
2904 static int initialize_quota(MFT_RECORD
*m
)
2906 int o_size
, q1_size
, q2_size
, err
, i
;
2907 INDEX_ENTRY
*idx_entry_o
, *idx_entry_q1
, *idx_entry_q2
;
2908 QUOTA_O_INDEX_DATA
*idx_entry_o_data
;
2909 QUOTA_CONTROL_ENTRY
*idx_entry_q1_data
, *idx_entry_q2_data
;
2912 /* q index entry num 1 */
2914 idx_entry_q1
= ntfs_calloc(q1_size
);
2917 idx_entry_q1
->data_offset
= const_cpu_to_le16(0x14);
2918 idx_entry_q1
->data_length
= const_cpu_to_le16(0x30);
2919 idx_entry_q1
->reservedV
= const_cpu_to_le32(0x00);
2920 idx_entry_q1
->length
= const_cpu_to_le16(0x48);
2921 idx_entry_q1
->key_length
= const_cpu_to_le16(0x04);
2922 idx_entry_q1
->ie_flags
= const_cpu_to_le16(0x00);
2923 idx_entry_q1
->reserved
= const_cpu_to_le16(0x00);
2924 idx_entry_q1
->key
.owner_id
= const_cpu_to_le32(0x01);
2925 idx_entry_q1_data
= (QUOTA_CONTROL_ENTRY
*)((char*)idx_entry_q1
2926 + le16_to_cpu(idx_entry_q1
->data_offset
));
2927 idx_entry_q1_data
->version
= const_cpu_to_le32(0x02);
2928 idx_entry_q1_data
->flags
= QUOTA_FLAG_DEFAULT_LIMITS
;
2929 idx_entry_q1_data
->bytes_used
= const_cpu_to_le64(0x00);
2930 idx_entry_q1_data
->change_time
= mkntfs_time();
2931 idx_entry_q1_data
->threshold
= cpu_to_sle64(-1);
2932 idx_entry_q1_data
->limit
= cpu_to_sle64(-1);
2933 idx_entry_q1_data
->exceeded_time
= const_cpu_to_le64(0);
2934 err
= insert_index_entry_in_res_dir_index(idx_entry_q1
, q1_size
, m
,
2935 NTFS_INDEX_Q
, 2, AT_UNUSED
);
2939 /* q index entry num 2 */
2941 idx_entry_q2
= ntfs_calloc(q2_size
);
2944 idx_entry_q2
->data_offset
= const_cpu_to_le16(0x14);
2945 idx_entry_q2
->data_length
= const_cpu_to_le16(0x40);
2946 idx_entry_q2
->reservedV
= const_cpu_to_le32(0x00);
2947 idx_entry_q2
->length
= const_cpu_to_le16(0x58);
2948 idx_entry_q2
->key_length
= const_cpu_to_le16(0x04);
2949 idx_entry_q2
->ie_flags
= const_cpu_to_le16(0x00);
2950 idx_entry_q2
->reserved
= const_cpu_to_le16(0x00);
2951 idx_entry_q2
->key
.owner_id
= QUOTA_FIRST_USER_ID
;
2952 idx_entry_q2_data
= (QUOTA_CONTROL_ENTRY
*)((char*)idx_entry_q2
2953 + le16_to_cpu(idx_entry_q2
->data_offset
));
2954 idx_entry_q2_data
->version
= const_cpu_to_le32(0x02);
2955 idx_entry_q2_data
->flags
= QUOTA_FLAG_DEFAULT_LIMITS
;
2956 idx_entry_q2_data
->bytes_used
= const_cpu_to_le64(0x00);
2957 idx_entry_q2_data
->change_time
= mkntfs_time();
2958 idx_entry_q2_data
->threshold
= cpu_to_sle64(-1);
2959 idx_entry_q2_data
->limit
= cpu_to_sle64(-1);
2960 idx_entry_q2_data
->exceeded_time
= const_cpu_to_le64(0);
2961 idx_entry_q2_data
->sid
.revision
= 1;
2962 idx_entry_q2_data
->sid
.sub_authority_count
= 2;
2963 for (i
= 0; i
< 5; i
++)
2964 idx_entry_q2_data
->sid
.identifier_authority
.value
[i
] = 0;
2965 idx_entry_q2_data
->sid
.identifier_authority
.value
[5] = 0x05;
2966 idx_entry_q2_data
->sid
.sub_authority
[0] =
2967 const_cpu_to_le32(SECURITY_BUILTIN_DOMAIN_RID
);
2968 idx_entry_q2_data
->sid
.sub_authority
[1] =
2969 const_cpu_to_le32(DOMAIN_ALIAS_RID_ADMINS
);
2970 err
= insert_index_entry_in_res_dir_index(idx_entry_q2
, q2_size
, m
,
2971 NTFS_INDEX_Q
, 2, AT_UNUSED
);
2976 idx_entry_o
= ntfs_calloc(o_size
);
2979 idx_entry_o
->data_offset
= const_cpu_to_le16(0x20);
2980 idx_entry_o
->data_length
= const_cpu_to_le16(0x04);
2981 idx_entry_o
->reservedV
= const_cpu_to_le32(0x00);
2982 idx_entry_o
->length
= const_cpu_to_le16(0x28);
2983 idx_entry_o
->key_length
= const_cpu_to_le16(0x10);
2984 idx_entry_o
->ie_flags
= const_cpu_to_le16(0x00);
2985 idx_entry_o
->reserved
= const_cpu_to_le16(0x00);
2986 idx_entry_o
->key
.sid
.revision
= 0x01;
2987 idx_entry_o
->key
.sid
.sub_authority_count
= 0x02;
2988 for (i
= 0; i
< 5; i
++)
2989 idx_entry_o
->key
.sid
.identifier_authority
.value
[i
] = 0;
2990 idx_entry_o
->key
.sid
.identifier_authority
.value
[5] = 0x05;
2991 idx_entry_o
->key
.sid
.sub_authority
[0] =
2992 const_cpu_to_le32(SECURITY_BUILTIN_DOMAIN_RID
);
2993 idx_entry_o
->key
.sid
.sub_authority
[1] =
2994 const_cpu_to_le32(DOMAIN_ALIAS_RID_ADMINS
);
2995 idx_entry_o_data
= (QUOTA_O_INDEX_DATA
*)((char*)idx_entry_o
2996 + le16_to_cpu(idx_entry_o
->data_offset
));
2997 idx_entry_o_data
->owner_id
= QUOTA_FIRST_USER_ID
;
2998 /* 20 00 00 00 padding after here on ntfs 3.1. 3.0 is unchecked. */
2999 idx_entry_o_data
->unknown
= const_cpu_to_le32(32);
3000 err
= insert_index_entry_in_res_dir_index(idx_entry_o
, o_size
, m
,
3001 NTFS_INDEX_O
, 2, AT_UNUSED
);
3008 * insert_file_link_in_dir_index
3010 * Insert the fully completed FILE_NAME_ATTR @file_name which is inside
3011 * the file with mft reference @file_ref into the index (allocation) block
3012 * @idx (which belongs to @file_ref's parent directory).
3014 * Return 0 on success or -errno on error.
3016 static int insert_file_link_in_dir_index(INDEX_BLOCK
*idx
, leMFT_REF file_ref
,
3017 FILE_NAME_ATTR
*file_name
, u32 file_name_size
)
3024 * Lookup dir entry @file_name in dir @idx to determine correct
3025 * insertion location. FIXME: Using a very oversimplified lookup
3026 * method which is sufficient for mkntfs but no good whatsoever in
3027 * real world scenario. (AIA)
3030 index_end
= (char*)&idx
->index
+ le32_to_cpu(idx
->index
.index_length
);
3031 ie
= (INDEX_ENTRY
*)((char*)&idx
->index
+
3032 le32_to_cpu(idx
->index
.entries_offset
));
3034 * Loop until we exceed valid memory (corruption case) or until we
3035 * reach the last entry.
3037 while ((char*)ie
< index_end
&& !(ie
->ie_flags
& INDEX_ENTRY_END
)) {
3040 ntfs_log_debug("file_name_attr1->file_name_length = %i\n",
3041 file_name
->file_name_length
);
3042 if (file_name
->file_name_length
) {
3044 i
= ntfs_ucstombs((ntfschar
*)&file_name
->file_name
,
3045 file_name
->file_name_length
, &__buf
, 0);
3047 ntfs_log_debug("Name contains non-displayable "
3048 "Unicode characters.\n");
3049 ntfs_log_debug("file_name_attr1->file_name = %s\n",
3053 ntfs_log_debug("file_name_attr2->file_name_length = %i\n",
3054 ie
->key
.file_name
.file_name_length
);
3055 if (ie
->key
.file_name
.file_name_length
) {
3057 i
= ntfs_ucstombs(ie
->key
.file_name
.file_name
,
3058 ie
->key
.file_name
.file_name_length
+ 1, &__buf
,
3061 ntfs_log_debug("Name contains non-displayable "
3062 "Unicode characters.\n");
3063 ntfs_log_debug("file_name_attr2->file_name = %s\n",
3070 i = ntfs_file_values_compare(file_name,
3071 (FILE_NAME_ATTR*)&ie->key.file_name, 1,
3072 IGNORE_CASE, g_vol->upcase, g_vol->upcase_len);
3074 i
= ntfs_names_full_collate(file_name
->file_name
, file_name
->file_name_length
,
3075 ((FILE_NAME_ATTR
*)&ie
->key
.file_name
)->file_name
, ((FILE_NAME_ATTR
*)&ie
->key
.file_name
)->file_name_length
,
3076 IGNORE_CASE
, g_vol
->upcase
, g_vol
->upcase_len
);
3078 * If @file_name collates before ie->key.file_name, there is no
3079 * matching index entry.
3083 /* If file names are not equal, continue search. */
3086 /* File names are equal when compared ignoring case. */
3088 * If BOTH file names are in the POSIX namespace, do a case
3089 * sensitive comparison as well. Otherwise the names match so
3090 * we return -EEXIST. FIXME: There are problems with this in a
3091 * real world scenario, when one is POSIX and one isn't, but
3092 * fine for mkntfs where we don't use POSIX namespace at all
3093 * and hence this following code is luxury. (AIA)
3095 if (file_name
->file_name_type
!= FILE_NAME_POSIX
||
3096 ie
->key
.file_name
.file_name_type
!= FILE_NAME_POSIX
)
3099 i = ntfs_file_values_compare(file_name,
3100 (FILE_NAME_ATTR*)&ie->key.file_name, 1,
3101 CASE_SENSITIVE, g_vol->upcase,
3104 i
= ntfs_names_full_collate(file_name
->file_name
, file_name
->file_name_length
,
3105 ((FILE_NAME_ATTR
*)&ie
->key
.file_name
)->file_name
, ((FILE_NAME_ATTR
*)&ie
->key
.file_name
)->file_name_length
,
3106 CASE_SENSITIVE
, g_vol
->upcase
, g_vol
->upcase_len
);
3109 /* Complete match. Bugger. Can't insert. */
3116 ntfs_log_debug("BUG: ie->length is zero, breaking out "
3121 ie
= (INDEX_ENTRY
*)((char*)ie
+ le16_to_cpu(ie
->length
));
3123 i
= (sizeof(INDEX_ENTRY_HEADER
) + file_name_size
+ 7) & ~7;
3124 err
= make_room_for_index_entry_in_index_block(idx
, ie
, i
);
3126 ntfs_log_error("make_room_for_index_entry_in_index_block "
3127 "failed: %s\n", strerror(-err
));
3130 /* Create entry in place and copy file name attribute value. */
3131 ie
->indexed_file
= file_ref
;
3132 ie
->length
= cpu_to_le16(i
);
3133 ie
->key_length
= cpu_to_le16(file_name_size
);
3134 ie
->ie_flags
= cpu_to_le16(0);
3135 ie
->reserved
= cpu_to_le16(0);
3136 memcpy((char*)&ie
->key
.file_name
, (char*)file_name
, file_name_size
);
3141 * create_hardlink_res
3143 * Create a file_name_attribute in the mft record @m_file which points to the
3144 * parent directory with mft reference @ref_parent.
3146 * Then, insert an index entry with this file_name_attribute in the index
3147 * root @idx of the index_root attribute of the parent directory.
3149 * @ref_file is the mft reference of @m_file.
3151 * Return 0 on success or -errno on error.
3153 static int create_hardlink_res(MFT_RECORD
*m_parent
, const leMFT_REF ref_parent
,
3154 MFT_RECORD
*m_file
, const leMFT_REF ref_file
,
3155 const s64 allocated_size
, const s64 data_size
,
3156 const FILE_ATTR_FLAGS flags
, const u16 packed_ea_size
,
3157 const u32 reparse_point_tag
, const char *file_name
,
3158 const FILE_NAME_TYPE_FLAGS file_name_type
)
3161 int i
, fn_size
, idx_size
;
3162 INDEX_ENTRY
*idx_entry_new
;
3165 /* Create the file_name attribute. */
3166 i
= (strlen(file_name
) + 1) * sizeof(ntfschar
);
3167 fn_size
= sizeof(FILE_NAME_ATTR
) + i
;
3168 fn
= ntfs_malloc(fn_size
);
3171 fn
->parent_directory
= ref_parent
;
3172 fn
->creation_time
= stdinfo_time(m_file
);
3173 fn
->last_data_change_time
= fn
->creation_time
;
3174 fn
->last_mft_change_time
= fn
->creation_time
;
3175 fn
->last_access_time
= fn
->creation_time
;
3176 fn
->allocated_size
= cpu_to_sle64(allocated_size
);
3177 fn
->data_size
= cpu_to_sle64(data_size
);
3178 fn
->file_attributes
= flags
;
3179 /* These are in a union so can't have both. */
3180 if (packed_ea_size
&& reparse_point_tag
) {
3184 if (packed_ea_size
) {
3188 if (packed_ea_size
) {
3189 fn
->packed_ea_size
= cpu_to_le16(packed_ea_size
);
3190 fn
->reserved
= cpu_to_le16(0);
3192 fn
->reparse_point_tag
= cpu_to_le32(reparse_point_tag
);
3194 fn
->file_name_type
= file_name_type
;
3195 uname
= fn
->file_name
;
3196 i
= ntfs_mbstoucs_libntfscompat(file_name
, &uname
, i
);
3203 return -ENAMETOOLONG
;
3205 /* No terminating null in file names. */
3206 fn
->file_name_length
= i
;
3207 fn_size
= sizeof(FILE_NAME_ATTR
) + i
* sizeof(ntfschar
);
3208 /* Increment the link count of @m_file. */
3209 i
= le16_to_cpu(m_file
->link_count
);
3211 ntfs_log_error("Too many hardlinks present already.\n");
3215 m_file
->link_count
= cpu_to_le16(i
+ 1);
3216 /* Add the file_name to @m_file. */
3217 i
= insert_resident_attr_in_mft_record(m_file
, AT_FILE_NAME
, NULL
, 0,
3218 CASE_SENSITIVE
, const_cpu_to_le16(0),
3219 RESIDENT_ATTR_IS_INDEXED
, (u8
*)fn
, fn_size
);
3221 ntfs_log_error("create_hardlink failed adding file name "
3222 "attribute: %s\n", strerror(-i
));
3224 /* Undo link count increment. */
3225 m_file
->link_count
= cpu_to_le16(
3226 le16_to_cpu(m_file
->link_count
) - 1);
3229 /* Insert the index entry for file_name in @idx. */
3230 idx_size
= (fn_size
+ 7) & ~7;
3231 idx_entry_new
= ntfs_calloc(idx_size
+ 0x10);
3234 idx_entry_new
->indexed_file
= ref_file
;
3235 idx_entry_new
->length
= cpu_to_le16(idx_size
+ 0x10);
3236 idx_entry_new
->key_length
= cpu_to_le16(fn_size
);
3237 memcpy((u8
*)idx_entry_new
+ 0x10, (u8
*)fn
, fn_size
);
3238 i
= insert_index_entry_in_res_dir_index(idx_entry_new
, idx_size
+ 0x10,
3239 m_parent
, NTFS_INDEX_I30
, 4, AT_FILE_NAME
);
3241 ntfs_log_error("create_hardlink failed inserting index entry: "
3242 "%s\n", strerror(-i
));
3243 /* FIXME: Remove the file name attribute from @m_file. */
3244 free(idx_entry_new
);
3246 /* Undo link count increment. */
3247 m_file
->link_count
= cpu_to_le16(
3248 le16_to_cpu(m_file
->link_count
) - 1);
3251 free(idx_entry_new
);
3259 * Create a file_name_attribute in the mft record @m_file which points to the
3260 * parent directory with mft reference @ref_parent.
3262 * Then, insert an index entry with this file_name_attribute in the index
3263 * block @idx of the index allocation attribute of the parent directory.
3265 * @ref_file is the mft reference of @m_file.
3267 * Return 0 on success or -errno on error.
3269 static int create_hardlink(INDEX_BLOCK
*idx
, const leMFT_REF ref_parent
,
3270 MFT_RECORD
*m_file
, const leMFT_REF ref_file
,
3271 const s64 allocated_size
, const s64 data_size
,
3272 const FILE_ATTR_FLAGS flags
, const u16 packed_ea_size
,
3273 const u32 reparse_point_tag
, const char *file_name
,
3274 const FILE_NAME_TYPE_FLAGS file_name_type
)
3280 /* Create the file_name attribute. */
3281 i
= (strlen(file_name
) + 1) * sizeof(ntfschar
);
3282 fn_size
= sizeof(FILE_NAME_ATTR
) + i
;
3283 fn
= ntfs_malloc(fn_size
);
3286 fn
->parent_directory
= ref_parent
;
3287 fn
->creation_time
= stdinfo_time(m_file
);
3288 fn
->last_data_change_time
= fn
->creation_time
;
3289 fn
->last_mft_change_time
= fn
->creation_time
;
3290 fn
->last_access_time
= fn
->creation_time
;
3291 /* allocated size depends on unnamed data being resident */
3292 if (allocated_size
&& non_resident_unnamed_data(m_file
))
3293 fn
->allocated_size
= cpu_to_sle64(allocated_size
);
3295 fn
->allocated_size
= cpu_to_sle64((data_size
+ 7) & -8);
3296 fn
->data_size
= cpu_to_sle64(data_size
);
3297 fn
->file_attributes
= flags
;
3298 /* These are in a union so can't have both. */
3299 if (packed_ea_size
&& reparse_point_tag
) {
3303 if (packed_ea_size
) {
3304 fn
->packed_ea_size
= cpu_to_le16(packed_ea_size
);
3305 fn
->reserved
= cpu_to_le16(0);
3307 fn
->reparse_point_tag
= cpu_to_le32(reparse_point_tag
);
3309 fn
->file_name_type
= file_name_type
;
3310 uname
= fn
->file_name
;
3311 i
= ntfs_mbstoucs_libntfscompat(file_name
, &uname
, i
);
3318 return -ENAMETOOLONG
;
3320 /* No terminating null in file names. */
3321 fn
->file_name_length
= i
;
3322 fn_size
= sizeof(FILE_NAME_ATTR
) + i
* sizeof(ntfschar
);
3323 /* Increment the link count of @m_file. */
3324 i
= le16_to_cpu(m_file
->link_count
);
3326 ntfs_log_error("Too many hardlinks present already.\n");
3330 m_file
->link_count
= cpu_to_le16(i
+ 1);
3331 /* Add the file_name to @m_file. */
3332 i
= insert_resident_attr_in_mft_record(m_file
, AT_FILE_NAME
, NULL
, 0,
3333 CASE_SENSITIVE
, cpu_to_le16(0),
3334 RESIDENT_ATTR_IS_INDEXED
, (u8
*)fn
, fn_size
);
3336 ntfs_log_error("create_hardlink failed adding file name attribute: "
3337 "%s\n", strerror(-i
));
3339 /* Undo link count increment. */
3340 m_file
->link_count
= cpu_to_le16(
3341 le16_to_cpu(m_file
->link_count
) - 1);
3344 /* Insert the index entry for file_name in @idx. */
3345 i
= insert_file_link_in_dir_index(idx
, ref_file
, fn
, fn_size
);
3347 ntfs_log_error("create_hardlink failed inserting index entry: %s\n",
3349 /* FIXME: Remove the file name attribute from @m_file. */
3351 /* Undo link count increment. */
3352 m_file
->link_count
= cpu_to_le16(
3353 le16_to_cpu(m_file
->link_count
) - 1);
3361 * index_obj_id_insert
3363 * Insert an index entry with the key @guid and data pointing to the mft record
3364 * @ref in the $O index root of the mft record @m (which must be the mft record
3367 * Return 0 on success or -errno on error.
3369 static int index_obj_id_insert(MFT_RECORD
*m
, const GUID
*guid
,
3370 const leMFT_REF ref
)
3372 INDEX_ENTRY
*idx_entry_new
;
3373 int data_ofs
, idx_size
, err
;
3374 OBJ_ID_INDEX_DATA
*oi
;
3377 * Insert the index entry for the object id in the index.
3379 * First determine the size of the index entry to be inserted. This
3380 * consists of the index entry header, followed by the index key, i.e.
3381 * the GUID, followed by the index data, i.e. OBJ_ID_INDEX_DATA.
3383 data_ofs
= (sizeof(INDEX_ENTRY_HEADER
) + sizeof(GUID
) + 7) & ~7;
3384 idx_size
= (data_ofs
+ sizeof(OBJ_ID_INDEX_DATA
) + 7) & ~7;
3385 idx_entry_new
= ntfs_calloc(idx_size
);
3388 idx_entry_new
->data_offset
= cpu_to_le16(data_ofs
);
3389 idx_entry_new
->data_length
= cpu_to_le16(sizeof(OBJ_ID_INDEX_DATA
));
3390 idx_entry_new
->length
= cpu_to_le16(idx_size
);
3391 idx_entry_new
->key_length
= cpu_to_le16(sizeof(GUID
));
3392 idx_entry_new
->key
.object_id
= *guid
;
3393 oi
= (OBJ_ID_INDEX_DATA
*)((u8
*)idx_entry_new
+ data_ofs
);
3394 oi
->mft_reference
= ref
;
3395 err
= insert_index_entry_in_res_dir_index(idx_entry_new
, idx_size
, m
,
3396 NTFS_INDEX_O
, 2, AT_UNUSED
);
3397 free(idx_entry_new
);
3399 ntfs_log_error("index_obj_id_insert failed inserting index "
3400 "entry: %s\n", strerror(-err
));
3409 static void mkntfs_cleanup(void)
3411 struct BITMAP_ALLOCATION
*p
, *q
;
3413 /* Close the volume */
3416 if (NDevOpen(g_vol
->dev
) && g_vol
->dev
->d_ops
->close(g_vol
->dev
))
3417 ntfs_log_perror("Warning: Could not close %s", g_vol
->dev
->d_name
);
3418 ntfs_device_free(g_vol
->dev
);
3420 free(g_vol
->vol_name
);
3421 free(g_vol
->attrdef
);
3422 free(g_vol
->upcase
);
3427 /* Free any memory we've used */
3428 free(g_bad_blocks
); g_bad_blocks
= NULL
;
3429 free(g_buf
); g_buf
= NULL
;
3430 free(g_index_block
); g_index_block
= NULL
;
3431 free(g_dynamic_buf
); g_dynamic_buf
= NULL
;
3432 free(g_mft_bitmap
); g_mft_bitmap
= NULL
;
3433 free(g_rl_bad
); g_rl_bad
= NULL
;
3434 free(g_rl_boot
); g_rl_boot
= NULL
;
3435 free(g_rl_logfile
); g_rl_logfile
= NULL
;
3436 free(g_rl_mft
); g_rl_mft
= NULL
;
3437 free(g_rl_mft_bmp
); g_rl_mft_bmp
= NULL
;
3438 free(g_rl_mftmirr
); g_rl_mftmirr
= NULL
;
3450 * mkntfs_open_partition -
3452 static BOOL
mkntfs_open_partition(ntfs_volume
*vol
)
3454 BOOL result
= FALSE
;
3457 unsigned long mnt_flags
;
3460 * Allocate and initialize an ntfs device structure and attach it to
3463 vol
->dev
= ntfs_device_alloc(opts
.dev_name
, 0, &ntfs_device_default_io_ops
, NULL
);
3465 ntfs_log_perror("Could not create device");
3469 /* Open the device for reading or reading and writing. */
3470 if (opts
.no_action
) {
3471 ntfs_log_quiet("Running in READ-ONLY mode!\n");
3476 if (vol
->dev
->d_ops
->open(vol
->dev
, i
)) {
3477 if (errno
== ENOENT
)
3478 ntfs_log_error("The device doesn't exist; did you specify it correctly?\n");
3480 ntfs_log_perror("Could not open %s", vol
->dev
->d_name
);
3483 /* Verify we are dealing with a block device. */
3484 if (vol
->dev
->d_ops
->stat(vol
->dev
, &sbuf
)) {
3485 ntfs_log_perror("Error getting information about %s", vol
->dev
->d_name
);
3489 if (!S_ISBLK(sbuf
.st_mode
)) {
3490 ntfs_log_error("%s is not a block device.\n", vol
->dev
->d_name
);
3492 ntfs_log_error("Refusing to make a filesystem here!\n");
3495 if (!opts
.num_sectors
) {
3496 if (!sbuf
.st_size
&& !sbuf
.st_blocks
) {
3497 ntfs_log_error("You must specify the number of sectors.\n");
3500 if (opts
.sector_size
) {
3502 opts
.num_sectors
= sbuf
.st_size
/ opts
.sector_size
;
3504 opts
.num_sectors
= ((s64
)sbuf
.st_blocks
<< 9) / opts
.sector_size
;
3507 opts
.num_sectors
= sbuf
.st_size
/ 512;
3509 opts
.num_sectors
= sbuf
.st_blocks
;
3510 opts
.sector_size
= 512;
3513 ntfs_log_warning("mkntfs forced anyway.\n");
3514 #ifdef HAVE_LINUX_MAJOR_H
3515 } else if ((IDE_DISK_MAJOR(MAJOR(sbuf
.st_rdev
)) &&
3516 MINOR(sbuf
.st_rdev
) % 64 == 0) ||
3517 (SCSI_DISK_MAJOR(MAJOR(sbuf
.st_rdev
)) &&
3518 MINOR(sbuf
.st_rdev
) % 16 == 0)) {
3519 ntfs_log_error("%s is entire device, not just one partition.\n", vol
->dev
->d_name
);
3521 ntfs_log_error("Refusing to make a filesystem here!\n");
3524 ntfs_log_warning("mkntfs forced anyway.\n");
3527 /* Make sure the file system is not mounted. */
3528 if (ntfs_check_if_mounted(vol
->dev
->d_name
, &mnt_flags
)) {
3529 ntfs_log_perror("Failed to determine whether %s is mounted", vol
->dev
->d_name
);
3530 } else if (mnt_flags
& NTFS_MF_MOUNTED
) {
3531 ntfs_log_error("%s is mounted.\n", vol
->dev
->d_name
);
3533 ntfs_log_error("Refusing to make a filesystem here!\n");
3536 ntfs_log_warning("mkntfs forced anyway. Hope /etc/mtab is incorrect.\n");
3544 * mkntfs_get_page_size - detect the system's memory page size.
3546 static long mkntfs_get_page_size(void)
3550 page_size
= sysconf(_SC_PAGESIZE
);
3553 #ifdef _SC_PAGE_SIZE
3554 page_size
= sysconf(_SC_PAGE_SIZE
);
3558 ntfs_log_warning("Failed to determine system page size. "
3559 "Assuming safe default of 4096 bytes.\n");
3562 ntfs_log_debug("System page size is %li bytes.\n", page_size
);
3567 * mkntfs_override_vol_params -
3569 static BOOL
mkntfs_override_vol_params(ntfs_volume
*vol
)
3574 BOOL winboot
= TRUE
;
3576 /* If user didn't specify the sector size, determine it now. */
3577 if (opts
.sector_size
< 0) {
3578 opts
.sector_size
= ntfs_device_sector_size_get(vol
->dev
);
3579 if (opts
.sector_size
< 0) {
3580 ntfs_log_warning("The sector size was not specified "
3581 "for %s and it could not be obtained "
3582 "automatically. It has been set to 512 "
3583 "bytes.\n", vol
->dev
->d_name
);
3584 opts
.sector_size
= 512;
3587 /* Validate sector size. */
3588 if ((opts
.sector_size
- 1) & opts
.sector_size
) {
3589 ntfs_log_error("The sector size is invalid. It must be a "
3590 "power of two, e.g. 512, 1024.\n");
3593 if (opts
.sector_size
< 256 || opts
.sector_size
> 4096) {
3594 ntfs_log_error("The sector size is invalid. The minimum size "
3595 "is 256 bytes and the maximum is 4096 bytes.\n");
3598 ntfs_log_debug("sector size = %ld bytes\n", opts
.sector_size
);
3599 /* Now set the device block size to the sector size. */
3600 if (ntfs_device_block_size_set(vol
->dev
, opts
.sector_size
))
3601 ntfs_log_debug("Failed to set the device block size to the "
3602 "sector size. This may cause problems when "
3603 "creating the backup boot sector and also may "
3604 "affect performance but should be harmless "
3605 "otherwise. Error: %s\n", strerror(errno
));
3606 /* If user didn't specify the number of sectors, determine it now. */
3607 if (opts
.num_sectors
< 0) {
3608 opts
.num_sectors
= ntfs_device_size_get(vol
->dev
,
3610 if (opts
.num_sectors
<= 0) {
3611 ntfs_log_error("Couldn't determine the size of %s. "
3612 "Please specify the number of sectors "
3613 "manually.\n", vol
->dev
->d_name
);
3617 ntfs_log_debug("number of sectors = %lld (0x%llx)\n", opts
.num_sectors
,
3620 * Reserve the last sector for the backup boot sector unless the
3621 * sector size is less than 512 bytes in which case reserve 512 bytes
3625 if (opts
.sector_size
< 512)
3626 i
= 512 / opts
.sector_size
;
3627 opts
.num_sectors
-= i
;
3628 /* If user didn't specify the partition start sector, determine it. */
3629 if (opts
.part_start_sect
< 0) {
3630 opts
.part_start_sect
= ntfs_device_partition_start_sector_get(
3632 if (opts
.part_start_sect
< 0) {
3633 ntfs_log_warning("The partition start sector was not "
3634 "specified for %s and it could not be obtained "
3635 "automatically. It has been set to 0.\n",
3637 opts
.part_start_sect
= 0;
3639 } else if (opts
.part_start_sect
>> 32) {
3640 ntfs_log_warning("The partition start sector specified "
3641 "for %s and the automatically determined value "
3642 "is too large. It has been set to 0.\n",
3644 opts
.part_start_sect
= 0;
3647 } else if (opts
.part_start_sect
>> 32) {
3648 ntfs_log_error("Invalid partition start sector. Maximum is "
3649 "4294967295 (2^32-1).\n");
3652 /* If user didn't specify the sectors per track, determine it now. */
3653 if (opts
.sectors_per_track
< 0) {
3654 opts
.sectors_per_track
= ntfs_device_sectors_per_track_get(
3656 if (opts
.sectors_per_track
< 0) {
3657 ntfs_log_warning("The number of sectors per track was "
3658 "not specified for %s and it could not be "
3659 "obtained automatically. It has been set to "
3660 "0.\n", vol
->dev
->d_name
);
3661 opts
.sectors_per_track
= 0;
3663 } else if (opts
.sectors_per_track
> 65535) {
3664 ntfs_log_warning("The number of sectors per track was "
3665 "not specified for %s and the automatically "
3666 "determined value is too large. It has been "
3667 "set to 0.\n", vol
->dev
->d_name
);
3668 opts
.sectors_per_track
= 0;
3671 } else if (opts
.sectors_per_track
> 65535) {
3672 ntfs_log_error("Invalid number of sectors per track. Maximum "
3676 /* If user didn't specify the number of heads, determine it now. */
3677 if (opts
.heads
< 0) {
3678 opts
.heads
= ntfs_device_heads_get(vol
->dev
);
3679 if (opts
.heads
< 0) {
3680 ntfs_log_warning("The number of heads was not "
3681 "specified for %s and it could not be obtained "
3682 "automatically. It has been set to 0.\n",
3686 } else if (opts
.heads
> 65535) {
3687 ntfs_log_warning("The number of heads was not "
3688 "specified for %s and the automatically "
3689 "determined value is too large. It has been "
3690 "set to 0.\n", vol
->dev
->d_name
);
3694 } else if (opts
.heads
> 65535) {
3695 ntfs_log_error("Invalid number of heads. Maximum is 65535.\n");
3698 volume_size
= opts
.num_sectors
* opts
.sector_size
;
3699 /* Validate volume size. */
3700 if (volume_size
< (1 << 20)) { /* 1MiB */
3701 ntfs_log_error("Device is too small (%llikiB). Minimum NTFS "
3702 "volume size is 1MiB.\n",
3703 (long long)(volume_size
/ 1024));
3706 ntfs_log_debug("volume size = %llikiB\n", volume_size
/ 1024);
3707 /* If user didn't specify the cluster size, determine it now. */
3708 if (!vol
->cluster_size
) {
3710 * Windows Vista always uses 4096 bytes as the default cluster
3711 * size regardless of the volume size so we do it, too.
3713 vol
->cluster_size
= 4096;
3714 /* For small volumes on devices with large sector sizes. */
3715 if (vol
->cluster_size
< (u32
)opts
.sector_size
)
3716 vol
->cluster_size
= opts
.sector_size
;
3718 * For huge volumes, grow the cluster size until the number of
3719 * clusters fits into 32 bits or the cluster size exceeds the
3720 * maximum limit of 64kiB.
3722 while (volume_size
>> (ffs(vol
->cluster_size
) - 1 + 32)) {
3723 vol
->cluster_size
<<= 1;
3724 if (vol
->cluster_size
> 65535) {
3725 ntfs_log_error("Device is too large to hold an "
3726 "NTFS volume (maximum size is "
3731 ntfs_log_quiet("Cluster size has been automatically set to %u "
3732 "bytes.\n", (unsigned)vol
->cluster_size
);
3734 /* Validate cluster size. */
3735 if (vol
->cluster_size
& (vol
->cluster_size
- 1)) {
3736 ntfs_log_error("The cluster size is invalid. It must be a "
3737 "power of two, e.g. 1024, 4096.\n");
3740 if (vol
->cluster_size
< (u32
)opts
.sector_size
) {
3741 ntfs_log_error("The cluster size is invalid. It must be equal "
3742 "to, or larger than, the sector size.\n");
3745 if (vol
->cluster_size
> 128 * (u32
)opts
.sector_size
) {
3746 ntfs_log_error("The cluster size is invalid. It cannot be "
3747 "more that 128 times the size of the sector "
3751 if (vol
->cluster_size
> 65536) {
3752 ntfs_log_error("The cluster size is invalid. The maximum "
3753 "cluster size is 65536 bytes (64kiB).\n");
3756 vol
->cluster_size_bits
= ffs(vol
->cluster_size
) - 1;
3757 ntfs_log_debug("cluster size = %u bytes\n",
3758 (unsigned int)vol
->cluster_size
);
3759 if (vol
->cluster_size
> 4096) {
3760 if (opts
.enable_compression
) {
3762 ntfs_log_error("Windows cannot use compression "
3763 "when the cluster size is "
3764 "larger than 4096 bytes.\n");
3767 opts
.enable_compression
= 0;
3769 ntfs_log_warning("Windows cannot use compression when the "
3770 "cluster size is larger than 4096 bytes. "
3771 "Compression has been disabled for this "
3774 vol
->nr_clusters
= volume_size
/ vol
->cluster_size
;
3776 * Check the cluster_size and num_sectors for consistency with
3777 * sector_size and num_sectors. And check both of these for consistency
3780 if ((vol
->nr_clusters
!= ((opts
.num_sectors
* opts
.sector_size
) /
3781 vol
->cluster_size
) ||
3782 (volume_size
/ opts
.sector_size
) != opts
.num_sectors
||
3783 (volume_size
/ vol
->cluster_size
) !=
3784 vol
->nr_clusters
)) {
3785 /* XXX is this code reachable? */
3786 ntfs_log_error("Illegal combination of volume/cluster/sector "
3787 "size and/or cluster/sector number.\n");
3790 ntfs_log_debug("number of clusters = %llu (0x%llx)\n",
3791 vol
->nr_clusters
, vol
->nr_clusters
);
3792 /* Number of clusters must fit within 32 bits (Win2k limitation). */
3793 if (vol
->nr_clusters
>> 32) {
3794 if (vol
->cluster_size
>= 65536) {
3795 ntfs_log_error("Device is too large to hold an NTFS "
3796 "volume (maximum size is 256TiB).\n");
3799 ntfs_log_error("Number of clusters exceeds 32 bits. Please "
3800 "try again with a larger\ncluster size or "
3801 "leave the cluster size unspecified and the "
3802 "smallest possible cluster size for the size "
3803 "of the device will be used.\n");
3806 page_size
= mkntfs_get_page_size();
3808 * Set the mft record size. By default this is 1024 but it has to be
3809 * at least as big as a sector and not bigger than a page on the system
3810 * or the NTFS kernel driver will not be able to mount the volume.
3811 * TODO: The mft record size should be user specifiable just like the
3812 * "inode size" can be specified on other Linux/Unix file systems.
3814 vol
->mft_record_size
= 1024;
3815 if (vol
->mft_record_size
< (u32
)opts
.sector_size
)
3816 vol
->mft_record_size
= opts
.sector_size
;
3817 if (vol
->mft_record_size
> (unsigned long)page_size
)
3818 ntfs_log_warning("Mft record size (%u bytes) exceeds system "
3819 "page size (%li bytes). You will not be able "
3820 "to mount this volume using the NTFS kernel "
3821 "driver.\n", (unsigned)vol
->mft_record_size
,
3823 vol
->mft_record_size_bits
= ffs(vol
->mft_record_size
) - 1;
3824 ntfs_log_debug("mft record size = %u bytes\n",
3825 (unsigned)vol
->mft_record_size
);
3827 * Set the index record size. By default this is 4096 but it has to be
3828 * at least as big as a sector and not bigger than a page on the system
3829 * or the NTFS kernel driver will not be able to mount the volume.
3830 * FIXME: Should we make the index record size to be user specifiable?
3832 vol
->indx_record_size
= 4096;
3833 if (vol
->indx_record_size
< (u32
)opts
.sector_size
)
3834 vol
->indx_record_size
= opts
.sector_size
;
3835 if (vol
->indx_record_size
> (unsigned long)page_size
)
3836 ntfs_log_warning("Index record size (%u bytes) exceeds system "
3837 "page size (%li bytes). You will not be able "
3838 "to mount this volume using the NTFS kernel "
3839 "driver.\n", (unsigned)vol
->indx_record_size
,
3841 vol
->indx_record_size_bits
= ffs(vol
->indx_record_size
) - 1;
3842 ntfs_log_debug("index record size = %u bytes\n",
3843 (unsigned)vol
->indx_record_size
);
3845 ntfs_log_warning("To boot from a device, Windows needs the "
3846 "'partition start sector', the 'sectors per "
3847 "track' and the 'number of heads' to be "
3849 ntfs_log_warning("Windows will not be able to boot from this "
3856 * mkntfs_initialize_bitmaps -
3858 static BOOL
mkntfs_initialize_bitmaps(void)
3861 int mft_bitmap_size
;
3863 /* Determine lcn bitmap byte size and allocate it. */
3864 g_lcn_bitmap_byte_size
= (g_vol
->nr_clusters
+ 7) >> 3;
3865 /* Needs to be multiple of 8 bytes. */
3866 g_lcn_bitmap_byte_size
= (g_lcn_bitmap_byte_size
+ 7) & ~7;
3867 i
= (g_lcn_bitmap_byte_size
+ g_vol
->cluster_size
- 1) &
3868 ~(g_vol
->cluster_size
- 1);
3869 ntfs_log_debug("g_lcn_bitmap_byte_size = %i, allocated = %llu\n",
3870 g_lcn_bitmap_byte_size
, i
);
3871 g_dynamic_buf_size
= mkntfs_get_page_size();
3872 g_dynamic_buf
= (u8
*)ntfs_calloc(g_dynamic_buf_size
);
3876 * $Bitmap can overlap the end of the volume. Any bits in this region
3877 * must be set. This region also encompasses the backup boot sector.
3879 if (!bitmap_allocate(g_vol
->nr_clusters
,
3880 ((s64
)g_lcn_bitmap_byte_size
<< 3) - g_vol
->nr_clusters
))
3883 * Mft size is 27 (NTFS 3.0+) mft records or one cluster, whichever is
3887 g_mft_size
*= g_vol
->mft_record_size
;
3888 if (g_mft_size
< (s32
)g_vol
->cluster_size
)
3889 g_mft_size
= g_vol
->cluster_size
;
3890 ntfs_log_debug("MFT size = %i (0x%x) bytes\n", g_mft_size
, g_mft_size
);
3891 /* Determine mft bitmap size and allocate it. */
3892 mft_bitmap_size
= g_mft_size
/ g_vol
->mft_record_size
;
3893 /* Convert to bytes, at least one. */
3894 g_mft_bitmap_byte_size
= (mft_bitmap_size
+ 7) >> 3;
3895 /* Mft bitmap is allocated in multiples of 8 bytes. */
3896 g_mft_bitmap_byte_size
= (g_mft_bitmap_byte_size
+ 7) & ~7;
3897 ntfs_log_debug("mft_bitmap_size = %i, g_mft_bitmap_byte_size = %i\n",
3898 mft_bitmap_size
, g_mft_bitmap_byte_size
);
3899 g_mft_bitmap
= ntfs_calloc(g_mft_bitmap_byte_size
);
3902 /* Create runlist for mft bitmap. */
3903 g_rl_mft_bmp
= ntfs_malloc(2 * sizeof(runlist
));
3907 g_rl_mft_bmp
[0].vcn
= 0LL;
3908 /* Mft bitmap is right after $Boot's data. */
3909 i
= (8192 + g_vol
->cluster_size
- 1) / g_vol
->cluster_size
;
3910 g_rl_mft_bmp
[0].lcn
= i
;
3912 * Size is always one cluster, even though valid data size and
3913 * initialized data size are only 8 bytes.
3915 g_rl_mft_bmp
[1].vcn
= 1LL;
3916 g_rl_mft_bmp
[0].length
= 1LL;
3917 g_rl_mft_bmp
[1].lcn
= -1LL;
3918 g_rl_mft_bmp
[1].length
= 0LL;
3919 /* Allocate cluster for mft bitmap. */
3920 return (bitmap_allocate(i
,1));
3924 * mkntfs_initialize_rl_mft -
3926 static BOOL
mkntfs_initialize_rl_mft(void)
3931 /* If user didn't specify the mft lcn, determine it now. */
3934 * We start at the higher value out of 16kiB and just after the
3937 g_mft_lcn
= g_rl_mft_bmp
[0].lcn
+ g_rl_mft_bmp
[0].length
;
3938 if (g_mft_lcn
* g_vol
->cluster_size
< 16 * 1024)
3939 g_mft_lcn
= (16 * 1024 + g_vol
->cluster_size
- 1) /
3940 g_vol
->cluster_size
;
3942 ntfs_log_debug("$MFT logical cluster number = 0x%llx\n", g_mft_lcn
);
3943 /* Determine MFT zone size. */
3944 g_mft_zone_end
= g_vol
->nr_clusters
;
3945 switch (opts
.mft_zone_multiplier
) { /* % of volume size in clusters */
3947 g_mft_zone_end
= g_mft_zone_end
>> 1; /* 50% */
3950 g_mft_zone_end
= g_mft_zone_end
* 3 >> 3;/* 37.5% */
3953 g_mft_zone_end
= g_mft_zone_end
>> 2; /* 25% */
3957 g_mft_zone_end
= g_mft_zone_end
>> 3; /* 12.5% */
3960 ntfs_log_debug("MFT zone size = %lldkiB\n", g_mft_zone_end
<<
3961 g_vol
->cluster_size_bits
>> 10 /* >> 10 == / 1024 */);
3963 * The mft zone begins with the mft data attribute, not at the beginning
3966 g_mft_zone_end
+= g_mft_lcn
;
3967 /* Create runlist for mft. */
3968 g_rl_mft
= ntfs_malloc(2 * sizeof(runlist
));
3972 g_rl_mft
[0].vcn
= 0LL;
3973 g_rl_mft
[0].lcn
= g_mft_lcn
;
3974 /* rounded up division by cluster size */
3975 j
= (g_mft_size
+ g_vol
->cluster_size
- 1) / g_vol
->cluster_size
;
3976 g_rl_mft
[1].vcn
= j
;
3977 g_rl_mft
[0].length
= j
;
3978 g_rl_mft
[1].lcn
= -1LL;
3979 g_rl_mft
[1].length
= 0LL;
3980 /* Allocate clusters for mft. */
3981 bitmap_allocate(g_mft_lcn
,j
);
3982 /* Determine mftmirr_lcn (middle of volume). */
3983 g_mftmirr_lcn
= (opts
.num_sectors
* opts
.sector_size
>> 1)
3984 / g_vol
->cluster_size
;
3985 ntfs_log_debug("$MFTMirr logical cluster number = 0x%llx\n",
3987 /* Create runlist for mft mirror. */
3988 g_rl_mftmirr
= ntfs_malloc(2 * sizeof(runlist
));
3992 g_rl_mftmirr
[0].vcn
= 0LL;
3993 g_rl_mftmirr
[0].lcn
= g_mftmirr_lcn
;
3995 * The mft mirror is either 4kb (the first four records) or one cluster
3996 * in size, which ever is bigger. In either case, it contains a
3997 * byte-for-byte identical copy of the beginning of the mft (i.e. either
3998 * the first four records (4kb) or the first cluster worth of records,
3999 * whichever is bigger).
4001 j
= (4 * g_vol
->mft_record_size
+ g_vol
->cluster_size
- 1) / g_vol
->cluster_size
;
4002 g_rl_mftmirr
[1].vcn
= j
;
4003 g_rl_mftmirr
[0].length
= j
;
4004 g_rl_mftmirr
[1].lcn
= -1LL;
4005 g_rl_mftmirr
[1].length
= 0LL;
4006 /* Allocate clusters for mft mirror. */
4007 done
= bitmap_allocate(g_mftmirr_lcn
,j
);
4008 g_logfile_lcn
= g_mftmirr_lcn
+ j
;
4009 ntfs_log_debug("$LogFile logical cluster number = 0x%llx\n",
4015 * mkntfs_initialize_rl_logfile -
4017 static BOOL
mkntfs_initialize_rl_logfile(void)
4022 /* Create runlist for log file. */
4023 g_rl_logfile
= ntfs_malloc(2 * sizeof(runlist
));
4028 volume_size
= g_vol
->nr_clusters
<< g_vol
->cluster_size_bits
;
4030 g_rl_logfile
[0].vcn
= 0LL;
4031 g_rl_logfile
[0].lcn
= g_logfile_lcn
;
4033 * Determine logfile_size from volume_size (rounded up to a cluster),
4034 * making sure it does not overflow the end of the volume.
4036 if (volume_size
< 2048LL * 1024) /* < 2MiB */
4037 g_logfile_size
= 256LL * 1024; /* -> 256kiB */
4038 else if (volume_size
< 4000000LL) /* < 4MB */
4039 g_logfile_size
= 512LL * 1024; /* -> 512kiB */
4040 else if (volume_size
<= 200LL * 1024 * 1024) /* < 200MiB */
4041 g_logfile_size
= 2048LL * 1024; /* -> 2MiB */
4044 * FIXME: The $LogFile size is 64 MiB upwards from 12GiB but
4045 * the "200" divider below apparently approximates "100" or
4046 * some other value as the volume size decreases. For example:
4047 * Volume size LogFile size Ratio
4048 * 8799808 46048 191.100
4049 * 8603248 45072 190.877
4050 * 7341704 38768 189.375
4051 * 6144828 32784 187.433
4052 * 4192932 23024 182.111
4054 if (volume_size
>= 12LL << 30) /* > 12GiB */
4055 g_logfile_size
= 64 << 20; /* -> 64MiB */
4057 g_logfile_size
= (volume_size
/ 200) &
4058 ~(g_vol
->cluster_size
- 1);
4060 j
= g_logfile_size
/ g_vol
->cluster_size
;
4061 while (g_rl_logfile
[0].lcn
+ j
>= g_vol
->nr_clusters
) {
4063 * $Logfile would overflow volume. Need to make it smaller than
4064 * the standard size. It's ok as we are creating a non-standard
4065 * volume anyway if it is that small.
4067 g_logfile_size
>>= 1;
4068 j
= g_logfile_size
/ g_vol
->cluster_size
;
4070 g_logfile_size
= (g_logfile_size
+ g_vol
->cluster_size
- 1) &
4071 ~(g_vol
->cluster_size
- 1);
4072 ntfs_log_debug("$LogFile (journal) size = %ikiB\n",
4073 g_logfile_size
/ 1024);
4075 * FIXME: The 256kiB limit is arbitrary. Should find out what the real
4076 * minimum requirement for Windows is so it doesn't blue screen.
4078 if (g_logfile_size
< 256 << 10) {
4079 ntfs_log_error("$LogFile would be created with invalid size. "
4080 "This is not allowed as it would cause Windows "
4081 "to blue screen and during boot.\n");
4084 g_rl_logfile
[1].vcn
= j
;
4085 g_rl_logfile
[0].length
= j
;
4086 g_rl_logfile
[1].lcn
= -1LL;
4087 g_rl_logfile
[1].length
= 0LL;
4088 /* Allocate clusters for log file. */
4089 return (bitmap_allocate(g_logfile_lcn
,j
));
4093 * mkntfs_initialize_rl_boot -
4095 static BOOL
mkntfs_initialize_rl_boot(void)
4098 /* Create runlist for $Boot. */
4099 g_rl_boot
= ntfs_malloc(2 * sizeof(runlist
));
4103 g_rl_boot
[0].vcn
= 0LL;
4104 g_rl_boot
[0].lcn
= 0LL;
4106 * $Boot is always 8192 (0x2000) bytes or 1 cluster, whichever is
4109 j
= (8192 + g_vol
->cluster_size
- 1) / g_vol
->cluster_size
;
4110 g_rl_boot
[1].vcn
= j
;
4111 g_rl_boot
[0].length
= j
;
4112 g_rl_boot
[1].lcn
= -1LL;
4113 g_rl_boot
[1].length
= 0LL;
4114 /* Allocate clusters for $Boot. */
4115 return (bitmap_allocate(0,j
));
4119 * mkntfs_initialize_rl_bad -
4121 static BOOL
mkntfs_initialize_rl_bad(void)
4123 /* Create runlist for $BadClus, $DATA named stream $Bad. */
4124 g_rl_bad
= ntfs_malloc(2 * sizeof(runlist
));
4128 g_rl_bad
[0].vcn
= 0LL;
4129 g_rl_bad
[0].lcn
= -1LL;
4131 * $BadClus named stream $Bad contains the whole volume as a single
4132 * sparse runlist entry.
4134 g_rl_bad
[1].vcn
= g_vol
->nr_clusters
;
4135 g_rl_bad
[0].length
= g_vol
->nr_clusters
;
4136 g_rl_bad
[1].lcn
= -1LL;
4137 g_rl_bad
[1].length
= 0LL;
4139 /* TODO: Mark bad blocks as such. */
4144 * mkntfs_fill_device_with_zeroes -
4146 static BOOL
mkntfs_fill_device_with_zeroes(void)
4149 * If not quick format, fill the device with 0s.
4150 * FIXME: Except bad blocks! (AIA)
4154 unsigned long long position
;
4155 float progress_inc
= (float)g_vol
->nr_clusters
/ 100;
4158 volume_size
= g_vol
->nr_clusters
<< g_vol
->cluster_size_bits
;
4160 ntfs_log_progress("Initializing device with zeroes: 0%%");
4161 for (position
= 0; position
< (unsigned long long)g_vol
->nr_clusters
;
4163 if (!(position
% (int)(progress_inc
+1))) {
4164 ntfs_log_progress("\b\b\b\b%3.0f%%", position
/
4167 bw
= mkntfs_write(g_vol
->dev
, g_buf
, g_vol
->cluster_size
);
4168 if (bw
!= (ssize_t
)g_vol
->cluster_size
) {
4169 if (bw
!= -1 || errno
!= EIO
) {
4170 ntfs_log_error("This should not happen.\n");
4174 ntfs_log_error("Error: Cluster zero is bad. "
4175 "Cannot create NTFS file "
4179 /* Add the baddie to our bad blocks list. */
4180 if (!append_to_bad_blocks(position
))
4182 ntfs_log_quiet("\nFound bad cluster (%lld). Adding to "
4183 "list of bad blocks.\nInitializing "
4184 "device with zeroes: %3.0f%%", position
,
4185 position
/ progress_inc
);
4186 /* Seek to next cluster. */
4187 g_vol
->dev
->d_ops
->seek(g_vol
->dev
,
4188 ((off_t
)position
+ 1) *
4189 g_vol
->cluster_size
, SEEK_SET
);
4192 ntfs_log_progress("\b\b\b\b100%%");
4193 position
= (volume_size
& (g_vol
->cluster_size
- 1)) /
4195 for (i
= 0; (unsigned long)i
< position
; i
++) {
4196 bw
= mkntfs_write(g_vol
->dev
, g_buf
, opts
.sector_size
);
4197 if (bw
!= opts
.sector_size
) {
4198 if (bw
!= -1 || errno
!= EIO
) {
4199 ntfs_log_error("This should not happen.\n");
4201 } else if (i
+ 1ull == position
) {
4202 ntfs_log_error("Error: Bad cluster found in "
4203 "location reserved for system "
4207 /* Seek to next sector. */
4208 g_vol
->dev
->d_ops
->seek(g_vol
->dev
,
4209 opts
.sector_size
, SEEK_CUR
);
4212 ntfs_log_progress(" - Done.\n");
4217 * mkntfs_sync_index_record
4219 * (ERSO) made a function out of this, but the reason for doing that
4220 * disappeared during coding....
4222 static BOOL
mkntfs_sync_index_record(INDEX_ALLOCATION
* idx
, MFT_RECORD
* m
,
4223 ntfschar
* name
, u32 name_len
)
4226 ntfs_attr_search_ctx
*ctx
;
4229 runlist
*rl_index
= NULL
;
4231 i
= 5 * sizeof(ntfschar
);
4232 ctx
= ntfs_attr_get_search_ctx(NULL
, m
);
4234 ntfs_log_perror("Failed to allocate attribute search context");
4237 /* FIXME: This should be IGNORE_CASE! */
4238 if (mkntfs_attr_lookup(AT_INDEX_ALLOCATION
, name
, name_len
,
4239 CASE_SENSITIVE
, 0, NULL
, 0, ctx
)) {
4240 ntfs_attr_put_search_ctx(ctx
);
4241 ntfs_log_error("BUG: $INDEX_ALLOCATION attribute not found.\n");
4245 rl_index
= ntfs_mapping_pairs_decompress(g_vol
, a
, NULL
);
4247 ntfs_attr_put_search_ctx(ctx
);
4248 ntfs_log_error("Failed to decompress runlist of $INDEX_ALLOCATION "
4252 if (sle64_to_cpu(a
->initialized_size
) < i
) {
4253 ntfs_attr_put_search_ctx(ctx
);
4255 ntfs_log_error("BUG: $INDEX_ALLOCATION attribute too short.\n");
4258 ntfs_attr_put_search_ctx(ctx
);
4259 i
= sizeof(INDEX_BLOCK
) - sizeof(INDEX_HEADER
) +
4260 le32_to_cpu(idx
->index
.allocated_size
);
4261 err
= ntfs_mst_pre_write_fixup((NTFS_RECORD
*)idx
, i
);
4264 ntfs_log_error("ntfs_mst_pre_write_fixup() failed while "
4265 "syncing index block.\n");
4268 lw
= ntfs_rlwrite(g_vol
->dev
, rl_index
, (u8
*)idx
, i
, NULL
,
4272 ntfs_log_error("Error writing $INDEX_ALLOCATION.\n");
4275 /* No more changes to @idx below here so no need for fixup: */
4276 /* ntfs_mst_post_write_fixup((NTFS_RECORD*)idx); */
4281 * create_file_volume -
4283 static BOOL
create_file_volume(MFT_RECORD
*m
, leMFT_REF root_ref
,
4284 VOLUME_FLAGS fl
, const GUID
*volume_guid
)
4289 ntfs_log_verbose("Creating $Volume (mft record 3)\n");
4290 m
= (MFT_RECORD
*)(g_buf
+ 3 * g_vol
->mft_record_size
);
4291 err
= create_hardlink(g_index_block
, root_ref
, m
,
4292 MK_LE_MREF(FILE_Volume
, FILE_Volume
), 0LL, 0LL,
4293 FILE_ATTR_HIDDEN
| FILE_ATTR_SYSTEM
, 0, 0,
4294 "$Volume", FILE_NAME_WIN32_AND_DOS
);
4296 init_system_file_sd(FILE_Volume
, &sd
, &i
);
4297 err
= add_attr_sd(m
, sd
, i
);
4300 err
= add_attr_data(m
, NULL
, 0, CASE_SENSITIVE
,
4301 const_cpu_to_le16(0), NULL
, 0);
4303 err
= add_attr_vol_name(m
, g_vol
->vol_name
, g_vol
->vol_name
?
4304 strlen(g_vol
->vol_name
) : 0);
4306 if (fl
& VOLUME_IS_DIRTY
)
4307 ntfs_log_quiet("Setting the volume dirty so check "
4308 "disk runs on next reboot into "
4310 err
= add_attr_vol_info(m
, fl
, g_vol
->major_ver
,
4313 if (!err
&& opts
.with_uuid
)
4314 err
= add_attr_object_id(m
, volume_guid
);
4316 ntfs_log_error("Couldn't create $Volume: %s\n",
4324 * create_backup_boot_sector
4326 * Return 0 on success or -1 if it couldn't be created.
4328 static int create_backup_boot_sector(u8
*buff
)
4334 ntfs_log_verbose("Creating backup boot sector.\n");
4336 * Write the first max(512, opts.sector_size) bytes from buf to the
4337 * last sector, but limit that to 8192 bytes of written data since that
4338 * is how big $Boot is (and how big our buffer is)..
4341 if (size
< opts
.sector_size
)
4342 size
= opts
.sector_size
;
4343 if (g_vol
->dev
->d_ops
->seek(g_vol
->dev
, (opts
.num_sectors
+ 1) *
4344 opts
.sector_size
- size
, SEEK_SET
) == (off_t
)-1) {
4345 ntfs_log_perror("Seek failed");
4350 bw
= mkntfs_write(g_vol
->dev
, buff
, size
);
4357 s
= "unknown error";
4358 /* At least some 2.4 kernels return EIO instead of ENOSPC. */
4359 if (bw
!= -1LL || (bw
== -1LL && e
!= ENOSPC
&& e
!= EIO
)) {
4360 ntfs_log_critical("Couldn't write backup boot sector: %s\n", s
);
4364 ntfs_log_error("Couldn't write backup boot sector. This is due to a "
4365 "limitation in the\nLinux kernel. This is not a major "
4366 "problem as Windows check disk will create the\n"
4367 "backup boot sector when it is run on your next boot "
4373 * mkntfs_create_root_structures -
4375 static BOOL
mkntfs_create_root_structures(void)
4377 NTFS_BOOT_SECTOR
*bs
;
4380 leMFT_REF extend_ref
;
4385 FILE_ATTR_FLAGS extend_flags
;
4386 VOLUME_FLAGS volume_flags
= const_cpu_to_le16(0);
4388 int buf_sds_first_size
;
4392 ntfs_log_quiet("Creating NTFS volume structures.\n");
4395 * Setup an empty mft record. Note, we can just give 0 as the mft
4396 * reference as we are creating an NTFS 1.2 volume for which the mft
4397 * reference is ignored by ntfs_mft_record_layout().
4399 * Copy the mft record onto all 16 records in the buffer and setup the
4400 * sequence numbers of each system file to equal the mft record number
4401 * of that file (only for $MFT is the sequence number 1 rather than 0).
4403 for (i
= 0; i
< nr_sysfiles
; i
++) {
4404 if (ntfs_mft_record_layout(g_vol
, 0, m
= (MFT_RECORD
*)(g_buf
+
4405 i
* g_vol
->mft_record_size
))) {
4406 ntfs_log_error("Failed to layout system mft records."
4410 if (i
== 0 || i
> 23)
4411 m
->sequence_number
= cpu_to_le16(1);
4413 m
->sequence_number
= cpu_to_le16(i
);
4416 * If only one cluster contains all system files then
4417 * fill the rest of it with empty, formatted records.
4419 if (nr_sysfiles
* (s32
)g_vol
->mft_record_size
< g_mft_size
) {
4420 for (i
= nr_sysfiles
;
4421 i
* (s32
)g_vol
->mft_record_size
< g_mft_size
; i
++) {
4422 m
= (MFT_RECORD
*)(g_buf
+ i
* g_vol
->mft_record_size
);
4423 if (ntfs_mft_record_layout(g_vol
, 0, m
)) {
4424 ntfs_log_error("Failed to layout mft record."
4428 m
->flags
= cpu_to_le16(0);
4429 m
->sequence_number
= cpu_to_le16(i
);
4433 * Create the 16 system files, adding the system information attribute
4434 * to each as well as marking them in use in the mft bitmap.
4436 for (i
= 0; i
< nr_sysfiles
; i
++) {
4439 m
= (MFT_RECORD
*)(g_buf
+ i
* g_vol
->mft_record_size
);
4440 if (i
< 16 || i
> 23) {
4441 m
->mft_record_number
= cpu_to_le32(i
);
4442 m
->flags
|= MFT_RECORD_IN_USE
;
4443 ntfs_bit_set(g_mft_bitmap
, 0LL + i
, 1);
4445 file_attrs
= FILE_ATTR_HIDDEN
| FILE_ATTR_SYSTEM
;
4446 if (i
== FILE_root
) {
4447 file_attrs
|= FILE_ATTR_ARCHIVE
;
4448 if (opts
.disable_indexing
)
4449 file_attrs
|= FILE_ATTR_NOT_CONTENT_INDEXED
;
4450 if (opts
.enable_compression
)
4451 file_attrs
|= FILE_ATTR_COMPRESSED
;
4453 /* setting specific security_id flag and */
4454 /* file permissions for ntfs 3.x */
4455 if (i
== 0 || i
== 1 || i
== 2 || i
== 6 || i
== 8 ||
4457 add_attr_std_info(m
, file_attrs
,
4458 cpu_to_le32(0x0100));
4459 } else if (i
== 9) {
4460 file_attrs
|= FILE_ATTR_VIEW_INDEX_PRESENT
;
4461 add_attr_std_info(m
, file_attrs
,
4462 cpu_to_le32(0x0101));
4463 } else if (i
== 11) {
4464 add_attr_std_info(m
, file_attrs
,
4465 cpu_to_le32(0x0101));
4466 } else if (i
== 24 || i
== 25 || i
== 26) {
4467 file_attrs
|= FILE_ATTR_ARCHIVE
;
4468 file_attrs
|= FILE_ATTR_VIEW_INDEX_PRESENT
;
4469 add_attr_std_info(m
, file_attrs
,
4470 cpu_to_le32(0x0101));
4472 add_attr_std_info(m
, file_attrs
,
4476 /* The root directory mft reference. */
4477 root_ref
= MK_LE_MREF(FILE_root
, FILE_root
);
4478 extend_ref
= MK_LE_MREF(11,11);
4479 ntfs_log_verbose("Creating root directory (mft record 5)\n");
4480 m
= (MFT_RECORD
*)(g_buf
+ 5 * g_vol
->mft_record_size
);
4481 m
->flags
|= MFT_RECORD_IS_DIRECTORY
;
4482 m
->link_count
= cpu_to_le16(le16_to_cpu(m
->link_count
) + 1);
4483 err
= add_attr_file_name(m
, root_ref
, 0LL, 0LL,
4484 FILE_ATTR_HIDDEN
| FILE_ATTR_SYSTEM
|
4485 FILE_ATTR_I30_INDEX_PRESENT
, 0, 0, ".",
4486 FILE_NAME_WIN32_AND_DOS
);
4488 init_root_sd(&sd
, &i
);
4489 err
= add_attr_sd(m
, sd
, i
);
4491 /* FIXME: This should be IGNORE_CASE */
4493 err
= add_attr_index_root(m
, "$I30", 4, CASE_SENSITIVE
,
4494 AT_FILE_NAME
, COLLATION_FILE_NAME
,
4495 g_vol
->indx_record_size
);
4496 /* FIXME: This should be IGNORE_CASE */
4498 err
= upgrade_to_large_index(m
, "$I30", 4, CASE_SENSITIVE
,
4501 ntfs_attr_search_ctx
*ctx
;
4503 ctx
= ntfs_attr_get_search_ctx(NULL
, m
);
4505 ntfs_log_perror("Failed to allocate attribute search "
4509 /* There is exactly one file name so this is ok. */
4510 if (mkntfs_attr_lookup(AT_FILE_NAME
, AT_UNNAMED
, 0,
4511 CASE_SENSITIVE
, 0, NULL
, 0, ctx
)) {
4512 ntfs_attr_put_search_ctx(ctx
);
4513 ntfs_log_error("BUG: $FILE_NAME attribute not found."
4518 err
= insert_file_link_in_dir_index(g_index_block
, root_ref
,
4519 (FILE_NAME_ATTR
*)((char*)a
+
4520 le16_to_cpu(a
->value_offset
)),
4521 le32_to_cpu(a
->value_length
));
4522 ntfs_attr_put_search_ctx(ctx
);
4525 ntfs_log_error("Couldn't create root directory: %s\n",
4529 /* Add all other attributes, on a per-file basis for clarity. */
4530 ntfs_log_verbose("Creating $MFT (mft record 0)\n");
4531 m
= (MFT_RECORD
*)g_buf
;
4532 err
= add_attr_data_positioned(m
, NULL
, 0, CASE_SENSITIVE
,
4533 const_cpu_to_le16(0), g_rl_mft
, g_buf
, g_mft_size
);
4535 err
= create_hardlink(g_index_block
, root_ref
, m
,
4536 MK_LE_MREF(FILE_MFT
, 1),
4538 | (g_vol
->cluster_size
- 1)) + 1,
4539 g_mft_size
, FILE_ATTR_HIDDEN
|
4540 FILE_ATTR_SYSTEM
, 0, 0, "$MFT",
4541 FILE_NAME_WIN32_AND_DOS
);
4542 /* mft_bitmap is not modified in mkntfs; no need to sync it later. */
4544 err
= add_attr_bitmap_positioned(m
, NULL
, 0, CASE_SENSITIVE
,
4546 g_mft_bitmap
, g_mft_bitmap_byte_size
);
4548 ntfs_log_error("Couldn't create $MFT: %s\n", strerror(-err
));
4551 ntfs_log_verbose("Creating $MFTMirr (mft record 1)\n");
4552 m
= (MFT_RECORD
*)(g_buf
+ 1 * g_vol
->mft_record_size
);
4553 err
= add_attr_data_positioned(m
, NULL
, 0, CASE_SENSITIVE
,
4554 const_cpu_to_le16(0), g_rl_mftmirr
, g_buf
,
4555 g_rl_mftmirr
[0].length
* g_vol
->cluster_size
);
4557 err
= create_hardlink(g_index_block
, root_ref
, m
,
4558 MK_LE_MREF(FILE_MFTMirr
, FILE_MFTMirr
),
4559 g_rl_mftmirr
[0].length
* g_vol
->cluster_size
,
4560 g_rl_mftmirr
[0].length
* g_vol
->cluster_size
,
4561 FILE_ATTR_HIDDEN
| FILE_ATTR_SYSTEM
, 0, 0,
4562 "$MFTMirr", FILE_NAME_WIN32_AND_DOS
);
4564 ntfs_log_error("Couldn't create $MFTMirr: %s\n",
4568 ntfs_log_verbose("Creating $LogFile (mft record 2)\n");
4569 m
= (MFT_RECORD
*)(g_buf
+ 2 * g_vol
->mft_record_size
);
4570 err
= add_attr_data_positioned(m
, NULL
, 0, CASE_SENSITIVE
,
4571 const_cpu_to_le16(0), g_rl_logfile
,
4572 (const u8
*)NULL
, g_logfile_size
);
4574 err
= create_hardlink(g_index_block
, root_ref
, m
,
4575 MK_LE_MREF(FILE_LogFile
, FILE_LogFile
),
4576 g_logfile_size
, g_logfile_size
,
4577 FILE_ATTR_HIDDEN
| FILE_ATTR_SYSTEM
, 0, 0,
4578 "$LogFile", FILE_NAME_WIN32_AND_DOS
);
4580 ntfs_log_error("Couldn't create $LogFile: %s\n",
4584 ntfs_log_verbose("Creating $AttrDef (mft record 4)\n");
4585 m
= (MFT_RECORD
*)(g_buf
+ 4 * g_vol
->mft_record_size
);
4586 err
= add_attr_data(m
, NULL
, 0, CASE_SENSITIVE
, const_cpu_to_le16(0),
4587 (u8
*)g_vol
->attrdef
, g_vol
->attrdef_len
);
4589 err
= create_hardlink(g_index_block
, root_ref
, m
,
4590 MK_LE_MREF(FILE_AttrDef
, FILE_AttrDef
),
4591 (g_vol
->attrdef_len
+ g_vol
->cluster_size
- 1) &
4592 ~(g_vol
->cluster_size
- 1), g_vol
->attrdef_len
,
4593 FILE_ATTR_HIDDEN
| FILE_ATTR_SYSTEM
, 0, 0,
4594 "$AttrDef", FILE_NAME_WIN32_AND_DOS
);
4596 init_system_file_sd(FILE_AttrDef
, &sd
, &i
);
4597 err
= add_attr_sd(m
, sd
, i
);
4600 ntfs_log_error("Couldn't create $AttrDef: %s\n",
4604 ntfs_log_verbose("Creating $Bitmap (mft record 6)\n");
4605 m
= (MFT_RECORD
*)(g_buf
+ 6 * g_vol
->mft_record_size
);
4606 /* the data attribute of $Bitmap must be non-resident or otherwise */
4607 /* windows 2003 will regard the volume as corrupt (ERSO) */
4609 err
= insert_non_resident_attr_in_mft_record(m
,
4610 AT_DATA
, NULL
, 0, CASE_SENSITIVE
,
4611 const_cpu_to_le16(0), (const u8
*)NULL
,
4612 g_lcn_bitmap_byte_size
, WRITE_BITMAP
);
4616 err
= create_hardlink(g_index_block
, root_ref
, m
,
4617 MK_LE_MREF(FILE_Bitmap
, FILE_Bitmap
),
4618 (g_lcn_bitmap_byte_size
+ g_vol
->cluster_size
-
4619 1) & ~(g_vol
->cluster_size
- 1),
4620 g_lcn_bitmap_byte_size
,
4621 FILE_ATTR_HIDDEN
| FILE_ATTR_SYSTEM
, 0, 0,
4622 "$Bitmap", FILE_NAME_WIN32_AND_DOS
);
4624 ntfs_log_error("Couldn't create $Bitmap: %s\n", strerror(-err
));
4627 ntfs_log_verbose("Creating $Boot (mft record 7)\n");
4628 m
= (MFT_RECORD
*)(g_buf
+ 7 * g_vol
->mft_record_size
);
4629 bs
= ntfs_calloc(8192);
4632 memcpy(bs
, boot_array
, sizeof(boot_array
));
4634 * Create the boot sector in bs. Note, that bs is already zeroed
4635 * in the boot sector section and that it has the NTFS OEM id/magic
4636 * already inserted, so no need to worry about these things.
4638 bs
->bpb
.bytes_per_sector
= cpu_to_le16(opts
.sector_size
);
4639 bs
->bpb
.sectors_per_cluster
= (u8
)(g_vol
->cluster_size
/
4641 bs
->bpb
.media_type
= 0xf8; /* hard disk */
4642 bs
->bpb
.sectors_per_track
= cpu_to_le16(opts
.sectors_per_track
);
4643 ntfs_log_debug("sectors per track = %ld (0x%lx)\n",
4644 opts
.sectors_per_track
, opts
.sectors_per_track
);
4645 bs
->bpb
.heads
= cpu_to_le16(opts
.heads
);
4646 ntfs_log_debug("heads = %ld (0x%lx)\n", opts
.heads
, opts
.heads
);
4647 bs
->bpb
.hidden_sectors
= cpu_to_le32(opts
.part_start_sect
);
4648 ntfs_log_debug("hidden sectors = %llu (0x%llx)\n", opts
.part_start_sect
,
4649 opts
.part_start_sect
);
4650 bs
->physical_drive
= 0x80; /* boot from hard disk */
4651 bs
->extended_boot_signature
= 0x80; /* everybody sets this, so we do */
4652 bs
->number_of_sectors
= cpu_to_sle64(opts
.num_sectors
);
4653 bs
->mft_lcn
= cpu_to_sle64(g_mft_lcn
);
4654 bs
->mftmirr_lcn
= cpu_to_sle64(g_mftmirr_lcn
);
4655 if (g_vol
->mft_record_size
>= g_vol
->cluster_size
) {
4656 bs
->clusters_per_mft_record
= g_vol
->mft_record_size
/
4657 g_vol
->cluster_size
;
4659 bs
->clusters_per_mft_record
= -(ffs(g_vol
->mft_record_size
) -
4661 if ((u32
)(1 << -bs
->clusters_per_mft_record
) !=
4662 g_vol
->mft_record_size
) {
4664 ntfs_log_error("BUG: calculated clusters_per_mft_record"
4665 " is wrong (= 0x%x)\n",
4666 bs
->clusters_per_mft_record
);
4670 ntfs_log_debug("clusters per mft record = %i (0x%x)\n",
4671 bs
->clusters_per_mft_record
,
4672 bs
->clusters_per_mft_record
);
4673 if (g_vol
->indx_record_size
>= g_vol
->cluster_size
) {
4674 bs
->clusters_per_index_record
= g_vol
->indx_record_size
/
4675 g_vol
->cluster_size
;
4677 bs
->clusters_per_index_record
= -g_vol
->indx_record_size_bits
;
4678 if ((1 << -bs
->clusters_per_index_record
) !=
4679 (s32
)g_vol
->indx_record_size
) {
4681 ntfs_log_error("BUG: calculated "
4682 "clusters_per_index_record is wrong "
4684 bs
->clusters_per_index_record
);
4688 ntfs_log_debug("clusters per index block = %i (0x%x)\n",
4689 bs
->clusters_per_index_record
,
4690 bs
->clusters_per_index_record
);
4691 /* Generate a 64-bit random number for the serial number. */
4692 bs
->volume_serial_number
= cpu_to_le64(((u64
)random() << 32) |
4693 ((u64
)random() & 0xffffffff));
4695 * Leave zero for now as NT4 leaves it zero, too. If want it later, see
4696 * ../libntfs/bootsect.c for how to calculate it.
4698 bs
->checksum
= cpu_to_le32(0);
4699 /* Make sure the bootsector is ok. */
4700 if (!ntfs_boot_sector_is_ntfs(bs
)) {
4702 ntfs_log_error("FATAL: Generated boot sector is invalid!\n");
4705 err
= add_attr_data_positioned(m
, NULL
, 0, CASE_SENSITIVE
,
4706 const_cpu_to_le16(0), g_rl_boot
, (u8
*)bs
, 8192);
4708 err
= create_hardlink(g_index_block
, root_ref
, m
,
4709 MK_LE_MREF(FILE_Boot
, FILE_Boot
),
4710 (8192 + g_vol
->cluster_size
- 1) &
4711 ~(g_vol
->cluster_size
- 1), 8192,
4712 FILE_ATTR_HIDDEN
| FILE_ATTR_SYSTEM
, 0, 0,
4713 "$Boot", FILE_NAME_WIN32_AND_DOS
);
4715 init_system_file_sd(FILE_Boot
, &sd
, &i
);
4716 err
= add_attr_sd(m
, sd
, i
);
4720 ntfs_log_error("Couldn't create $Boot: %s\n", strerror(-err
));
4723 if (create_backup_boot_sector((u8
*)bs
)) {
4725 * Pre-2.6 kernels couldn't access the last sector if it was
4726 * odd and we failed to set the device block size to the sector
4727 * size, hence we schedule chkdsk to create it.
4729 volume_flags
|= VOLUME_IS_DIRTY
;
4733 * We cheat a little here and if the user has requested all times to be
4734 * set to zero then we set the GUID to zero as well. This options is
4735 * only used for development purposes so that should be fine.
4737 if (!opts
.use_epoch_time
) {
4738 /* Generate a GUID for the volume. */
4740 uuid_generate((void*)&vol_guid
);
4742 ntfs_generate_guid(&vol_guid
);
4745 memset(&vol_guid
, 0, sizeof(vol_guid
));
4746 if (!create_file_volume(m
, root_ref
, volume_flags
, &vol_guid
))
4748 ntfs_log_verbose("Creating $BadClus (mft record 8)\n");
4749 m
= (MFT_RECORD
*)(g_buf
+ 8 * g_vol
->mft_record_size
);
4750 /* FIXME: This should be IGNORE_CASE */
4751 /* Create a sparse named stream of size equal to the volume size. */
4752 err
= add_attr_data_positioned(m
, "$Bad", 4, CASE_SENSITIVE
,
4753 const_cpu_to_le16(0), g_rl_bad
, NULL
,
4754 g_vol
->nr_clusters
* g_vol
->cluster_size
);
4756 err
= add_attr_data(m
, NULL
, 0, CASE_SENSITIVE
,
4757 const_cpu_to_le16(0), NULL
, 0);
4760 err
= create_hardlink(g_index_block
, root_ref
, m
,
4761 MK_LE_MREF(FILE_BadClus
, FILE_BadClus
),
4762 0LL, 0LL, FILE_ATTR_HIDDEN
| FILE_ATTR_SYSTEM
,
4763 0, 0, "$BadClus", FILE_NAME_WIN32_AND_DOS
);
4766 ntfs_log_error("Couldn't create $BadClus: %s\n",
4770 /* create $Secure (NTFS 3.0+) */
4771 ntfs_log_verbose("Creating $Secure (mft record 9)\n");
4772 m
= (MFT_RECORD
*)(g_buf
+ 9 * g_vol
->mft_record_size
);
4773 m
->flags
|= MFT_RECORD_IS_VIEW_INDEX
;
4775 err
= create_hardlink(g_index_block
, root_ref
, m
,
4776 MK_LE_MREF(9, 9), 0LL, 0LL,
4777 FILE_ATTR_HIDDEN
| FILE_ATTR_SYSTEM
|
4778 FILE_ATTR_VIEW_INDEX_PRESENT
, 0, 0,
4779 "$Secure", FILE_NAME_WIN32_AND_DOS
);
4781 buf_sds_first_size
= 0;
4785 buf_sds_first_size
= 0xfc;
4786 buf_sds_size
= 0x40000 + buf_sds_first_size
;
4787 buf_sds
= ntfs_calloc(buf_sds_size
);
4790 init_secure_sds(buf_sds
);
4791 memcpy(buf_sds
+ 0x40000, buf_sds
, buf_sds_first_size
);
4792 err
= add_attr_data(m
, "$SDS", 4, CASE_SENSITIVE
,
4793 const_cpu_to_le16(0), (u8
*)buf_sds
,
4796 /* FIXME: This should be IGNORE_CASE */
4798 err
= add_attr_index_root(m
, "$SDH", 4, CASE_SENSITIVE
,
4799 AT_UNUSED
, COLLATION_NTOFS_SECURITY_HASH
,
4800 g_vol
->indx_record_size
);
4801 /* FIXME: This should be IGNORE_CASE */
4803 err
= add_attr_index_root(m
, "$SII", 4, CASE_SENSITIVE
,
4804 AT_UNUSED
, COLLATION_NTOFS_ULONG
,
4805 g_vol
->indx_record_size
);
4807 err
= initialize_secure(buf_sds
, buf_sds_first_size
, m
);
4810 ntfs_log_error("Couldn't create $Secure: %s\n",
4814 ntfs_log_verbose("Creating $UpCase (mft record 0xa)\n");
4815 m
= (MFT_RECORD
*)(g_buf
+ 0xa * g_vol
->mft_record_size
);
4816 err
= add_attr_data(m
, NULL
, 0, CASE_SENSITIVE
, const_cpu_to_le16(0),
4817 (u8
*)g_vol
->upcase
, g_vol
->upcase_len
<< 1);
4819 * The $Info only exists since Windows 8, but it apparently
4820 * does not disturb chkdsk from earlier versions.
4823 err
= add_attr_data(m
, "$Info", 5, CASE_SENSITIVE
,
4824 const_cpu_to_le16(0),
4825 (u8
*)g_upcaseinfo
, sizeof(struct UPCASEINFO
));
4827 err
= create_hardlink(g_index_block
, root_ref
, m
,
4828 MK_LE_MREF(FILE_UpCase
, FILE_UpCase
),
4829 ((g_vol
->upcase_len
<< 1) +
4830 g_vol
->cluster_size
- 1) &
4831 ~(g_vol
->cluster_size
- 1),
4832 g_vol
->upcase_len
<< 1,
4833 FILE_ATTR_HIDDEN
| FILE_ATTR_SYSTEM
, 0, 0,
4834 "$UpCase", FILE_NAME_WIN32_AND_DOS
);
4836 ntfs_log_error("Couldn't create $UpCase: %s\n", strerror(-err
));
4839 ntfs_log_verbose("Creating $Extend (mft record 11)\n");
4841 * $Extend index must be resident. Otherwise, w2k3 will regard the
4842 * volume as corrupt. (ERSO)
4844 m
= (MFT_RECORD
*)(g_buf
+ 11 * g_vol
->mft_record_size
);
4845 m
->flags
|= MFT_RECORD_IS_DIRECTORY
;
4847 err
= create_hardlink(g_index_block
, root_ref
, m
,
4848 MK_LE_MREF(11, 11), 0LL, 0LL,
4849 FILE_ATTR_HIDDEN
| FILE_ATTR_SYSTEM
|
4850 FILE_ATTR_I30_INDEX_PRESENT
, 0, 0,
4851 "$Extend", FILE_NAME_WIN32_AND_DOS
);
4852 /* FIXME: This should be IGNORE_CASE */
4854 err
= add_attr_index_root(m
, "$I30", 4, CASE_SENSITIVE
,
4855 AT_FILE_NAME
, COLLATION_FILE_NAME
,
4856 g_vol
->indx_record_size
);
4858 ntfs_log_error("Couldn't create $Extend: %s\n",
4862 /* NTFS reserved system files (mft records 0xc-0xf) */
4863 for (i
= 0xc; i
< 0x10; i
++) {
4864 ntfs_log_verbose("Creating system file (mft record 0x%x)\n", i
);
4865 m
= (MFT_RECORD
*)(g_buf
+ i
* g_vol
->mft_record_size
);
4866 err
= add_attr_data(m
, NULL
, 0, CASE_SENSITIVE
,
4867 const_cpu_to_le16(0), NULL
, 0);
4869 init_system_file_sd(i
, &sd
, &j
);
4870 err
= add_attr_sd(m
, sd
, j
);
4873 ntfs_log_error("Couldn't create system file %i (0x%x): "
4874 "%s\n", i
, i
, strerror(-err
));
4878 /* create systemfiles for ntfs volumes (3.1) */
4879 /* starting with file 24 (ignoring file 16-23) */
4880 extend_flags
= FILE_ATTR_HIDDEN
| FILE_ATTR_SYSTEM
|
4881 FILE_ATTR_ARCHIVE
| FILE_ATTR_VIEW_INDEX_PRESENT
;
4882 ntfs_log_verbose("Creating $Quota (mft record 24)\n");
4883 m
= (MFT_RECORD
*)(g_buf
+ 24 * g_vol
->mft_record_size
);
4884 m
->flags
|= MFT_RECORD_IS_4
;
4885 m
->flags
|= MFT_RECORD_IS_VIEW_INDEX
;
4887 err
= create_hardlink_res((MFT_RECORD
*)(g_buf
+
4888 11 * g_vol
->mft_record_size
), extend_ref
, m
,
4889 MK_LE_MREF(24, 1), 0LL, 0LL, extend_flags
,
4890 0, 0, "$Quota", FILE_NAME_WIN32_AND_DOS
);
4891 /* FIXME: This should be IGNORE_CASE */
4893 err
= add_attr_index_root(m
, "$Q", 2, CASE_SENSITIVE
, AT_UNUSED
,
4894 COLLATION_NTOFS_ULONG
, g_vol
->indx_record_size
);
4895 /* FIXME: This should be IGNORE_CASE */
4897 err
= add_attr_index_root(m
, "$O", 2, CASE_SENSITIVE
, AT_UNUSED
,
4898 COLLATION_NTOFS_SID
, g_vol
->indx_record_size
);
4900 err
= initialize_quota(m
);
4902 ntfs_log_error("Couldn't create $Quota: %s\n", strerror(-err
));
4905 ntfs_log_verbose("Creating $ObjId (mft record 25)\n");
4906 m
= (MFT_RECORD
*)(g_buf
+ 25 * g_vol
->mft_record_size
);
4907 m
->flags
|= MFT_RECORD_IS_4
;
4908 m
->flags
|= MFT_RECORD_IS_VIEW_INDEX
;
4910 err
= create_hardlink_res((MFT_RECORD
*)(g_buf
+
4911 11 * g_vol
->mft_record_size
), extend_ref
,
4912 m
, MK_LE_MREF(25, 1), 0LL, 0LL,
4913 extend_flags
, 0, 0, "$ObjId",
4914 FILE_NAME_WIN32_AND_DOS
);
4916 /* FIXME: This should be IGNORE_CASE */
4918 err
= add_attr_index_root(m
, "$O", 2, CASE_SENSITIVE
, AT_UNUSED
,
4919 COLLATION_NTOFS_ULONGS
,
4920 g_vol
->indx_record_size
);
4921 if (!err
&& opts
.with_uuid
)
4922 err
= index_obj_id_insert(m
, &vol_guid
,
4923 MK_LE_MREF(FILE_Volume
, FILE_Volume
));
4925 ntfs_log_error("Couldn't create $ObjId: %s\n",
4929 ntfs_log_verbose("Creating $Reparse (mft record 26)\n");
4930 m
= (MFT_RECORD
*)(g_buf
+ 26 * g_vol
->mft_record_size
);
4931 m
->flags
|= MFT_RECORD_IS_4
;
4932 m
->flags
|= MFT_RECORD_IS_VIEW_INDEX
;
4934 err
= create_hardlink_res((MFT_RECORD
*)(g_buf
+
4935 11 * g_vol
->mft_record_size
),
4936 extend_ref
, m
, MK_LE_MREF(26, 1),
4937 0LL, 0LL, extend_flags
, 0, 0,
4938 "$Reparse", FILE_NAME_WIN32_AND_DOS
);
4939 /* FIXME: This should be IGNORE_CASE */
4941 err
= add_attr_index_root(m
, "$R", 2, CASE_SENSITIVE
, AT_UNUSED
,
4942 COLLATION_NTOFS_ULONGS
, g_vol
->indx_record_size
);
4944 ntfs_log_error("Couldn't create $Reparse: %s\n",
4954 static int mkntfs_redirect(struct mkntfs_options
*opts2
)
4958 ntfs_attr_search_ctx
*ctx
= NULL
;
4965 ntfs_log_error("Internal error: invalid parameters to mkntfs_options.\n");
4968 /* Initialize the random number generator with the current time. */
4969 srandom(le64_to_cpu(mkntfs_time())/10000000);
4970 /* Allocate and initialize ntfs_volume structure g_vol. */
4971 g_vol
= ntfs_volume_alloc();
4973 ntfs_log_perror("Could not create volume");
4976 /* Create NTFS 3.1 (Windows XP/Vista) volumes. */
4977 g_vol
->major_ver
= 3;
4978 g_vol
->minor_ver
= 1;
4979 /* Transfer some options to the volume. */
4981 g_vol
->vol_name
= strdup(opts
.label
);
4982 if (!g_vol
->vol_name
) {
4983 ntfs_log_perror("Could not copy volume name");
4987 if (opts
.cluster_size
>= 0)
4988 g_vol
->cluster_size
= opts
.cluster_size
;
4989 /* Length is in unicode characters. */
4990 g_vol
->upcase_len
= ntfs_upcase_build_default(&g_vol
->upcase
);
4991 /* Since Windows 8, there is a $Info stream in $UpCase */
4993 (struct UPCASEINFO
*)ntfs_malloc(sizeof(struct UPCASEINFO
));
4994 if (!g_vol
->upcase_len
|| !g_upcaseinfo
)
4996 /* If the CRC is correct, chkdsk does not warn about obsolete table */
4997 crc64(0,(byte
*)NULL
,0); /* initialize the crc computation */
4998 upcase_crc
= crc64(0,(byte
*)g_vol
->upcase
,
4999 g_vol
->upcase_len
* sizeof(ntfschar
));
5000 /* keep the version fields as zero */
5001 memset(g_upcaseinfo
, 0, sizeof(struct UPCASEINFO
));
5002 g_upcaseinfo
->len
= cpu_to_le32(sizeof(struct UPCASEINFO
));
5003 g_upcaseinfo
->crc
= cpu_to_le64(upcase_crc
);
5004 g_vol
->attrdef
= ntfs_malloc(sizeof(attrdef_ntfs3x_array
));
5005 if (!g_vol
->attrdef
) {
5006 ntfs_log_perror("Could not create attrdef structure");
5009 memcpy(g_vol
->attrdef
, attrdef_ntfs3x_array
,
5010 sizeof(attrdef_ntfs3x_array
));
5011 g_vol
->attrdef_len
= sizeof(attrdef_ntfs3x_array
);
5012 /* Open the partition. */
5013 if (!mkntfs_open_partition(g_vol
))
5016 * Decide on the sector size, cluster size, mft record and index record
5017 * sizes as well as the number of sectors/tracks/heads/size, etc.
5019 if (!mkntfs_override_vol_params(g_vol
))
5021 /* Initialize $Bitmap and $MFT/$BITMAP related stuff. */
5022 if (!mkntfs_initialize_bitmaps())
5024 /* Initialize MFT & set g_logfile_lcn. */
5025 if (!mkntfs_initialize_rl_mft())
5027 /* Initialize $LogFile. */
5028 if (!mkntfs_initialize_rl_logfile())
5030 /* Initialize $Boot. */
5031 if (!mkntfs_initialize_rl_boot())
5033 /* Allocate a buffer large enough to hold the mft. */
5034 g_buf
= ntfs_calloc(g_mft_size
);
5037 /* Create runlist for $BadClus, $DATA named stream $Bad. */
5038 if (!mkntfs_initialize_rl_bad())
5040 /* If not quick format, fill the device with 0s. */
5041 if (!opts
.quick_format
) {
5042 if (!mkntfs_fill_device_with_zeroes())
5045 /* Create NTFS volume structures. */
5046 if (!mkntfs_create_root_structures())
5049 * - Do not step onto bad blocks!!!
5050 * - If any bad blocks were specified or found, modify $BadClus,
5051 * allocating the bad clusters in $Bitmap.
5052 * - C&w bootsector backup bootsector (backup in last sector of the
5054 * - If NTFS 3.0+, c&w $Secure file and $Extend directory with the
5055 * corresponding special files in it, i.e. $ObjId, $Quota, $Reparse,
5056 * and $UsnJrnl. And others? Or not all necessary?
5057 * - RE: Populate $root with the system files (and $Extend directory if
5058 * applicable). Possibly should move this as far to the top as
5059 * possible and update during each subsequent c&w of each system file.
5061 ntfs_log_verbose("Syncing root directory index record.\n");
5062 if (!mkntfs_sync_index_record(g_index_block
, (MFT_RECORD
*)(g_buf
+ 5 *
5063 g_vol
->mft_record_size
), NTFS_INDEX_I30
, 4))
5066 ntfs_log_verbose("Syncing $Bitmap.\n");
5067 m
= (MFT_RECORD
*)(g_buf
+ 6 * g_vol
->mft_record_size
);
5069 ctx
= ntfs_attr_get_search_ctx(NULL
, m
);
5071 ntfs_log_perror("Could not create an attribute search context");
5075 if (mkntfs_attr_lookup(AT_DATA
, AT_UNNAMED
, 0, CASE_SENSITIVE
,
5077 ntfs_log_error("BUG: $DATA attribute not found.\n");
5082 if (a
->non_resident
) {
5083 runlist
*rl
= ntfs_mapping_pairs_decompress(g_vol
, a
, NULL
);
5085 ntfs_log_error("ntfs_mapping_pairs_decompress() failed\n");
5088 lw
= ntfs_rlwrite(g_vol
->dev
, rl
, (const u8
*)NULL
,
5089 g_lcn_bitmap_byte_size
, NULL
, WRITE_BITMAP
);
5092 if (lw
!= g_lcn_bitmap_byte_size
) {
5093 ntfs_log_error("ntfs_rlwrite: %s\n", lw
== -1 ?
5094 strerror(err
) : "unknown error");
5098 /* Error : the bitmap must be created non resident */
5099 ntfs_log_error("Error : the global bitmap is resident\n");
5104 * No need to sync $MFT/$BITMAP as that has never been modified since
5107 ntfs_log_verbose("Syncing $MFT.\n");
5108 pos
= g_mft_lcn
* g_vol
->cluster_size
;
5110 for (i
= 0; i
< g_mft_size
/ (s32
)g_vol
->mft_record_size
; i
++) {
5111 if (!opts
.no_action
)
5112 lw
= ntfs_mst_pwrite(g_vol
->dev
, pos
, 1, g_vol
->mft_record_size
, g_buf
+ i
* g_vol
->mft_record_size
);
5114 ntfs_log_error("ntfs_mst_pwrite: %s\n", lw
== -1 ?
5115 strerror(errno
) : "unknown error");
5118 pos
+= g_vol
->mft_record_size
;
5120 ntfs_log_verbose("Updating $MFTMirr.\n");
5121 pos
= g_mftmirr_lcn
* g_vol
->cluster_size
;
5123 for (i
= 0; i
< g_rl_mftmirr
[0].length
* g_vol
->cluster_size
/ g_vol
->mft_record_size
; i
++) {
5124 m
= (MFT_RECORD
*)(g_buf
+ i
* g_vol
->mft_record_size
);
5126 * Decrement the usn by one, so it becomes the same as the one
5127 * in $MFT once it is mst protected. - This is as we need the
5128 * $MFTMirr to have the exact same byte by byte content as
5129 * $MFT, rather than just equivalent meaning content.
5131 if (ntfs_mft_usn_dec(m
)) {
5132 ntfs_log_error("ntfs_mft_usn_dec");
5135 if (!opts
.no_action
)
5136 lw
= ntfs_mst_pwrite(g_vol
->dev
, pos
, 1, g_vol
->mft_record_size
, g_buf
+ i
* g_vol
->mft_record_size
);
5138 ntfs_log_error("ntfs_mst_pwrite: %s\n", lw
== -1 ?
5139 strerror(errno
) : "unknown error");
5142 pos
+= g_vol
->mft_record_size
;
5144 ntfs_log_verbose("Syncing device.\n");
5145 if (g_vol
->dev
->d_ops
->sync(g_vol
->dev
)) {
5146 ntfs_log_error("Syncing device. FAILED");
5149 ntfs_log_quiet("mkntfs completed successfully. Have a nice day.\n");
5152 ntfs_attr_put_search_ctx(ctx
);
5153 mkntfs_cleanup(); /* Device is unlocked and closed here */
5163 * Return: 0 Success, the program worked
5164 * 1 Error, something went wrong
5166 int main(int argc
, char *argv
[])
5170 ntfs_log_set_handler(ntfs_log_handler_outerr
);
5173 mkntfs_init_options(&opts
); /* Set up the options */
5175 if (!mkntfs_parse_options(argc
, argv
, &opts
)) /* Read the command line options */
5178 result
= mkntfs_redirect(&opts
);