ReactOS 0.4.15-dev-7842-g558ab78
Mke2fs.c
Go to the documentation of this file.
1/*
2 * PROJECT: Mke2fs
3 * FILE: Disk.c
4 * PROGRAMMER: Matt Wu <mattwu@163.com>
5 * HOMEPAGE: http://ext2.yeah.net
6 */
7
8/* INCLUDES **************************************************************/
9
10#include "Mke2fs.h"
11
12#include <fmifs/fmifs.h>
13#include <debug.h>
14
15/* GLOBALS ***************************************************************/
16
17int inode_ratio = 4096;
18
20
21/* This is needed for the ext2fs driver to mount the volume */
22#define ZAP_BOOTBLOCK
23
24/* FUNCTIONS *************************************************************/
25
26int int_log2(int arg)
27{
28 int l = 0;
29
30 arg >>= 1;
31
32 while (arg)
33 {
34 l++;
35 arg >>= 1;
36 }
37
38 return l;
39}
40
41int int_log10(unsigned int arg)
42{
43 int l;
44
45 for (l=0; arg ; l++)
46 arg = arg / 10;
47
48 return l;
49}
50
51
52static char default_str[] = "default";
53
55 const char *type;
56 int size;
59} settings[] = {
60 { default_str, 0, 4096, 8192 },
61 { default_str, 512, 1024, 4096 },
62 { default_str, 3, 1024, 8192 },
63 { "journal", 0, 4096, 8192 },
64 { "news", 0, 4096, 4096 },
65 { "largefile", 0, 4096, 1024 * 1024 },
66 { "largefile4", 0, 4096, 4096 * 1024 },
67 { 0, 0, 0, 0},
68};
69
70void set_fs_defaults(const char *fs_type,
72 int blocksize, int *inode_ratio)
73{
74 int megs;
75 int ratio = 0;
76 struct mke2fs_defaults *p;
77
78 megs = (super->s_blocks_count * (EXT2_BLOCK_SIZE(super) / 1024) / 1024);
79
80 if (inode_ratio)
81 ratio = *inode_ratio;
82
83 if (!fs_type)
85
86 for (p = settings; p->type; p++)
87 {
88 if ((strcmp(p->type, fs_type) != 0) &&
89 (strcmp(p->type, default_str) != 0))
90 continue;
91
92 if ((p->size != 0) &&
93 (megs > p->size))
94 continue;
95
96 if (ratio == 0)
97 *inode_ratio = p->inode_ratio;
98
99 if (blocksize == 0)
100 {
101 super->s_log_frag_size = super->s_log_block_size =
102 int_log2(p->blocksize >> EXT2_MIN_BLOCK_LOG_SIZE);
103 }
104 }
105
106 if (blocksize == 0)
107 {
108 super->s_blocks_count /= EXT2_BLOCK_SIZE(super) / 1024;
109 }
110}
111
112/*
113 * Helper function which zeros out _num_ blocks starting at _blk_. In
114 * case of an error, the details of the error is returned via _ret_blk_
115 * and _ret_count_ if they are non-NULL pointers. Returns 0 on
116 * success, and an error code on an error.
117 *
118 * As a special case, if the first argument is NULL, then it will
119 * attempt to free the static zeroizing buffer. (This is to keep
120 * programs that check for memory leaks happy.)
121 */
123 ULONG *ret_blk, ULONG *ret_count)
124{
125 ULONG j, count;
126 static unsigned char *buf;
127 bool retval;
128
129 /* If fs is null, clean up the static buffer and return */
130 if (!fs)
131 {
132 if (buf)
133 {
134 RtlFreeHeap(RtlGetProcessHeap(), 0, buf);
135 buf = 0;
136 }
137 return true;
138 }
139
140#define STRIDE_LENGTH 8
141
142 /* Allocate the zeroizing buffer if necessary */
143 if (!buf)
144 {
145 buf = (unsigned char *)
146 RtlAllocateHeap(RtlGetProcessHeap(), 0, fs->blocksize * STRIDE_LENGTH);
147 if (!buf)
148 {
149 DPRINT1("Mke2fs: while allocating zeroizing buffer");
150 if (ret_blk)
151 *ret_blk = blk;
152 return false;
153 }
154 memset(buf, 0, fs->blocksize * STRIDE_LENGTH);
155 }
156
157 /* OK, do the write loop */
158 for (j=0; j < num; j += STRIDE_LENGTH, blk += STRIDE_LENGTH)
159 {
160 if (num-j > STRIDE_LENGTH)
162 else
163 count = num - j;
164
165 retval = NT_SUCCESS(Ext2WriteDisk(
166 fs,
167 ((ULONGLONG)blk * fs->blocksize),
168 count * fs->blocksize,
169 buf));
170
171 if (!retval)
172 {
173 if (ret_count)
174 *ret_count = count;
175
176 if (ret_blk)
177 *ret_blk = blk;
178
179 return retval;
180 }
181 }
182
183 return true;
184}
185
186
187bool zap_sector(PEXT2_FILESYS Ext2Sys, int sect, int nsect)
188{
189 unsigned char *buf;
190 ULONG *magic;
191
192 buf = (unsigned char *)
193 RtlAllocateHeap(RtlGetProcessHeap(), 0, SECTOR_SIZE*nsect);
194 if (!buf)
195 {
196 DPRINT1("Mke2fs: Out of memory erasing sectors %d-%d\n",
197 sect, sect + nsect - 1);
198 return false;
199 }
200
201#define BSD_DISKMAGIC (0x82564557UL) /* The disk magic number */
202#define BSD_MAGICDISK (0x57455682UL) /* The disk magic number reversed */
203#define BSD_LABEL_OFFSET 64
204
205 if (sect == 0)
206 {
208 Ext2Sys,
209 (LONGLONG)(sect * SECTOR_SIZE),
211
212 // Check for a BSD disklabel, and don't erase it if so
214 if ((*magic == BSD_DISKMAGIC) || (*magic == BSD_MAGICDISK))
215 goto clean_up;
216 }
217
218 memset(buf, 0, (ULONG)nsect * SECTOR_SIZE);
219
220 // Write buf to disk
221 Ext2WriteDisk( Ext2Sys,
222 (LONGLONG)(sect * SECTOR_SIZE),
223 (ULONG)nsect * SECTOR_SIZE,
224 buf );
225
226clean_up:
227
228 RtlFreeHeap(RtlGetProcessHeap(), 0, buf);
229
230 return true;
231}
232
235 ULONG inum,
236 char *name,
237 ULONG *no,
239{
240 bool retval;
241 EXT2_INODE parent_inode, inode;
242 ULONG ino = inum;
243 //ULONG scratch_ino;
244 ULONG blk;
245 char *block = 0;
246 int filetype = 0;
247
248 LARGE_INTEGER SysTime;
249
250 NtQuerySystemTime(&SysTime);
251
252 /*
253 * Allocate an inode, if necessary
254 */
255 if (!ino)
256 {
257 retval = ext2_new_inode(fs, parent, LINUX_S_IFDIR | 0755, 0, &ino);
258 if (!retval)
259 goto cleanup;
260 }
261
262 if (no)
263 *no = ino;
264
265 /*
266 * Allocate a data block for the directory
267 */
268 retval = ext2_new_block(fs, 0, 0, &blk);
269 if (!retval)
270 goto cleanup;
271
272 /*
273 * Create a scratch template for the directory
274 */
275 retval = ext2_new_dir_block(fs, ino, parent, &block);
276 if (!retval)
277 goto cleanup;
278
279 /*
280 * Get the parent's inode, if necessary
281 */
282 if (parent != ino)
283 {
284 retval = ext2_load_inode(fs, parent, &parent_inode);
285 if (!retval)
286 goto cleanup;
287 }
288 else
289 {
290 memset(&parent_inode, 0, sizeof(parent_inode));
291 }
292
293 /*
294 * Create the inode structure....
295 */
296 memset(&inode, 0, sizeof(EXT2_INODE));
297 inode.i_mode = (USHORT)(LINUX_S_IFDIR | (0777 & ~fs->umask));
298 inode.i_uid = inode.i_gid = 0;
299 inode.i_blocks = fs->blocksize / 512;
300 inode.i_block[0] = blk;
301 inode.i_links_count = 2;
304 inode.i_size = fs->blocksize;
305
306 /*
307 * Write out the inode and inode data block
308 */
309 retval = ext2_write_block(fs, blk, block);
310 if (!retval)
311 goto cleanup;
312
313 retval = ext2_save_inode(fs, ino, &inode);
314 if (!retval)
315 goto cleanup;
316
317 if (pid)
318 {
319 *pid = inode;
320 }
321
322 if (parent != ino)
323 {
324 /*
325 * Add entry for this inode to parent dir 's block
326 */
327
328 if (fs->ext2_sb->s_feature_incompat & EXT2_FEATURE_INCOMPAT_FILETYPE)
330
331 retval = ext2_add_entry(fs, parent, ino, filetype, name);
332
333 if (!retval)
334 goto cleanup;
335
336 /*
337 * Update parent inode's counts
338 */
339
340 parent_inode.i_links_count++;
341 retval = ext2_save_inode(fs, parent, &parent_inode);
342 if (!retval)
343 goto cleanup;
344
345 }
346
347 /*
348 * Update accounting....
349 */
351 ext2_inode_alloc_stats2(fs, ino, +1, 1);
352
353cleanup:
354
355 if (block)
356 {
357 RtlFreeHeap(RtlGetProcessHeap(), 0, block);
358 block = NULL;
359 }
360
361 return retval;
362}
363
365{
366 bool retval;
368
370
371 if (!retval)
372 {
373 DPRINT1("Mke2fs: while creating root dir");
374 return false;
375 }
376
377 {
378 inode.i_uid = 0;
379 inode.i_gid = 0;
380
382 if (!retval)
383 {
384 DPRINT1("Mke2fs: while setting root inode ownership");
385 return false;
386 }
387 }
388
389 return true;
390}
391
393{
394 bool retval;
395 ULONG ino;
396 char *name = "lost+found";
397 int lpf_size = 0;
399 ULONG dwBlk = 0;
400 BOOLEAN bExt= TRUE;
401
403
404 char * buf;
405
406 buf = (char *)RtlAllocateHeap(RtlGetProcessHeap(), 0, Ext2Sys->blocksize);
407 if (!buf)
408 {
409 bExt = FALSE;
410 }
411 else
412 {
413 memset(buf, 0, Ext2Sys->blocksize);
414
416 dir->rec_len = Ext2Sys->blocksize;
417 }
418
419 Ext2Sys->umask = 077;
420 retval = ext2_mkdir(Ext2Sys, EXT2_ROOT_INO, 0, name, &ino, &inode);
421
422 if (!retval)
423 {
424 DPRINT1("Mke2fs: while creating /lost+found.\n");
425 return false;
426 }
427
428 if (!bExt)
429 goto errorout;
430
431 lpf_size = inode.i_size;
432
433 while(TRUE)
434 {
435 if (lpf_size >= 16*1024)
436 break;
437
438 retval = ext2_alloc_block(Ext2Sys, 0, &dwBlk);
439
440 if (! retval)
441 {
442 DPRINT1("Mke2fs: create_lost_and_found: error alloc block.\n");
443 break;
444 }
445
446 retval = ext2_expand_inode(Ext2Sys, &inode, dwBlk);
447 if (!retval)
448 {
449 DPRINT1("Mke2fs: errors when expanding /lost+found.\n");
450 break;
451 }
452
453 ext2_write_block(Ext2Sys, dwBlk, buf);
454
455 inode.i_blocks += (Ext2Sys->blocksize/SECTOR_SIZE);
456 lpf_size += Ext2Sys->blocksize;
457 }
458
459 {
460 inode.i_size = lpf_size;
461
462 ASSERT( (inode.i_size/Ext2Sys->blocksize) ==
463 Ext2DataBlocks(Ext2Sys, inode.i_blocks/(Ext2Sys->blocksize/SECTOR_SIZE)));
464
465 ASSERT( (inode.i_blocks/(Ext2Sys->blocksize/SECTOR_SIZE)) ==
466 Ext2TotalBlocks(Ext2Sys, inode.i_size/Ext2Sys->blocksize));
467
468 }
469
470 ext2_save_inode(Ext2Sys, ino, &inode);
471
472errorout:
473
474 if (buf)
475 {
476 RtlFreeHeap(RtlGetProcessHeap(), 0, buf);
477 }
478
479 return true;
480}
481
482/*
483 * This function forces out the primary superblock. We need to only
484 * write out those fields which we have changed, since if the
485 * filesystem is mounted, it may have changed some of the other
486 * fields.
487 *
488 * It takes as input a superblock which has already been byte swapped
489 * (if necessary).
490 */
491
493{
494 bool bRet;
495
497 Ext2Sys,
499 SUPERBLOCK_SIZE, (PUCHAR)super));
500
501
502
503 return bRet;
504}
505
506
507/*
508 * Updates the revision to EXT2_DYNAMIC_REV
509 */
511{
512 PEXT2_SUPER_BLOCK sb = fs->ext2_sb;
513
514 if (sb->s_rev_level > EXT2_GOOD_OLD_REV)
515 return;
516
517 sb->s_rev_level = EXT2_DYNAMIC_REV;
518 sb->s_first_ino = EXT2_GOOD_OLD_FIRST_INO;
519 sb->s_inode_size = EXT2_GOOD_OLD_INODE_SIZE;
520 /* s_uuid is handled by e2fsck already */
521 /* other fields should be left alone */
522}
523
524
526{
527 ULONG i,j,maxgroup,sgrp;
528 ULONG group_block;
529 bool retval;
530 char *group_ptr;
531 unsigned long fs_state;
532 PEXT2_SUPER_BLOCK super_shadow = 0;
533 PEXT2_GROUP_DESC group_shadow = 0;
534
535 LARGE_INTEGER SysTime;
536
537 NtQuerySystemTime(&SysTime);
538
539 fs_state = fs->ext2_sb->s_state;
540
541 RtlTimeToSecondsSince1970(&SysTime, &fs->ext2_sb->s_wtime);
542 fs->ext2_sb->s_block_group_nr = 0;
543
544 super_shadow = fs->ext2_sb;
545 group_shadow = fs->group_desc;
546
547 /*
548 * Write out master superblock. This has to be done
549 * separately, since it is located at a fixed location
550 * (SUPERBLOCK_OFFSET).
551 */
552 retval = write_primary_superblock(fs, super_shadow);
553 if (!retval)
554 goto errout;
555
556 /*
557 * If this is an external journal device, don't write out the
558 * block group descriptors or any of the backup superblocks
559 */
560 if (fs->ext2_sb->s_feature_incompat &
562 {
563 retval = false;
564 goto errout;
565 }
566
567 /*
568 * Set the state of the FS to be non-valid. (The state has
569 * already been backed up earlier, and will be restored when
570 * we exit.)
571 */
572 fs->ext2_sb->s_state &= ~EXT2_VALID_FS;
573
574 /*
575 * Write out the master group descriptors, and the backup
576 * superblocks and group descriptors.
577 */
578 group_block = fs->ext2_sb->s_first_data_block;
579 maxgroup = fs->group_desc_count;
580
581 for (i = 0; i < maxgroup; i++)
582 {
583 if (!ext2_bg_has_super(fs->ext2_sb, i))
584 goto next_group;
585
586 sgrp = i;
587 if (sgrp > ((1 << 16) - 1))
588 sgrp = (1 << 16) - 1;
589
590 fs->ext2_sb->s_block_group_nr = (USHORT) sgrp;
591
592 if (i !=0 )
593 {
594 retval = NT_SUCCESS(Ext2WriteDisk(
595 fs,
596 ((ULONGLONG)group_block * fs->blocksize),
597 SUPERBLOCK_SIZE, (PUCHAR)super_shadow));
598
599 if (!retval)
600 {
601 goto errout;
602 }
603 }
604
605 group_ptr = (char *) group_shadow;
606
607 for (j=0; j < fs->desc_blocks; j++)
608 {
609
610 retval = NT_SUCCESS(Ext2WriteDisk(
611 fs,
612 ((ULONGLONG)(group_block+1+j) * fs->blocksize),
613 fs->blocksize, (PUCHAR) group_ptr));
614
615 if (!retval)
616 {
617 goto errout;
618 }
619
620 group_ptr += fs->blocksize;
621 }
622
623 next_group:
624 group_block += EXT2_BLOCKS_PER_GROUP(fs->ext2_sb);
625
626 }
627
628 fs->ext2_sb->s_block_group_nr = 0;
629
630 /*
631 * If the write_bitmaps() function is present, call it to
632 * flush the bitmaps. This is done this way so that a simple
633 * program that doesn't mess with the bitmaps doesn't need to
634 * drag in the bitmaps.c code.
635 */
636 retval = ext2_write_bitmaps(fs);
637 if (!retval)
638 goto errout;
639
640 /*
641 * Flush the blocks out to disk
642 */
643
644 // retval = io_channel_flush(fs->io);
645
646errout:
647
648 fs->ext2_sb->s_state = (USHORT) fs_state;
649
650 return retval;
651}
652
653
655{
656 bool retval = false;
657 char *buf = NULL;
658 ULONG blk;
659 ULONG count;
660
661 if (!retval)
662 {
663 DPRINT1("Mke2fs: ext2_create_journal_dev: while initializing journal superblock.\n");
664 return false;
665 }
666
667 DPRINT("Mke2fs: Zeroing journal device: \n");
668
669 retval = zero_blocks(fs, 0, fs->ext2_sb->s_blocks_count,
670 &blk, &count);
671
672 zero_blocks(0, 0, 0, 0, 0);
673
674 if (!retval)
675 {
676 DPRINT1("Mke2fs: create_journal_dev: while zeroing journal device (block %lu, count %lu).\n",
677 blk, count);
678 return false;
679 }
680
681 retval = NT_SUCCESS(Ext2WriteDisk(
682 fs,
683 ((ULONGLONG)blk * (fs->ext2_sb->s_first_data_block+1)),
684 fs->blocksize, (unsigned char *)buf));
685
686 if (!retval)
687 {
688 DPRINT1("Mke2fs: create_journal_dev: while writing journal superblock.\n");
689 return false;
690 }
691
692 return true;
693}
694
695#define BLOCK_BITS (Ext2Sys->ext2_sb->s_log_block_size + 10)
696
697ULONG
698Ext2DataBlocks(PEXT2_FILESYS Ext2Sys, ULONG TotalBlocks)
699{
700 ULONG dwData[4] = {1, 1, 1, 1};
701 ULONG dwMeta[4] = {0, 0, 0, 0};
702 ULONG DataBlocks = 0;
703 ULONG i, j;
704
705 if (TotalBlocks <= EXT2_NDIR_BLOCKS)
706 {
707 return TotalBlocks;
708 }
709
710 TotalBlocks -= EXT2_NDIR_BLOCKS;
711
712 for (i = 0; i < 4; i++)
713 {
714 dwData[i] = dwData[i] << ((BLOCK_BITS - 2) * i);
715
716 if (i > 0)
717 {
718 dwMeta[i] = 1 + (dwMeta[i - 1] << (BLOCK_BITS - 2));
719 }
720 }
721
722 for( i=1; (i < 4) && (TotalBlocks > 0); i++)
723 {
724 if (TotalBlocks >= (dwData[i] + dwMeta[i]))
725 {
726 TotalBlocks -= (dwData[i] + dwMeta[i]);
727 DataBlocks += dwData[i];
728 }
729 else
730 {
731 ULONG dwDivide = 0;
732 ULONG dwRemain = 0;
733
734 for (j=i; (j > 0) && (TotalBlocks > 0); j--)
735 {
736 dwDivide = (TotalBlocks - 1) / (dwData[j-1] + dwMeta[j-1]);
737 dwRemain = (TotalBlocks - 1) % (dwData[j-1] + dwMeta[j-1]);
738
739 DataBlocks += (dwDivide * dwData[j-1]);
740 TotalBlocks = dwRemain;
741 }
742 }
743 }
744
745 return (DataBlocks + EXT2_NDIR_BLOCKS);
746}
747
748
749ULONG
751{
752 ULONG dwData[4] = {1, 1, 1, 1};
753 ULONG dwMeta[4] = {0, 0, 0, 0};
754 ULONG TotalBlocks = 0;
755 ULONG i, j;
756
757 if (DataBlocks <= EXT2_NDIR_BLOCKS)
758 {
759 return DataBlocks;
760 }
761
762 DataBlocks -= EXT2_NDIR_BLOCKS;
763
764 for (i = 0; i < 4; i++)
765 {
766 dwData[i] = dwData[i] << ((BLOCK_BITS - 2) * i);
767
768 if (i > 0)
769 {
770 dwMeta[i] = 1 + (dwMeta[i - 1] << (BLOCK_BITS - 2));
771 }
772 }
773
774 for( i=1; (i < 4) && (DataBlocks > 0); i++)
775 {
776 if (DataBlocks >= dwData[i])
777 {
778 DataBlocks -= dwData[i];
779 TotalBlocks += (dwData[i] + dwMeta[i]);
780 }
781 else
782 {
783 ULONG dwDivide = 0;
784 ULONG dwRemain = 0;
785
786 for (j=i; (j > 0) && (DataBlocks > 0); j--)
787 {
788 dwDivide = (DataBlocks) / (dwData[j-1]);
789 dwRemain = (DataBlocks) % (dwData[j-1]);
790
791 TotalBlocks += (dwDivide * (dwData[j-1] + dwMeta[j-1]) + 1);
792 DataBlocks = dwRemain;
793 }
794 }
795 }
796
797 return (TotalBlocks + EXT2_NDIR_BLOCKS);
798}
799
800
802NTAPI
804 IN PUNICODE_STRING DriveRoot,
807 IN BOOLEAN BackwardCompatible,
808 IN MEDIA_TYPE MediaType,
811{
812 BOOLEAN bRet;
814 /* Super Block: 1024 bytes long */
815 EXT2_SUPER_BLOCK Ext2Sb;
816 /* File Sys Structure */
817 EXT2_FILESYS FileSys;
818 ULONG Percent;
819 ULONG rsv;
821 ULONG start;
822 ULONG ret_blk;
823
824 // FIXME:
825 UNREFERENCED_PARAMETER(BackwardCompatible);
826 UNREFERENCED_PARAMETER(MediaType);
827
828 if (Callback != NULL)
829 {
830 Callback(PROGRESS, 0, (PVOID)&Percent);
831 }
832
833
834 RtlZeroMemory(&Ext2Sb, sizeof(EXT2_SUPER_BLOCK));
835 RtlZeroMemory(&FileSys, sizeof(EXT2_FILESYS));
836 FileSys.ext2_sb = &Ext2Sb;
837
838
839 if (!NT_SUCCESS(Ext2OpenDevice(&FileSys, DriveRoot)))
840 {
841 DPRINT1("Mke2fs: Volume %wZ does not exist, ...\n", DriveRoot);
842 goto clean_up;
843 }
844
845
846 if (!NT_SUCCESS(Ext2GetMediaInfo(&FileSys)))
847 {
848 DPRINT1("Mke2fs: Can't get media information\n");
849 goto clean_up;
850 }
851
853
854 Ext2Sb.s_blocks_count = FileSys.PartInfo.PartitionLength.QuadPart /
855 EXT2_BLOCK_SIZE(&Ext2Sb);
856
857
858 /*
859 * Calculate number of inodes based on the inode ratio
860 */
861 Ext2Sb.s_inodes_count =
862 (ULONG)(((LONGLONG) Ext2Sb.s_blocks_count * EXT2_BLOCK_SIZE(&Ext2Sb)) / inode_ratio);
863
864 /*
865 * Calculate number of blocks to reserve
866 */
867 Ext2Sb.s_r_blocks_count = (Ext2Sb.s_blocks_count * 5) / 100;
868
869
870 Status = Ext2LockVolume(&FileSys);
871 if (NT_SUCCESS(Status))
872 {
873 bLocked = TRUE;
874 }
875
877
878 // Initialize
879 if (!ext2_initialize_sb(&FileSys))
880 {
881 DPRINT1("Mke2fs: error...\n");
882 goto clean_up;
883 }
884
885
886 zap_sector(&FileSys, 2, 6);
887
888 /*
889 * Generate a UUID for it...
890 */
891 {
892 __u8 uuid[16];
893 uuid_generate(&uuid[0]);
894 memcpy(&Ext2Sb.s_uuid[0], &uuid[0], 16);
895 }
896
897 /*
898 * Add "jitter" to the superblock's check interval so that we
899 * don't check all the filesystems at the same time. We use a
900 * kludgy hack of using the UUID to derive a random jitter value.
901 */
902 {
903 ULONG i, val;
904
905 for (i = 0, val = 0 ; i < sizeof(Ext2Sb.s_uuid); i++)
906 val += Ext2Sb.s_uuid[i];
907
908 Ext2Sb.s_max_mnt_count += val % EXT2_DFL_MAX_MNT_COUNT;
909 }
910
911 /*
912 * Set the volume label...
913 */
914 if (Label)
915 {
916 ANSI_STRING ansi_label;
917 ansi_label.MaximumLength = sizeof(Ext2Sb.s_volume_name);
918 ansi_label.Length = 0;
919 ansi_label.Buffer = Ext2Sb.s_volume_name;
921 }
922
923 ext2_print_super(&Ext2Sb);
924
925 bRet = ext2_allocate_tables(&FileSys);
926 if (!bRet)
927 {
928 goto clean_up;
929 }
930
931 /* rsv must be a power of two (64kB is MD RAID sb alignment) */
932 rsv = 65536 / FileSys.blocksize;
933 blocks = Ext2Sb.s_blocks_count;
934
935#ifdef ZAP_BOOTBLOCK
936 DPRINT1("Mke2fs: zeroing volume boot record\n");
937 zap_sector(&FileSys, 0, 2);
938#endif
939
940 /*
941 * Wipe out any old MD RAID (or other) metadata at the end
942 * of the device. This will also verify that the device is
943 * as large as we think. Be careful with very small devices.
944 */
945
946 start = (blocks & ~(rsv - 1));
947 if (start > rsv)
948 start -= rsv;
949
950 bRet = TRUE;
951 if (start > 0)
952 bRet = zero_blocks(&FileSys, start, blocks - start, &ret_blk, NULL);
953
954 if (!bRet)
955 {
956 DPRINT1("Mke2fs: zeroing block %lu at end of filesystem", ret_blk);
957 goto clean_up;
958 }
959
960 write_inode_tables(&FileSys);
961
962 create_root_dir(&FileSys);
963 create_lost_and_found(&FileSys);
964
965 ext2_reserve_inodes(&FileSys);
966
967 create_bad_block_inode(&FileSys, NULL);
968
969 DPRINT("Mke2fs: Writing superblocks and filesystem accounting information ... \n");
970
971 if (!QuickFormat)
972 {
973 DPRINT1("Mke2fs: Slow format not supported yet\n");
974 }
975
976 if (!ext2_flush(&FileSys))
977 {
978 DPRINT1("Mke2fs: Warning, had trouble writing out superblocks.\n");
979 goto clean_up;
980 }
981
982 DPRINT("Mke2fs: Writing superblocks and filesystem accounting information done!\n");
983
985
986clean_up:
987
988 // Clean up ...
989 ext2_free_group_desc(&FileSys);
990
991 ext2_free_block_bitmap(&FileSys);
992 ext2_free_inode_bitmap(&FileSys);
993
994 if(bLocked)
995 {
996 Ext2DisMountVolume(&FileSys);
997 Ext2UnLockVolume(&FileSys);
998 }
999
1000 Ext2CloseDevice(&FileSys);
1001
1002 return NT_SUCCESS(Status);
1003}
1004
1005BOOLEAN
1006NTAPI
1008 IN PUNICODE_STRING DriveRoot,
1012 IN BOOLEAN CheckOnlyIfDirty,
1013 IN BOOLEAN ScanDrive,
1014 IN PVOID pUnknown1,
1015 IN PVOID pUnknown2,
1016 IN PVOID pUnknown3,
1017 IN PVOID pUnknown4,
1019{
1022 return TRUE;
1023}
bool create_bad_block_inode(PEXT2_FILESYS Ext2Sys, PEXT2_BADBLK_LIST bb_list)
Definition: Badblock.c:16
bool ext2_write_bitmaps(PEXT2_FILESYS fs)
Definition: Bitmap.c:342
void ext2_free_inode_bitmap(PEXT2_FILESYS Ext2Sys)
Definition: Bitmap.c:194
void ext2_free_block_bitmap(PEXT2_FILESYS Ext2Sys)
Definition: Bitmap.c:205
NTSTATUS Ext2GetMediaInfo(PEXT2_FILESYS Ext2Sys)
Definition: Disk.c:1162
NTSTATUS Ext2OpenDevice(PEXT2_FILESYS Ext2Sys, PUNICODE_STRING DeviceName)
Definition: Disk.c:1282
NTSTATUS Ext2DisMountVolume(PEXT2_FILESYS Ext2Sys)
Definition: Disk.c:1260
NTSTATUS Ext2WriteDisk(PEXT2_FILESYS Ext2Sys, ULONGLONG Offset, ULONG Length, PVOID Buffer)
Definition: Disk.c:1059
NTSTATUS Ext2UnLockVolume(PEXT2_FILESYS Ext2Sys)
Definition: Disk.c:1237
NTSTATUS Ext2CloseDevice(PEXT2_FILESYS Ext2Sys)
Definition: Disk.c:1342
void ext2_free_group_desc(PEXT2_FILESYS Ext2Sys)
Definition: Group.c:61
bool ext2_bg_has_super(PEXT2_SUPER_BLOCK pExt2Sb, int group_block)
Definition: Group.c:30
bool ext2_add_entry(PEXT2_FILESYS Ext2Sys, ULONG parent, ULONG inode, int filetype, char *name)
Definition: Inode.c:619
bool ext2_expand_inode(PEXT2_FILESYS Ext2Sys, PEXT2_INODE Inode, ULONG newBlk)
Definition: Inode.c:212
bool ext2_reserve_inodes(PEXT2_FILESYS fs)
Definition: Inode.c:681
bool ext2_load_inode(PEXT2_FILESYS Ext2Sys, ULONG no, PEXT2_INODE pInode)
Definition: Inode.c:41
bool ext2_new_inode(PEXT2_FILESYS fs, ULONG dir, int mode, PEXT2_INODE_BITMAP map, ULONG *ret)
Definition: Inode.c:84
bool ext2_save_inode(PEXT2_FILESYS Ext2Sys, ULONG no, PEXT2_INODE pInode)
Definition: Inode.c:59
void ext2_inode_alloc_stats2(PEXT2_FILESYS fs, ULONG ino, int inuse, int isdir)
Definition: Memory.c:37
void ext2_block_alloc_stats(PEXT2_FILESYS fs, ULONG blk, int inuse)
Definition: Memory.c:61
bool ext2_new_block(PEXT2_FILESYS fs, ULONG goal, PEXT2_BLOCK_BITMAP map, ULONG *ret)
Definition: Memory.c:254
bool ext2_write_block(PEXT2_FILESYS fs, ULONG block, void *inbuf)
Definition: Memory.c:394
bool ext2_new_dir_block(PEXT2_FILESYS fs, ULONG dir_ino, ULONG parent_ino, char **block)
Definition: Memory.c:349
bool ext2_alloc_block(PEXT2_FILESYS fs, ULONG goal, ULONG *ret)
Definition: Memory.c:293
bool ext2_allocate_tables(PEXT2_FILESYS Ext2Sys)
Definition: Memory.c:75
bool write_inode_tables(PEXT2_FILESYS fs)
Definition: Memory.c:221
BOOLEAN bLocked
Definition: Mke2fs.c:19
int int_log2(int arg)
Definition: Mke2fs.c:26
bool create_journal_dev(PEXT2_FILESYS fs)
Definition: Mke2fs.c:654
bool write_primary_superblock(PEXT2_FILESYS Ext2Sys, PEXT2_SUPER_BLOCK super)
Definition: Mke2fs.c:492
bool zero_blocks(PEXT2_FILESYS fs, ULONG blk, ULONG num, ULONG *ret_blk, ULONG *ret_count)
Definition: Mke2fs.c:122
#define BSD_LABEL_OFFSET
void ext2_update_dynamic_rev(PEXT2_FILESYS fs)
Definition: Mke2fs.c:510
bool create_root_dir(PEXT2_FILESYS fs)
Definition: Mke2fs.c:364
static char default_str[]
Definition: Mke2fs.c:52
BOOLEAN NTAPI Ext2Chkdsk(IN PUNICODE_STRING DriveRoot, IN PFMIFSCALLBACK Callback, IN BOOLEAN FixErrors, IN BOOLEAN Verbose, IN BOOLEAN CheckOnlyIfDirty, IN BOOLEAN ScanDrive, IN PVOID pUnknown1, IN PVOID pUnknown2, IN PVOID pUnknown3, IN PVOID pUnknown4, IN PULONG ExitStatus)
Definition: Mke2fs.c:1007
#define BSD_MAGICDISK
int inode_ratio
Definition: Mke2fs.c:17
bool ext2_mkdir(PEXT2_FILESYS fs, ULONG parent, ULONG inum, char *name, ULONG *no, PEXT2_INODE pid)
Definition: Mke2fs.c:233
bool ext2_flush(PEXT2_FILESYS fs)
Definition: Mke2fs.c:525
struct mke2fs_defaults settings[]
bool create_lost_and_found(PEXT2_FILESYS Ext2Sys)
Definition: Mke2fs.c:392
int int_log10(unsigned int arg)
Definition: Mke2fs.c:41
void set_fs_defaults(const char *fs_type, PEXT2_SUPER_BLOCK super, int blocksize, int *inode_ratio)
Definition: Mke2fs.c:70
ULONG Ext2TotalBlocks(PEXT2_FILESYS Ext2Sys, ULONG DataBlocks)
Definition: Mke2fs.c:750
bool zap_sector(PEXT2_FILESYS Ext2Sys, int sect, int nsect)
Definition: Mke2fs.c:187
#define BSD_DISKMAGIC
ULONG Ext2DataBlocks(PEXT2_FILESYS Ext2Sys, ULONG TotalBlocks)
Definition: Mke2fs.c:698
#define BLOCK_BITS
Definition: Mke2fs.c:695
#define STRIDE_LENGTH
BOOLEAN NTAPI Ext2Format(IN PUNICODE_STRING DriveRoot, IN PFMIFSCALLBACK Callback, IN BOOLEAN QuickFormat, IN BOOLEAN BackwardCompatible, IN MEDIA_TYPE MediaType, IN PUNICODE_STRING Label, IN ULONG ClusterSize)
Definition: Mke2fs.c:803
void ext2_print_super(PEXT2_SUPER_BLOCK pExt2Sb)
Definition: Super.c:20
void uuid_generate(__u8 *uuid)
Definition: Uuid.c:17
bool ext2_initialize_sb(PEXT2_FILESYS pExt2Sys)
Definition: Super.c:74
#define LINUX_S_IFDIR
Definition: Mke2fs.h:85
#define SUPERBLOCK_SIZE
Definition: Mke2fs.h:205
#define SUPERBLOCK_OFFSET
Definition: Mke2fs.h:204
unsigned char BOOLEAN
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
unsigned int dir
Definition: maze.c:112
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
BOOL FixErrors
Definition: chkdsk.c:69
BOOL Verbose
Definition: chkdsk.c:72
BOOL QuickFormat
Definition: format.c:66
PWCHAR Label
Definition: format.c:70
DWORD ClusterSize
Definition: format.c:67
#define UNIMPLEMENTED
Definition: debug.h:115
u8 __u8
Definition: btrfs.h:17
#define EXT2_BLOCK_SIZE(sb)
Definition: ext2.h:186
#define EXT2_GOOD_OLD_INODE_SIZE
Definition: ext2.h:54
struct ext2_dirent * PEXT2_DIR_ENTRY
Definition: ext2.h:174
#define EXT2_ROOT_INO
Definition: ext2.h:177
#define SECTOR_SIZE
Definition: fs.h:22
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:590
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:608
r l[0]
Definition: byte_order.h:168
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static WCHAR no[MAX_STRING_RESOURCE_LEN]
Definition: object.c:2340
static void cleanup(void)
Definition: main.c:1335
superblock * sb
Definition: btrfs.c:4261
r parent
Definition: btrfs.c:3010
#define EXT2_GOOD_OLD_FIRST_INO
Definition: ext2_fs.h:66
#define EXT2_NDIR_BLOCKS
Definition: ext2_fs.h:177
#define EXT2_BLOCKS_PER_GROUP(s)
Definition: ext2_fs.h:169
#define EXT2_FEATURE_INCOMPAT_FILETYPE
Definition: ext2_fs.h:471
#define EXT2_DFL_MAX_MNT_COUNT
Definition: ext2_fs.h:332
#define EXT2_GOOD_OLD_REV
Definition: ext2_fs.h:426
#define EXT2_MIN_BLOCK_LOG_SIZE
Definition: ext2_fs.h:83
#define EXT2_DYNAMIC_REV
Definition: ext2_fs.h:427
NTSTATUS Ext2ReadDisk(IN PEXT2_VCB Vcb, IN ULONGLONG Offset, IN ULONG Size, IN PVOID Buffer, IN BOOLEAN bVerify)
Definition: block.c:559
NTSTATUS Ext2LockVolume(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: fsctl.c:136
#define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV
Definition: ext3_fs.h:681
@ PROGRESS
Definition: fmifs.h:68
BOOLEAN(NTAPI * PFMIFSCALLBACK)(IN CALLBACKCOMMAND Command, IN ULONG SubAction, IN PVOID ActionInfo)
Definition: fmifs.h:89
Status
Definition: gdiplustypes.h:25
GLuint start
Definition: gl.h:1545
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLuint GLfloat * val
Definition: glext.h:7180
GLfloat GLfloat p
Definition: glext.h:8902
GLuint GLuint num
Definition: glext.h:9618
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
BOOLEAN NTAPI RtlTimeToSecondsSince1970(PLARGE_INTEGER Time, PULONG ElapsedSeconds)
Definition: msctf.idl:550
#define blk
Definition: linetest.c:70
__u8 fs_type[8]
Definition: mkdosfs.c:5
static int blocks
Definition: mkdosfs.c:527
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define ASSERT(a)
Definition: mode.c:44
static HANDLE ULONG_PTR dwData
Definition: file.c:35
_In_ NTSTATUS ExitStatus
Definition: psfuncs.h:867
u32_t magic(void)
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToAnsiString(PANSI_STRING DestinationString, PUNICODE_STRING SourceString, BOOLEAN AllocateDestinationString)
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
enum _MEDIA_TYPE MEDIA_TYPE
NTSTATUS NTAPI NtQuerySystemTime(OUT PLARGE_INTEGER SystemTime)
Definition: time.c:483
unsigned short USHORT
Definition: pedump.c:61
#define EXT2_FT_DIR
Definition: ext2_fs.h:531
#define memset(x, y, z)
Definition: compat.h:39
LOCAL char * filetype(int t)
Definition: tree.c:114
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
USHORT MaximumLength
Definition: env_spec_w32.h:377
LARGE_INTEGER PartitionLength
Definition: ntdddisk.h:414
PEXT2_SUPER_BLOCK ext2_sb
Definition: Mke2fs.h:159
__u32 umask
Definition: Mke2fs.h:170
PARTITION_INFORMATION PartInfo
Definition: Mke2fs.h:186
int blocksize
Definition: Mke2fs.h:154
__u16 i_links_count
Definition: ext2_fs.h:233
Definition: ffs.h:70
Definition: fs.h:78
__u64 i_blocks
Definition: fs.h:85
gid_t i_gid
Definition: fs.h:89
__u32 i_block[15]
Definition: fs.h:86
__u32 i_mtime
Definition: fs.h:83
loff_t i_size
Definition: fs.h:80
umode_t i_mode
Definition: fs.h:87
uid_t i_uid
Definition: fs.h:88
__u32 i_atime
Definition: fs.h:81
__u32 i_ctime
Definition: fs.h:82
const char * type
Definition: Mke2fs.c:55
int blocksize
Definition: Mke2fs.c:57
int inode_ratio
Definition: Mke2fs.c:58
Definition: name.c:39
uint32_t * PULONG
Definition: typedefs.h:59
int64_t LONGLONG
Definition: typedefs.h:68
#define NTAPI
Definition: typedefs.h:36
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define IN
Definition: typedefs.h:39
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
LONGLONG QuadPart
Definition: typedefs.h:114
_In_ WDFINTERRUPT _In_ PFN_WDF_INTERRUPT_SYNCHRONIZE Callback
Definition: wdfinterrupt.h:458
_In_ ULONG_PTR _In_ ULONG _Out_ ULONG_PTR * pid
Definition: winddi.h:3837
void * arg
Definition: msvc.h:10
static unsigned int block
Definition: xmlmemory.c:101