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);
3554
ntfs_log_warning("Failed to determine system page size. "
3555
"Assuming safe default of 4096 bytes.\n");
3558
ntfs_log_debug("System page size is %li bytes.\n", page_size);
3563
* mkntfs_override_vol_params -
3565
static BOOL mkntfs_override_vol_params(ntfs_volume *vol)
3570
BOOL winboot = TRUE;
3572
/* If user didn't specify the sector size, determine it now. */
3573
if (opts.sector_size < 0) {
3574
opts.sector_size = ntfs_device_sector_size_get(vol->dev);
3575
if (opts.sector_size < 0) {
3576
ntfs_log_warning("The sector size was not specified "
3577
"for %s and it could not be obtained "
3578
"automatically. It has been set to 512 "
3579
"bytes.\n", vol->dev->d_name);
3580
opts.sector_size = 512;
3583
/* Validate sector size. */
3584
if ((opts.sector_size - 1) & opts.sector_size) {
3585
ntfs_log_error("The sector size is invalid. It must be a "
3586
"power of two, e.g. 512, 1024.\n");
3589
if (opts.sector_size < 256 || opts.sector_size > 4096) {
3590
ntfs_log_error("The sector size is invalid. The minimum size "
3591
"is 256 bytes and the maximum is 4096 bytes.\n");
3594
ntfs_log_debug("sector size = %ld bytes\n", opts.sector_size);
3595
/* Now set the device block size to the sector size. */
3596
if (ntfs_device_block_size_set(vol->dev, opts.sector_size))
3597
ntfs_log_debug("Failed to set the device block size to the "
3598
"sector size. This may cause problems when "
3599
"creating the backup boot sector and also may "
3600
"affect performance but should be harmless "
3601
"otherwise. Error: %s\n", strerror(errno));
3602
/* If user didn't specify the number of sectors, determine it now. */
3603
if (opts.num_sectors < 0) {
3604
opts.num_sectors = ntfs_device_size_get(vol->dev,
3606
if (opts.num_sectors <= 0) {
3607
ntfs_log_error("Couldn't determine the size of %s. "
3608
"Please specify the number of sectors "
3609
"manually.\n", vol->dev->d_name);
3613
ntfs_log_debug("number of sectors = %lld (0x%llx)\n", opts.num_sectors,
3616
* Reserve the last sector for the backup boot sector unless the
3617
* sector size is less than 512 bytes in which case reserve 512 bytes
3621
if (opts.sector_size < 512)
3622
i = 512 / opts.sector_size;
3623
opts.num_sectors -= i;
3624
/* If user didn't specify the partition start sector, determine it. */
3625
if (opts.part_start_sect < 0) {
3626
opts.part_start_sect = ntfs_device_partition_start_sector_get(
3628
if (opts.part_start_sect < 0) {
3629
ntfs_log_warning("The partition start sector was not "
3630
"specified for %s and it could not be obtained "
3631
"automatically. It has been set to 0.\n",
3633
opts.part_start_sect = 0;
3635
} else if (opts.part_start_sect >> 32) {
3636
ntfs_log_warning("The partition start sector specified "
3637
"for %s and the automatically determined value "
3638
"is too large. It has been set to 0.\n",
3640
opts.part_start_sect = 0;
3643
} else if (opts.part_start_sect >> 32) {
3644
ntfs_log_error("Invalid partition start sector. Maximum is "
3645
"4294967295 (2^32-1).\n");
3648
/* If user didn't specify the sectors per track, determine it now. */
3649
if (opts.sectors_per_track < 0) {
3650
opts.sectors_per_track = ntfs_device_sectors_per_track_get(
3652
if (opts.sectors_per_track < 0) {
3653
ntfs_log_warning("The number of sectors per track was "
3654
"not specified for %s and it could not be "
3655
"obtained automatically. It has been set to "
3656
"0.\n", vol->dev->d_name);
3657
opts.sectors_per_track = 0;
3659
} else if (opts.sectors_per_track > 65535) {
3660
ntfs_log_warning("The number of sectors per track was "
3661
"not specified for %s and the automatically "
3662
"determined value is too large. It has been "
3663
"set to 0.\n", vol->dev->d_name);
3664
opts.sectors_per_track = 0;
3667
} else if (opts.sectors_per_track > 65535) {
3668
ntfs_log_error("Invalid number of sectors per track. Maximum "
3672
/* If user didn't specify the number of heads, determine it now. */
3673
if (opts.heads < 0) {
3674
opts.heads = ntfs_device_heads_get(vol->dev);
3675
if (opts.heads < 0) {
3676
ntfs_log_warning("The number of heads was not "
3677
"specified for %s and it could not be obtained "
3678
"automatically. It has been set to 0.\n",
3682
} else if (opts.heads > 65535) {
3683
ntfs_log_warning("The number of heads was not "
3684
"specified for %s and the automatically "
3685
"determined value is too large. It has been "
3686
"set to 0.\n", vol->dev->d_name);
3690
} else if (opts.heads > 65535) {
3691
ntfs_log_error("Invalid number of heads. Maximum is 65535.\n");
3694
volume_size = opts.num_sectors * opts.sector_size;
3695
/* Validate volume size. */
3696
if (volume_size < (1 << 20)) { /* 1MiB */
3697
ntfs_log_error("Device is too small (%llikiB). Minimum NTFS "
3698
"volume size is 1MiB.\n",
3699
(long long)(volume_size / 1024));
3702
ntfs_log_debug("volume size = %llikiB\n", volume_size / 1024);
3703
/* If user didn't specify the cluster size, determine it now. */
3704
if (!vol->cluster_size) {
3706
* Windows Vista always uses 4096 bytes as the default cluster
3707
* size regardless of the volume size so we do it, too.
3709
vol->cluster_size = 4096;
3710
/* For small volumes on devices with large sector sizes. */
3711
if (vol->cluster_size < (u32)opts.sector_size)
3712
vol->cluster_size = opts.sector_size;
3714
* For huge volumes, grow the cluster size until the number of
3715
* clusters fits into 32 bits or the cluster size exceeds the
3716
* maximum limit of 64kiB.
3718
while (volume_size >> (ffs(vol->cluster_size) - 1 + 32)) {
3719
vol->cluster_size <<= 1;
3720
if (vol->cluster_size > 65535) {
3721
ntfs_log_error("Device is too large to hold an "
3722
"NTFS volume (maximum size is "
3727
ntfs_log_quiet("Cluster size has been automatically set to %u "
3728
"bytes.\n", (unsigned)vol->cluster_size);
3730
/* Validate cluster size. */
3731
if (vol->cluster_size & (vol->cluster_size - 1)) {
3732
ntfs_log_error("The cluster size is invalid. It must be a "
3733
"power of two, e.g. 1024, 4096.\n");
3736
if (vol->cluster_size < (u32)opts.sector_size) {
3737
ntfs_log_error("The cluster size is invalid. It must be equal "
3738
"to, or larger than, the sector size.\n");
3741
if (vol->cluster_size > 128 * (u32)opts.sector_size) {
3742
ntfs_log_error("The cluster size is invalid. It cannot be "
3743
"more that 128 times the size of the sector "
3747
if (vol->cluster_size > 65536) {
3748
ntfs_log_error("The cluster size is invalid. The maximum "
3749
"cluster size is 65536 bytes (64kiB).\n");
3752
vol->cluster_size_bits = ffs(vol->cluster_size) - 1;
3753
ntfs_log_debug("cluster size = %u bytes\n",
3754
(unsigned int)vol->cluster_size);
3755
if (vol->cluster_size > 4096) {
3756
if (opts.enable_compression) {
3758
ntfs_log_error("Windows cannot use compression "
3759
"when the cluster size is "
3760
"larger than 4096 bytes.\n");
3763
opts.enable_compression = 0;
3765
ntfs_log_warning("Windows cannot use compression when the "
3766
"cluster size is larger than 4096 bytes. "
3767
"Compression has been disabled for this "
3770
vol->nr_clusters = volume_size / vol->cluster_size;
3772
* Check the cluster_size and num_sectors for consistency with
3773
* sector_size and num_sectors. And check both of these for consistency
3776
if ((vol->nr_clusters != ((opts.num_sectors * opts.sector_size) /
3777
vol->cluster_size) ||
3778
(volume_size / opts.sector_size) != opts.num_sectors ||
3779
(volume_size / vol->cluster_size) !=
3780
vol->nr_clusters)) {
3781
/* XXX is this code reachable? */
3782
ntfs_log_error("Illegal combination of volume/cluster/sector "
3783
"size and/or cluster/sector number.\n");
3786
ntfs_log_debug("number of clusters = %llu (0x%llx)\n",
3787
vol->nr_clusters, vol->nr_clusters);
3788
/* Number of clusters must fit within 32 bits (Win2k limitation). */
3789
if (vol->nr_clusters >> 32) {
3790
if (vol->cluster_size >= 65536) {
3791
ntfs_log_error("Device is too large to hold an NTFS "
3792
"volume (maximum size is 256TiB).\n");
3795
ntfs_log_error("Number of clusters exceeds 32 bits. Please "
3796
"try again with a larger\ncluster size or "
3797
"leave the cluster size unspecified and the "
3798
"smallest possible cluster size for the size "
3799
"of the device will be used.\n");
3802
page_size = mkntfs_get_page_size();
3804
* Set the mft record size. By default this is 1024 but it has to be
3805
* at least as big as a sector and not bigger than a page on the system
3806
* or the NTFS kernel driver will not be able to mount the volume.
3807
* TODO: The mft record size should be user specifiable just like the
3808
* "inode size" can be specified on other Linux/Unix file systems.
3810
vol->mft_record_size = 1024;
3811
if (vol->mft_record_size < (u32)opts.sector_size)
3812
vol->mft_record_size = opts.sector_size;
3813
if (vol->mft_record_size > (unsigned long)page_size)
3814
ntfs_log_warning("Mft record size (%u bytes) exceeds system "
3815
"page size (%li bytes). You will not be able "
3816
"to mount this volume using the NTFS kernel "
3817
"driver.\n", (unsigned)vol->mft_record_size,
3819
vol->mft_record_size_bits = ffs(vol->mft_record_size) - 1;
3820
ntfs_log_debug("mft record size = %u bytes\n",
3821
(unsigned)vol->mft_record_size);
3823
* Set the index record size. By default this is 4096 but it has to be
3824
* at least as big as a sector and not bigger than a page on the system
3825
* or the NTFS kernel driver will not be able to mount the volume.
3826
* FIXME: Should we make the index record size to be user specifiable?
3828
vol->indx_record_size = 4096;
3829
if (vol->indx_record_size < (u32)opts.sector_size)
3830
vol->indx_record_size = opts.sector_size;
3831
if (vol->indx_record_size > (unsigned long)page_size)
3832
ntfs_log_warning("Index record size (%u bytes) exceeds system "
3833
"page size (%li bytes). You will not be able "
3834
"to mount this volume using the NTFS kernel "
3835
"driver.\n", (unsigned)vol->indx_record_size,
3837
vol->indx_record_size_bits = ffs(vol->indx_record_size) - 1;
3838
ntfs_log_debug("index record size = %u bytes\n",
3839
(unsigned)vol->indx_record_size);
3841
ntfs_log_warning("To boot from a device, Windows needs the "
3842
"'partition start sector', the 'sectors per "
3843
"track' and the 'number of heads' to be "
3845
ntfs_log_warning("Windows will not be able to boot from this "
3852
* mkntfs_initialize_bitmaps -
3854
static BOOL mkntfs_initialize_bitmaps(void)
3857
int mft_bitmap_size;
3859
/* Determine lcn bitmap byte size and allocate it. */
3860
g_lcn_bitmap_byte_size = (g_vol->nr_clusters + 7) >> 3;
3861
/* Needs to be multiple of 8 bytes. */
3862
g_lcn_bitmap_byte_size = (g_lcn_bitmap_byte_size + 7) & ~7;
3863
i = (g_lcn_bitmap_byte_size + g_vol->cluster_size - 1) &
3864
~(g_vol->cluster_size - 1);
3865
ntfs_log_debug("g_lcn_bitmap_byte_size = %i, allocated = %llu\n",
3866
g_lcn_bitmap_byte_size, i);
3867
g_dynamic_buf_size = mkntfs_get_page_size();
3868
g_dynamic_buf = (u8*)ntfs_calloc(g_dynamic_buf_size);
3872
* $Bitmap can overlap the end of the volume. Any bits in this region
3873
* must be set. This region also encompasses the backup boot sector.
3875
if (!bitmap_allocate(g_vol->nr_clusters,
3876
((s64)g_lcn_bitmap_byte_size << 3) - g_vol->nr_clusters))
3879
* Mft size is 27 (NTFS 3.0+) mft records or one cluster, whichever is
3883
g_mft_size *= g_vol->mft_record_size;
3884
if (g_mft_size < (s32)g_vol->cluster_size)
3885
g_mft_size = g_vol->cluster_size;
3886
ntfs_log_debug("MFT size = %i (0x%x) bytes\n", g_mft_size, g_mft_size);
3887
/* Determine mft bitmap size and allocate it. */
3888
mft_bitmap_size = g_mft_size / g_vol->mft_record_size;
3889
/* Convert to bytes, at least one. */
3890
g_mft_bitmap_byte_size = (mft_bitmap_size + 7) >> 3;
3891
/* Mft bitmap is allocated in multiples of 8 bytes. */
3892
g_mft_bitmap_byte_size = (g_mft_bitmap_byte_size + 7) & ~7;
3893
ntfs_log_debug("mft_bitmap_size = %i, g_mft_bitmap_byte_size = %i\n",
3894
mft_bitmap_size, g_mft_bitmap_byte_size);
3895
g_mft_bitmap = ntfs_calloc(g_mft_bitmap_byte_size);
3898
/* Create runlist for mft bitmap. */
3899
g_rl_mft_bmp = ntfs_malloc(2 * sizeof(runlist));
3903
g_rl_mft_bmp[0].vcn = 0LL;
3904
/* Mft bitmap is right after $Boot's data. */
3905
i = (8192 + g_vol->cluster_size - 1) / g_vol->cluster_size;
3906
g_rl_mft_bmp[0].lcn = i;
3908
* Size is always one cluster, even though valid data size and
3909
* initialized data size are only 8 bytes.
3911
g_rl_mft_bmp[1].vcn = 1LL;
3912
g_rl_mft_bmp[0].length = 1LL;
3913
g_rl_mft_bmp[1].lcn = -1LL;
3914
g_rl_mft_bmp[1].length = 0LL;
3915
/* Allocate cluster for mft bitmap. */
3916
return (bitmap_allocate(i,1));
3920
* mkntfs_initialize_rl_mft -
3922
static BOOL mkntfs_initialize_rl_mft(void)
3927
/* If user didn't specify the mft lcn, determine it now. */
3930
* We start at the higher value out of 16kiB and just after the
3933
g_mft_lcn = g_rl_mft_bmp[0].lcn + g_rl_mft_bmp[0].length;
3934
if (g_mft_lcn * g_vol->cluster_size < 16 * 1024)
3935
g_mft_lcn = (16 * 1024 + g_vol->cluster_size - 1) /
3936
g_vol->cluster_size;
3938
ntfs_log_debug("$MFT logical cluster number = 0x%llx\n", g_mft_lcn);
3939
/* Determine MFT zone size. */
3940
g_mft_zone_end = g_vol->nr_clusters;
3941
switch (opts.mft_zone_multiplier) { /* % of volume size in clusters */
3943
g_mft_zone_end = g_mft_zone_end >> 1; /* 50% */
3946
g_mft_zone_end = g_mft_zone_end * 3 >> 3;/* 37.5% */
3949
g_mft_zone_end = g_mft_zone_end >> 2; /* 25% */
3953
g_mft_zone_end = g_mft_zone_end >> 3; /* 12.5% */
3956
ntfs_log_debug("MFT zone size = %lldkiB\n", g_mft_zone_end <<
3957
g_vol->cluster_size_bits >> 10 /* >> 10 == / 1024 */);
3959
* The mft zone begins with the mft data attribute, not at the beginning
3962
g_mft_zone_end += g_mft_lcn;
3963
/* Create runlist for mft. */
3964
g_rl_mft = ntfs_malloc(2 * sizeof(runlist));
3968
g_rl_mft[0].vcn = 0LL;
3969
g_rl_mft[0].lcn = g_mft_lcn;
3970
/* rounded up division by cluster size */
3971
j = (g_mft_size + g_vol->cluster_size - 1) / g_vol->cluster_size;
3972
g_rl_mft[1].vcn = j;
3973
g_rl_mft[0].length = j;
3974
g_rl_mft[1].lcn = -1LL;
3975
g_rl_mft[1].length = 0LL;
3976
/* Allocate clusters for mft. */
3977
bitmap_allocate(g_mft_lcn,j);
3978
/* Determine mftmirr_lcn (middle of volume). */
3979
g_mftmirr_lcn = (opts.num_sectors * opts.sector_size >> 1)
3980
/ g_vol->cluster_size;
3981
ntfs_log_debug("$MFTMirr logical cluster number = 0x%llx\n",
3983
/* Create runlist for mft mirror. */
3984
g_rl_mftmirr = ntfs_malloc(2 * sizeof(runlist));
3988
g_rl_mftmirr[0].vcn = 0LL;
3989
g_rl_mftmirr[0].lcn = g_mftmirr_lcn;
3991
* The mft mirror is either 4kb (the first four records) or one cluster
3992
* in size, which ever is bigger. In either case, it contains a
3993
* byte-for-byte identical copy of the beginning of the mft (i.e. either
3994
* the first four records (4kb) or the first cluster worth of records,
3995
* whichever is bigger).
3997
j = (4 * g_vol->mft_record_size + g_vol->cluster_size - 1) / g_vol->cluster_size;
3998
g_rl_mftmirr[1].vcn = j;
3999
g_rl_mftmirr[0].length = j;
4000
g_rl_mftmirr[1].lcn = -1LL;
4001
g_rl_mftmirr[1].length = 0LL;
4002
/* Allocate clusters for mft mirror. */
4003
done = bitmap_allocate(g_mftmirr_lcn,j);
4004
g_logfile_lcn = g_mftmirr_lcn + j;
4005
ntfs_log_debug("$LogFile logical cluster number = 0x%llx\n",
4011
* mkntfs_initialize_rl_logfile -
4013
static BOOL mkntfs_initialize_rl_logfile(void)
4018
/* Create runlist for log file. */
4019
g_rl_logfile = ntfs_malloc(2 * sizeof(runlist));
4024
volume_size = g_vol->nr_clusters << g_vol->cluster_size_bits;
4026
g_rl_logfile[0].vcn = 0LL;
4027
g_rl_logfile[0].lcn = g_logfile_lcn;
4029
* Determine logfile_size from volume_size (rounded up to a cluster),
4030
* making sure it does not overflow the end of the volume.
4032
if (volume_size < 2048LL * 1024) /* < 2MiB */
4033
g_logfile_size = 256LL * 1024; /* -> 256kiB */
4034
else if (volume_size < 4000000LL) /* < 4MB */
4035
g_logfile_size = 512LL * 1024; /* -> 512kiB */
4036
else if (volume_size <= 200LL * 1024 * 1024) /* < 200MiB */
4037
g_logfile_size = 2048LL * 1024; /* -> 2MiB */
4040
* FIXME: The $LogFile size is 64 MiB upwards from 12GiB but
4041
* the "200" divider below apparently approximates "100" or
4042
* some other value as the volume size decreases. For example:
4043
* Volume size LogFile size Ratio
4044
* 8799808 46048 191.100
4045
* 8603248 45072 190.877
4046
* 7341704 38768 189.375
4047
* 6144828 32784 187.433
4048
* 4192932 23024 182.111
4050
if (volume_size >= 12LL << 30) /* > 12GiB */
4051
g_logfile_size = 64 << 20; /* -> 64MiB */
4053
g_logfile_size = (volume_size / 200) &
4054
~(g_vol->cluster_size - 1);
4056
j = g_logfile_size / g_vol->cluster_size;
4057
while (g_rl_logfile[0].lcn + j >= g_vol->nr_clusters) {
4059
* $Logfile would overflow volume. Need to make it smaller than
4060
* the standard size. It's ok as we are creating a non-standard
4061
* volume anyway if it is that small.
4063
g_logfile_size >>= 1;
4064
j = g_logfile_size / g_vol->cluster_size;
4066
g_logfile_size = (g_logfile_size + g_vol->cluster_size - 1) &
4067
~(g_vol->cluster_size - 1);
4068
ntfs_log_debug("$LogFile (journal) size = %ikiB\n",
4069
g_logfile_size / 1024);
4071
* FIXME: The 256kiB limit is arbitrary. Should find out what the real
4072
* minimum requirement for Windows is so it doesn't blue screen.
4074
if (g_logfile_size < 256 << 10) {
4075
ntfs_log_error("$LogFile would be created with invalid size. "
4076
"This is not allowed as it would cause Windows "
4077
"to blue screen and during boot.\n");
4080
g_rl_logfile[1].vcn = j;
4081
g_rl_logfile[0].length = j;
4082
g_rl_logfile[1].lcn = -1LL;
4083
g_rl_logfile[1].length = 0LL;
4084
/* Allocate clusters for log file. */
4085
return (bitmap_allocate(g_logfile_lcn,j));
4089
* mkntfs_initialize_rl_boot -
4091
static BOOL mkntfs_initialize_rl_boot(void)
4094
/* Create runlist for $Boot. */
4095
g_rl_boot = ntfs_malloc(2 * sizeof(runlist));
4099
g_rl_boot[0].vcn = 0LL;
4100
g_rl_boot[0].lcn = 0LL;
4102
* $Boot is always 8192 (0x2000) bytes or 1 cluster, whichever is
4105
j = (8192 + g_vol->cluster_size - 1) / g_vol->cluster_size;
4106
g_rl_boot[1].vcn = j;
4107
g_rl_boot[0].length = j;
4108
g_rl_boot[1].lcn = -1LL;
4109
g_rl_boot[1].length = 0LL;
4110
/* Allocate clusters for $Boot. */
4111
return (bitmap_allocate(0,j));
4115
* mkntfs_initialize_rl_bad -
4117
static BOOL mkntfs_initialize_rl_bad(void)
4119
/* Create runlist for $BadClus, $DATA named stream $Bad. */
4120
g_rl_bad = ntfs_malloc(2 * sizeof(runlist));
4124
g_rl_bad[0].vcn = 0LL;
4125
g_rl_bad[0].lcn = -1LL;
4127
* $BadClus named stream $Bad contains the whole volume as a single
4128
* sparse runlist entry.
4130
g_rl_bad[1].vcn = g_vol->nr_clusters;
4131
g_rl_bad[0].length = g_vol->nr_clusters;
4132
g_rl_bad[1].lcn = -1LL;
4133
g_rl_bad[1].length = 0LL;
4135
/* TODO: Mark bad blocks as such. */
4140
* mkntfs_fill_device_with_zeroes -
4142
static BOOL mkntfs_fill_device_with_zeroes(void)
4145
* If not quick format, fill the device with 0s.
4146
* FIXME: Except bad blocks! (AIA)
4150
unsigned long long position;
4151
float progress_inc = (float)g_vol->nr_clusters / 100;
4154
volume_size = g_vol->nr_clusters << g_vol->cluster_size_bits;
4156
ntfs_log_progress("Initializing device with zeroes: 0%%");
4157
for (position = 0; position < (unsigned long long)g_vol->nr_clusters;
4159
if (!(position % (int)(progress_inc+1))) {
4160
ntfs_log_progress("\b\b\b\b%3.0f%%", position /
4163
bw = mkntfs_write(g_vol->dev, g_buf, g_vol->cluster_size);
4164
if (bw != (ssize_t)g_vol->cluster_size) {
4165
if (bw != -1 || errno != EIO) {
4166
ntfs_log_error("This should not happen.\n");
4170
ntfs_log_error("Error: Cluster zero is bad. "
4171
"Cannot create NTFS file "
4175
/* Add the baddie to our bad blocks list. */
4176
if (!append_to_bad_blocks(position))
4178
ntfs_log_quiet("\nFound bad cluster (%lld). Adding to "
4179
"list of bad blocks.\nInitializing "
4180
"device with zeroes: %3.0f%%", position,
4181
position / progress_inc);
4182
/* Seek to next cluster. */
4183
g_vol->dev->d_ops->seek(g_vol->dev,
4184
((off_t)position + 1) *
4185
g_vol->cluster_size, SEEK_SET);
4188
ntfs_log_progress("\b\b\b\b100%%");
4189
position = (volume_size & (g_vol->cluster_size - 1)) /
4191
for (i = 0; (unsigned long)i < position; i++) {
4192
bw = mkntfs_write(g_vol->dev, g_buf, opts.sector_size);
4193
if (bw != opts.sector_size) {
4194
if (bw != -1 || errno != EIO) {
4195
ntfs_log_error("This should not happen.\n");
4197
} else if (i + 1ull == position) {
4198
ntfs_log_error("Error: Bad cluster found in "
4199
"location reserved for system "
4203
/* Seek to next sector. */
4204
g_vol->dev->d_ops->seek(g_vol->dev,
4205
opts.sector_size, SEEK_CUR);
4208
ntfs_log_progress(" - Done.\n");
4213
* mkntfs_sync_index_record
4215
* (ERSO) made a function out of this, but the reason for doing that
4216
* disappeared during coding....
4218
static BOOL mkntfs_sync_index_record(INDEX_ALLOCATION* idx, MFT_RECORD* m,
4219
ntfschar* name, u32 name_len)
4222
ntfs_attr_search_ctx *ctx;
4225
runlist *rl_index = NULL;
4227
i = 5 * sizeof(ntfschar);
4228
ctx = ntfs_attr_get_search_ctx(NULL, m);
4230
ntfs_log_perror("Failed to allocate attribute search context");
4233
/* FIXME: This should be IGNORE_CASE! */
4234
if (mkntfs_attr_lookup(AT_INDEX_ALLOCATION, name, name_len,
4235
CASE_SENSITIVE, 0, NULL, 0, ctx)) {
4236
ntfs_attr_put_search_ctx(ctx);
4237
ntfs_log_error("BUG: $INDEX_ALLOCATION attribute not found.\n");
4241
rl_index = ntfs_mapping_pairs_decompress(g_vol, a, NULL);
4243
ntfs_attr_put_search_ctx(ctx);
4244
ntfs_log_error("Failed to decompress runlist of $INDEX_ALLOCATION "
4248
if (sle64_to_cpu(a->initialized_size) < i) {
4249
ntfs_attr_put_search_ctx(ctx);
4251
ntfs_log_error("BUG: $INDEX_ALLOCATION attribute too short.\n");
4254
ntfs_attr_put_search_ctx(ctx);
4255
i = sizeof(INDEX_BLOCK) - sizeof(INDEX_HEADER) +
4256
le32_to_cpu(idx->index.allocated_size);
4257
err = ntfs_mst_pre_write_fixup((NTFS_RECORD*)idx, i);
4260
ntfs_log_error("ntfs_mst_pre_write_fixup() failed while "
4261
"syncing index block.\n");
4264
lw = ntfs_rlwrite(g_vol->dev, rl_index, (u8*)idx, i, NULL,
4268
ntfs_log_error("Error writing $INDEX_ALLOCATION.\n");
4271
/* No more changes to @idx below here so no need for fixup: */
4272
/* ntfs_mst_post_write_fixup((NTFS_RECORD*)idx); */
4277
* create_file_volume -
4279
static BOOL create_file_volume(MFT_RECORD *m, leMFT_REF root_ref,
4280
VOLUME_FLAGS fl, const GUID *volume_guid)
4285
ntfs_log_verbose("Creating $Volume (mft record 3)\n");
4286
m = (MFT_RECORD*)(g_buf + 3 * g_vol->mft_record_size);
4287
err = create_hardlink(g_index_block, root_ref, m,
4288
MK_LE_MREF(FILE_Volume, FILE_Volume), 0LL, 0LL,
4289
FILE_ATTR_HIDDEN | FILE_ATTR_SYSTEM, 0, 0,
4290
"$Volume", FILE_NAME_WIN32_AND_DOS);
4292
init_system_file_sd(FILE_Volume, &sd, &i);
4293
err = add_attr_sd(m, sd, i);
4296
err = add_attr_data(m, NULL, 0, CASE_SENSITIVE,
4297
const_cpu_to_le16(0), NULL, 0);
4299
err = add_attr_vol_name(m, g_vol->vol_name, g_vol->vol_name ?
4300
strlen(g_vol->vol_name) : 0);
4302
if (fl & VOLUME_IS_DIRTY)
4303
ntfs_log_quiet("Setting the volume dirty so check "
4304
"disk runs on next reboot into "
4306
err = add_attr_vol_info(m, fl, g_vol->major_ver,
4309
if (!err && opts.with_uuid)
4310
err = add_attr_object_id(m, volume_guid);
4312
ntfs_log_error("Couldn't create $Volume: %s\n",
4320
* create_backup_boot_sector
4322
* Return 0 on success or -1 if it couldn't be created.
4324
static int create_backup_boot_sector(u8 *buff)
4330
ntfs_log_verbose("Creating backup boot sector.\n");
4332
* Write the first max(512, opts.sector_size) bytes from buf to the
4333
* last sector, but limit that to 8192 bytes of written data since that
4334
* is how big $Boot is (and how big our buffer is)..
4337
if (size < opts.sector_size)
4338
size = opts.sector_size;
4339
if (g_vol->dev->d_ops->seek(g_vol->dev, (opts.num_sectors + 1) *
4340
opts.sector_size - size, SEEK_SET) == (off_t)-1) {
4341
ntfs_log_perror("Seek failed");
4346
bw = mkntfs_write(g_vol->dev, buff, size);
4353
s = "unknown error";
4354
/* At least some 2.4 kernels return EIO instead of ENOSPC. */
4355
if (bw != -1LL || (bw == -1LL && e != ENOSPC && e != EIO)) {
4356
ntfs_log_critical("Couldn't write backup boot sector: %s\n", s);
4360
ntfs_log_error("Couldn't write backup boot sector. This is due to a "
4361
"limitation in the\nLinux kernel. This is not a major "
4362
"problem as Windows check disk will create the\n"
4363
"backup boot sector when it is run on your next boot "
4369
* mkntfs_create_root_structures -
4371
static BOOL mkntfs_create_root_structures(void)
4373
NTFS_BOOT_SECTOR *bs;
4376
leMFT_REF extend_ref;
4381
FILE_ATTR_FLAGS extend_flags;
4382
VOLUME_FLAGS volume_flags = const_cpu_to_le16(0);
4384
int buf_sds_first_size;
4388
ntfs_log_quiet("Creating NTFS volume structures.\n");
4391
* Setup an empty mft record. Note, we can just give 0 as the mft
4392
* reference as we are creating an NTFS 1.2 volume for which the mft
4393
* reference is ignored by ntfs_mft_record_layout().
4395
* Copy the mft record onto all 16 records in the buffer and setup the
4396
* sequence numbers of each system file to equal the mft record number
4397
* of that file (only for $MFT is the sequence number 1 rather than 0).
4399
for (i = 0; i < nr_sysfiles; i++) {
4400
if (ntfs_mft_record_layout(g_vol, 0, m = (MFT_RECORD *)(g_buf +
4401
i * g_vol->mft_record_size))) {
4402
ntfs_log_error("Failed to layout system mft records."
4406
if (i == 0 || i > 23)
4407
m->sequence_number = cpu_to_le16(1);
4409
m->sequence_number = cpu_to_le16(i);
4412
* If only one cluster contains all system files then
4413
* fill the rest of it with empty, formatted records.
4415
if (nr_sysfiles * (s32)g_vol->mft_record_size < g_mft_size) {
4416
for (i = nr_sysfiles;
4417
i * (s32)g_vol->mft_record_size < g_mft_size; i++) {
4418
m = (MFT_RECORD *)(g_buf + i * g_vol->mft_record_size);
4419
if (ntfs_mft_record_layout(g_vol, 0, m)) {
4420
ntfs_log_error("Failed to layout mft record."
4424
m->flags = cpu_to_le16(0);
4425
m->sequence_number = cpu_to_le16(i);
4429
* Create the 16 system files, adding the system information attribute
4430
* to each as well as marking them in use in the mft bitmap.
4432
for (i = 0; i < nr_sysfiles; i++) {
4435
m = (MFT_RECORD*)(g_buf + i * g_vol->mft_record_size);
4436
if (i < 16 || i > 23) {
4437
m->mft_record_number = cpu_to_le32(i);
4438
m->flags |= MFT_RECORD_IN_USE;
4439
ntfs_bit_set(g_mft_bitmap, 0LL + i, 1);
4441
file_attrs = FILE_ATTR_HIDDEN | FILE_ATTR_SYSTEM;
4442
if (i == FILE_root) {
4443
file_attrs |= FILE_ATTR_ARCHIVE;
4444
if (opts.disable_indexing)
4445
file_attrs |= FILE_ATTR_NOT_CONTENT_INDEXED;
4446
if (opts.enable_compression)
4447
file_attrs |= FILE_ATTR_COMPRESSED;
4449
/* setting specific security_id flag and */
4450
/* file permissions for ntfs 3.x */
4451
if (i == 0 || i == 1 || i == 2 || i == 6 || i == 8 ||
4453
add_attr_std_info(m, file_attrs,
4454
cpu_to_le32(0x0100));
4455
} else if (i == 9) {
4456
file_attrs |= FILE_ATTR_VIEW_INDEX_PRESENT;
4457
add_attr_std_info(m, file_attrs,
4458
cpu_to_le32(0x0101));
4459
} else if (i == 11) {
4460
add_attr_std_info(m, file_attrs,
4461
cpu_to_le32(0x0101));
4462
} else if (i == 24 || i == 25 || i == 26) {
4463
file_attrs |= FILE_ATTR_ARCHIVE;
4464
file_attrs |= FILE_ATTR_VIEW_INDEX_PRESENT;
4465
add_attr_std_info(m, file_attrs,
4466
cpu_to_le32(0x0101));
4468
add_attr_std_info(m, file_attrs,
4472
/* The root directory mft reference. */
4473
root_ref = MK_LE_MREF(FILE_root, FILE_root);
4474
extend_ref = MK_LE_MREF(11,11);
4475
ntfs_log_verbose("Creating root directory (mft record 5)\n");
4476
m = (MFT_RECORD*)(g_buf + 5 * g_vol->mft_record_size);
4477
m->flags |= MFT_RECORD_IS_DIRECTORY;
4478
m->link_count = cpu_to_le16(le16_to_cpu(m->link_count) + 1);
4479
err = add_attr_file_name(m, root_ref, 0LL, 0LL,
4480
FILE_ATTR_HIDDEN | FILE_ATTR_SYSTEM |
4481
FILE_ATTR_I30_INDEX_PRESENT, 0, 0, ".",
4482
FILE_NAME_WIN32_AND_DOS);
4484
init_root_sd(&sd, &i);
4485
err = add_attr_sd(m, sd, i);
4487
/* FIXME: This should be IGNORE_CASE */
4489
err = add_attr_index_root(m, "$I30", 4, CASE_SENSITIVE,
4490
AT_FILE_NAME, COLLATION_FILE_NAME,
4491
g_vol->indx_record_size);
4492
/* FIXME: This should be IGNORE_CASE */
4494
err = upgrade_to_large_index(m, "$I30", 4, CASE_SENSITIVE,
4497
ntfs_attr_search_ctx *ctx;
4499
ctx = ntfs_attr_get_search_ctx(NULL, m);
4501
ntfs_log_perror("Failed to allocate attribute search "
4505
/* There is exactly one file name so this is ok. */
4506
if (mkntfs_attr_lookup(AT_FILE_NAME, AT_UNNAMED, 0,
4507
CASE_SENSITIVE, 0, NULL, 0, ctx)) {
4508
ntfs_attr_put_search_ctx(ctx);
4509
ntfs_log_error("BUG: $FILE_NAME attribute not found."
4514
err = insert_file_link_in_dir_index(g_index_block, root_ref,
4515
(FILE_NAME_ATTR*)((char*)a +
4516
le16_to_cpu(a->value_offset)),
4517
le32_to_cpu(a->value_length));
4518
ntfs_attr_put_search_ctx(ctx);
4521
ntfs_log_error("Couldn't create root directory: %s\n",
4525
/* Add all other attributes, on a per-file basis for clarity. */
4526
ntfs_log_verbose("Creating $MFT (mft record 0)\n");
4527
m = (MFT_RECORD*)g_buf;
4528
err = add_attr_data_positioned(m, NULL, 0, CASE_SENSITIVE,
4529
const_cpu_to_le16(0), g_rl_mft, g_buf, g_mft_size);
4531
err = create_hardlink(g_index_block, root_ref, m,
4532
MK_LE_MREF(FILE_MFT, 1),
4534
| (g_vol->cluster_size - 1)) + 1,
4535
g_mft_size, FILE_ATTR_HIDDEN |
4536
FILE_ATTR_SYSTEM, 0, 0, "$MFT",
4537
FILE_NAME_WIN32_AND_DOS);
4538
/* mft_bitmap is not modified in mkntfs; no need to sync it later. */
4540
err = add_attr_bitmap_positioned(m, NULL, 0, CASE_SENSITIVE,
4542
g_mft_bitmap, g_mft_bitmap_byte_size);
4544
ntfs_log_error("Couldn't create $MFT: %s\n", strerror(-err));
4547
ntfs_log_verbose("Creating $MFTMirr (mft record 1)\n");
4548
m = (MFT_RECORD*)(g_buf + 1 * g_vol->mft_record_size);
4549
err = add_attr_data_positioned(m, NULL, 0, CASE_SENSITIVE,
4550
const_cpu_to_le16(0), g_rl_mftmirr, g_buf,
4551
g_rl_mftmirr[0].length * g_vol->cluster_size);
4553
err = create_hardlink(g_index_block, root_ref, m,
4554
MK_LE_MREF(FILE_MFTMirr, FILE_MFTMirr),
4555
g_rl_mftmirr[0].length * g_vol->cluster_size,
4556
g_rl_mftmirr[0].length * g_vol->cluster_size,
4557
FILE_ATTR_HIDDEN | FILE_ATTR_SYSTEM, 0, 0,
4558
"$MFTMirr", FILE_NAME_WIN32_AND_DOS);
4560
ntfs_log_error("Couldn't create $MFTMirr: %s\n",
4564
ntfs_log_verbose("Creating $LogFile (mft record 2)\n");
4565
m = (MFT_RECORD*)(g_buf + 2 * g_vol->mft_record_size);
4566
err = add_attr_data_positioned(m, NULL, 0, CASE_SENSITIVE,
4567
const_cpu_to_le16(0), g_rl_logfile,
4568
(const u8*)NULL, g_logfile_size);
4570
err = create_hardlink(g_index_block, root_ref, m,
4571
MK_LE_MREF(FILE_LogFile, FILE_LogFile),
4572
g_logfile_size, g_logfile_size,
4573
FILE_ATTR_HIDDEN | FILE_ATTR_SYSTEM, 0, 0,
4574
"$LogFile", FILE_NAME_WIN32_AND_DOS);
4576
ntfs_log_error("Couldn't create $LogFile: %s\n",
4580
ntfs_log_verbose("Creating $AttrDef (mft record 4)\n");
4581
m = (MFT_RECORD*)(g_buf + 4 * g_vol->mft_record_size);
4582
err = add_attr_data(m, NULL, 0, CASE_SENSITIVE, const_cpu_to_le16(0),
4583
(u8*)g_vol->attrdef, g_vol->attrdef_len);
4585
err = create_hardlink(g_index_block, root_ref, m,
4586
MK_LE_MREF(FILE_AttrDef, FILE_AttrDef),
4587
(g_vol->attrdef_len + g_vol->cluster_size - 1) &
4588
~(g_vol->cluster_size - 1), g_vol->attrdef_len,
4589
FILE_ATTR_HIDDEN | FILE_ATTR_SYSTEM, 0, 0,
4590
"$AttrDef", FILE_NAME_WIN32_AND_DOS);
4592
init_system_file_sd(FILE_AttrDef, &sd, &i);
4593
err = add_attr_sd(m, sd, i);
4596
ntfs_log_error("Couldn't create $AttrDef: %s\n",
4600
ntfs_log_verbose("Creating $Bitmap (mft record 6)\n");
4601
m = (MFT_RECORD*)(g_buf + 6 * g_vol->mft_record_size);
4602
/* the data attribute of $Bitmap must be non-resident or otherwise */
4603
/* windows 2003 will regard the volume as corrupt (ERSO) */
4605
err = insert_non_resident_attr_in_mft_record(m,
4606
AT_DATA, NULL, 0, CASE_SENSITIVE,
4607
const_cpu_to_le16(0), (const u8*)NULL,
4608
g_lcn_bitmap_byte_size, WRITE_BITMAP);
4612
err = create_hardlink(g_index_block, root_ref, m,
4613
MK_LE_MREF(FILE_Bitmap, FILE_Bitmap),
4614
(g_lcn_bitmap_byte_size + g_vol->cluster_size -
4615
1) & ~(g_vol->cluster_size - 1),
4616
g_lcn_bitmap_byte_size,
4617
FILE_ATTR_HIDDEN | FILE_ATTR_SYSTEM, 0, 0,
4618
"$Bitmap", FILE_NAME_WIN32_AND_DOS);
4620
ntfs_log_error("Couldn't create $Bitmap: %s\n", strerror(-err));
4623
ntfs_log_verbose("Creating $Boot (mft record 7)\n");
4624
m = (MFT_RECORD*)(g_buf + 7 * g_vol->mft_record_size);
4625
bs = ntfs_calloc(8192);
4628
memcpy(bs, boot_array, sizeof(boot_array));
4630
* Create the boot sector in bs. Note, that bs is already zeroed
4631
* in the boot sector section and that it has the NTFS OEM id/magic
4632
* already inserted, so no need to worry about these things.
4634
bs->bpb.bytes_per_sector = cpu_to_le16(opts.sector_size);
4635
bs->bpb.sectors_per_cluster = (u8)(g_vol->cluster_size /
4637
bs->bpb.media_type = 0xf8; /* hard disk */
4638
bs->bpb.sectors_per_track = cpu_to_le16(opts.sectors_per_track);
4639
ntfs_log_debug("sectors per track = %ld (0x%lx)\n",
4640
opts.sectors_per_track, opts.sectors_per_track);
4641
bs->bpb.heads = cpu_to_le16(opts.heads);
4642
ntfs_log_debug("heads = %ld (0x%lx)\n", opts.heads, opts.heads);
4643
bs->bpb.hidden_sectors = cpu_to_le32(opts.part_start_sect);
4644
ntfs_log_debug("hidden sectors = %llu (0x%llx)\n", opts.part_start_sect,
4645
opts.part_start_sect);
4646
bs->physical_drive = 0x80; /* boot from hard disk */
4647
bs->extended_boot_signature = 0x80; /* everybody sets this, so we do */
4648
bs->number_of_sectors = cpu_to_sle64(opts.num_sectors);
4649
bs->mft_lcn = cpu_to_sle64(g_mft_lcn);
4650
bs->mftmirr_lcn = cpu_to_sle64(g_mftmirr_lcn);
4651
if (g_vol->mft_record_size >= g_vol->cluster_size) {
4652
bs->clusters_per_mft_record = g_vol->mft_record_size /
4653
g_vol->cluster_size;
4655
bs->clusters_per_mft_record = -(ffs(g_vol->mft_record_size) -
4657
if ((u32)(1 << -bs->clusters_per_mft_record) !=
4658
g_vol->mft_record_size) {
4660
ntfs_log_error("BUG: calculated clusters_per_mft_record"
4661
" is wrong (= 0x%x)\n",
4662
bs->clusters_per_mft_record);
4666
ntfs_log_debug("clusters per mft record = %i (0x%x)\n",
4667
bs->clusters_per_mft_record,
4668
bs->clusters_per_mft_record);
4669
if (g_vol->indx_record_size >= g_vol->cluster_size) {
4670
bs->clusters_per_index_record = g_vol->indx_record_size /
4671
g_vol->cluster_size;
4673
bs->clusters_per_index_record = -g_vol->indx_record_size_bits;
4674
if ((1 << -bs->clusters_per_index_record) !=
4675
(s32)g_vol->indx_record_size) {
4677
ntfs_log_error("BUG: calculated "
4678
"clusters_per_index_record is wrong "
4680
bs->clusters_per_index_record);
4684
ntfs_log_debug("clusters per index block = %i (0x%x)\n",
4685
bs->clusters_per_index_record,
4686
bs->clusters_per_index_record);
4687
/* Generate a 64-bit random number for the serial number. */
4688
bs->volume_serial_number = cpu_to_le64(((u64)random() << 32) |
4689
((u64)random() & 0xffffffff));
4691
* Leave zero for now as NT4 leaves it zero, too. If want it later, see
4692
* ../libntfs/bootsect.c for how to calculate it.
4694
bs->checksum = cpu_to_le32(0);
4695
/* Make sure the bootsector is ok. */
4696
if (!ntfs_boot_sector_is_ntfs(bs)) {
4698
ntfs_log_error("FATAL: Generated boot sector is invalid!\n");
4701
err = add_attr_data_positioned(m, NULL, 0, CASE_SENSITIVE,
4702
const_cpu_to_le16(0), g_rl_boot, (u8*)bs, 8192);
4704
err = create_hardlink(g_index_block, root_ref, m,
4705
MK_LE_MREF(FILE_Boot, FILE_Boot),
4706
(8192 + g_vol->cluster_size - 1) &
4707
~(g_vol->cluster_size - 1), 8192,
4708
FILE_ATTR_HIDDEN | FILE_ATTR_SYSTEM, 0, 0,
4709
"$Boot", FILE_NAME_WIN32_AND_DOS);
4711
init_system_file_sd(FILE_Boot, &sd, &i);
4712
err = add_attr_sd(m, sd, i);
4716
ntfs_log_error("Couldn't create $Boot: %s\n", strerror(-err));
4719
if (create_backup_boot_sector((u8*)bs)) {
4721
* Pre-2.6 kernels couldn't access the last sector if it was
4722
* odd and we failed to set the device block size to the sector
4723
* size, hence we schedule chkdsk to create it.
4725
volume_flags |= VOLUME_IS_DIRTY;
4729
* We cheat a little here and if the user has requested all times to be
4730
* set to zero then we set the GUID to zero as well. This options is
4731
* only used for development purposes so that should be fine.
4733
if (!opts.use_epoch_time) {
4734
/* Generate a GUID for the volume. */
4736
uuid_generate((void*)&vol_guid);
4738
ntfs_generate_guid(&vol_guid);
4741
memset(&vol_guid, 0, sizeof(vol_guid));
4742
if (!create_file_volume(m, root_ref, volume_flags, &vol_guid))
4744
ntfs_log_verbose("Creating $BadClus (mft record 8)\n");
4745
m = (MFT_RECORD*)(g_buf + 8 * g_vol->mft_record_size);
4746
/* FIXME: This should be IGNORE_CASE */
4747
/* Create a sparse named stream of size equal to the volume size. */
4748
err = add_attr_data_positioned(m, "$Bad", 4, CASE_SENSITIVE,
4749
const_cpu_to_le16(0), g_rl_bad, NULL,
4750
g_vol->nr_clusters * g_vol->cluster_size);
4752
err = add_attr_data(m, NULL, 0, CASE_SENSITIVE,
4753
const_cpu_to_le16(0), NULL, 0);
4756
err = create_hardlink(g_index_block, root_ref, m,
4757
MK_LE_MREF(FILE_BadClus, FILE_BadClus),
4758
0LL, 0LL, FILE_ATTR_HIDDEN | FILE_ATTR_SYSTEM,
4759
0, 0, "$BadClus", FILE_NAME_WIN32_AND_DOS);
4762
ntfs_log_error("Couldn't create $BadClus: %s\n",
4766
/* create $Secure (NTFS 3.0+) */
4767
ntfs_log_verbose("Creating $Secure (mft record 9)\n");
4768
m = (MFT_RECORD*)(g_buf + 9 * g_vol->mft_record_size);
4769
m->flags |= MFT_RECORD_IS_VIEW_INDEX;
4771
err = create_hardlink(g_index_block, root_ref, m,
4772
MK_LE_MREF(9, 9), 0LL, 0LL,
4773
FILE_ATTR_HIDDEN | FILE_ATTR_SYSTEM |
4774
FILE_ATTR_VIEW_INDEX_PRESENT, 0, 0,
4775
"$Secure", FILE_NAME_WIN32_AND_DOS);
4777
buf_sds_first_size = 0;
4781
buf_sds_first_size = 0xfc;
4782
buf_sds_size = 0x40000 + buf_sds_first_size;
4783
buf_sds = ntfs_calloc(buf_sds_size);
4786
init_secure_sds(buf_sds);
4787
memcpy(buf_sds + 0x40000, buf_sds, buf_sds_first_size);
4788
err = add_attr_data(m, "$SDS", 4, CASE_SENSITIVE,
4789
const_cpu_to_le16(0), (u8*)buf_sds,
4792
/* FIXME: This should be IGNORE_CASE */
4794
err = add_attr_index_root(m, "$SDH", 4, CASE_SENSITIVE,
4795
AT_UNUSED, COLLATION_NTOFS_SECURITY_HASH,
4796
g_vol->indx_record_size);
4797
/* FIXME: This should be IGNORE_CASE */
4799
err = add_attr_index_root(m, "$SII", 4, CASE_SENSITIVE,
4800
AT_UNUSED, COLLATION_NTOFS_ULONG,
4801
g_vol->indx_record_size);
4803
err = initialize_secure(buf_sds, buf_sds_first_size, m);
4806
ntfs_log_error("Couldn't create $Secure: %s\n",
4810
ntfs_log_verbose("Creating $UpCase (mft record 0xa)\n");
4811
m = (MFT_RECORD*)(g_buf + 0xa * g_vol->mft_record_size);
4812
err = add_attr_data(m, NULL, 0, CASE_SENSITIVE, const_cpu_to_le16(0),
4813
(u8*)g_vol->upcase, g_vol->upcase_len << 1);
4815
* The $Info only exists since Windows 8, but it apparently
4816
* does not disturb chkdsk from earlier versions.
4819
err = add_attr_data(m, "$Info", 5, CASE_SENSITIVE,
4820
const_cpu_to_le16(0),
4821
(u8*)g_upcaseinfo, sizeof(struct UPCASEINFO));
4823
err = create_hardlink(g_index_block, root_ref, m,
4824
MK_LE_MREF(FILE_UpCase, FILE_UpCase),
4825
((g_vol->upcase_len << 1) +
4826
g_vol->cluster_size - 1) &
4827
~(g_vol->cluster_size - 1),
4828
g_vol->upcase_len << 1,
4829
FILE_ATTR_HIDDEN | FILE_ATTR_SYSTEM, 0, 0,
4830
"$UpCase", FILE_NAME_WIN32_AND_DOS);
4832
ntfs_log_error("Couldn't create $UpCase: %s\n", strerror(-err));
4835
ntfs_log_verbose("Creating $Extend (mft record 11)\n");
4837
* $Extend index must be resident. Otherwise, w2k3 will regard the
4838
* volume as corrupt. (ERSO)
4840
m = (MFT_RECORD*)(g_buf + 11 * g_vol->mft_record_size);
4841
m->flags |= MFT_RECORD_IS_DIRECTORY;
4843
err = create_hardlink(g_index_block, root_ref, m,
4844
MK_LE_MREF(11, 11), 0LL, 0LL,
4845
FILE_ATTR_HIDDEN | FILE_ATTR_SYSTEM |
4846
FILE_ATTR_I30_INDEX_PRESENT, 0, 0,
4847
"$Extend", FILE_NAME_WIN32_AND_DOS);
4848
/* FIXME: This should be IGNORE_CASE */
4850
err = add_attr_index_root(m, "$I30", 4, CASE_SENSITIVE,
4851
AT_FILE_NAME, COLLATION_FILE_NAME,
4852
g_vol->indx_record_size);
4854
ntfs_log_error("Couldn't create $Extend: %s\n",
4858
/* NTFS reserved system files (mft records 0xc-0xf) */
4859
for (i = 0xc; i < 0x10; i++) {
4860
ntfs_log_verbose("Creating system file (mft record 0x%x)\n", i);
4861
m = (MFT_RECORD*)(g_buf + i * g_vol->mft_record_size);
4862
err = add_attr_data(m, NULL, 0, CASE_SENSITIVE,
4863
const_cpu_to_le16(0), NULL, 0);
4865
init_system_file_sd(i, &sd, &j);
4866
err = add_attr_sd(m, sd, j);
4869
ntfs_log_error("Couldn't create system file %i (0x%x): "
4870
"%s\n", i, i, strerror(-err));
4874
/* create systemfiles for ntfs volumes (3.1) */
4875
/* starting with file 24 (ignoring file 16-23) */
4876
extend_flags = FILE_ATTR_HIDDEN | FILE_ATTR_SYSTEM |
4877
FILE_ATTR_ARCHIVE | FILE_ATTR_VIEW_INDEX_PRESENT;
4878
ntfs_log_verbose("Creating $Quota (mft record 24)\n");
4879
m = (MFT_RECORD*)(g_buf + 24 * g_vol->mft_record_size);
4880
m->flags |= MFT_RECORD_IS_4;
4881
m->flags |= MFT_RECORD_IS_VIEW_INDEX;
4883
err = create_hardlink_res((MFT_RECORD*)(g_buf +
4884
11 * g_vol->mft_record_size), extend_ref, m,
4885
MK_LE_MREF(24, 1), 0LL, 0LL, extend_flags,
4886
0, 0, "$Quota", FILE_NAME_WIN32_AND_DOS);
4887
/* FIXME: This should be IGNORE_CASE */
4889
err = add_attr_index_root(m, "$Q", 2, CASE_SENSITIVE, AT_UNUSED,
4890
COLLATION_NTOFS_ULONG, g_vol->indx_record_size);
4891
/* FIXME: This should be IGNORE_CASE */
4893
err = add_attr_index_root(m, "$O", 2, CASE_SENSITIVE, AT_UNUSED,
4894
COLLATION_NTOFS_SID, g_vol->indx_record_size);
4896
err = initialize_quota(m);
4898
ntfs_log_error("Couldn't create $Quota: %s\n", strerror(-err));
4901
ntfs_log_verbose("Creating $ObjId (mft record 25)\n");
4902
m = (MFT_RECORD*)(g_buf + 25 * g_vol->mft_record_size);
4903
m->flags |= MFT_RECORD_IS_4;
4904
m->flags |= MFT_RECORD_IS_VIEW_INDEX;
4906
err = create_hardlink_res((MFT_RECORD*)(g_buf +
4907
11 * g_vol->mft_record_size), extend_ref,
4908
m, MK_LE_MREF(25, 1), 0LL, 0LL,
4909
extend_flags, 0, 0, "$ObjId",
4910
FILE_NAME_WIN32_AND_DOS);
4912
/* FIXME: This should be IGNORE_CASE */
4914
err = add_attr_index_root(m, "$O", 2, CASE_SENSITIVE, AT_UNUSED,
4915
COLLATION_NTOFS_ULONGS,
4916
g_vol->indx_record_size);
4917
if (!err && opts.with_uuid)
4918
err = index_obj_id_insert(m, &vol_guid,
4919
MK_LE_MREF(FILE_Volume, FILE_Volume));
4921
ntfs_log_error("Couldn't create $ObjId: %s\n",
4925
ntfs_log_verbose("Creating $Reparse (mft record 26)\n");
4926
m = (MFT_RECORD*)(g_buf + 26 * g_vol->mft_record_size);
4927
m->flags |= MFT_RECORD_IS_4;
4928
m->flags |= MFT_RECORD_IS_VIEW_INDEX;
4930
err = create_hardlink_res((MFT_RECORD*)(g_buf +
4931
11 * g_vol->mft_record_size),
4932
extend_ref, m, MK_LE_MREF(26, 1),
4933
0LL, 0LL, extend_flags, 0, 0,
4934
"$Reparse", FILE_NAME_WIN32_AND_DOS);
4935
/* FIXME: This should be IGNORE_CASE */
4937
err = add_attr_index_root(m, "$R", 2, CASE_SENSITIVE, AT_UNUSED,
4938
COLLATION_NTOFS_ULONGS, g_vol->indx_record_size);
4940
ntfs_log_error("Couldn't create $Reparse: %s\n",
4950
static int mkntfs_redirect(struct mkntfs_options *opts2)
4954
ntfs_attr_search_ctx *ctx = NULL;
4961
ntfs_log_error("Internal error: invalid parameters to mkntfs_options.\n");
4964
/* Initialize the random number generator with the current time. */
4965
srandom(le64_to_cpu(mkntfs_time())/10000000);
4966
/* Allocate and initialize ntfs_volume structure g_vol. */
4967
g_vol = ntfs_volume_alloc();
4969
ntfs_log_perror("Could not create volume");
4972
/* Create NTFS 3.1 (Windows XP/Vista) volumes. */
4973
g_vol->major_ver = 3;
4974
g_vol->minor_ver = 1;
4975
/* Transfer some options to the volume. */
4977
g_vol->vol_name = strdup(opts.label);
4978
if (!g_vol->vol_name) {
4979
ntfs_log_perror("Could not copy volume name");
4983
if (opts.cluster_size >= 0)
4984
g_vol->cluster_size = opts.cluster_size;
4985
/* Length is in unicode characters. */
4986
g_vol->upcase_len = ntfs_upcase_build_default(&g_vol->upcase);
4987
/* Since Windows 8, there is a $Info stream in $UpCase */
4989
(struct UPCASEINFO*)ntfs_malloc(sizeof(struct UPCASEINFO));
4990
if (!g_vol->upcase_len || !g_upcaseinfo)
4992
/* If the CRC is correct, chkdsk does not warn about obsolete table */
4993
crc64(0,(byte*)NULL,0); /* initialize the crc computation */
4994
upcase_crc = crc64(0,(byte*)g_vol->upcase,
4995
g_vol->upcase_len * sizeof(ntfschar));
4996
/* keep the version fields as zero */
4997
memset(g_upcaseinfo, 0, sizeof(struct UPCASEINFO));
4998
g_upcaseinfo->len = cpu_to_le32(sizeof(struct UPCASEINFO));
4999
g_upcaseinfo->crc = cpu_to_le64(upcase_crc);
5000
g_vol->attrdef = ntfs_malloc(sizeof(attrdef_ntfs3x_array));
5001
if (!g_vol->attrdef) {
5002
ntfs_log_perror("Could not create attrdef structure");
5005
memcpy(g_vol->attrdef, attrdef_ntfs3x_array,
5006
sizeof(attrdef_ntfs3x_array));
5007
g_vol->attrdef_len = sizeof(attrdef_ntfs3x_array);
5008
/* Open the partition. */
5009
if (!mkntfs_open_partition(g_vol))
5012
* Decide on the sector size, cluster size, mft record and index record
5013
* sizes as well as the number of sectors/tracks/heads/size, etc.
5015
if (!mkntfs_override_vol_params(g_vol))
5017
/* Initialize $Bitmap and $MFT/$BITMAP related stuff. */
5018
if (!mkntfs_initialize_bitmaps())
5020
/* Initialize MFT & set g_logfile_lcn. */
5021
if (!mkntfs_initialize_rl_mft())
5023
/* Initialize $LogFile. */
5024
if (!mkntfs_initialize_rl_logfile())
5026
/* Initialize $Boot. */
5027
if (!mkntfs_initialize_rl_boot())
5029
/* Allocate a buffer large enough to hold the mft. */
5030
g_buf = ntfs_calloc(g_mft_size);
5033
/* Create runlist for $BadClus, $DATA named stream $Bad. */
5034
if (!mkntfs_initialize_rl_bad())
5036
/* If not quick format, fill the device with 0s. */
5037
if (!opts.quick_format) {
5038
if (!mkntfs_fill_device_with_zeroes())
5041
/* Create NTFS volume structures. */
5042
if (!mkntfs_create_root_structures())
5045
* - Do not step onto bad blocks!!!
5046
* - If any bad blocks were specified or found, modify $BadClus,
5047
* allocating the bad clusters in $Bitmap.
5048
* - C&w bootsector backup bootsector (backup in last sector of the
5050
* - If NTFS 3.0+, c&w $Secure file and $Extend directory with the
5051
* corresponding special files in it, i.e. $ObjId, $Quota, $Reparse,
5052
* and $UsnJrnl. And others? Or not all necessary?
5053
* - RE: Populate $root with the system files (and $Extend directory if
5054
* applicable). Possibly should move this as far to the top as
5055
* possible and update during each subsequent c&w of each system file.
5057
ntfs_log_verbose("Syncing root directory index record.\n");
5058
if (!mkntfs_sync_index_record(g_index_block, (MFT_RECORD*)(g_buf + 5 *
5059
g_vol->mft_record_size), NTFS_INDEX_I30, 4))
5062
ntfs_log_verbose("Syncing $Bitmap.\n");
5063
m = (MFT_RECORD*)(g_buf + 6 * g_vol->mft_record_size);
5065
ctx = ntfs_attr_get_search_ctx(NULL, m);
5067
ntfs_log_perror("Could not create an attribute search context");
5071
if (mkntfs_attr_lookup(AT_DATA, AT_UNNAMED, 0, CASE_SENSITIVE,
5073
ntfs_log_error("BUG: $DATA attribute not found.\n");
5078
if (a->non_resident) {
5079
runlist *rl = ntfs_mapping_pairs_decompress(g_vol, a, NULL);
5081
ntfs_log_error("ntfs_mapping_pairs_decompress() failed\n");
5084
lw = ntfs_rlwrite(g_vol->dev, rl, (const u8*)NULL,
5085
g_lcn_bitmap_byte_size, NULL, WRITE_BITMAP);
5088
if (lw != g_lcn_bitmap_byte_size) {
5089
ntfs_log_error("ntfs_rlwrite: %s\n", lw == -1 ?
5090
strerror(err) : "unknown error");
5094
/* Error : the bitmap must be created non resident */
5095
ntfs_log_error("Error : the global bitmap is resident\n");
5100
* No need to sync $MFT/$BITMAP as that has never been modified since
5103
ntfs_log_verbose("Syncing $MFT.\n");
5104
pos = g_mft_lcn * g_vol->cluster_size;
5106
for (i = 0; i < g_mft_size / (s32)g_vol->mft_record_size; i++) {
5107
if (!opts.no_action)
5108
lw = ntfs_mst_pwrite(g_vol->dev, pos, 1, g_vol->mft_record_size, g_buf + i * g_vol->mft_record_size);
5110
ntfs_log_error("ntfs_mst_pwrite: %s\n", lw == -1 ?
5111
strerror(errno) : "unknown error");
5114
pos += g_vol->mft_record_size;
5116
ntfs_log_verbose("Updating $MFTMirr.\n");
5117
pos = g_mftmirr_lcn * g_vol->cluster_size;
5119
for (i = 0; i < g_rl_mftmirr[0].length * g_vol->cluster_size / g_vol->mft_record_size; i++) {
5120
m = (MFT_RECORD*)(g_buf + i * g_vol->mft_record_size);
5122
* Decrement the usn by one, so it becomes the same as the one
5123
* in $MFT once it is mst protected. - This is as we need the
5124
* $MFTMirr to have the exact same byte by byte content as
5125
* $MFT, rather than just equivalent meaning content.
5127
if (ntfs_mft_usn_dec(m)) {
5128
ntfs_log_error("ntfs_mft_usn_dec");
5131
if (!opts.no_action)
5132
lw = ntfs_mst_pwrite(g_vol->dev, pos, 1, g_vol->mft_record_size, g_buf + i * g_vol->mft_record_size);
5134
ntfs_log_error("ntfs_mst_pwrite: %s\n", lw == -1 ?
5135
strerror(errno) : "unknown error");
5138
pos += g_vol->mft_record_size;
5140
ntfs_log_verbose("Syncing device.\n");
5141
if (g_vol->dev->d_ops->sync(g_vol->dev)) {
5142
ntfs_log_error("Syncing device. FAILED");
5145
ntfs_log_quiet("mkntfs completed successfully. Have a nice day.\n");
5148
ntfs_attr_put_search_ctx(ctx);
5149
mkntfs_cleanup(); /* Device is unlocked and closed here */
5159
* Return: 0 Success, the program worked
5160
* 1 Error, something went wrong
5162
int main(int argc, char *argv[])
5166
ntfs_log_set_handler(ntfs_log_handler_outerr);
5169
mkntfs_init_options(&opts); /* Set up the options */
5171
if (!mkntfs_parse_options(argc, argv, &opts)) /* Read the command line options */
5174
result = mkntfs_redirect(&opts);