ReactOS  0.4.13-dev-235-g7373cb3
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 
17 int 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 
26 int 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 
41 int 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 
52 static char default_str[] = "default";
53 
55  const char *type;
56  int size;
57  int blocksize;
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 
70 void set_fs_defaults(const char *fs_type,
71  PEXT2_SUPER_BLOCK super,
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 
187 bool 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  {
207  Ext2ReadDisk(
208  Ext2Sys,
209  (LONGLONG)(sect * SECTOR_SIZE),
210  SECTOR_SIZE, buf);
211 
212  // Check for a BSD disklabel, and don't erase it if so
213  magic = (ULONG *) (buf + BSD_LABEL_OFFSET);
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 
226 clean_up:
227 
228  RtlFreeHeap(RtlGetProcessHeap(), 0, buf);
229 
230  return true;
231 }
232 
234  ULONG parent,
235  ULONG inum,
236  char *name,
237  ULONG *no,
238  PEXT2_INODE pid )
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 
353 cleanup:
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 
381  retval = ext2_save_inode(fs, EXT2_ROOT_INO, &inode);
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 
415  dir = (PEXT2_DIR_ENTRY) buf;
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 
472 errorout:
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 
496  bRet = NT_SUCCESS(Ext2WriteDisk(
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 
646 errout:
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 
697 ULONG
698 Ext2DataBlocks(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 
749 ULONG
750 Ext2TotalBlocks(PEXT2_FILESYS Ext2Sys, ULONG DataBlocks)
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 
801 NTSTATUS
802 NTAPI
804  IN FMIFS_MEDIA_FLAG MediaFlag,
809 {
810  BOOLEAN bRet = FALSE;
812  /* Super Block: 1024 bytes long */
813  EXT2_SUPER_BLOCK Ext2Sb;
814  /* File Sys Structure */
815  EXT2_FILESYS FileSys;
816  ULONG Percent;
817  ULONG rsv;
818  ULONG blocks;
819  ULONG start;
820  ULONG ret_blk;
821 
822 
823  if (Callback != NULL)
824  {
825  Callback(PROGRESS, 0, (PVOID)&Percent);
826  }
827 
828 
829  RtlZeroMemory(&Ext2Sb, sizeof(EXT2_SUPER_BLOCK));
830  RtlZeroMemory(&FileSys, sizeof(EXT2_FILESYS));
831  FileSys.ext2_sb = &Ext2Sb;
832 
833 
834  if (!NT_SUCCESS(Ext2OpenDevice(&FileSys, DriveRoot)))
835  {
836  DPRINT1("Mke2fs: Volume %wZ does not exist, ...\n", DriveRoot);
837  goto clean_up;
838  }
839 
840 
841  if (!NT_SUCCESS(Ext2GetMediaInfo(&FileSys)))
842  {
843  DPRINT1("Mke2fs: Can't get media information\n");
844  goto clean_up;
845  }
846 
848 
849  Ext2Sb.s_blocks_count = FileSys.PartInfo.PartitionLength.QuadPart /
850  EXT2_BLOCK_SIZE(&Ext2Sb);
851 
852 
853  /*
854  * Calculate number of inodes based on the inode ratio
855  */
856  Ext2Sb.s_inodes_count =
857  (ULONG)(((LONGLONG) Ext2Sb.s_blocks_count * EXT2_BLOCK_SIZE(&Ext2Sb)) / inode_ratio);
858 
859  /*
860  * Calculate number of blocks to reserve
861  */
862  Ext2Sb.s_r_blocks_count = (Ext2Sb.s_blocks_count * 5) / 100;
863 
864 
865  Status = Ext2LockVolume(&FileSys);
866  if (NT_SUCCESS(Status))
867  {
868  bLocked = TRUE;
869  }
870 
871 
872  // Initialize
873  if (!ext2_initialize_sb(&FileSys))
874  {
875  DPRINT1("Mke2fs: error...\n");
876  goto clean_up;
877  }
878 
879 
880  zap_sector(&FileSys, 2, 6);
881 
882  /*
883  * Generate a UUID for it...
884  */
885  {
886  __u8 uuid[16];
887  uuid_generate(&uuid[0]);
888  memcpy(&Ext2Sb.s_uuid[0], &uuid[0], 16);
889  }
890 
891  /*
892  * Add "jitter" to the superblock's check interval so that we
893  * don't check all the filesystems at the same time. We use a
894  * kludgy hack of using the UUID to derive a random jitter value.
895  */
896  {
897  ULONG i, val;
898 
899  for (i = 0, val = 0 ; i < sizeof(Ext2Sb.s_uuid); i++)
900  val += Ext2Sb.s_uuid[i];
901 
902  Ext2Sb.s_max_mnt_count += val % EXT2_DFL_MAX_MNT_COUNT;
903  }
904 
905  /*
906  * Set the volume label...
907  */
908  if (Label)
909  {
910  ANSI_STRING ansi_label;
911  ansi_label.MaximumLength = sizeof(Ext2Sb.s_volume_name);
912  ansi_label.Length = 0;
913  ansi_label.Buffer = Ext2Sb.s_volume_name;
915  }
916 
917  ext2_print_super(&Ext2Sb);
918 
919  bRet = ext2_allocate_tables(&FileSys);
920 
921  if (!bRet)
922  {
923  goto clean_up;
924  }
925 
926  /* rsv must be a power of two (64kB is MD RAID sb alignment) */
927  rsv = 65536 / FileSys.blocksize;
928  blocks = Ext2Sb.s_blocks_count;
929 
930 #ifdef ZAP_BOOTBLOCK
931  DPRINT1("Mke2fs: zeroing volume boot record\n");
932  zap_sector(&FileSys, 0, 2);
933 #endif
934 
935  /*
936  * Wipe out any old MD RAID (or other) metadata at the end
937  * of the device. This will also verify that the device is
938  * as large as we think. Be careful with very small devices.
939  */
940 
941  start = (blocks & ~(rsv - 1));
942  if (start > rsv)
943  start -= rsv;
944 
945  if (start > 0)
946  bRet = zero_blocks(&FileSys, start, blocks - start, &ret_blk, NULL);
947 
948  if (!bRet)
949  {
950  DPRINT1("Mke2fs: zeroing block %lu at end of filesystem", ret_blk);
951  goto clean_up;
952  }
953 
954  write_inode_tables(&FileSys);
955 
956  create_root_dir(&FileSys);
957  create_lost_and_found(&FileSys);
958 
959  ext2_reserve_inodes(&FileSys);
960 
961  create_bad_block_inode(&FileSys, NULL);
962 
963  DPRINT("Mke2fs: Writing superblocks and filesystem accounting information ... \n");
964 
965  if (!QuickFormat)
966  {
967  DPRINT1("Mke2fs: Slow format not supported yet\n");
968  }
969 
970  if (!ext2_flush(&FileSys))
971  {
972  bRet = false;
973  DPRINT1("Mke2fs: Warning, had trouble writing out superblocks.\n");
974  goto clean_up;
975  }
976 
977  DPRINT("Mke2fs: Writing superblocks and filesystem accounting information done!\n");
978 
979  bRet = true;
981 
982 clean_up:
983 
984  // Clean up ...
985  ext2_free_group_desc(&FileSys);
986 
987  ext2_free_block_bitmap(&FileSys);
988  ext2_free_inode_bitmap(&FileSys);
989 
990  if(bLocked)
991  {
992  Ext2DisMountVolume(&FileSys);
993  Ext2UnLockVolume(&FileSys);
994  }
995 
996  Ext2CloseDevice(&FileSys);
997 
998  if (Callback != NULL)
999  {
1000  Callback(DONE, 0, (PVOID)&bRet);
1001  }
1002 
1003  return Status;
1004 }
1005 
1006 NTSTATUS
1007 NTAPI
1010  IN BOOLEAN Verbose,
1011  IN BOOLEAN CheckOnlyIfDirty,
1012  IN BOOLEAN ScanDrive,
1014 {
1015  UNIMPLEMENTED;
1016  return STATUS_SUCCESS;
1017 }
bool ext2_save_inode(PEXT2_FILESYS Ext2Sys, ULONG no, PEXT2_INODE pInode)
Definition: Inode.c:59
static unsigned int block
Definition: xmlmemory.c:118
bool ext2_flush(PEXT2_FILESYS fs)
Definition: Mke2fs.c:525
struct mke2fs_defaults settings[]
static char default_str[]
Definition: Mke2fs.c:52
unsigned char __u8
Definition: compat.h:88
int blocksize
Definition: Mke2fs.h:154
_In_ ULONG_PTR _In_ ULONG _Out_ ULONG_PTR * pid
Definition: winddi.h:3835
#define IN
Definition: typedefs.h:38
bool write_primary_superblock(PEXT2_FILESYS Ext2Sys, PEXT2_SUPER_BLOCK super)
Definition: Mke2fs.c:492
#define TRUE
Definition: types.h:120
LARGE_INTEGER PartitionLength
Definition: ntdddisk.h:394
ULONG Ext2DataBlocks(PEXT2_FILESYS Ext2Sys, ULONG TotalBlocks)
Definition: Mke2fs.c:698
#define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV
Definition: ext3_fs.h:681
#define BSD_DISKMAGIC
BOOL Verbose
Definition: chkdsk.c:72
bool ext2_load_inode(PEXT2_FILESYS Ext2Sys, ULONG no, PEXT2_INODE pInode)
Definition: Inode.c:41
#define SUPERBLOCK_SIZE
Definition: Mke2fs.h:205
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
BOOLEAN NTAPI RtlTimeToSecondsSince1970(PLARGE_INTEGER Time, PULONG ElapsedSeconds)
bool ext2_add_entry(PEXT2_FILESYS Ext2Sys, ULONG parent, ULONG inode, int filetype, char *name)
Definition: Inode.c:619
superblock * sb
Definition: btrfs.c:3896
umode_t i_mode
Definition: fs.h:87
GLuint GLuint GLsizei count
Definition: gl.h:1545
NTSTATUS Ext2WriteDisk(PEXT2_FILESYS Ext2Sys, ULONGLONG Offset, ULONG Length, PVOID Buffer)
Definition: Disk.c:1059
unsigned char * PUCHAR
Definition: retypes.h:3
void ext2_inode_alloc_stats2(PEXT2_FILESYS fs, ULONG ino, int inuse, int isdir)
Definition: Memory.c:37
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:603
NTSTATUS Ext2OpenDevice(PEXT2_FILESYS Ext2Sys, PUNICODE_STRING DeviceName)
Definition: Disk.c:1282
NTSTATUS Ext2ReadDisk(IN PEXT2_VCB Vcb, IN ULONGLONG Offset, IN ULONG Size, IN PVOID Buffer, IN BOOLEAN bVerify)
Definition: block.c:539
void set_fs_defaults(const char *fs_type, PEXT2_SUPER_BLOCK super, int blocksize, int *inode_ratio)
Definition: Mke2fs.c:70
u32_t magic(void)
static HANDLE ULONG_PTR dwData
Definition: file.c:35
Definition: fmifs.h:68
#define EXT2_GOOD_OLD_REV
Definition: ext2_fs.h:426
void * arg
Definition: msvc.h:12
__u32 i_atime
Definition: fs.h:81
Definition: fs.h:235
NTSTATUS Ext2GetMediaInfo(PEXT2_FILESYS Ext2Sys)
Definition: Disk.c:1162
__u32 i_mtime
Definition: fs.h:83
void ext2_free_inode_bitmap(PEXT2_FILESYS Ext2Sys)
Definition: Bitmap.c:194
void ext2_block_alloc_stats(PEXT2_FILESYS fs, ULONG blk, int inuse)
Definition: Memory.c:61
Definition: fs.h:78
__u32 i_block[15]
Definition: fs.h:86
void ext2_print_super(PEXT2_SUPER_BLOCK pExt2Sb)
Definition: Super.c:20
#define EXT2_DFL_MAX_MNT_COUNT
Definition: ext2_fs.h:332
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
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
NTSTATUS Ext2UnLockVolume(PEXT2_FILESYS Ext2Sys)
Definition: Disk.c:1237
#define SECTOR_SIZE
Definition: winldr.h:34
#define BSD_MAGICDISK
bool ext2_expand_inode(PEXT2_FILESYS Ext2Sys, PEXT2_INODE Inode, ULONG newBlk)
Definition: Inode.c:212
const char * type
Definition: Mke2fs.c:55
void ext2_update_dynamic_rev(PEXT2_FILESYS fs)
Definition: Mke2fs.c:510
gid_t i_gid
Definition: fs.h:89
#define EXT2_VALID_FS
Definition: ext2_fs.h:310
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
int int_log2(int arg)
Definition: Mke2fs.c:26
void DPRINT(...)
Definition: polytest.cpp:61
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToAnsiString(PANSI_STRING DestinationString, PUNICODE_STRING SourceString, BOOLEAN AllocateDestinationString)
bool ext2_initialize_sb(PEXT2_FILESYS pExt2Sys)
Definition: Super.c:74
unsigned int dir
Definition: maze.c:112
bool ext2_allocate_tables(PEXT2_FILESYS Ext2Sys)
Definition: Memory.c:75
static int blocks
Definition: mkdosfs.c:527
BOOL QuickFormat
Definition: format.c:66
__u64 i_blocks
Definition: fs.h:85
GLuint GLfloat * val
Definition: glext.h:7180
#define EXT2_FEATURE_INCOMPAT_FILETYPE
Definition: ext2_fs.h:471
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
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:585
r l[0]
Definition: byte_order.h:167
#define EXT2_ROOT_INO
Definition: ext2.h:177
USHORT MaximumLength
Definition: env_spec_w32.h:377
int64_t LONGLONG
Definition: typedefs.h:66
__u32 i_ctime
Definition: fs.h:82
static WCHAR no[MAX_STRING_RESOURCE_LEN]
Definition: object.c:2340
bool zap_sector(PEXT2_FILESYS Ext2Sys, int sect, int nsect)
Definition: Mke2fs.c:187
BOOLEAN bLocked
Definition: Mke2fs.c:19
#define EXT2_NDIR_BLOCKS
Definition: ext2_fs.h:177
void ext2_free_block_bitmap(PEXT2_FILESYS Ext2Sys)
Definition: Bitmap.c:205
r parent
Definition: btrfs.c:2677
#define EXT2_DYNAMIC_REV
Definition: ext2_fs.h:427
loff_t i_size
Definition: fs.h:80
bool create_lost_and_found(PEXT2_FILESYS Ext2Sys)
Definition: Mke2fs.c:392
bool ext2_write_bitmaps(PEXT2_FILESYS fs)
Definition: Bitmap.c:342
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
uid_t i_uid
Definition: fs.h:88
uint64_t ULONGLONG
Definition: typedefs.h:65
struct ext2_dirent * PEXT2_DIR_ENTRY
Definition: ext2.h:174
DWORD ClusterSize
Definition: format.c:67
NTSTATUS NTAPI Ext2Chkdsk(IN PUNICODE_STRING DriveRoot, IN BOOLEAN FixErrors, IN BOOLEAN Verbose, IN BOOLEAN CheckOnlyIfDirty, IN BOOLEAN ScanDrive, IN PFMIFSCALLBACK Callback)
Definition: Mke2fs.c:1008
int int_log10(unsigned int arg)
Definition: Mke2fs.c:41
__u8 fs_type[8]
Definition: mkdosfs.c:363
GLuint GLuint num
Definition: glext.h:9618
NTSTATUS Ext2LockVolume(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: fsctl.c:136
bool ext2_reserve_inodes(PEXT2_FILESYS fs)
Definition: Inode.c:681
#define BLOCK_BITS
Definition: Mke2fs.c:695
int blocksize
Definition: Mke2fs.c:57
NTSTATUS Ext2DisMountVolume(PEXT2_FILESYS Ext2Sys)
Definition: Disk.c:1260
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define SUPERBLOCK_OFFSET
Definition: Mke2fs.h:204
bool ext2_bg_has_super(PEXT2_SUPER_BLOCK pExt2Sb, int group_block)
Definition: Group.c:30
bool create_bad_block_inode(PEXT2_FILESYS Ext2Sys, PEXT2_BADBLK_LIST bb_list)
Definition: Badblock.c:16
#define blk
Definition: linetest.c:70
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define LINUX_S_IFDIR
Definition: Mke2fs.h:85
void ext2_free_group_desc(PEXT2_FILESYS Ext2Sys)
Definition: Group.c:61
Status
Definition: gdiplustypes.h:24
bool ext2_mkdir(PEXT2_FILESYS fs, ULONG parent, ULONG inum, char *name, ULONG *no, PEXT2_INODE pid)
Definition: Mke2fs.c:233
__u32 umask
Definition: Mke2fs.h:170
bool zero_blocks(PEXT2_FILESYS fs, ULONG blk, ULONG num, ULONG *ret_blk, ULONG *ret_count)
Definition: Mke2fs.c:122
void uuid_generate(__u8 *uuid)
Definition: Uuid.c:17
#define STRIDE_LENGTH
BOOLEAN(NTAPI * PFMIFSCALLBACK)(IN CALLBACKCOMMAND Command, IN ULONG SubAction, IN PVOID ActionInfo)
Definition: fmifs.h:89
#define EXT2_BLOCK_SIZE(sb)
Definition: ext2.h:186
unsigned short USHORT
Definition: pedump.c:61
bool ext2_new_block(PEXT2_FILESYS fs, ULONG goal, PEXT2_BLOCK_BITMAP map, ULONG *ret)
Definition: Memory.c:254
GLuint start
Definition: gl.h:1545
NTSTATUS NTAPI Ext2Format(IN PUNICODE_STRING DriveRoot, IN FMIFS_MEDIA_FLAG MediaFlag, IN PUNICODE_STRING Label, IN BOOLEAN QuickFormat, IN ULONG ClusterSize, IN PFMIFSCALLBACK Callback)
Definition: Mke2fs.c:803
ULONG Ext2TotalBlocks(PEXT2_FILESYS Ext2Sys, ULONG DataBlocks)
Definition: Mke2fs.c:750
int inode_ratio
Definition: Mke2fs.c:58
PARTITION_INFORMATION PartInfo
Definition: Mke2fs.h:186
BOOL FixErrors
Definition: chkdsk.c:69
#define DPRINT1
Definition: precomp.h:8
bool ext2_new_inode(PEXT2_FILESYS fs, ULONG dir, int mode, PEXT2_INODE_BITMAP map, ULONG *ret)
Definition: Inode.c:84
#define EXT2_GOOD_OLD_INODE_SIZE
Definition: ext2.h:54
#define EXT2_GOOD_OLD_FIRST_INO
Definition: ext2_fs.h:66
int inode_ratio
Definition: Mke2fs.c:17
Definition: name.c:36
bool create_root_dir(PEXT2_FILESYS fs)
Definition: Mke2fs.c:364
Definition: msctf.idl:510
unsigned int ULONG
Definition: retypes.h:1
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#define UNIMPLEMENTED
Definition: debug.h:114
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
PWCHAR Label
Definition: format.c:70
NTSTATUS NTAPI NtQuerySystemTime(OUT PLARGE_INTEGER SystemTime)
Definition: time.c:417
char * cleanup(char *str)
Definition: wpickclick.c:99
LOCAL char * filetype(int t)
Definition: tree.c:114
bool ext2_write_block(PEXT2_FILESYS fs, ULONG block, void *inbuf)
Definition: Memory.c:394
#define DONE
Definition: rnr20lib.h:14
bool ext2_new_dir_block(PEXT2_FILESYS fs, ULONG dir_ino, ULONG parent_ino, char **block)
Definition: Memory.c:349
GLfloat GLfloat p
Definition: glext.h:8902
NTSTATUS Ext2CloseDevice(PEXT2_FILESYS Ext2Sys)
Definition: Disk.c:1342
#define EXT2_BLOCKS_PER_GROUP(s)
Definition: ext2_fs.h:169
return STATUS_SUCCESS
Definition: btrfs.c:2745
bool create_journal_dev(PEXT2_FILESYS fs)
Definition: Mke2fs.c:654
__u16 i_links_count
Definition: ext2_fs.h:233
#define BSD_LABEL_OFFSET
#define memset(x, y, z)
Definition: compat.h:39
LPFNPSPCALLBACK Callback
Definition: desk.c:111
bool write_inode_tables(PEXT2_FILESYS fs)
Definition: Memory.c:221
#define EXT2_MIN_BLOCK_LOG_SIZE
Definition: ext2_fs.h:83
PEXT2_SUPER_BLOCK ext2_sb
Definition: Mke2fs.h:159
LONGLONG QuadPart
Definition: typedefs.h:112
bool ext2_alloc_block(PEXT2_FILESYS fs, ULONG goal, ULONG *ret)
Definition: Memory.c:293
FMIFS_MEDIA_FLAG
Definition: fmifs.h:37