ReactOS  0.4.15-dev-2965-g9a42267
generic.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYRIGHT.TXT
3  * PROJECT: Ext2 File System Driver for WinNT/2K/XP
4  * FILE: generic.c
5  * PROGRAMMER: Matt Wu <mattwu@163.com>
6  * HOMEPAGE: http://www.ext2fsd.com
7  * UPDATE HISTORY:
8  */
9 
10 /* INCLUDES *****************************************************************/
11 
12 #include "ext2fs.h"
13 #include "linux/ext4.h"
14 
15 /* GLOBALS ***************************************************************/
16 
18 
19 /* DEFINITIONS *************************************************************/
20 
21 
22 /* FUNCTIONS ***************************************************************/
23 
28 {
30  PEXT2_SUPER_BLOCK Ext2Sb = NULL;
31 
32  Ext2Sb = (PEXT2_SUPER_BLOCK)
34  PagedPool,
37  );
38  if (!Ext2Sb) {
40  goto errorout;
41  }
42 
44  Vcb,
47  (PVOID) Ext2Sb,
48  bVerify );
49 
50  if (!NT_SUCCESS(Status)) {
51  Ext2FreePool(Ext2Sb, EXT2_SB_MAGIC);
52  Ext2Sb = NULL;
53  }
54 
55 errorout:
56 
57  *Sb = Ext2Sb;
58  return Status;
59 }
60 
61 
62 BOOLEAN
64  IN PEXT2_IRP_CONTEXT IrpContext,
66 )
67 {
69  BOOLEAN rc;
70 
72  rc = Ext2SaveBuffer( IrpContext,
73  Vcb,
74  offset,
76  Vcb->SuperBlock
77  );
78 
79  if (IsFlagOn(Vcb->Flags, VCB_FLOPPY_DISK)) {
81  }
82 
83  return rc;
84 }
85 
86 
87 BOOLEAN
89  IN PEXT2_IRP_CONTEXT IrpContext,
91 )
92 {
95 
97  if (!CcCopyRead(
98  Vcb->Volume,
101  TRUE,
102  (PVOID)Vcb->SuperBlock,
103  &iosb )) {
104  return FALSE;
105  }
106 
107  if (!NT_SUCCESS(iosb.Status)) {
108  return FALSE;
109  }
110 
111  /* reload root inode */
112  if (Vcb->McbTree) {
113 
114  if (!Ext2LoadInode(Vcb, &Vcb->McbTree->Inode))
115  return FALSE;
116 
117  /* initializeroot node */
118  Vcb->McbTree->CreationTime = Ext2NtTime(Vcb->McbTree->Inode.i_ctime);
119  Vcb->McbTree->LastAccessTime = Ext2NtTime(Vcb->McbTree->Inode.i_atime);
120  Vcb->McbTree->LastWriteTime = Ext2NtTime(Vcb->McbTree->Inode.i_mtime);
121  Vcb->McbTree->ChangeTime = Ext2NtTime(Vcb->McbTree->Inode.i_mtime);
122  }
123 
124  return TRUE;
125 }
126 
127 VOID
129 {
130  struct ext3_sb_info *sbi = &Vcb->sbi;
131  unsigned long i;
132 
133  if (NULL == Vcb->sbi.s_gd) {
134  return;
135  }
136 
137  for (i = 0; i < Vcb->sbi.s_gdb_count; i++) {
138  if (Vcb->sbi.s_gd[i].bh) {
139  fini_bh(&sbi->s_gd[i].bh);
140  Vcb->sbi.s_gd[i].bh = NULL;
141  }
142  }
143 }
144 
145 VOID
147 {
148  struct ext3_sb_info *sbi = &Vcb->sbi;
149  unsigned long i;
150 
151 
152  if (NULL == Vcb->sbi.s_gd) {
153  return;
154  }
155 
157 
158  kfree(Vcb->sbi.s_gd);
159  Vcb->sbi.s_gd = NULL;
160 
161  ClearFlag(Vcb->Flags, VCB_GD_LOADED);
162 }
163 
164 
165 BOOLEAN
167 {
168  struct super_block *sb = &Vcb->sb;
169  struct ext3_sb_info *sbi = &Vcb->sbi;
170  unsigned long i;
171  BOOLEAN rc = FALSE;
172 
173  _SEH2_TRY {
174 
175  ExAcquireResourceExclusiveLite(&Vcb->sbi.s_gd_lock, TRUE);
176  ASSERT (NULL != sbi->s_gd);
177 
178  for (i = 0; i < sbi->s_gdb_count; i++) {
179  ASSERT (sbi->s_gd[i].block);
180  if (sbi->s_gd[i].bh)
181  continue;
182  sbi->s_gd[i].bh = sb_getblk(sb, sbi->s_gd[i].block);
183  if (!sbi->s_gd[i].bh) {
184  DEBUG(DL_ERR, ("Ext2LoadGroupBH: can't read group descriptor %d\n", i));
185  DbgBreak();
186  _SEH2_LEAVE;
187  }
188  sbi->s_gd[i].gd = (struct ext4_group_desc *)sbi->s_gd[i].bh->b_data;
189  }
190 
191  rc = TRUE;
192 
193  } _SEH2_FINALLY {
194 
195  ExReleaseResourceLite(&Vcb->sbi.s_gd_lock);
196  } _SEH2_END;
197 
198  return rc;
199 }
200 
201 
202 BOOLEAN
204 {
205  struct super_block *sb = &Vcb->sb;
206  struct ext3_sb_info *sbi = &Vcb->sbi;
207  ext3_fsblk_t sb_block = 1;
208  unsigned long i;
209  BOOLEAN rc = FALSE;
210 
211  _SEH2_TRY {
212 
213  ExAcquireResourceExclusiveLite(&Vcb->sbi.s_gd_lock, TRUE);
214 
215  if (NULL == sbi->s_gd) {
216  sbi->s_gd = kzalloc(sbi->s_gdb_count * sizeof(struct ext3_gd),
217  GFP_KERNEL);
218  }
219  if (sbi->s_gd == NULL) {
220  DEBUG(DL_ERR, ("Ext2LoadGroup: not enough memory.\n"));
221  _SEH2_LEAVE;
222  }
223 
225  sb_block = EXT4_MIN_BLOCK_SIZE / BLOCK_SIZE;
226  }
227 
228  for (i = 0; i < sbi->s_gdb_count; i++) {
229  sbi->s_gd[i].block = descriptor_loc(sb, sb_block, i);
230  if (!sbi->s_gd[i].block) {
231  DEBUG(DL_ERR, ("Ext2LoadGroup: can't locate group descriptor %d\n", i));
232  _SEH2_LEAVE;
233  }
234  }
235 
236  if (!Ext2LoadGroupBH(Vcb)) {
237  DEBUG(DL_ERR, ("Ext2LoadGroup: Failed to load group descriptions !\n"));
238  _SEH2_LEAVE;
239  }
240 
241  if (!ext4_check_descriptors(sb)) {
242  DbgBreak();
243  DEBUG(DL_ERR, ("Ext2LoadGroup: group descriptors corrupted !\n"));
244  _SEH2_LEAVE;
245  }
246 
247  SetFlag(Vcb->Flags, VCB_GD_LOADED);
248  rc = TRUE;
249 
250  } _SEH2_FINALLY {
251 
252  if (!rc)
253  Ext2PutGroup(Vcb);
254 
255  ExReleaseResourceLite(&Vcb->sbi.s_gd_lock);
256  } _SEH2_END;
257 
258  return rc;
259 }
260 
261 VOID
263 {
264  struct ext3_sb_info *sbi = &Vcb->sbi;
265 
266  /* do nothing if Vcb is not initialized yet */
267  if (!IsFlagOn(Vcb->Flags, VCB_INITIALIZED))
268  return;
269 
270  _SEH2_TRY {
271 
272  /* acquire bd lock to avoid bh creation */
273  ExAcquireResourceExclusiveLite(&Vcb->bd.bd_bh_lock, TRUE);
274 
275  SetFlag(Vcb->Flags, VCB_BEING_DROPPED);
277 
278  while (!IsListEmpty(&Vcb->bd.bd_bh_free)) {
279  struct buffer_head *bh;
280  PLIST_ENTRY l;
281  l = RemoveHeadList(&Vcb->bd.bd_bh_free);
282  bh = CONTAINING_RECORD(l, struct buffer_head, b_link);
284  if (0 == atomic_read(&bh->b_count)) {
285  buffer_head_remove(&Vcb->bd, bh);
286  free_buffer_head(bh);
287  }
288  }
289 
290  } _SEH2_FINALLY {
291  ExReleaseResourceLite(&Vcb->bd.bd_bh_lock);
292  } _SEH2_END;
293 
295 }
296 
297 
298 VOID
300 {
301  ULONG len;
302 
303  if (e.QuadPart <= s.QuadPart)
304  return;
305 
306  /* loop per 2G */
307  while (s.QuadPart < e.QuadPart) {
308  if (e.QuadPart > s.QuadPart + 1024 * 1024 * 1024) {
309  len = 1024 * 1024 * 1024;
310  } else {
311  len = (ULONG) (e.QuadPart - s.QuadPart);
312  }
313  CcFlushCache(&Vcb->SectionObject, &s, len, NULL);
314  s.QuadPart += len;
315  }
316 }
317 
318 NTSTATUS
320 {
321  LARGE_INTEGER s = {0}, o;
322  struct ext3_sb_info *sbi = &Vcb->sbi;
323  struct rb_node *node;
324  struct buffer_head *bh;
325 
326  if (!IsFlagOn(Vcb->Flags, VCB_GD_LOADED)) {
327  CcFlushCache(&Vcb->SectionObject, NULL, 0, NULL);
328  goto errorout;
329  }
330 
332 
333  _SEH2_TRY {
334 
335  /* acqurie gd block */
336  ExAcquireResourceExclusiveLite(&Vcb->sbi.s_gd_lock, TRUE);
337 
338  /* acquire bd lock to avoid bh creation */
339  ExAcquireResourceExclusiveLite(&Vcb->bd.bd_bh_lock, TRUE);
340 
341  /* drop unused bh */
342  Ext2DropBH(Vcb);
343 
344  /* flush volume with all outstanding bh skipped */
345 
346  node = rb_first(&Vcb->bd.bd_bh_root);
347  while (node) {
348 
349  bh = container_of(node, struct buffer_head, b_rb_node);
350  node = rb_next(node);
351 
352  o.QuadPart = bh->b_blocknr << BLOCK_BITS;
353  ASSERT(o.QuadPart >= s.QuadPart);
354 
355  if (o.QuadPart == s.QuadPart) {
356  s.QuadPart = s.QuadPart + bh->b_size;
357  continue;
358  }
359 
360  if (o.QuadPart > s.QuadPart) {
361  Ext2FlushRange(Vcb, s, o);
362  s.QuadPart = (bh->b_blocknr << BLOCK_BITS) + bh->b_size;
363  continue;
364  }
365  }
366 
367  o = Vcb->PartitionInformation.PartitionLength;
368  Ext2FlushRange(Vcb, s, o);
369 
370  } _SEH2_FINALLY {
371 
372  ExReleaseResourceLite(&Vcb->bd.bd_bh_lock);
373  ExReleaseResourceLite(&Vcb->sbi.s_gd_lock);
374  } _SEH2_END;
375 
376 errorout:
377  return STATUS_SUCCESS;
378 }
379 
380 
381 BOOLEAN
383  IN PEXT2_IRP_CONTEXT IrpContext,
384  IN PEXT2_VCB Vcb,
385  IN ULONG Group
386 )
387 {
388  struct ext4_group_desc *gd;
389  struct buffer_head *gb = NULL;
390  unsigned long i;
391 
392  gd = ext4_get_group_desc(&Vcb->sb, Group, &gb);
393  if (!gd)
394  return 0;
395 
396  gd->bg_checksum = ext4_group_desc_csum(&Vcb->sbi, Group, gd);
397  mark_buffer_dirty(gb);
398  fini_bh(&gb);
399 
400  return TRUE;
401 }
402 
403 
404 BOOLEAN
406  IN PEXT2_IRP_CONTEXT IrpContext,
408 )
409 {
410  return TRUE;
411 }
412 
413 BOOLEAN
415  IN PEXT2_VCB Vcb,
416  IN ULONG inode,
418 )
419 {
420  PEXT2_GROUP_DESC gd;
421  struct buffer_head *bh = NULL;
422  ext4_fsblk_t loc;
423  int group;
424 
426  DEBUG(DL_ERR, ( "Ext2GetInodeLba: Inode value %xh is invalid.\n",inode));
427  *offset = 0;
428  return FALSE;
429  }
430 
431  group = (inode - 1) / INODES_PER_GROUP ;
432  gd = ext4_get_group_desc(&Vcb->sb, group, &bh);
433  if (!bh) {
434  *offset = 0;
435  DbgBreak();
436  return FALSE;
437  }
438  loc = (LONGLONG)ext4_inode_table(&Vcb->sb, gd);
439  loc = loc << BLOCK_BITS;
440  loc = loc + ((inode - 1) % INODES_PER_GROUP) * Vcb->InodeSize;
441 
442  *offset = loc;
443  __brelse(bh);
444 
445  return TRUE;
446 }
447 
448 void Ext2DecodeInode(struct inode *dst, struct ext3_inode *src)
449 {
450  dst->i_mode = src->i_mode;
451  dst->i_flags = src->i_flags;
452  dst->i_uid = src->i_uid;
453  dst->i_gid = src->i_gid;
454  dst->i_nlink = src->i_links_count;
455  dst->i_generation = src->i_generation;
456  dst->i_size = src->i_size;
457  if (S_ISREG(src->i_mode)) {
458  dst->i_size |= (loff_t)src->i_size_high << 32;
459  }
460  dst->i_file_acl = src->i_file_acl_lo;
461  dst->i_file_acl |= (ext4_fsblk_t)src->osd2.linux2.l_i_file_acl_high << 32;
462  dst->i_atime = src->i_atime;
463  dst->i_ctime = src->i_ctime;
464  dst->i_mtime = src->i_mtime;
465  dst->i_dtime = src->i_dtime;
466  dst->i_blocks = ext3_inode_blocks(src, dst);
467  memcpy(&dst->i_block[0], &src->i_block[0], sizeof(__u32) * 15);
470  dst->i_extra_isize = src->i_extra_isize;
471  else
472  dst->i_extra_isize = 0;
473 }
474 
475 void Ext2EncodeInode(struct ext3_inode *dst, struct inode *src)
476 {
477  dst->i_mode = src->i_mode;
478  dst->i_flags = src->i_flags;
479  dst->i_uid = src->i_uid;
480  dst->i_gid = src->i_gid;
481  dst->i_links_count = src->i_nlink;
482  dst->i_generation = src->i_generation;
483  dst->i_size = (__u32)src->i_size;
484  if (S_ISREG(src->i_mode)) {
485  dst->i_size_high = (__u32)(src->i_size >> 32);
486  }
487  dst->i_file_acl_lo = (__u32)src->i_file_acl;
488  dst->osd2.linux2.l_i_file_acl_high |= (__u16)(src->i_file_acl >> 32);
489  dst->i_atime = src->i_atime;
490  dst->i_ctime = src->i_ctime;
491  dst->i_mtime = src->i_mtime;
492  dst->i_dtime = src->i_dtime;
493  dst->i_extra_isize = src->i_extra_isize;
494  ASSERT(src->i_sb);
496  memcpy(&dst->i_block[0], &src->i_block[0], sizeof(__u32) * 15);
499  dst->i_extra_isize = src->i_extra_isize;
500 }
501 
502 
503 BOOLEAN
505  IN struct inode *Inode)
506 {
507  struct ext3_inode ext3i = {0};
509 
510  if (!Ext2GetInodeLba(Vcb, Inode->i_ino, &offset)) {
511  DEBUG(DL_ERR, ("Ext2LoadInode: failed inode %u.\n", Inode->i_ino));
512  return FALSE;
513  }
514 
515  if (!Ext2LoadBuffer(NULL, Vcb, offset, sizeof(ext3i), &ext3i)) {
516  return FALSE;
517  }
518 
519  Ext2DecodeInode(Inode, &ext3i);
520 
521  return TRUE;
522 }
523 
524 
525 BOOLEAN
527  IN PEXT2_IRP_CONTEXT IrpContext,
528  IN PEXT2_VCB Vcb,
529  IN ULONG Inode)
530 {
531  LONGLONG Offset = 0;
532  BOOLEAN rc;
533 
534  rc = Ext2GetInodeLba(Vcb, Inode, &Offset);
535  if (!rc) {
536  DEBUG(DL_ERR, ( "Ext2SaveInode: failed inode %u.\n", Inode));
537  goto errorout;
538  }
539 
540  rc = Ext2ZeroBuffer(IrpContext, Vcb, Offset, Vcb->InodeSize);
541 
542 errorout:
543 
544  return rc;
545 }
546 
547 BOOLEAN
549  IN PEXT2_VCB Vcb,
550  IN struct inode *Inode)
551 {
552  struct ext3_inode ext3i = {0};
553 
554  LONGLONG Offset = 0;
555  ULONG InodeSize = sizeof(ext3i);
556  BOOLEAN rc = 0;
557 
558  DEBUG(DL_INF, ( "Ext2SaveInode: Saving Inode %xh: Mode=%xh Size=%xh\n",
559  Inode->i_ino, Inode->i_mode, Inode->i_size));
560  rc = Ext2GetInodeLba(Vcb, Inode->i_ino, &Offset);
561  if (!rc) {
562  DEBUG(DL_ERR, ( "Ext2SaveInode: failed inode %u.\n", Inode->i_ino));
563  goto errorout;
564  }
565 
566  rc = Ext2LoadBuffer(NULL, Vcb, Offset, InodeSize, &ext3i);
567  if (!rc) {
568  DEBUG(DL_ERR, ( "Ext2SaveInode: failed reading inode %u.\n", Inode->i_ino));
569  goto errorout;;
570  }
571 
572  Ext2EncodeInode(&ext3i, Inode);
573  if (InodeSize > Vcb->InodeSize)
574  InodeSize = Vcb->InodeSize;
575  rc = Ext2SaveBuffer(IrpContext, Vcb, Offset, InodeSize, &ext3i);
576 
577  if (rc && IsFlagOn(Vcb->Flags, VCB_FLOPPY_DISK)) {
579  }
580 
581 errorout:
582  return rc;
583 }
584 
585 BOOLEAN
587  IN struct inode *Inode,
588  IN PEXT2_INODE InodeXattr)
589 {
592 
593  if (!Ext2GetInodeLba(Vcb, Inode->i_ino, &Offset)) {
594  DEBUG(DL_ERR, ("Ext2LoadRawInode: error get inode(%xh)'s addr.\n", Inode->i_ino));
595  return FALSE;
596  }
597 
598  if (!CcCopyRead(
599  Vcb->Volume,
601  Vcb->InodeSize,
602  PIN_WAIT,
603  (PVOID)InodeXattr,
604  &IoStatus)) {
605  return FALSE;
606  }
607 
608  if (!NT_SUCCESS(IoStatus.Status)) {
609  return FALSE;
610  }
611 
612  Ext2EncodeInode(InodeXattr, Inode);
613  return TRUE;
614 }
615 
616 BOOLEAN
618  IN PEXT2_VCB Vcb,
619  IN struct inode *Inode,
620  IN PEXT2_INODE InodeXattr)
621 {
623  LONGLONG Offset = 0;
624  ULONG InodeSize = Vcb->InodeSize;
625  BOOLEAN rc = 0;
626 
627  /* There is no way to put EA information in such a small inode */
628  if (InodeSize == EXT2_GOOD_OLD_INODE_SIZE)
629  return FALSE;
630 
631  DEBUG(DL_INF, ("Ext2SaveInodeXattr: Saving Inode %xh: Mode=%xh Size=%xh\n",
632  Inode->i_ino, Inode->i_mode, Inode->i_size));
633  rc = Ext2GetInodeLba(Vcb, Inode->i_ino, &Offset);
634  if (!rc) {
635  DEBUG(DL_ERR, ("Ext2SaveInodeXattr: error get inode(%xh)'s addr.\n", Inode->i_ino));
636  goto errorout;
637  }
638 
639  rc = Ext2SaveBuffer(IrpContext,
640  Vcb,
641  Offset + EXT2_GOOD_OLD_INODE_SIZE + Inode->i_extra_isize,
642  InodeSize - EXT2_GOOD_OLD_INODE_SIZE - Inode->i_extra_isize,
643  (char *)InodeXattr + EXT2_GOOD_OLD_INODE_SIZE + Inode->i_extra_isize);
644 
645  if (rc && IsFlagOn(Vcb->Flags, VCB_FLOPPY_DISK)) {
647  }
648 
649 errorout:
650  return rc;
651 }
652 
653 
654 BOOLEAN
656  IN ULONG Index,
657  IN PVOID Buffer )
658 {
659  struct buffer_head *bh = NULL;
660  BOOLEAN rc = 0;
661 
662  _SEH2_TRY {
663 
664  bh = sb_getblk(&Vcb->sb, (sector_t)Index);
665 
666  if (!bh) {
667  DEBUG(DL_ERR, ("Ext2Loadblock: can't load block %u\n", Index));
668  DbgBreak();
669  _SEH2_LEAVE;
670  }
671 
672  if (!buffer_uptodate(bh)) {
673  int err = bh_submit_read(bh);
674  if (err < 0) {
675  DEBUG(DL_ERR, ("Ext2LoadBlock: reading failed %d\n", err));
676  _SEH2_LEAVE;
677  }
678  }
679 
681  rc = TRUE;
682 
683  } _SEH2_FINALLY {
684 
685  if (bh)
686  fini_bh(&bh);
687  } _SEH2_END;
688 
689  return rc;
690 }
691 
692 
693 BOOLEAN
695  IN PEXT2_VCB Vcb,
696  IN ULONG Index,
697  IN PVOID Buf )
698 {
699  struct buffer_head *bh = NULL;
700  BOOLEAN rc = 0;
701 
702  _SEH2_TRY {
703 
704  bh = sb_getblk_zero(&Vcb->sb, (sector_t)Index);
705 
706  if (!bh) {
707  DEBUG(DL_ERR, ("Ext2Saveblock: can't load block %u\n", Index));
708  DbgBreak();
709  _SEH2_LEAVE;
710  }
711 
712  if (!buffer_uptodate(bh)) {
713  }
714 
715  RtlCopyMemory(bh->b_data, Buf, BLOCK_SIZE);
716  mark_buffer_dirty(bh);
717  rc = TRUE;
718 
719  } _SEH2_FINALLY {
720 
721  if (bh)
722  fini_bh(&bh);
723  } _SEH2_END;
724 
725  return rc;
726 }
727 
728 BOOLEAN
730  IN PEXT2_VCB Vcb,
732  IN ULONG size,
733  IN PVOID buf )
734 {
735  struct buffer_head *bh = NULL;
736  BOOLEAN rc;
737 
738  _SEH2_TRY {
739 
740  while (size) {
741 
742  sector_t block;
743  ULONG len = 0, delta = 0;
744 
745  block = (sector_t) (offset >> BLOCK_BITS);
746  delta = (ULONG)offset & (BLOCK_SIZE - 1);
747  len = BLOCK_SIZE - delta;
748  if (size < len)
749  len = size;
750 
751  bh = sb_getblk(&Vcb->sb, block);
752  if (!bh) {
753  DEBUG(DL_ERR, ("Ext2SaveBuffer: can't load block %I64u\n", block));
754  DbgBreak();
755  _SEH2_LEAVE;
756  }
757 
758  if (!buffer_uptodate(bh)) {
759  int err = bh_submit_read(bh);
760  if (err < 0) {
761  DEBUG(DL_ERR, ("Ext2SaveBuffer: bh_submit_read failed: %d\n", err));
762  _SEH2_LEAVE;
763  }
764  }
765 
766  _SEH2_TRY {
767  RtlCopyMemory(buf, bh->b_data + delta, len);
768  } _SEH2_FINALLY {
769  fini_bh(&bh);
770  } _SEH2_END;
771 
772  buf = (PUCHAR)buf + len;
773  offset = offset + len;
774  size = size - len;
775  }
776 
777  rc = TRUE;
778 
779  } _SEH2_FINALLY {
780 
781  if (bh)
782  fini_bh(&bh);
783 
784  } _SEH2_END;
785 
786  return rc;
787 }
788 
789 
790 BOOLEAN
792  IN PEXT2_VCB Vcb,
794  IN ULONG size
795  )
796 {
797  struct buffer_head *bh = NULL;
798  BOOLEAN rc = 0;
799 
800  _SEH2_TRY {
801 
802  while (size) {
803 
804  sector_t block;
805  ULONG len = 0, delta = 0;
806 
807  block = (sector_t) (offset >> BLOCK_BITS);
808  delta = (ULONG)offset & (BLOCK_SIZE - 1);
809  len = BLOCK_SIZE - delta;
810  if (size < len)
811  len = size;
812 
813  if (delta == 0 && len >= BLOCK_SIZE) {
814  bh = sb_getblk_zero(&Vcb->sb, block);
815  } else {
816  bh = sb_getblk(&Vcb->sb, block);
817  }
818 
819  if (!bh) {
820  DEBUG(DL_ERR, ("Ext2SaveBuffer: can't load block %I64u\n", block));
821  DbgBreak();
822  _SEH2_LEAVE;
823  }
824 
825  if (!buffer_uptodate(bh)) {
826  int err = bh_submit_read(bh);
827  if (err < 0) {
828  DEBUG(DL_ERR, ("Ext2SaveBuffer: bh_submit_read failed: %d\n", err));
829  _SEH2_LEAVE;
830  }
831  }
832 
833  _SEH2_TRY {
834  if (delta == 0 && len >= BLOCK_SIZE) {
835  /* bh (cache) was already cleaned as zero */
836  } else {
837  RtlZeroMemory(bh->b_data + delta, len);
838  }
839  mark_buffer_dirty(bh);
840  } _SEH2_FINALLY {
841  fini_bh(&bh);
842  } _SEH2_END;
843 
844  offset = offset + len;
845  size = size - len;
846  }
847 
848  rc = TRUE;
849 
850  } _SEH2_FINALLY {
851 
852  if (bh)
853  fini_bh(&bh);
854 
855  } _SEH2_END;
856 
857  return rc;
858 }
859 
860 
861 #define SIZE_256K 0x40000
862 
863 BOOLEAN
865  IN PEXT2_VCB Vcb,
867  IN ULONG Size,
868  IN PVOID Buf )
869 {
870  BOOLEAN rc;
871 
872  while (Size) {
873 
874  PBCB Bcb;
875  PVOID Buffer;
876  ULONG Length;
877 
878  Length = (ULONG)Offset & (SIZE_256K - 1);
879  Length = SIZE_256K - Length;
880  if (Size < Length)
881  Length = Size;
882 
883  if ( !CcPreparePinWrite(
884  Vcb->Volume,
885  (PLARGE_INTEGER) (&Offset),
886  Length,
887  FALSE,
889  &Bcb,
890  &Buffer )) {
891 
892  DEBUG(DL_ERR, ( "Ext2SaveBuffer: failed to PinLock offset %I64xh ...\n", Offset));
893  return FALSE;
894  }
895 
896  _SEH2_TRY {
897 
898  RtlCopyMemory(Buffer, Buf, Length);
900  SetFlag(Vcb->Volume->Flags, FO_FILE_MODIFIED);
901 
903  if (!rc) {
904  DbgBreak();
905  Ext2Sleep(100);
907  }
908 
909  } _SEH2_FINALLY {
910  CcUnpinData(Bcb);
911  } _SEH2_END;
912 
913  Buf = (PUCHAR)Buf + Length;
914  Offset = Offset + Length;
915  Size = Size - Length;
916  }
917 
918  return rc;
919 }
920 
921 
922 VOID
924  IN PEXT2_IRP_CONTEXT IrpContext,
926 )
927 {
928  Vcb->SuperBlock->s_free_inodes_count = ext4_count_free_inodes(&Vcb->sb);
930  Ext2SaveSuper(IrpContext, Vcb);
931 }
932 
933 NTSTATUS
935  IN PEXT2_IRP_CONTEXT IrpContext,
936  IN PEXT2_VCB Vcb,
937  IN ULONG GroupHint,
938  IN ULONG BlockHint,
939  OUT PULONG Block,
941 )
942 {
943  struct super_block *sb = &Vcb->sb;
944  PEXT2_GROUP_DESC gd;
945  struct buffer_head *gb = NULL;
946  struct buffer_head *bh = NULL;
947  ext4_fsblk_t bitmap_blk;
948 
949  RTL_BITMAP BlockBitmap;
950 
951  ULONG Group = 0;
952  ULONG Index = 0xFFFFFFFF;
953  ULONG dwHint = 0;
954  ULONG Count = 0;
955  ULONG Length = 0;
956 
958 
959  *Block = 0;
960 
962 
963  /* validate the hint group and hint block */
964  if (GroupHint >= Vcb->sbi.s_groups_count) {
965  DbgBreak();
966  GroupHint = Vcb->sbi.s_groups_count - 1;
967  }
968 
969  if (BlockHint != 0) {
970  GroupHint = (BlockHint - EXT2_FIRST_DATA_BLOCK) / BLOCKS_PER_GROUP;
971  dwHint = (BlockHint - EXT2_FIRST_DATA_BLOCK) % BLOCKS_PER_GROUP;
972  }
973 
974  Group = GroupHint;
975 
976 Again:
977 
978  if (bh)
979  fini_bh(&bh);
980 
981  if (gb)
982  fini_bh(&gb);
983 
984  gd = ext4_get_group_desc(sb, Group, &gb);
985  if (!gd) {
986  DbgBreak();
988  goto errorout;
989  }
990 
991  bitmap_blk = ext4_block_bitmap(sb, gd);
992 
993  if (gd->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
994  bh = sb_getblk_zero(sb, bitmap_blk);
995  if (!bh) {
996  DbgBreak();
998  goto errorout;
999  }
1000  gd->bg_checksum = ext4_group_desc_csum(EXT3_SB(sb), Group, gd);
1001  ext4_init_block_bitmap(sb, bh, Group, gd);
1002  set_buffer_uptodate(bh);
1003  gd->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT);
1004  Ext2SaveGroup(IrpContext, Vcb, Group);
1005  } else {
1006  bh = sb_getblk(sb, bitmap_blk);
1007  if (!bh) {
1008  DbgBreak();
1010  goto errorout;
1011  }
1012  }
1013 
1014  if (!buffer_uptodate(bh)) {
1015  int err = bh_submit_read(bh);
1016  if (err < 0) {
1017  DbgPrint("bh_submit_read error! err: %d\n", err);
1019  goto errorout;
1020  }
1021  }
1022 
1023  if (ext4_free_blks_count(sb, gd)) {
1024 
1025  if (Group == Vcb->sbi.s_groups_count - 1) {
1026 
1028 
1029  /* s_blocks_count is integer multiple of s_blocks_per_group */
1030  if (Length == 0) {
1032  }
1033  } else {
1035  }
1036 
1037  /* initialize bitmap buffer */
1038  RtlInitializeBitMap(&BlockBitmap, (PULONG)bh->b_data, Length);
1039 
1040  /* try to find a clear bit range */
1041  Index = RtlFindClearBits(&BlockBitmap, *Number, dwHint);
1042 
1043  /* We could not get new block in the prefered group */
1044  if (Index == 0xFFFFFFFF) {
1045 
1046  /* search clear bits from the hint block */
1047  Count = RtlFindNextForwardRunClear(&BlockBitmap, dwHint, &Index);
1048  if (dwHint != 0 && Count == 0) {
1049  /* search clear bits from the very beginning */
1050  Count = RtlFindNextForwardRunClear(&BlockBitmap, 0, &Index);
1051  }
1052 
1053  if (Count == 0) {
1054 
1055  RtlZeroMemory(&BlockBitmap, sizeof(RTL_BITMAP));
1056 
1057  /* no blocks found: set bg_free_blocks_count to 0 */
1058  ext4_free_blks_set(sb, gd, 0);
1059  Ext2SaveGroup(IrpContext, Vcb, Group);
1060 
1061  /* will try next group */
1062  goto Again;
1063 
1064  } else {
1065 
1066  /* we got free blocks */
1067  if (Count <= *Number) {
1068  *Number = Count;
1069  }
1070  }
1071  }
1072 
1073  } else {
1074 
1075  /* try next group */
1076  dwHint = 0;
1077  Group = (Group + 1) % Vcb->sbi.s_groups_count;
1078  if (Group != GroupHint) {
1079  goto Again;
1080  }
1081 
1082  Index = 0xFFFFFFFF;
1083  }
1084 
1085  if (Index < Length) {
1086 
1087  /* mark block bits as allocated */
1088  RtlSetBits(&BlockBitmap, Index, *Number);
1089 
1090  /* set block bitmap dirty in cache */
1091  mark_buffer_dirty(bh);
1092 
1093  /* update group description */
1094  ext4_free_blks_set(sb, gd, RtlNumberOfClearBits(&BlockBitmap));
1095  Ext2SaveGroup(IrpContext, Vcb, Group);
1096 
1097  /* update Vcb free blocks */
1098  Ext2UpdateVcbStat(IrpContext, Vcb);
1099 
1100  /* validate the new allocated block number */
1102  if (*Block >= TOTAL_BLOCKS || *Block + *Number > TOTAL_BLOCKS) {
1103  DbgBreak();
1104  dwHint = 0;
1105  goto Again;
1106  }
1107 
1108  if (ext4_block_bitmap(sb, gd) == *Block ||
1109  ext4_inode_bitmap(sb, gd) == *Block ||
1110  ext4_inode_table(sb, gd) == *Block ) {
1111  DbgBreak();
1112  dwHint = 0;
1113  goto Again;
1114  }
1115 
1116  /* Always remove dirty MCB to prevent Volume's lazy writing.
1117  Metadata blocks will be re-added during modifications.*/
1118  if (Ext2RemoveBlockExtent(Vcb, NULL, *Block, *Number)) {
1119  } else {
1120  DbgBreak();
1121  Ext2RemoveBlockExtent(Vcb, NULL, *Block, *Number);
1122  }
1123 
1124  DEBUG(DL_INF, ("Ext2NewBlock: Block %xh - %x allocated.\n",
1125  *Block, *Block + *Number));
1127  }
1128 
1129 errorout:
1130 
1131  ExReleaseResourceLite(&Vcb->MetaBlock);
1132 
1133  if (bh)
1134  fini_bh(&bh);
1135 
1136  if (gb)
1137  fini_bh(&gb);
1138 
1139  return Status;
1140 }
1141 
1142 NTSTATUS
1144  IN PEXT2_IRP_CONTEXT IrpContext,
1145  IN PEXT2_VCB Vcb,
1146  IN ULONG Block,
1147  IN ULONG Number
1148 )
1149 {
1150  struct super_block *sb = &Vcb->sb;
1151  PEXT2_GROUP_DESC gd;
1152  struct buffer_head *gb = NULL;
1153  ext4_fsblk_t bitmap_blk;
1154 
1155  RTL_BITMAP BlockBitmap;
1157 
1158  PBCB BitmapBcb;
1159  PVOID BitmapCache;
1160 
1161  ULONG Group;
1162  ULONG Index;
1163  ULONG Length;
1164  ULONG Count;
1165 
1167 
1168  ExAcquireResourceExclusiveLite(&Vcb->MetaBlock, TRUE);
1169 
1170  DEBUG(DL_INF, ("Ext2FreeBlock: Block %xh - %x to be freed.\n",
1171  Block, Block + Number));
1172 
1175 
1176 Again:
1177 
1178  if (gb)
1179  fini_bh(&gb);
1180 
1181  if ( Block < EXT2_FIRST_DATA_BLOCK ||
1182  Block >= TOTAL_BLOCKS ||
1183  Group >= Vcb->sbi.s_groups_count) {
1184 
1185  DbgBreak();
1187 
1188  } else {
1189 
1190  gd = ext4_get_group_desc(sb, Group, &gb);
1191  if (!gd) {
1192  DbgBreak();
1194  goto errorout;
1195  }
1196  bitmap_blk = ext4_block_bitmap(sb, gd);
1197 
1198  /* check the block is valid or not */
1199  if (bitmap_blk >= TOTAL_BLOCKS) {
1200  DbgBreak();
1202  goto errorout;
1203  }
1204 
1205  /* get bitmap block offset and length */
1206  Offset.QuadPart = bitmap_blk;
1207  Offset.QuadPart = Offset.QuadPart << BLOCK_BITS;
1208 
1209  if (Group == Vcb->sbi.s_groups_count - 1) {
1210 
1212 
1213  /* s_blocks_count is integer multiple of s_blocks_per_group */
1214  if (Length == 0) {
1216  }
1217 
1218  } else {
1220  }
1221 
1222  /* read and initialize bitmap */
1223  if (!CcPinRead( Vcb->Volume,
1224  &Offset,
1225  Vcb->BlockSize,
1226  PIN_WAIT,
1227  &BitmapBcb,
1228  &BitmapCache ) ) {
1229 
1230  DEBUG(DL_ERR, ("Ext2FreeBlock: failed to PinLock bitmap block %xh.\n",
1231  bitmap_blk));
1233  DbgBreak();
1234  goto errorout;
1235  }
1236 
1237  /* clear usused bits */
1238  RtlInitializeBitMap(&BlockBitmap, BitmapCache, Length);
1239  Count = min(Length - Index, Number);
1240  RtlClearBits(&BlockBitmap, Index, Count);
1241 
1242  /* update group description table */
1243  ext4_free_blks_set(sb, gd, RtlNumberOfClearBits(&BlockBitmap));
1244 
1245  /* indict the cache range is dirty */
1246  CcSetDirtyPinnedData(BitmapBcb, NULL );
1247  Ext2AddVcbExtent(Vcb, Offset.QuadPart, (LONGLONG)Vcb->BlockSize);
1248  CcUnpinData(BitmapBcb);
1249  BitmapBcb = NULL;
1250  BitmapCache = NULL;
1251  Ext2SaveGroup(IrpContext, Vcb, Group);
1252 
1253  /* remove dirty MCB to prevent Volume's lazy writing. */
1254  if (Ext2RemoveBlockExtent(Vcb, NULL, Block, Count)) {
1255  } else {
1256  DbgBreak();
1257  Ext2RemoveBlockExtent(Vcb, NULL, Block, Count);
1258  }
1259 
1260  /* save super block (used/unused blocks statics) */
1261  Ext2UpdateVcbStat(IrpContext, Vcb);
1262 
1263  /* try next group to clear all remaining */
1264  Number -= Count;
1265  if (Number) {
1266  Group += 1;
1267  if (Group < Vcb->sbi.s_groups_count) {
1268  Index = 0;
1269  Block += Count;
1270  goto Again;
1271  } else {
1272  DEBUG(DL_ERR, ("Ext2FreeBlock: block number beyonds max group.\n"));
1273  goto errorout;
1274  }
1275  }
1276  }
1277 
1279 
1280 errorout:
1281 
1282  if (gb)
1283  fini_bh(&gb);
1284 
1285  ExReleaseResourceLite(&Vcb->MetaBlock);
1286 
1287  return Status;
1288 }
1289 
1290 
1291 NTSTATUS
1293  IN PEXT2_IRP_CONTEXT IrpContext,
1294  IN PEXT2_VCB Vcb,
1295  IN ULONG GroupHint,
1296  IN ULONG Type,
1297  OUT PULONG Inode
1298 )
1299 {
1300  struct super_block *sb = &Vcb->sb;
1301  PEXT2_GROUP_DESC gd;
1302  struct buffer_head *gb = NULL;
1303  struct buffer_head *bh = NULL;
1304  ext4_fsblk_t bitmap_blk;
1305 
1306  RTL_BITMAP InodeBitmap;
1307 
1308  ULONG Group, i, j;
1309  ULONG Average, Length;
1310 
1311  ULONG dwInode;
1312 
1314 
1315  *Inode = dwInode = 0XFFFFFFFF;
1316 
1317  ExAcquireResourceExclusiveLite(&Vcb->MetaInode, TRUE);
1318 
1319  if (GroupHint >= Vcb->sbi.s_groups_count)
1320  GroupHint = GroupHint % Vcb->sbi.s_groups_count;
1321 
1322 repeat:
1323 
1324  if (bh)
1325  fini_bh(&bh);
1326 
1327  if (gb)
1328  fini_bh(&gb);
1329 
1330  Group = i = 0;
1331  gd = NULL;
1332 
1333  if (Type == EXT2_FT_DIR) {
1334 
1335  Average = Vcb->SuperBlock->s_free_inodes_count / Vcb->sbi.s_groups_count;
1336 
1337  for (j = 0; j < Vcb->sbi.s_groups_count; j++) {
1338 
1339  i = (j + GroupHint) % (Vcb->sbi.s_groups_count);
1340  gd = ext4_get_group_desc(sb, i, &gb);
1341  if (!gd) {
1342  DbgBreak();
1344  goto errorout;
1345  }
1346 
1347  if ((gd->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT)) ||
1348  (ext4_used_dirs_count(sb, gd) << 8 <
1349  ext4_free_inodes_count(sb, gd)) ) {
1350  Group = i + 1;
1351  break;
1352  }
1353  fini_bh(&gb);
1354  }
1355 
1356  if (!Group) {
1357 
1359 
1360  gd = NULL;
1361 
1362  /* get the group with the biggest vacancy */
1363  for (j = 0; j < Vcb->sbi.s_groups_count; j++) {
1364 
1365  struct buffer_head *gt = NULL;
1366  desc = ext4_get_group_desc(sb, j, &gt);
1367  if (!desc) {
1368  DbgBreak();
1370  goto errorout;
1371  }
1372 
1373  /* return the group if it's not initialized yet */
1374  if (desc->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT)) {
1375  Group = j + 1;
1376  gd = desc;
1377 
1378  if (gb)
1379  fini_bh(&gb);
1380  gb = gt;
1381  gt = NULL;
1382  break;
1383  }
1384 
1385  if (!gd) {
1386  if (ext4_free_inodes_count(sb, desc) > 0) {
1387  Group = j + 1;
1388  gd = desc;
1389  if (gb)
1390  fini_bh(&gb);
1391  gb = gt;
1392  gt = NULL;
1393  }
1394  } else {
1396  ext4_free_inodes_count(sb, gd)) {
1397  Group = j + 1;
1398  gd = desc;
1399  if (gb)
1400  fini_bh(&gb);
1401  gb = gt;
1402  gt = NULL;
1403  break;
1404  }
1405  }
1406  if (gt)
1407  fini_bh(&gt);
1408  }
1409  }
1410 
1411  } else {
1412 
1413  /*
1414  * Try to place the inode in its parent directory (GroupHint)
1415  */
1416 
1417  gd = ext4_get_group_desc(sb, GroupHint, &gb);
1418  if (!gb) {
1419  DbgBreak();
1421  goto errorout;
1422  }
1423 
1424  if (gd->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT) ||
1425  ext4_free_inodes_count(sb, gd)) {
1426 
1427  Group = GroupHint + 1;
1428 
1429  } else {
1430 
1431  /* this group is 100% cocucpied */
1432  fini_bh(&gb);
1433 
1434  i = GroupHint;
1435 
1436  /*
1437  * Use a quadratic hash to find a group with a free inode
1438  */
1439 
1440  for (j = 1; j < Vcb->sbi.s_groups_count; j <<= 1) {
1441 
1442 
1443  i = (i + j) % Vcb->sbi.s_groups_count;
1444  gd = ext4_get_group_desc(sb, i, &gb);
1445  if (!gd) {
1446  DbgBreak();
1448  goto errorout;
1449  }
1450 
1451  if (gd->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT) ||
1452  ext4_free_inodes_count(sb, gd)) {
1453  Group = i + 1;
1454  break;
1455  }
1456 
1457  fini_bh(&gb);
1458  }
1459  }
1460 
1461  if (!Group) {
1462  /*
1463  * That failed: try linear search for a free inode
1464  */
1465  i = GroupHint;
1466  for (j = 2; j < Vcb->sbi.s_groups_count; j++) {
1467 
1468  i = (i + 1) % Vcb->sbi.s_groups_count;
1469  gd = ext4_get_group_desc(sb, i, &gb);
1470  if (!gd) {
1471  DbgBreak();
1473  goto errorout;
1474  }
1475 
1476  if (gd->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT) ||
1477  ext4_free_inodes_count(sb, gd)) {
1478  Group = i + 1;
1479  break;
1480  }
1481 
1482  fini_bh(&gb);
1483  }
1484  }
1485  }
1486 
1487  if (gd == NULL || Group == 0) {
1488  goto errorout;
1489  }
1490 
1491  /* finally we got the group, but is it valid ? */
1492  if (Group > Vcb->sbi.s_groups_count) {
1493  DbgBreak();
1494  goto errorout;
1495  }
1496 
1497  /* valid group number starts from 1, not 0 */
1498  Group -= 1;
1499 
1500  ASSERT(gd);
1501  bitmap_blk = ext4_inode_bitmap(sb, gd);
1502  /* check the block is valid or not */
1503  if (bitmap_blk == 0 || bitmap_blk >= TOTAL_BLOCKS) {
1504  DbgBreak();
1506  goto errorout;
1507  }
1508 
1509  if (gd->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT)) {
1510  bh = sb_getblk_zero(sb, bitmap_blk);
1511  if (!bh) {
1512  DbgBreak();
1514  goto errorout;
1515  }
1516  gd->bg_checksum = ext4_group_desc_csum(EXT3_SB(sb), Group, gd);
1517  ext4_init_inode_bitmap(sb, bh, Group, gd);
1518  set_buffer_uptodate(bh);
1519  gd->bg_flags &= cpu_to_le16(~EXT4_BG_INODE_UNINIT);
1520  Ext2SaveGroup(IrpContext, Vcb, Group);
1521  } else {
1522  bh = sb_getblk(sb, bitmap_blk);
1523  if (!bh) {
1524  DbgBreak();
1526  goto errorout;
1527  }
1528  }
1529 
1530  if (!buffer_uptodate(bh)) {
1531  int err = bh_submit_read(bh);
1532  if (err < 0) {
1533  DbgPrint("bh_submit_read error! err: %d\n", err);
1535  goto errorout;
1536  }
1537  }
1538 
1539  if (Vcb->sbi.s_groups_count == 1) {
1540  Length = INODES_COUNT;
1541  } else {
1542  if (Group + 1 == Vcb->sbi.s_groups_count) {
1544  if (!Length) {
1545  /* INODES_COUNT is integer multiple of INODES_PER_GROUP */
1547  }
1548  } else {
1550  }
1551  }
1552 
1553  RtlInitializeBitMap(&InodeBitmap, (PULONG)bh->b_data, Length);
1554  dwInode = RtlFindClearBits(&InodeBitmap, 1, 0);
1555 
1556  if (dwInode == 0xFFFFFFFF || dwInode >= Length) {
1557 
1558  RtlZeroMemory(&InodeBitmap, sizeof(RTL_BITMAP));
1559  if (ext4_free_inodes_count(sb, gd) > 0) {
1560  ext4_free_inodes_set(sb, gd, 0);
1561  Ext2SaveGroup(IrpContext, Vcb, Group);
1562  }
1563  goto repeat;
1564 
1565  } else {
1566 
1567  __u32 count = 0;
1568 
1569  /* update unused inodes count */
1570  count = ext4_free_inodes_count(sb, gd) - 1;
1572 
1573  RtlSetBits(&InodeBitmap, dwInode, 1);
1574 
1575  /* set block bitmap dirty in cache */
1576  mark_buffer_dirty(bh);
1577 
1578  /* If we didn't allocate from within the initialized part of the inode
1579  * table then we need to initialize up to this inode. */
1581 
1582  __u32 free;
1583 
1584  if (gd->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT)) {
1585  gd->bg_flags &= cpu_to_le16(~EXT4_BG_INODE_UNINIT);
1586  /* When marking the block group with
1587  * ~EXT4_BG_INODE_UNINIT we don't want to depend
1588  * on the value of bg_itable_unused even though
1589  * mke2fs could have initialized the same for us.
1590  * Instead we calculated the value below
1591  */
1592 
1593  free = 0;
1594  } else {
1596  }
1597 
1598  /*
1599  * Check the relative inode number against the last used
1600  * relative inode number in this group. if it is greater
1601  * we need to update the bg_itable_unused count
1602  *
1603  */
1604  if (dwInode + 1 > free) {
1606  (EXT3_INODES_PER_GROUP(sb) - 1 - dwInode));
1607  }
1608 
1609  /* We may have to initialize the block bitmap if it isn't already */
1610  if (gd->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
1611 
1612  struct buffer_head *block_bitmap_bh = NULL;
1613 
1614  /* recheck and clear flag under lock if we still need to */
1615  block_bitmap_bh = sb_getblk_zero(sb, ext4_block_bitmap(sb, gd));
1616  if (block_bitmap_bh) {
1617  gd->bg_checksum = ext4_group_desc_csum(EXT3_SB(sb), Group, gd);
1618  free = ext4_init_block_bitmap(sb, block_bitmap_bh, Group, gd);
1619  set_buffer_uptodate(block_bitmap_bh);
1620  brelse(block_bitmap_bh);
1621  gd->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT);
1622  ext4_free_blks_set(sb, gd, free);
1623  Ext2SaveGroup(IrpContext, Vcb, Group);
1624  }
1625  }
1626  }
1627 
1628  *Inode = dwInode + 1 + Group * INODES_PER_GROUP;
1629 
1630  /* update group_desc / super_block */
1631  if (Type == EXT2_FT_DIR) {
1633  }
1634  Ext2SaveGroup(IrpContext, Vcb, Group);
1635  Ext2UpdateVcbStat(IrpContext, Vcb);
1637  }
1638 
1639 errorout:
1640 
1641  ExReleaseResourceLite(&Vcb->MetaInode);
1642 
1643  if (bh)
1644  fini_bh(&bh);
1645 
1646  if (gb)
1647  fini_bh(&gb);
1648 
1649 
1650  return Status;
1651 }
1652 
1653 NTSTATUS
1655  IN PEXT2_IRP_CONTEXT IrpContext,
1656  IN PEXT2_VCB Vcb,
1657  IN ULONG group
1658  )
1659 {
1660  struct super_block *sb = &Vcb->sb;
1661  PEXT2_GROUP_DESC gd;
1662  struct buffer_head *gb = NULL;
1663  NTSTATUS status;
1664 
1665  ExAcquireResourceExclusiveLite(&Vcb->MetaInode, TRUE);
1666 
1667  /* get group desc */
1668  gd = ext4_get_group_desc(sb, group, &gb);
1669  if (!gd) {
1671  goto errorout;
1672  }
1673 
1674  /* update group_desc and super_block */
1676  Ext2SaveGroup(IrpContext, Vcb, group);
1677  Ext2UpdateVcbStat(IrpContext, Vcb);
1679 
1680 errorout:
1681 
1682  ExReleaseResourceLite(&Vcb->MetaInode);
1683 
1684  if (gb)
1685  fini_bh(&gb);
1686 
1687  return status;
1688 }
1689 
1690 
1691 NTSTATUS
1693  IN PEXT2_IRP_CONTEXT IrpContext,
1694  IN PEXT2_VCB Vcb,
1695  IN ULONG Inode,
1696  IN ULONG Type
1697 )
1698 {
1699  struct super_block *sb = &Vcb->sb;
1700  PEXT2_GROUP_DESC gd;
1701  struct buffer_head *gb = NULL;
1702  struct buffer_head *bh = NULL;
1703  ext4_fsblk_t bitmap_blk;
1704 
1705  RTL_BITMAP InodeBitmap;
1706  ULONG Group;
1707  ULONG Length;
1709 
1710  ULONG dwIno;
1711  BOOLEAN bModified = FALSE;
1712 
1714 
1715  ExAcquireResourceExclusiveLite(&Vcb->MetaInode, TRUE);
1716 
1717  Group = (Inode - 1) / INODES_PER_GROUP;
1718  dwIno = (Inode - 1) % INODES_PER_GROUP;
1719 
1720  DEBUG(DL_INF, ( "Ext2FreeInode: Inode: %xh (Group/Off = %xh/%xh)\n",
1721  Inode, Group, dwIno));
1722 
1723  if (Group >= Vcb->sbi.s_groups_count) {
1724  DbgBreak();
1725  goto errorout;
1726  }
1727 
1728  gd = ext4_get_group_desc(sb, Group, &gb);
1729  if (!gd) {
1730  DbgBreak();
1732  goto errorout;
1733  }
1734 
1735  bitmap_blk = ext4_inode_bitmap(sb, gd);
1736  bh = sb_getblk(sb, bitmap_blk);
1737  if (!bh) {
1738  DbgBreak();
1740  goto errorout;
1741  }
1742  if (!buffer_uptodate(bh)) {
1743  int err = bh_submit_read(bh);
1744  if (err < 0) {
1745  DbgPrint("bh_submit_read error! err: %d\n", err);
1747  goto errorout;
1748  }
1749  }
1750 
1751  if (Group == Vcb->sbi.s_groups_count - 1) {
1752 
1754  if (!Length) {
1755  /* s_inodes_count is integer multiple of s_inodes_per_group */
1757  }
1758  } else {
1760  }
1761 
1762  RtlInitializeBitMap(&InodeBitmap, (PULONG)bh->b_data, Length);
1763 
1764  if (RtlCheckBit(&InodeBitmap, dwIno) == 0) {
1765  DbgBreak();
1767  } else {
1768  RtlClearBits(&InodeBitmap, dwIno, 1);
1769  bModified = TRUE;
1770  }
1771 
1772  if (bModified) {
1773  /* update group free inodes */
1775  RtlNumberOfClearBits(&InodeBitmap));
1776 
1777  /* set inode block dirty and add to vcb dirty range */
1778  mark_buffer_dirty(bh);
1779 
1780  /* update group_desc and super_block */
1781  if (Type == EXT2_FT_DIR) {
1782  ext4_used_dirs_set(sb, gd,
1783  ext4_used_dirs_count(sb, gd) - 1);
1784  }
1785  Ext2SaveGroup(IrpContext, Vcb, Group);
1786  Ext2UpdateVcbStat(IrpContext, Vcb);
1788  }
1789 
1790 errorout:
1791 
1792  ExReleaseResourceLite(&Vcb->MetaInode);
1793 
1794  if (bh)
1795  fini_bh(&bh);
1796 
1797  if (gb)
1798  fini_bh(&gb);
1799 
1800  return Status;
1801 }
1802 
1803 
1804 NTSTATUS
1806  IN PEXT2_IRP_CONTEXT IrpContext,
1807  IN PEXT2_VCB Vcb,
1808  IN PEXT2_FCB Dcb,
1809  IN struct inode *Inode,
1811  struct dentry **Dentry
1812 )
1813 {
1814  struct dentry *de = NULL;
1815 
1817  OEM_STRING oem;
1818  int rc;
1819 
1820  BOOLEAN MainResourceAcquired = FALSE;
1821 
1822  if (!IsDirectory(Dcb)) {
1823  DbgBreak();
1824  return STATUS_NOT_A_DIRECTORY;
1825  }
1826 
1827  ExAcquireResourceExclusiveLite(&Dcb->MainResource, TRUE);
1828  MainResourceAcquired = TRUE;
1829 
1830  _SEH2_TRY {
1831 
1832  Ext2ReferXcb(&Dcb->ReferenceCount);
1833  de = Ext2BuildEntry(Vcb, Dcb->Mcb, FileName);
1834  if (!de) {
1836  _SEH2_LEAVE;
1837  }
1838  de->d_inode = Inode;
1839 
1840  rc = ext3_add_entry(IrpContext, de, Inode);
1841  status = Ext2WinntError(rc);
1842  if (NT_SUCCESS(status)) {
1843 
1844  /* increase dir inode's nlink for .. */
1845  if (S_ISDIR(Inode->i_mode)) {
1846  ext3_inc_count(Dcb->Inode);
1847  ext3_mark_inode_dirty(IrpContext, Dcb->Inode);
1848  }
1849 
1850  /* increase inode nlink reference */
1851  ext3_inc_count(Inode);
1852  ext3_mark_inode_dirty(IrpContext, Inode);
1853 
1854  if (Dentry) {
1855  *Dentry = de;
1856  de = NULL;
1857  }
1858  }
1859 
1860  } _SEH2_FINALLY {
1861 
1862  Ext2DerefXcb(&Dcb->ReferenceCount);
1863 
1864  if (MainResourceAcquired) {
1865  ExReleaseResourceLite(&Dcb->MainResource);
1866  }
1867 
1868  if (de)
1869  Ext2FreeEntry(de);
1870  } _SEH2_END;
1871 
1872  return status;
1873 }
1874 
1875 
1876 NTSTATUS
1878  IN PEXT2_IRP_CONTEXT IrpContext,
1879  IN PEXT2_VCB Vcb,
1880  IN PEXT2_FCB Dcb,
1881  IN PEXT2_MCB Mcb,
1882  IN umode_t mode
1883  )
1884 {
1885  struct inode *dir = Dcb->Inode;
1886  struct buffer_head *bh = NULL;
1887  struct ext3_dir_entry_2 *de;
1888  struct inode *inode;
1890  BOOLEAN MainResourceAcquired = FALSE;
1891 
1893  return STATUS_SUCCESS;
1894  }
1895 
1896  if (!IsDirectory(Dcb)) {
1897  return STATUS_NOT_A_DIRECTORY;
1898  }
1899 
1900  ExAcquireResourceExclusiveLite(&Dcb->MainResource, TRUE);
1901  MainResourceAcquired = TRUE;
1902 
1903  _SEH2_TRY {
1904 
1905  Ext2ReferXcb(&Dcb->ReferenceCount);
1906 
1907  bh = ext3_find_entry(IrpContext, Mcb->de, &de);
1908  if (!bh)
1909  _SEH2_LEAVE;
1910 
1911  inode = &Mcb->Inode;
1912  if (le32_to_cpu(de->inode) != inode->i_ino)
1913  _SEH2_LEAVE;
1914 
1916  mark_buffer_dirty(bh);
1917 
1918  if (S_ISDIR(inode->i_mode) == S_ISDIR(mode)) {
1919  } else if (S_ISDIR(inode->i_mode)) {
1921  } else if (S_ISDIR(mode)) {
1923  }
1924  dir->i_ctime = dir->i_mtime = ext3_current_time(dir);
1925  ext3_mark_inode_dirty(IrpContext, dir);
1926 
1927  inode->i_mode = mode;
1928  ext3_mark_inode_dirty(IrpContext, inode);
1929 
1931 
1932  } _SEH2_FINALLY {
1933 
1934  Ext2DerefXcb(&Dcb->ReferenceCount);
1935 
1936  if (MainResourceAcquired)
1937  ExReleaseResourceLite(&Dcb->MainResource);
1938 
1939  if (bh)
1940  brelse(bh);
1941  } _SEH2_END;
1942 
1943  return Status;
1944 }
1945 
1946 NTSTATUS
1948  IN PEXT2_IRP_CONTEXT IrpContext,
1949  IN PEXT2_VCB Vcb,
1950  IN PEXT2_FCB Dcb,
1951  IN PEXT2_MCB Mcb
1952 )
1953 {
1954  struct inode *dir = Dcb->Inode;
1955  struct buffer_head *bh = NULL;
1956  struct ext3_dir_entry_2 *de;
1957  struct inode *inode;
1958  int rc = -ENOENT;
1960  BOOLEAN MainResourceAcquired = FALSE;
1961 
1962  if (!IsDirectory(Dcb)) {
1963  return STATUS_NOT_A_DIRECTORY;
1964  }
1965 
1966  ExAcquireResourceExclusiveLite(&Dcb->MainResource, TRUE);
1967  MainResourceAcquired = TRUE;
1968 
1969  _SEH2_TRY {
1970 
1971  Ext2ReferXcb(&Dcb->ReferenceCount);
1972 
1973  bh = ext3_find_entry(IrpContext, Mcb->de, &de);
1974  if (!bh)
1975  _SEH2_LEAVE;
1976 
1977  inode = &Mcb->Inode;
1978  if (le32_to_cpu(de->inode) != inode->i_ino)
1979  _SEH2_LEAVE;
1980 
1981  if (!inode->i_nlink) {
1982  ext3_warning (inode->i_sb, "ext3_unlink",
1983  "Deleting nonexistent file (%lu), %d",
1984  inode->i_ino, inode->i_nlink);
1985  inode->i_nlink = 1;
1986  }
1987  rc = ext3_delete_entry(IrpContext, dir, de, bh);
1988  if (rc) {
1989  Status = Ext2WinntError(rc);
1990  _SEH2_LEAVE;
1991  }
1992  /*
1993  if (!inode->i_nlink)
1994  ext3_orphan_add(handle, inode);
1995  */
1996  inode->i_ctime = dir->i_ctime = dir->i_mtime = ext3_current_time(dir);
1998  ext3_mark_inode_dirty(IrpContext, inode);
1999 
2000  /* decrease dir inode's nlink for .. */
2001  if (S_ISDIR(inode->i_mode)) {
2004  ext3_mark_inode_dirty(IrpContext, dir);
2005  }
2006 
2008 
2009  } _SEH2_FINALLY {
2010 
2011  Ext2DerefXcb(&Dcb->ReferenceCount);
2012 
2013  if (MainResourceAcquired)
2014  ExReleaseResourceLite(&Dcb->MainResource);
2015 
2016  if (bh)
2017  brelse(bh);
2018  } _SEH2_END;
2019 
2020  return Status;
2021 }
2022 
2023 NTSTATUS
2025  IN PEXT2_IRP_CONTEXT IrpContext,
2026  IN PEXT2_VCB Vcb,
2027  IN PEXT2_FCB Dcb,
2028  IN ULONG OldParent,
2029  IN ULONG NewParent )
2030 {
2032 
2033  PEXT2_DIR_ENTRY2 pSelf = NULL;
2035 
2036  ULONG dwBytes = 0;
2037 
2038  BOOLEAN MainResourceAcquired = FALSE;
2039 
2040  ULONG Offset = 0;
2041 
2042  if (!IsDirectory(Dcb)) {
2043  return STATUS_NOT_A_DIRECTORY;
2044  }
2045 
2046  if (OldParent == NewParent) {
2047  return STATUS_SUCCESS;
2048  }
2049 
2050  MainResourceAcquired =
2051  ExAcquireResourceExclusiveLite(&Dcb->MainResource, TRUE);
2052 
2053  _SEH2_TRY {
2054 
2055  Ext2ReferXcb(&Dcb->ReferenceCount);
2056 
2057  pSelf = (PEXT2_DIR_ENTRY2)
2059  PagedPool,
2062  );
2063  if (!pSelf) {
2064  DEBUG(DL_ERR, ( "Ex2SetParentEntry: failed to allocate pSelf.\n"));
2066  _SEH2_LEAVE;
2067  }
2068 
2069  dwBytes = 0;
2070 
2071  //
2072  // Reading the DCB contents
2073  //
2074 
2076  IrpContext,
2077  Vcb,
2078  Dcb->Mcb,
2079  (ULONGLONG)Offset,
2080  (PVOID)pSelf,
2082  FALSE,
2083  &dwBytes );
2084 
2085  if (!NT_SUCCESS(Status)) {
2086  DEBUG(DL_ERR, ( "Ext2SetParentEntry: failed to read directory.\n"));
2087  _SEH2_LEAVE;
2088  }
2089 
2090  ASSERT(dwBytes == EXT2_DIR_REC_LEN(1) + EXT2_DIR_REC_LEN(2));
2091 
2092  pParent = (PEXT2_DIR_ENTRY2)((PUCHAR)pSelf + pSelf->rec_len);
2093 
2094  if (pSelf->name_len == 1 && pSelf->name[0] == '.' &&
2095  pParent->name_len == 2 && pParent->name[0] == '.' &&
2096  pParent->name[1] == '.') {
2097 
2098  if (pParent->inode != OldParent) {
2099  DbgBreak();
2100  }
2101  pParent->inode = NewParent;
2102 
2104  IrpContext,
2105  Vcb,
2106  Dcb->Mcb,
2107  (ULONGLONG)Offset,
2108  pSelf,
2109  dwBytes,
2110  FALSE,
2111  &dwBytes );
2112  } else {
2113  DbgBreak();
2114  }
2115 
2116  } _SEH2_FINALLY {
2117 
2118 
2119  if (Ext2DerefXcb(&Dcb->ReferenceCount) == 0) {
2120  DEBUG(DL_ERR, ( "Ext2SetParentEntry: Dcb reference goes to ZERO.\n"));
2121  }
2122 
2123  if (MainResourceAcquired) {
2124  ExReleaseResourceLite(&Dcb->MainResource);
2125  }
2126 
2127  if (pSelf) {
2129  }
2130  } _SEH2_END;
2131 
2132  return Status;
2133 }
2134 
2135 int ext3_check_dir_entry (const char * function, struct inode * dir,
2136  struct ext3_dir_entry_2 * de,
2137  struct buffer_head * bh,
2138  unsigned long offset)
2139 {
2140  const char * error_msg = NULL;
2141  const int rlen = ext3_rec_len_from_disk(de->rec_len);
2142 
2143  if (rlen < EXT3_DIR_REC_LEN(1))
2144  error_msg = "rec_len is smaller than minimal";
2145  else if (rlen % 4 != 0)
2146  error_msg = "rec_len % 4 != 0";
2147  else if (rlen < EXT3_DIR_REC_LEN(de->name_len))
2148  error_msg = "rec_len is too small for name_len";
2149  else if ((char *) de + rlen > bh->b_data + dir->i_sb->s_blocksize)
2150  error_msg = "directory entry across blocks";
2151  else if (le32_to_cpu(de->inode) >
2152  le32_to_cpu(EXT3_SB(dir->i_sb)->s_es->s_inodes_count))
2153  error_msg = "inode out of bounds";
2154 
2155  if (error_msg != NULL) {
2156  DEBUG(DL_ERR, ("%s: bad entry in directory %u: %s - "
2157  "offset=%u, inode=%u, rec_len=%d, name_len=%d\n",
2158  function, dir->i_ino, error_msg, offset,
2159  (unsigned long) le32_to_cpu(de->inode),
2160  rlen, de->name_len));
2161  }
2162  return error_msg == NULL ? 1 : 0;
2163 }
2164 
2165 
2166 /*
2167  * p is at least 6 bytes before the end of page
2168  */
2169 struct ext3_dir_entry_2 *
2171 {
2172  return (struct ext3_dir_entry_2 *)((char *)p +
2173  ext3_rec_len_from_disk(p->rec_len));
2174 }
2175 
2176 #define MAX_LFS_FILESIZE 0x7fffffffffffffff
2177 
2178 /*
2179  * Maximal extent format file size.
2180  * Resulting logical blkno at s_maxbytes must fit in our on-disk
2181  * extent format containers, within a sector_t, and within i_blocks
2182  * in the vfs. ext4 inode has 48 bits of i_block in fsblock units,
2183  * so that won't be a limiting factor.
2184  *
2185  * Note, this does *not* consider any metadata overhead for vfs i_blocks.
2186  */
2187 static loff_t ext4_max_size(int blkbits, int has_huge_files)
2188 {
2189  loff_t res;
2191 
2192  /* small i_blocks in vfs inode? */
2193  if (!has_huge_files || sizeof(blkcnt_t) < sizeof(u64)) {
2194  /*
2195  * CONFIG_LBD is not enabled implies the inode
2196  * i_block represent total blocks in 512 bytes
2197  * 32 == size of vfs inode i_blocks * 8
2198  */
2199  upper_limit = (1LL << 32) - 1;
2200 
2201  /* total blocks in file system block size */
2202  upper_limit >>= (blkbits - 9);
2203  upper_limit <<= blkbits;
2204  }
2205 
2206  /* 32-bit extent-start container, ee_block */
2207  res = 1LL << 32;
2208  res <<= blkbits;
2209  res -= 1;
2210 
2211  /* Sanity check against vm- & vfs- imposed limits */
2212  if (res > upper_limit)
2213  res = upper_limit;
2214 
2215  return res;
2216 }
2217 
2218 /*
2219  * Maximal extent format file size.
2220  * Resulting logical blkno at s_maxbytes must fit in our on-disk
2221  * extent format containers, within a sector_t, and within i_blocks
2222  * in the vfs. ext4 inode has 48 bits of i_block in fsblock units,
2223  * so that won't be a limiting factor.
2224  *
2225  * Note, this does *not* consider any metadata overhead for vfs i_blocks.
2226  */
2227 loff_t ext3_max_size(int blkbits, int has_huge_files)
2228 {
2229  loff_t res;
2231 
2232  /* small i_blocks in vfs inode? */
2233  if (!has_huge_files) {
2234  /*
2235  * CONFIG_LBD is not enabled implies the inode
2236  * i_block represent total blocks in 512 bytes
2237  * 32 == size of vfs inode i_blocks * 8
2238  */
2239  upper_limit = ((loff_t)1 << 32) - 1;
2240 
2241  /* total blocks in file system block size */
2242  upper_limit >>= (blkbits - 9);
2243  upper_limit <<= blkbits;
2244  }
2245 
2246  /* 32-bit extent-start container, ee_block */
2247  res = (loff_t)1 << 32;
2248  res <<= blkbits;
2249  res -= 1;
2250 
2251  /* Sanity check against vm- & vfs- imposed limits */
2252  if (res > upper_limit)
2253  res = upper_limit;
2254 
2255  return res;
2256 }
2257 
2258 /*
2259  * Maximal bitmap file size. There is a direct, and {,double-,triple-}indirect
2260  * block limit, and also a limit of (2^48 - 1) 512-byte sectors in i_blocks.
2261  * We need to be 1 filesystem block less than the 2^48 sector limit.
2262  */
2263 loff_t ext3_max_bitmap_size(int bits, int has_huge_files)
2264 {
2266  int meta_blocks;
2268  /* This is calculated to be the largest file size for a
2269  * dense, bitmapped file such that the total number of
2270  * sectors in the file, including data and all indirect blocks,
2271  * does not exceed 2^48 -1
2272  * __u32 i_blocks_lo and _u16 i_blocks_high representing the
2273  * total number of 512 bytes blocks of the file
2274  */
2275 
2276  if (!has_huge_files) {
2277  /*
2278  * !has_huge_files or CONFIG_LBD is not enabled
2279  * implies the inode i_block represent total blocks in
2280  * 512 bytes 32 == size of vfs inode i_blocks * 8
2281  */
2282  upper_limit = ((loff_t)1 << 32) - 1;
2283 
2284  /* total blocks in file system block size */
2285  upper_limit >>= (bits - 9);
2286 
2287  } else {
2288  /*
2289  * We use 48 bit ext4_inode i_blocks
2290  * With EXT4_HUGE_FILE_FL set the i_blocks
2291  * represent total number of blocks in
2292  * file system block size
2293  */
2294  upper_limit = ((loff_t)1 << 48) - 1;
2295 
2296  }
2297 
2298  /* indirect blocks */
2299  meta_blocks = 1;
2300  /* double indirect blocks */
2301  meta_blocks += 1 + ((loff_t)1 << (bits-2));
2302  /* tripple indirect blocks */
2303  meta_blocks += 1 + ((loff_t)1 << (bits-2)) + ((loff_t)1 << (2*(bits-2)));
2304 
2305  upper_limit -= meta_blocks;
2306  upper_limit <<= bits;
2307 
2308  res += (loff_t)1 << (bits-2);
2309  res += (loff_t)1 << (2*(bits-2));
2310  res += (loff_t)1 << (3*(bits-2));
2311  res <<= bits;
2312  if (res > upper_limit)
2313  res = upper_limit;
2314 
2315  if (res > MAX_LFS_FILESIZE)
2317 
2318  return res;
2319 }
2320 
2322  struct inode *inode)
2323 {
2324  blkcnt_t i_blocks ;
2325  struct super_block *sb = inode->i_sb;
2326  PEXT2_VCB Vcb = (PEXT2_VCB)sb->s_priv;
2327 
2330  /* we are using combined 48 bit field */
2331  i_blocks = ((u64)le16_to_cpu(raw_inode->i_blocks_high)) << 32 |
2332  le32_to_cpu(raw_inode->i_blocks);
2333  if (inode->i_flags & EXT4_HUGE_FILE_FL) {
2334  /* i_blocks represent file system block size */
2335  return i_blocks << (BLOCK_BITS - 9);
2336  } else {
2337  return i_blocks;
2338  }
2339  } else {
2340  return le32_to_cpu(raw_inode->i_blocks);
2341  }
2342 }
2343 
2344 int ext3_inode_blocks_set(struct ext3_inode *raw_inode,
2345  struct inode * inode)
2346 {
2347  u64 i_blocks = inode->i_blocks;
2348  struct super_block *sb = inode->i_sb;
2349  PEXT2_VCB Vcb = (PEXT2_VCB)sb->s_priv;
2350 
2351  if (i_blocks < 0x100000000) {
2352  /*
2353  * i_blocks can be represnted in a 32 bit variable
2354  * as multiple of 512 bytes
2355  */
2356  raw_inode->i_blocks = cpu_to_le32(i_blocks);
2357  raw_inode->i_blocks_high = 0;
2359  return 0;
2360  }
2361 
2365  }
2366 
2367  if (i_blocks <= 0xffffffffffff) {
2368  /*
2369  * i_blocks can be represented in a 48 bit variable
2370  * as multiple of 512 bytes
2371  */
2372  raw_inode->i_blocks = (__u32)cpu_to_le32(i_blocks);
2373  raw_inode->i_blocks_high = (__u16)cpu_to_le16(i_blocks >> 32);
2375  } else {
2377  /* i_block is stored in file system block size */
2378  i_blocks = i_blocks >> (BLOCK_BITS - 9);
2379  raw_inode->i_blocks = (__u32)cpu_to_le32(i_blocks);
2380  raw_inode->i_blocks_high = (__u16)cpu_to_le16(i_blocks >> 32);
2381  }
2382  return 0;
2383 }
2384 
2386  struct ext4_group_desc *bg)
2387 {
2388  return le32_to_cpu(bg->bg_block_bitmap) |
2390  (ext4_fsblk_t)le32_to_cpu(bg->bg_block_bitmap_hi) << 32 : 0);
2391 }
2392 
2394  struct ext4_group_desc *bg)
2395 {
2396  return le32_to_cpu(bg->bg_inode_bitmap) |
2398  (ext4_fsblk_t)le32_to_cpu(bg->bg_inode_bitmap_hi) << 32 : 0);
2399 }
2400 
2402  struct ext4_group_desc *bg)
2403 {
2404  return le32_to_cpu(bg->bg_inode_table) |
2406  (ext4_fsblk_t)le32_to_cpu(bg->bg_inode_table_hi) << 32 : 0);
2407 }
2408 
2410  struct ext4_group_desc *bg)
2411 {
2412  return le16_to_cpu(bg->bg_free_blocks_count) |
2414  (__u32)le16_to_cpu(bg->bg_free_blocks_count_hi) << 16 : 0);
2415 }
2416 
2418  struct ext4_group_desc *bg)
2419 {
2420  return le16_to_cpu(bg->bg_free_inodes_count) |
2422  (__u32)le16_to_cpu(bg->bg_free_inodes_count_hi) << 16 : 0);
2423 }
2424 
2426  struct ext4_group_desc *bg)
2427 {
2428  return le16_to_cpu(bg->bg_used_dirs_count) |
2430  (__u32)le16_to_cpu(bg->bg_used_dirs_count_hi) << 16 : 0);
2431 }
2432 
2434  struct ext4_group_desc *bg)
2435 {
2436  return le16_to_cpu(bg->bg_itable_unused) |
2438  (__u32)le16_to_cpu(bg->bg_itable_unused_hi) << 16 : 0);
2439 }
2440 
2442  struct ext4_group_desc *bg, ext4_fsblk_t blk)
2443 {
2446  bg->bg_block_bitmap_hi = cpu_to_le32(blk >> 32);
2447 }
2448 
2450  struct ext4_group_desc *bg, ext4_fsblk_t blk)
2451 {
2454  bg->bg_inode_bitmap_hi = cpu_to_le32(blk >> 32);
2455 }
2456 
2458  struct ext4_group_desc *bg, ext4_fsblk_t blk)
2459 {
2462  bg->bg_inode_table_hi = cpu_to_le32(blk >> 32);
2463 }
2464 
2466  struct ext4_group_desc *bg, __u32 count)
2467 {
2471 }
2472 
2474  struct ext4_group_desc *bg, __u32 count)
2475 {
2479 }
2480 
2482  struct ext4_group_desc *bg, __u32 count)
2483 {
2487 }
2488 
2490  struct ext4_group_desc *bg, __u32 count)
2491 {
2494  bg->bg_itable_unused_hi = cpu_to_le16(count >> 16);
2495 }
2496 
2498 __u16 const crc16_table[256] = {
2499  0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
2500  0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
2501  0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
2502  0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
2503  0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
2504  0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
2505  0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
2506  0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
2507  0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
2508  0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
2509  0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
2510  0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
2511  0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
2512  0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
2513  0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
2514  0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
2515  0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
2516  0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
2517  0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
2518  0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
2519  0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
2520  0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
2521  0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
2522  0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
2523  0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
2524  0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
2525  0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
2526  0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
2527  0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
2528  0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
2529  0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
2530  0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
2531 };
2532 
2533 static inline __u16 crc16_byte(__u16 crc, const __u8 data)
2534 {
2535  return (crc >> 8) ^ crc16_table[(crc ^ data) & 0xff];
2536 }
2537 
2538 __u16 crc16(__u16 crc, __u8 const *buffer, size_t len)
2539 {
2540  while (len--)
2541  crc = crc16_byte(crc, *buffer++);
2542  return crc;
2543 }
2544 
2546  struct ext4_group_desc *gdp)
2547 {
2548  int offset;
2549  __u16 crc = 0;
2550  __le32 le_group = cpu_to_le32(block_group);
2551 
2552  /* old crc16 code */
2553  if (!(sbi->s_es->s_feature_ro_compat &
2555  return 0;
2556 
2557  offset = offsetof(struct ext4_group_desc, bg_checksum);
2558 
2559  crc = crc16(~0, sbi->s_es->s_uuid, sizeof(sbi->s_es->s_uuid));
2560  crc = crc16(crc, (__u8 *)&le_group, sizeof(le_group));
2561  crc = crc16(crc, (__u8 *)gdp, offset);
2562  offset += sizeof(gdp->bg_checksum); /* skip checksum */
2563  /* for checksum of struct ext4_group_desc do the rest...*/
2564  if ((sbi->s_es->s_feature_incompat &
2566  offset < le16_to_cpu(sbi->s_es->s_desc_size))
2567  crc = crc16(crc, (__u8 *)gdp + offset,
2568  le16_to_cpu(sbi->s_es->s_desc_size) -
2569  offset);
2570 
2571  return cpu_to_le16(crc);
2572 }
2573 
2574 int ext4_group_desc_csum_verify(struct ext3_sb_info *sbi, __u32 block_group,
2575  struct ext4_group_desc *gdp)
2576 {
2577  if ((sbi->s_es->s_feature_ro_compat & cpu_to_le32(EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) &&
2578  (gdp->bg_checksum != ext4_group_desc_csum(sbi, block_group, gdp)))
2579  return 0;
2580 
2581  return 1;
2582 }
2583 
2584 
2586 {
2587  ext3_group_t num = b;
2588 
2589  while (a > num)
2590  num *= b;
2591  return num == a;
2592 }
2593 
2595 {
2596  if (group <= 1)
2597  return 1;
2598  if (!(group & 1))
2599  return 0;
2600  return (test_root(group, 7) || test_root(group, 5) ||
2601  test_root(group, 3));
2602 }
2603 
2613 {
2617  return 0;
2618  return 1;
2619 }
2620 
2621 static unsigned long ext4_bg_num_gdb_meta(struct super_block *sb,
2623 {
2624  unsigned long metagroup = group / EXT4_DESC_PER_BLOCK(sb);
2625  ext4_group_t first = metagroup * EXT4_DESC_PER_BLOCK(sb);
2626  ext4_group_t last = first + EXT4_DESC_PER_BLOCK(sb) - 1;
2627 
2628  if (group == first || group == first + 1 || group == last)
2629  return 1;
2630  return 0;
2631 }
2632 
2633 static unsigned long ext4_bg_num_gdb_nometa(struct super_block *sb,
2635 {
2636  return ext3_bg_has_super(sb, group) ? EXT3_SB(sb)->s_gdb_count : 0;
2637 }
2638 
2649 {
2650  unsigned long first_meta_bg =
2651  le32_to_cpu(EXT3_SB(sb)->s_es->s_first_meta_bg);
2652  unsigned long metagroup = group / EXT4_DESC_PER_BLOCK(sb);
2653 
2655  metagroup < first_meta_bg)
2656  return ext4_bg_num_gdb_nometa(sb, group);
2657 
2658  return ext4_bg_num_gdb_meta(sb,group);
2659 
2660 }
2661 
2663  ext3_fsblk_t logical_sb_block, unsigned int nr)
2664 {
2665  struct ext3_sb_info *sbi = EXT3_SB(sb);
2666  ext3_group_t bg, first_meta_bg;
2667  int has_super = 0;
2668 
2669  first_meta_bg = le32_to_cpu(sbi->s_es->s_first_meta_bg);
2670 
2672  nr < first_meta_bg)
2673  return logical_sb_block + nr + 1;
2674  bg = sbi->s_desc_per_block * nr;
2675  if (ext3_bg_has_super(sb, bg))
2676  has_super = 1;
2677  return (has_super + ext3_group_first_block_no(sb, bg));
2678 }
2679 
2680 #define ext4_set_bit(n, p) set_bit((int)(n), (unsigned long *)(p))
2681 
2682 /*
2683  * The free inodes are managed by bitmaps. A file system contains several
2684  * blocks groups. Each group contains 1 bitmap block for blocks, 1 bitmap
2685  * block for inodes, N blocks for the inode table and data blocks.
2686  *
2687  * The file system contains group descriptors which are located after the
2688  * super block. Each descriptor contains the number of the bitmap block and
2689  * the free blocks count in the block.
2690  */
2691 
2692 /*
2693  * To avoid calling the atomic setbit hundreds or thousands of times, we only
2694  * need to use it within a single byte (to ensure we get endianness right).
2695  * We can use memset for the rest of the bitmap as there are no other users.
2696  */
2697 void mark_bitmap_end(int start_bit, int end_bit, char *bitmap)
2698 {
2699  int i;
2700 
2701  if (start_bit >= end_bit)
2702  return;
2703 
2704  DEBUG(DL_INF, ("mark end bits +%d through +%d used\n", start_bit, end_bit));
2705  for (i = start_bit; (unsigned)i < ((start_bit + 7) & ~7UL); i++)
2706  ext4_set_bit(i, bitmap);
2707  if (i < end_bit)
2708  memset(bitmap + (i >> 3), 0xff, (end_bit - i) >> 3);
2709 }
2710 
2711 /* Initializes an uninitialized inode bitmap */
2712 unsigned ext4_init_inode_bitmap(struct super_block *sb, struct buffer_head *bh,
2713  ext4_group_t block_group,
2714  struct ext4_group_desc *gdp)
2715 {
2716  struct ext3_sb_info *sbi = EXT3_SB(sb);
2717 
2718  mark_buffer_dirty(bh);
2719 
2720  /* If checksum is bad mark all blocks and inodes use to prevent
2721  * allocation, essentially implementing a per-group read-only flag. */
2722  if (!ext4_group_desc_csum_verify(sbi, block_group, gdp)) {
2723  ext4_error(sb, __FUNCTION__, "Checksum bad for group %u",
2724  block_group);
2725  ext4_free_blks_set(sb, gdp, 0);
2726  ext4_free_inodes_set(sb, gdp, 0);
2727  ext4_itable_unused_set(sb, gdp, 0);
2728  memset(bh->b_data, 0xff, sb->s_blocksize);
2729  return 0;
2730  }
2731 
2732  memset(bh->b_data, 0, (EXT4_INODES_PER_GROUP(sb) + 7) / 8);
2733  mark_bitmap_end(EXT4_INODES_PER_GROUP(sb), sb->s_blocksize * 8,
2734  bh->b_data);
2735  ext4_itable_unused_set(sb, gdp, EXT4_INODES_PER_GROUP(sb));
2736 
2737  return EXT4_INODES_PER_GROUP(sb);
2738 }
2739 
2740 /*
2741  * Calculate the block group number and offset, given a block number
2742  */
2744  ext4_group_t *blockgrpp, ext4_grpblk_t *offsetp)
2745 {
2746  struct ext3_super_block *es = EXT3_SB(sb)->s_es;
2748 
2749  blocknr = blocknr - le32_to_cpu(es->s_first_data_block);
2750  offset = do_div(blocknr, EXT4_BLOCKS_PER_GROUP(sb));
2751  if (offsetp)
2752  *offsetp = offset;
2753  if (blockgrpp)
2754  *blockgrpp = (ext4_grpblk_t)blocknr;
2755 
2756 }
2757 
2759  ext4_group_t block_group)
2760 {
2761  ext4_group_t actual_group;
2762  ext4_get_group_no_and_offset(sb, block, &actual_group, NULL);
2763  if (actual_group == block_group)
2764  return 1;
2765  return 0;
2766 }
2767 
2769  ext4_group_t block_group)
2770 {
2771  ext4_fsblk_t tmp;
2772  struct ext3_sb_info *sbi = EXT3_SB(sb);
2773  /* block bitmap, inode bitmap, and inode table blocks */
2774  int used_blocks = sbi->s_itb_per_group + 2;
2775 
2777  struct ext4_group_desc *gdp;
2778  struct buffer_head *bh = NULL;
2779 
2780  gdp = ext4_get_group_desc(sb, block_group, &bh);
2782  block_group))
2783  used_blocks--;
2784 
2786  block_group))
2787  used_blocks--;
2788 
2789  tmp = ext4_inode_table(sb, gdp);
2790  for (; tmp < ext4_inode_table(sb, gdp) +
2791  sbi->s_itb_per_group; tmp++) {
2792  if (!ext4_block_in_group(sb, tmp, block_group))
2793  used_blocks -= 1;
2794  }
2795  if (bh)
2796  fini_bh(&bh);
2797  }
2798  return used_blocks;
2799 }
2800 
2801 /* Initializes an uninitialized block bitmap if given, and returns the
2802  * number of blocks free in the group. */
2803 unsigned ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh,
2804  ext4_group_t block_group, struct ext4_group_desc *gdp)
2805 {
2806  int bit, bit_max;
2807  unsigned free_blocks, group_blocks;
2808  struct ext3_sb_info *sbi = EXT3_SB(sb);
2809 
2810  if (bh) {
2811  mark_buffer_dirty(bh);
2812  /* If checksum is bad mark all blocks used to prevent allocation
2813  * essentially implementing a per-group read-only flag. */
2814  if (!ext4_group_desc_csum_verify(sbi, block_group, gdp)) {
2816  "Checksum bad for group %u", block_group);
2817  ext4_free_blks_set(sb, gdp, 0);
2818  ext4_free_inodes_set(sb, gdp, 0);
2819  ext4_itable_unused_set(sb, gdp, 0);
2820  memset(bh->b_data, 0xff, sb->s_blocksize);
2821  return 0;
2822  }
2823  memset(bh->b_data, 0, sb->s_blocksize);
2824  }
2825 
2826  /* Check for superblock and gdt backups in this group */
2827  bit_max = ext3_bg_has_super(sb, block_group);
2828 
2830  block_group < le32_to_cpu(sbi->s_es->s_first_meta_bg) *
2831  sbi->s_desc_per_block) {
2832  if (bit_max) {
2833  bit_max += ext4_bg_num_gdb(sb, block_group);
2834  bit_max +=
2835  le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks);
2836  }
2837  } else { /* For META_BG_BLOCK_GROUPS */
2838  bit_max += ext4_bg_num_gdb(sb, block_group);
2839  }
2840 
2841  if (block_group == sbi->s_groups_count - 1) {
2842  /*
2843  * Even though mke2fs always initialize first and last group
2844  * if some other tool enabled the EXT4_BG_BLOCK_UNINIT we need
2845  * to make sure we calculate the right free blocks
2846  */
2847  group_blocks = (unsigned int)(ext3_blocks_count(sbi->s_es) -
2848  le32_to_cpu(sbi->s_es->s_first_data_block) -
2849  (EXT4_BLOCKS_PER_GROUP(sb) * (sbi->s_groups_count - 1)));
2850  } else {
2851  group_blocks = EXT4_BLOCKS_PER_GROUP(sb);
2852  }
2853 
2854  free_blocks = group_blocks - bit_max;
2855 
2856  if (bh) {
2857  ext4_fsblk_t start, tmp;
2858  int flex_bg = 0;
2859 
2860  for (bit = 0; bit < bit_max; bit++)
2861  ext4_set_bit(bit, bh->b_data);
2862 
2863  start = ext3_group_first_block_no(sb, block_group);
2864 
2867  flex_bg = 1;
2868 
2869  /* Set bits for block and inode bitmaps, and inode table */
2870  tmp = ext4_block_bitmap(sb, gdp);
2871  if (!flex_bg || ext4_block_in_group(sb, tmp, block_group))
2872  ext4_set_bit(tmp - start, bh->b_data);
2873 
2874  tmp = ext4_inode_bitmap(sb, gdp);
2875  if (!flex_bg || ext4_block_in_group(sb, tmp, block_group))
2876  ext4_set_bit(tmp - start, bh->b_data);
2877 
2878  tmp = ext4_inode_table(sb, gdp);
2879  for (; tmp < ext4_inode_table(sb, gdp) +
2880  sbi->s_itb_per_group; tmp++) {
2881  if (!flex_bg ||
2882  ext4_block_in_group(sb, tmp, block_group))
2883  ext4_set_bit(tmp - start, bh->b_data);
2884  }
2885  /*
2886  * Also if the number of blocks within the group is
2887  * less than the blocksize * 8 ( which is the size
2888  * of bitmap ), set rest of the block bitmap to 1
2889  */
2890  mark_bitmap_end(group_blocks, sb->s_blocksize * 8, bh->b_data);
2891  }
2892  return free_blocks - ext4_group_used_meta_blocks(sb, block_group);
2893 }
2894 
2903  ext4_group_t block_group, struct buffer_head **bh)
2904 {
2905  struct ext4_group_desc *desc = NULL;
2906  struct ext3_sb_info *sbi = EXT3_SB(sb);
2907  PEXT2_VCB vcb = sb->s_priv;
2910 
2911  if (bh)
2912  *bh = NULL;
2913 
2914  if (block_group >= sbi->s_groups_count) {
2915  ext4_error(sb, "ext4_get_group_desc",
2916  "block_group >= groups_count - "
2917  "block_group = %u, groups_count = %u",
2918  block_group, sbi->s_groups_count);
2919 
2920  return NULL;
2921  }
2922 
2923  _SEH2_TRY {
2924 
2925  group = block_group >> EXT4_DESC_PER_BLOCK_BITS(sb);
2926  offset = block_group & (EXT4_DESC_PER_BLOCK(sb) - 1);
2927 
2928  if (!sbi->s_gd) {
2929  if (!Ext2LoadGroup(vcb)) {
2930  _SEH2_LEAVE;
2931  }
2932  } else if ( !sbi->s_gd[group].block ||
2933  !sbi->s_gd[group].bh) {
2934  if (!Ext2LoadGroupBH(vcb)) {
2935  _SEH2_LEAVE;
2936  }
2937  }
2938 
2939  desc = (struct ext4_group_desc *)((PCHAR)sbi->s_gd[group].gd +
2940  offset * EXT4_DESC_SIZE(sb));
2941  if (bh) {
2942  atomic_inc(&sbi->s_gd[group].bh->b_count);
2943  *bh = sbi->s_gd[group].bh;
2944  }
2945  } _SEH2_FINALLY {
2946  /* do cleanup */
2947  } _SEH2_END;
2948 
2949  return desc;
2950 }
2951 
2952 
2960 {
2961  ext4_fsblk_t desc_count;
2962  struct ext4_group_desc *gdp;
2963  struct buffer_head *bh = NULL;
2964  ext4_group_t i;
2965  ext4_group_t ngroups = EXT3_SB(sb)->s_groups_count;
2966 
2967  desc_count = 0;
2968  smp_rmb();
2969  for (i = 0; i < ngroups; i++) {
2970  gdp = ext4_get_group_desc(sb, i, &bh);
2971  if (!bh)
2972  continue;
2973  desc_count += ext4_free_blks_count(sb, gdp);
2974  fini_bh(&bh);
2975  }
2976 
2977  return desc_count;
2978 }
2979 
2980 unsigned long ext4_count_free_inodes(struct super_block *sb)
2981 {
2982  unsigned long desc_count;
2983  struct ext4_group_desc *gdp;
2984  struct buffer_head *bh = NULL;
2985  ext4_group_t i;
2986 
2987  desc_count = 0;
2988  for (i = 0; i < EXT3_SB(sb)->s_groups_count; i++) {
2989  gdp = ext4_get_group_desc(sb, i, &bh);
2990  if (!bh)
2991  continue;
2992  desc_count += ext4_free_inodes_count(sb, gdp);
2993  fini_bh(&bh);
2994  }
2995  return desc_count;
2996 }
2997 
2998 /* Called at mount-time, super-block is locked */
2999 unsigned long ext4_count_dirs(struct super_block * sb)
3000 {
3001  struct ext4_group_desc *gdp;
3002  struct buffer_head *bh = NULL;
3003  unsigned long count = 0;
3004  ext4_group_t i;
3005 
3006  for (i = 0; i < EXT3_SB(sb)->s_groups_count; i++) {
3007  gdp = ext4_get_group_desc(sb, i, &bh);
3008  if (!bh)
3009  continue;
3010  count += ext4_used_dirs_count(sb, gdp);
3011  fini_bh(&bh);
3012  }
3013  return count;
3014 }
3015 
3016 /* Called at mount-time, super-block is locked */
3018 {
3019  PEXT2_VCB Vcb = sb->s_priv;
3020  struct ext3_sb_info *sbi = EXT3_SB(sb);
3021  ext4_fsblk_t first_block = le32_to_cpu(sbi->s_es->s_first_data_block);
3022  ext4_fsblk_t last_block;
3023  ext4_fsblk_t block_bitmap;
3024  ext4_fsblk_t inode_bitmap;
3025  ext4_fsblk_t inode_table;
3026  int flexbg_flag = 0;
3027  ext4_group_t i;
3028 
3030  flexbg_flag = 1;
3031 
3032  DEBUG(DL_INF, ("Checking group descriptors"));
3033 
3034  for (i = 0; i < sbi->s_groups_count; i++) {
3035 
3036  struct buffer_head *bh = NULL;
3037  struct ext4_group_desc *gdp = ext4_get_group_desc(sb, i, &bh);
3038 
3039  if (!bh)
3040  continue;
3041 
3042  if (i == sbi->s_groups_count - 1 || flexbg_flag)
3043  last_block = ext3_blocks_count(sbi->s_es) - 1;
3044  else
3045  last_block = first_block +
3046  (EXT3_BLOCKS_PER_GROUP(sb) - 1);
3047 
3048  block_bitmap = ext4_block_bitmap(sb, gdp);
3049  if (block_bitmap < first_block || block_bitmap > last_block) {
3050  printk(KERN_ERR "EXT4-fs: ext4_check_descriptors: "
3051  "Block bitmap for group %u not in group "
3052  "(block %llu)!\n", i, block_bitmap);
3053  __brelse(bh);
3054  return 0;
3055  }
3056  inode_bitmap = ext4_inode_bitmap(sb, gdp);
3057  if (inode_bitmap < first_block || inode_bitmap > last_block) {
3058  printk(KERN_ERR "EXT4-fs: ext4_check_descriptors: "
3059  "Inode bitmap for group %u not in group "
3060  "(block %llu)!\n", i, inode_bitmap);
3061  __brelse(bh);
3062  return 0;
3063  }
3064  inode_table = ext4_inode_table(sb, gdp);
3065  if (inode_table < first_block ||
3066  inode_table + sbi->s_itb_per_group - 1 > last_block) {
3067  printk(KERN_ERR "EXT4-fs: ext4_check_descriptors: "
3068  "Inode table for group %u not in group "
3069  "(block %llu)!\n", i, inode_table);
3070  __brelse(bh);
3071  return 0;
3072  }
3073 
3074  if (!ext4_group_desc_csum_verify(sbi, i, gdp)) {
3075  printk(KERN_ERR "EXT4-fs: ext4_check_descriptors: "
3076  "Checksum for group %u failed (%u!=%u)\n",
3078  gdp)),
3079  le16_to_cpu(gdp->bg_checksum));
3080  if (!IsVcbReadOnly(Vcb)) {
3081  __brelse(bh);
3082  return 0;
3083  }
3084  }
3085 
3086  if (!flexbg_flag)
3087  first_block += EXT4_BLOCKS_PER_GROUP(sb);
3088 
3089  __brelse(bh);
3090  }
3091 
3093  sbi->s_es->s_free_inodes_count = cpu_to_le32(ext4_count_free_inodes(sb));
3094  return 1;
3095 }
static unsigned int block
Definition: xmlmemory.c:118
NTSTATUS Ext2WinntError(int rc)
Definition: misc.c:410
signed char * PCHAR
Definition: retypes.h:7
BOOLEAN Ext2SaveInode(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN struct inode *Inode)
Definition: generic.c:548
__le16 bg_free_inodes_count_hi
Definition: ext3_fs.h:150
unsigned char __u8
Definition: compat.h:88
BOOLEAN Ext2ReadInode(PEXT2_VOLUME_INFO Volume, ULONG Inode, PEXT2_INODE InodeBuffer)
Definition: ext2.c:907
static PIO_STATUS_BLOCK iosb
Definition: file.c:98
VOID Ext2UpdateVcbStat(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb)
Definition: generic.c:923
VOID Ext2DropBH(IN PEXT2_VCB Vcb)
Definition: generic.c:262
#define IN
Definition: typedefs.h:39
__u32 ext4_used_dirs_count(struct super_block *sb, struct ext4_group_desc *bg)
Definition: generic.c:2425
__u16 const crc16_table[256]
Definition: generic.c:2498
int ext4_check_descriptors(struct super_block *sb)
Definition: generic.c:3017
#define LL
Definition: tui.h:84
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define EXT4_FEATURE_RO_COMPAT_HUGE_FILE
Definition: ext3_fs.h:699
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
IN PVCB IN VBO IN ULONG OUT PBCB * Bcb
Definition: fatprocs.h:411
NTSTATUS Ext2FlushVcb(IN PEXT2_VCB Vcb)
Definition: generic.c:319
#define EXT3_DIR_REC_LEN(len)
Definition: ext3_fs.h:867
static const WCHAR * error_msg[8]
Definition: odbccp32.c:62
#define EXT4_MIN_BLOCK_SIZE
Definition: ext3_fs.h:169
unsigned __int64 sector_t
Definition: types.h:78
void ext4_free_inodes_set(struct super_block *sb, struct ext4_group_desc *bg, __u32 count)
Definition: generic.c:2473
unsigned long ext4_bg_num_gdb(struct super_block *sb, ext4_group_t group)
Definition: generic.c:2648
VOID NTAPI CcFlushCache(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN OPTIONAL PLARGE_INTEGER FileOffset, IN ULONG Length, OUT OPTIONAL PIO_STATUS_BLOCK IoStatus)
Definition: cachesub.c:222
BOOLEAN Ext2ClearInode(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN ULONG Inode)
Definition: generic.c:526
void ext4_used_dirs_set(struct super_block *sb, struct ext4_group_desc *bg, __u32 count)
Definition: generic.c:2481
#define DbgPrint
Definition: loader.c:25
__le16 bg_free_inodes_count
Definition: ext3_fs.h:140
ULONG nr
Definition: thread.c:7
void ext3_update_dx_flag(struct inode *inode)
Definition: htree.c:368
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
static void fini_bh(struct buffer_head **bh)
Definition: module.h:951
LARGE_INTEGER Ext2NtTime(IN ULONG i_time)
Definition: misc.c:40
POINT last
Definition: font.c:46
atomic_t b_count
Definition: module.h:730
struct ext2_sblock * PEXT2_SUPER_BLOCK
Definition: ext2.h:171
superblock * sb
Definition: btrfs.c:4220
#define TRUE
Definition: types.h:120
static struct buffer_head * sb_getblk(struct super_block *sb, sector_t block)
Definition: module.h:966
#define SIZE_256K
Definition: generic.c:861
#define EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER
Definition: ext3_fs.h:671
void ext4_free_blks_set(struct super_block *sb, struct ext4_group_desc *bg, __u32 count)
Definition: generic.c:2465
void ext4_itable_unused_set(struct super_block *sb, struct ext4_group_desc *bg, __u32 count)
Definition: generic.c:2489
static int ext3_group_sparse(ext3_group_t group)
Definition: generic.c:2594
Definition: ext3_fs.h:774
void free_buffer_head(struct buffer_head *bh)
Definition: linux.c:346
#define __u16
Definition: types.h:13
#define EXT2_FIRST_DATA_BLOCK
Definition: ext2fs.h:103
VOID NTAPI CcSetDirtyPinnedData(IN PVOID BcbVoid, IN OPTIONAL PLARGE_INTEGER Lsn)
Definition: cachesub.c:121
__le16 bg_used_dirs_count
Definition: ext3_fs.h:141
umode_t i_mode
Definition: fs.h:87
Definition: fs.h:64
_In_opt_ PSID Group
Definition: rtlfuncs.h:1605
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define u64
Definition: types.h:10
unsigned char * PUCHAR
Definition: retypes.h:3
struct rb_node * rb_next(struct rb_node *)
Definition: rbtree.c:320
#define free
Definition: debug_ros.c:5
#define EXT4_FEATURE_INCOMPAT_META_BG
Definition: ext3_fs.h:708
BOOLEAN Ext2SaveSuper(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb)
Definition: generic.c:63
unsigned long ext4_count_dirs(struct super_block *sb)
Definition: generic.c:2999
BOOLEAN Ext2LoadBuffer(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN LONGLONG offset, IN ULONG size, IN PVOID buf)
Definition: generic.c:729
const GLint * first
Definition: glext.h:5794
#define le16_to_cpu
Definition: module.h:149
NTSYSAPI void WINAPI RtlInitializeBitMap(PRTL_BITMAP, PULONG, ULONG)
LONG NTSTATUS
Definition: precomp.h:26
#define MAX_LFS_FILESIZE
Definition: generic.c:2176
LIST_ENTRY b_link
Definition: module.h:714
NTSTATUS Ext2FreeInode(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN ULONG Inode, IN ULONG Type)
Definition: generic.c:1692
#define do_div(n, b)
Definition: module.h:1220
NTSTATUS Ext2ReadDisk(IN PEXT2_VCB Vcb, IN ULONGLONG Offset, IN ULONG Size, IN PVOID Buffer, IN BOOLEAN bVerify)
Definition: block.c:539
VOID NTAPI CcUnpinData(IN PVOID Bcb)
Definition: pinsup.c:955
int ext4_group_desc_csum_verify(struct ext3_sb_info *sbi, __u32 block_group, struct ext4_group_desc *gdp)
Definition: generic.c:2574
VOID Ext2FlushRange(IN PEXT2_VCB Vcb, LARGE_INTEGER s, LARGE_INTEGER e)
Definition: generic.c:299
void mark_bitmap_end(int start_bit, int end_bit, char *bitmap)
Definition: generic.c:2697
__u32 ext4_free_inodes_count(struct super_block *sb, struct ext4_group_desc *bg)
Definition: generic.c:2417
unsigned long s_desc_per_block
Definition: ext3_fs_sb.h:39
__u16 i_nlink
Definition: fs.h:91
#define GFP_KERNEL
Definition: module.h:658
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
size_t b_size
Definition: module.h:724
#define PIN_WAIT
BOOLEAN Ext2LoadInodeXattr(IN PEXT2_VCB Vcb, IN struct inode *Inode, IN PEXT2_INODE InodeXattr)
Definition: generic.c:586
GLuint buffer
Definition: glext.h:5915
__le16 bg_free_blocks_count
Definition: ext3_fs.h:139
#define RtlCheckBit(BMH, BP)
Definition: rtlfuncs.h:3152
#define EXT4_BG_INODE_UNINIT
Definition: ext3_fs.h:733
#define atomic_read(v)
Definition: atomic.h:23
#define EXT2_DIR_REC_LEN(name_len)
Definition: ext2_fs.h:536
__le16 bg_itable_unused
Definition: ext3_fs.h:144
unsigned ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh, ext4_group_t block_group, struct ext4_group_desc *gdp)
Definition: generic.c:2803
#define EXT4_DESC_SIZE(s)
Definition: ext3_fs.h:174
struct ext3_dir_entry_2 * ext3_next_entry(struct ext3_dir_entry_2 *p)
Definition: generic.c:2170
STRING OEM_STRING
Definition: umtypes.h:203
#define EXT3_NDIR_BLOCKS
Definition: ext3_fs.h:197
if(dx==0 &&dy==0)
Definition: linetemp.h:174
BOOLEAN Ext2SaveBlock(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN ULONG Index, IN PVOID Buf)
Definition: generic.c:694
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * bits
Definition: glext.h:10929
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
struct rb_node * rb_first(struct rb_root *)
Definition: rbtree.c:294
ULONG32 u32
Definition: btrfs.h:14
__le32 bg_inode_table_hi
Definition: ext3_fs.h:148
struct ext3_gd * s_gd
Definition: ext3_fs_sb.h:35
unsigned long ext4_count_free_inodes(struct super_block *sb)
Definition: generic.c:2980
_SEH2_TRY
Definition: create.c:4226
ext4_fsblk_t ext4_inode_bitmap(struct super_block *sb, struct ext4_group_desc *bg)
Definition: generic.c:2393
#define EXT4_BG_BLOCK_UNINIT
Definition: ext3_fs.h:734
ext4_fsblk_t ext4_count_free_blocks(struct super_block *sb)
Definition: generic.c:2959
unsigned long long ext4_fsblk_t
Definition: ext3_fs_i.h:27
static void brelse(struct buffer_head *bh)
Definition: module.h:945
void ext3_dec_count(struct inode *inode)
Definition: htree.c:312
__le16 bg_used_dirs_count_hi
Definition: ext3_fs.h:151
Definition: fs.h:78
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
static int ext4_group_used_meta_blocks(struct super_block *sb, ext4_group_t block_group)
Definition: generic.c:2768
void Ext2EncodeInode(struct ext3_inode *dst, struct inode *src)
Definition: generic.c:475
__GNU_EXTENSION typedef __int64 * PLONGLONG
Definition: ntbasedef.h:382
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
struct node node
VOID Ext2FreeEntry(IN struct dentry *de)
Definition: memory.c:432
#define EXT4_MIN_DESC_SIZE_64BIT
Definition: ext3_fs.h:171
#define FO_FILE_MODIFIED
Definition: iotypes.h:1788
void ext4_inode_bitmap_set(struct super_block *sb, struct ext4_group_desc *bg, ext4_fsblk_t blk)
Definition: generic.c:2449
#define STATUS_NOT_A_DIRECTORY
Definition: udferr_usr.h:169
#define FALSE
Definition: types.h:117
int ext3_mark_inode_dirty(struct ext2_icb *icb, struct inode *in)
Definition: htree.c:360
#define TOTAL_BLOCKS
Definition: ext2fs.h:101
struct rb_node b_rb_node
Definition: module.h:731
#define a
Definition: ke_i.h:78
#define e
Definition: ke_i.h:82
static const WCHAR desc[]
Definition: protectdata.c:36
static int test_root(ext3_group_t a, ext3_group_t b)
Definition: generic.c:2585
unsigned __int64 blkcnt_t
Definition: types.h:79
BOOLEAN Ext2RefreshSuper(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb)
Definition: generic.c:88
VOID Ext2DropGroupBH(IN PEXT2_VCB Vcb)
Definition: generic.c:128
BOOLEAN Ext2LoadGroupBH(IN PEXT2_VCB Vcb)
Definition: generic.c:166
loff_t ext3_max_size(int blkbits, int has_huge_files)
Definition: generic.c:2227
#define IsFlagOn(a, b)
Definition: ext2fs.h:177
NTSTATUS Ext2WriteInode(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN PEXT2_MCB Mcb, IN ULONGLONG Offset, IN PVOID Buffer, IN ULONG Size, IN BOOLEAN bDirectIo, OUT PULONG dwReturn)
Definition: write.c:652
#define le32_to_cpu
Definition: module.h:147
VOID Ext2StartFloppyFlushDpc(PEXT2_VCB Vcb, PEXT2_FCB Fcb, PFILE_OBJECT FileObject)
Definition: write.c:123
unsigned char BOOLEAN
void Ext2DecodeInode(struct inode *dst, struct ext3_inode *src)
Definition: generic.c:448
#define BLOCK_BITS
Definition: stream.h:22
#define __le16
Definition: types.h:39
static loff_t ext4_max_size(int blkbits, int has_huge_files)
Definition: generic.c:2187
NTSTATUS Ext2RemoveEntry(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN PEXT2_FCB Dcb, IN PEXT2_MCB Mcb)
Definition: generic.c:1947
#define offsetof(TYPE, MEMBER)
BOOLEAN NTAPI ExIsResourceAcquiredExclusiveLite(IN PERESOURCE Resource)
Definition: resource.c:1619
__le32 bg_inode_table
Definition: ext3_fs.h:138
#define EXT3_SET_RO_COMPAT_FEATURE(sb, mask)
Definition: ext3_fs.h:653
#define EXT4_FEATURE_INCOMPAT_FLEX_BG
Definition: ext3_fs.h:712
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
Definition: bufpool.h:45
NTSYSAPI ULONG WINAPI RtlFindClearBits(PCRTL_BITMAP, ULONG, ULONG)
Definition: fs.h:117
unsigned int dir
Definition: maze.c:112
#define EXT3_FEATURE_INCOMPAT_FILETYPE
Definition: ext3_fs.h:679
#define EXT4_FEATURE_INCOMPAT_64BIT
Definition: ext3_fs.h:710
NTSTATUS Ext2UpdateGroupDirStat(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN ULONG group)
Definition: generic.c:1654
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define SUPER_BLOCK
Definition: ext2fs.h:90
__u64 i_blocks
Definition: fs.h:85
#define b
Definition: ke_i.h:79
__u32 i_flags
Definition: fs.h:94
#define EXT4_HUGE_FILE_FL
Definition: ext3_fs.h:262
static BOOL bVerify
Definition: verify.c:27
BOOLEAN Ext2RemoveBlockExtent(IN PEXT2_VCB Vcb, IN PEXT2_MCB Mcb, IN ULONG Start, IN ULONG Number)
Definition: memory.c:1097
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
void ext4_block_bitmap_set(struct super_block *sb, struct ext4_group_desc *bg, ext4_fsblk_t blk)
Definition: generic.c:2441
r l[0]
Definition: byte_order.h:167
VOID Ext2Sleep(ULONG ms)
Definition: misc.c:297
Status
Definition: gdiplustypes.h:24
GLboolean GLuint group
Definition: glext.h:11120
NTSTATUS Ext2FreeBlock(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN ULONG Block, IN ULONG Number)
Definition: generic.c:1143
__le32 bg_block_bitmap
Definition: ext3_fs.h:136
Definition: uimain.c:88
int64_t LONGLONG
Definition: typedefs.h:68
int Count
Definition: noreturn.cpp:7
int ext4_grpblk_t
Definition: ext3_fs_i.h:23
#define EXT4_FEATURE_RO_COMPAT_GDT_CSUM
Definition: ext3_fs.h:700
static void atomic_inc(atomic_t volatile *v)
Definition: atomic.h:95
struct ext3_super_block * s_es
Definition: ext3_fs_sb.h:61
NTSTATUS Ext2SetFileType(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN PEXT2_FCB Dcb, IN PEXT2_MCB Mcb, IN umode_t mode)
Definition: generic.c:1877
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
asmlinkage int printk(const char *fmt,...)
Definition: output.c:76
#define BLOCK_SIZE
Definition: dlist.c:220
__u32 i_ctime
Definition: fs.h:82
GLsizeiptr size
Definition: glext.h:5919
BOOLEAN Ext2LoadGroup(IN PEXT2_VCB Vcb)
Definition: generic.c:203
unsigned short __u16
Definition: compat.h:89
static struct buffer_head * sb_getblk_zero(struct super_block *sb, sector_t block)
Definition: module.h:972
#define ASSERT(a)
Definition: mode.c:44
BOOLEAN Ext2LoadBlock(IN PEXT2_VCB Vcb, IN ULONG Index, IN PVOID Buffer)
Definition: generic.c:655
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define DL_INF
Definition: ext2fs.h:1399
void ext3_warning(struct super_block *sb, const char *function, char *fmt,...)
Definition: htree.c:212
GLintptr offset
Definition: glext.h:5920
_In_ WDFCOLLECTION _In_ ULONG Index
#define IsVcbReadOnly(Vcb)
Definition: ext2fs.h:805
uint64_t ULONGLONG
Definition: typedefs.h:67
#define S_ISDIR(mode)
Definition: various.h:18
BOOLEAN Ext2ZeroBuffer(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN LONGLONG offset, IN ULONG size)
Definition: generic.c:791
#define ext4_set_bit(n, p)
Definition: generic.c:2680
#define Vcb
Definition: cdprocs.h:1415
#define KERN_ERR
Definition: module.h:223
struct ext3_dir_entry_2 * PEXT2_DIR_ENTRY2
Definition: ext2fs.h:109
BOOLEAN Ext2AddVcbExtent(IN PEXT2_VCB Vcb, IN LONGLONG Vbn, IN LONGLONG Length)
Definition: memory.c:648
#define __u32
Definition: types.h:15
unsigned long s_gdb_count
Definition: ext3_fs_sb.h:38
#define container_of(ptr, type, member)
Definition: glue.h:15
Type
Definition: Type.h:6
#define EXT3_HAS_RO_COMPAT_FEATURE(sb, mask)
Definition: ext3_fs.h:647
GLuint GLuint num
Definition: glext.h:9618
__u32 ext3_current_time(struct inode *in)
Definition: htree.c:204
blkcnt_t b_blocknr
Definition: module.h:723
ext3_fsblk_t descriptor_loc(struct super_block *sb, ext3_fsblk_t logical_sb_block, unsigned int nr)
Definition: generic.c:2662
#define Ext2ReferXcb(_C)
Definition: ext2fs.h:967
unsigned int __u32
Definition: compat.h:90
__u32 ext4_free_blks_count(struct super_block *sb, struct ext4_group_desc *bg)
Definition: generic.c:2409
static unsigned long ext4_bg_num_gdb_meta(struct super_block *sb, ext4_group_t group)
Definition: generic.c:2621
__le32 inode
Definition: ext3_fs.h:775
ext4_fsblk_t ext4_inode_table(struct super_block *sb, struct ext4_group_desc *bg)
Definition: generic.c:2401
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
BOOLEAN NTAPI CcPinRead(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN ULONG Flags, OUT PVOID *Bcb, OUT PVOID *Buffer)
Definition: pinsup.c:802
NTSTATUS Ext2NewBlock(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN ULONG GroupHint, IN ULONG BlockHint, OUT PULONG Block, IN OUT PULONG Number)
Definition: generic.c:934
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
NTSTATUS Ext2AddEntry(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN PEXT2_FCB Dcb, IN struct inode *Inode, IN PUNICODE_STRING FileName, struct dentry **Dentry)
Definition: generic.c:1805
loff_t ext3_max_bitmap_size(int bits, int has_huge_files)
Definition: generic.c:2263
unsigned __int64 loff_t
Definition: types.h:80
void __brelse(struct buffer_head *)
Definition: linux.c:800
NTSTATUS Ext2LoadSuper(IN PEXT2_VCB Vcb, IN BOOLEAN bVerify, OUT PEXT2_SUPER_BLOCK *Sb)
Definition: generic.c:25
#define EXT3_HAS_INCOMPAT_FEATURE(sb, mask)
Definition: ext3_fs.h:649
unsigned int ext3_group_t
Definition: ext3_fs_i.h:34
ULONG64 u64
Definition: btrfs.h:15
BOOLEAN NTAPI CcCopyRead(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, OUT PVOID Buffer, OUT PIO_STATUS_BLOCK IoStatus)
Definition: copysup.c:43
struct buffer_head * ext3_find_entry(struct ext2_icb *icb, struct dentry *dentry, struct ext3_dir_entry_2 **res_dir)
Definition: htree.c:2166
void ext3_inc_count(struct inode *inode)
Definition: htree.c:307
__le16 ext4_group_desc_csum(struct ext3_sb_info *sbi, __u32 block_group, struct ext4_group_desc *gdp)
Definition: generic.c:2545
#define smp_rmb()
Definition: module.h:1209
int ext3_add_entry(struct ext2_icb *icb, struct dentry *dentry, struct inode *inode)
Definition: htree.c:1946
_Must_inspect_result_ _In_ PFLT_INSTANCE _Out_ PBOOLEAN IsDirectory
Definition: fltkernel.h:1139
__le32 bg_inode_bitmap
Definition: ext3_fs.h:137
#define EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE
Definition: ext3_fs.h:702
DWORD upper_limit
Definition: apphelp.c:212
#define blk
Definition: linetest.c:70
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
GLdouble s
Definition: gl.h:2039
Definition: typedefs.h:119
GLenum src
Definition: glext.h:6340
#define err(...)
static void ext3_free_blocks_count_set(struct ext3_super_block *es, ext3_fsblk_t blk)
Definition: ext2fs.h:1717
int bh_submit_read(struct buffer_head *bh)
Definition: linux.c:884
void mark_buffer_dirty(struct buffer_head *bh)
Definition: linux.c:906
GLenum mode
Definition: glext.h:6217
_In_opt_ PENTER_STATE_SYSTEM_HANDLER _In_opt_ PVOID _In_ LONG _In_opt_ LONG volatile * Number
Definition: ntpoapi.h:204
__u32 i_ino
Definition: fs.h:79
__le16 bg_free_blocks_count_hi
Definition: ext3_fs.h:149
static int repeat
Definition: xmllint.c:143
BOOLEAN Ext2SaveBuffer(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN LONGLONG Offset, IN ULONG Size, IN PVOID Buf)
Definition: generic.c:864
char * b_data
Definition: module.h:725
ClearFlag(Dirent->Flags, DIRENT_FLAG_NOT_PERSISTENT)
#define SUPER_BLOCK_SIZE
Definition: ext2fs.h:86
#define EXT2_DENTRY_MAGIC
Definition: ext2fs.h:295
static unsigned long ext4_bg_num_gdb_nometa(struct super_block *sb, ext4_group_t group)
Definition: generic.c:2633
#define DL_ERR
Definition: ext2fs.h:1397
BOOLEAN Ext2SaveGroup(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN ULONG Group)
Definition: generic.c:382
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
int ext3_delete_entry(struct ext2_icb *icb, struct inode *dir, struct ext3_dir_entry_2 *de_del, struct buffer_head *bh)
Definition: htree.c:2005
NTSYSAPI void WINAPI RtlClearBits(PRTL_BITMAP, ULONG, ULONG)
int ext3_inode_blocks_set(struct ext3_inode *raw_inode, struct inode *inode)
Definition: generic.c:2344
ext4_fsblk_t ext4_block_bitmap(struct super_block *sb, struct ext4_group_desc *bg)
Definition: generic.c:2385
__u32 ext4_itable_unused_count(struct super_block *sb, struct ext4_group_desc *bg)
Definition: generic.c:2433
unsigned int ext4_group_t
Definition: ext3_fs_i.h:35
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
_SEH2_END
Definition: create.c:4400
#define VCB_FLOPPY_DISK
Definition: ext2fs.h:797
void buffer_head_remove(struct block_device *bdev, struct buffer_head *bh)
Definition: linux.c:424
__u8 name_len
Definition: ext3_fs.h:777
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
blkcnt_t ext3_inode_blocks(struct ext3_inode *raw_inode, struct inode *inode)
Definition: generic.c:2321
GLuint start
Definition: gl.h:1545
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
IN PVCB IN ULONG IN OUT PULONG IN BOOLEAN OUT PLARGE_MCB Mcb
Definition: fatprocs.h:343
GLenum GLenum dst
Definition: glext.h:6340
#define EXT3_INODES_PER_GROUP(s)
Definition: ext3_fs.h:191
int ext3_check_dir_entry(const char *function, struct inode *dir, struct ext3_dir_entry_2 *de, struct buffer_head *bh, unsigned long offset)
Definition: generic.c:2135
NTSYSAPI void WINAPI RtlSetBits(PRTL_BITMAP, ULONG, ULONG)
_SEH2_FINALLY
Definition: create.c:4371
#define SUPER_BLOCK_OFFSET
Definition: ext2fs.h:85
void ext4_inode_table_set(struct super_block *sb, struct ext4_group_desc *bg, ext4_fsblk_t blk)
Definition: generic.c:2457
unsigned long s_itb_per_group
Definition: ext3_fs_sb.h:44
static int ext4_block_in_group(struct super_block *sb, ext4_fsblk_t block, ext4_group_t block_group)
Definition: generic.c:2758
unsigned int * PULONG
Definition: retypes.h:1
#define min(a, b)
Definition: monoChain.cc:55
Definition: arc.h:46
int ext3_bg_has_super(struct super_block *sb, ext3_group_t group)
Definition: generic.c:2612
#define NULL
Definition: types.h:112
#define EXT3_MIN_BLOCK_SIZE
Definition: ext3_fs.h:75
__u16 crc16(__u16 crc, __u8 const *buffer, size_t len)
Definition: generic.c:2538
void ext4_get_group_no_and_offset(struct super_block *sb, ext4_fsblk_t blocknr, ext4_group_t *blockgrpp, ext4_grpblk_t *offsetp)
Definition: generic.c:2743
VOID Ext2PutGroup(IN PEXT2_VCB Vcb)
Definition: generic.c:146
#define PIN_EXCLUSIVE
unsigned ext4_init_inode_bitmap(struct super_block *sb, struct buffer_head *bh, ext4_group_t block_group, struct ext4_group_desc *gdp)
Definition: generic.c:2712
NTSYSAPI ULONG WINAPI RtlFindNextForwardRunClear(PCRTL_BITMAP, ULONG, PULONG)
static unsigned ext3_rec_len_from_disk(__le16 dlen)
Definition: ext3_fs.h:871
#define EXT2_GOOD_OLD_INODE_SIZE
Definition: ext2.h:54
#define VCB_BEING_DROPPED
Definition: ext2fs.h:789
#define OUT
Definition: typedefs.h:40
GLuint res
Definition: glext.h:9613
#define STATUS_DISK_FULL
Definition: udferr_usr.h:155
#define VCB_GD_LOADED
Definition: ext2fs.h:787
#define STATUS_DISK_CORRUPT_ERROR
Definition: udferr_usr.h:147
__in UCHAR __in POWER_STATE __in_opt PVOID __in PIO_STATUS_BLOCK IoStatus
Definition: mxum.h:155
unsigned int ULONG
Definition: retypes.h:1
#define INODES_PER_GROUP
Definition: ext2fs.h:99
FxObject * pParent
Definition: fxdpcapi.cpp:86
Definition: rbtree.h:97
#define EXT2_SB_MAGIC
Definition: ext2fs.h:297
struct super_block * i_sb
Definition: fs.h:96
BOOLEAN Ext2RefreshGroup(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb)
Definition: generic.c:405
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define INODES_COUNT
Definition: ext2fs.h:97
struct ext4_group_desc * ext4_get_group_desc(struct super_block *sb, ext4_group_t block_group, struct buffer_head **bh)
Definition: generic.c:2902
#define DbgBreak()
Definition: ext2fs.h:46
VOID Ext2FreePool(IN PVOID P, IN ULONG Tag)
Definition: debug.c:2697
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
__le16 rec_len
Definition: ext3_fs.h:776
unsigned long s_groups_count
Definition: ext3_fs_sb.h:43
BOOLEAN Ext2SaveInodeXattr(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN struct inode *Inode, IN PEXT2_INODE InodeXattr)
Definition: generic.c:617
struct _EXT2_VCB * PEXT2_VCB
#define DEBUG(args)
Definition: rdesktop.h:129
unsigned long long ext3_fsblk_t
Definition: ext3_fs_i.h:26
PEXT2_GLOBAL Ext2Global
Definition: init.c:16
#define STATUS_SUCCESS
Definition: shellext.h:65
BOOLEAN Ext2LoadInode(IN PEXT2_VCB Vcb, IN struct inode *Inode)
Definition: generic.c:504
#define VCB_INITIALIZED
Definition: ext2fs.h:779
#define EXT3_BLOCKS_PER_GROUP(s)
Definition: ext3_fs.h:189
NTSTATUS Ext2NewInode(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN ULONG GroupHint, IN ULONG Type, OUT PULONG Inode)
Definition: generic.c:1292
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
#define _SEH2_LEAVE
Definition: filesup.c:20
GLfloat GLfloat p
Definition: glext.h:8902
__le16 bg_itable_unused_hi
Definition: ext3_fs.h:152
__le16 bg_checksum
Definition: ext3_fs.h:145
#define cpu_to_le16
Definition: module.h:148
static ext3_fsblk_t ext3_blocks_count(struct ext3_super_block *es)
Definition: ext2fs.h:1692
PVOID Ext2AllocatePool(IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes, IN ULONG Tag)
Definition: debug.c:2684
#define __FUNCTION__
Definition: types.h:112
#define memset(x, y, z)
Definition: compat.h:39
NTSYSAPI ULONG WINAPI RtlNumberOfClearBits(PCRTL_BITMAP)
BOOLEAN NTAPI CcPreparePinWrite(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Zero, IN ULONG Flags, OUT PVOID *Bcb, OUT PVOID *Buffer)
Definition: pinsup.c:827
static SERVICE_STATUS status
Definition: service.c:31
__le32 bg_inode_bitmap_hi
Definition: ext3_fs.h:147
NTSTATUS Ext2SetParentEntry(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN PEXT2_FCB Dcb, IN ULONG OldParent, IN ULONG NewParent)
Definition: generic.c:2024
#define S_ISREG(mode)
Definition: various.h:17
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB _Outptr_result_maybenull_ PDCB * Dcb
Definition: create.c:4137
#define UL
Definition: tui.h:82
BOOLEAN Ext2GetInodeLba(IN PEXT2_VCB Vcb, IN ULONG inode, OUT PLONGLONG offset)
Definition: generic.c:414
#define ext4_error
Definition: ext2fs.h:2476
#define EXT3_SB(sb)
Definition: ext3_fs.h:615
#define BLOCKS_PER_GROUP
Definition: ext2fs.h:100
__le32 bg_block_bitmap_hi
Definition: ext3_fs.h:146
#define cpu_to_le32
Definition: module.h:146
#define Ext2DerefXcb(_C)
Definition: ext2fs.h:968
void * kzalloc(int size, int flags)
Definition: linux.c:34
void ext3_set_de_type(struct super_block *sb, struct ext3_dir_entry_2 *de, umode_t mode)
Definition: htree.c:347
static unsigned(__cdecl *hash_bstr)(bstr_t s)
#define es
Definition: i386-dis.c:433
static __u16 crc16_byte(__u16 crc, const __u8 data)
Definition: generic.c:2533
struct inode * d_inode
Definition: fs.h:123
void kfree(const void *)
__le32 i_blocks
Definition: ext3_fs.h:355
#define __le32
Definition: types.h:40
Definition: dlist.c:348
#define STATUS_CANT_WAIT
Definition: ntstatus.h:452
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
struct dentry * Ext2BuildEntry(PEXT2_VCB Vcb, PEXT2_MCB Dcb, PUNICODE_STRING FileName)
Definition: memory.c:444
unsigned short umode_t
Definition: types.h:71
Definition: ps.c:97