ReactOS  0.4.13-dev-551-gf37fb1f
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 BOOLEAN
863  IN PEXT2_VCB Vcb,
865  IN ULONG size,
866  IN PVOID buf )
867 {
868  struct buffer_head *bh = NULL;
869  BOOLEAN rc = 0;
870 
871  _SEH2_TRY {
872 
873  while (size) {
874 
875  sector_t block;
876  ULONG len = 0, delta = 0;
877 
878  block = (sector_t) (offset >> BLOCK_BITS);
879  delta = (ULONG)offset & (BLOCK_SIZE - 1);
880  len = BLOCK_SIZE - delta;
881  if (size < len)
882  len = size;
883 
884  if (delta == 0 && len >= BLOCK_SIZE) {
885  bh = sb_getblk_zero(&Vcb->sb, block);
886  } else {
887  bh = sb_getblk(&Vcb->sb, block);
888  }
889 
890  if (!bh) {
891  DEBUG(DL_ERR, ("Ext2SaveBuffer: can't load block %I64u\n", block));
892  DbgBreak();
893  _SEH2_LEAVE;
894  }
895 
896  if (!buffer_uptodate(bh)) {
897  int err = bh_submit_read(bh);
898  if (err < 0) {
899  DEBUG(DL_ERR, ("Ext2SaveBuffer: bh_submit_read failed: %d\n", err));
900  _SEH2_LEAVE;
901  }
902  }
903 
904  _SEH2_TRY {
905  RtlCopyMemory(bh->b_data + delta, buf, len);
906  mark_buffer_dirty(bh);
907  } _SEH2_FINALLY {
908  fini_bh(&bh);
909  } _SEH2_END;
910 
911  buf = (PUCHAR)buf + len;
912  offset = offset + len;
913  size = size - len;
914  }
915 
916  rc = TRUE;
917 
918  } _SEH2_FINALLY {
919 
920  if (bh)
921  fini_bh(&bh);
922 
923  } _SEH2_END;
924 
925  return rc;
926 }
927 
928 
929 VOID
931  IN PEXT2_IRP_CONTEXT IrpContext,
933 )
934 {
935  Vcb->SuperBlock->s_free_inodes_count = ext4_count_free_inodes(&Vcb->sb);
937  Ext2SaveSuper(IrpContext, Vcb);
938 }
939 
940 NTSTATUS
942  IN PEXT2_IRP_CONTEXT IrpContext,
943  IN PEXT2_VCB Vcb,
944  IN ULONG GroupHint,
945  IN ULONG BlockHint,
946  OUT PULONG Block,
948 )
949 {
950  struct super_block *sb = &Vcb->sb;
951  PEXT2_GROUP_DESC gd;
952  struct buffer_head *gb = NULL;
953  struct buffer_head *bh = NULL;
954  ext4_fsblk_t bitmap_blk;
955 
956  RTL_BITMAP BlockBitmap;
957 
958  ULONG Group = 0;
959  ULONG Index = 0xFFFFFFFF;
960  ULONG dwHint = 0;
961  ULONG Count = 0;
962  ULONG Length = 0;
963 
965 
966  *Block = 0;
967 
969 
970  /* validate the hint group and hint block */
971  if (GroupHint >= Vcb->sbi.s_groups_count) {
972  DbgBreak();
973  GroupHint = Vcb->sbi.s_groups_count - 1;
974  }
975 
976  if (BlockHint != 0) {
977  GroupHint = (BlockHint - EXT2_FIRST_DATA_BLOCK) / BLOCKS_PER_GROUP;
978  dwHint = (BlockHint - EXT2_FIRST_DATA_BLOCK) % BLOCKS_PER_GROUP;
979  }
980 
981  Group = GroupHint;
982 
983 Again:
984 
985  if (bh)
986  fini_bh(&bh);
987 
988  if (gb)
989  fini_bh(&gb);
990 
991  gd = ext4_get_group_desc(sb, Group, &gb);
992  if (!gd) {
993  DbgBreak();
995  goto errorout;
996  }
997 
998  bitmap_blk = ext4_block_bitmap(sb, gd);
999 
1000  if (gd->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
1001  bh = sb_getblk_zero(sb, bitmap_blk);
1002  if (!bh) {
1003  DbgBreak();
1005  goto errorout;
1006  }
1007  gd->bg_checksum = ext4_group_desc_csum(EXT3_SB(sb), Group, gd);
1008  ext4_init_block_bitmap(sb, bh, Group, gd);
1009  set_buffer_uptodate(bh);
1010  gd->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT);
1011  Ext2SaveGroup(IrpContext, Vcb, Group);
1012  } else {
1013  bh = sb_getblk(sb, bitmap_blk);
1014  if (!bh) {
1015  DbgBreak();
1017  goto errorout;
1018  }
1019  }
1020 
1021  if (!buffer_uptodate(bh)) {
1022  int err = bh_submit_read(bh);
1023  if (err < 0) {
1024  DbgPrint("bh_submit_read error! err: %d\n", err);
1026  goto errorout;
1027  }
1028  }
1029 
1030  if (ext4_free_blks_count(sb, gd)) {
1031 
1032  if (Group == Vcb->sbi.s_groups_count - 1) {
1033 
1035 
1036  /* s_blocks_count is integer multiple of s_blocks_per_group */
1037  if (Length == 0) {
1039  }
1040  } else {
1042  }
1043 
1044  /* initialize bitmap buffer */
1045  RtlInitializeBitMap(&BlockBitmap, (PULONG)bh->b_data, Length);
1046 
1047  /* try to find a clear bit range */
1048  Index = RtlFindClearBits(&BlockBitmap, *Number, dwHint);
1049 
1050  /* We could not get new block in the prefered group */
1051  if (Index == 0xFFFFFFFF) {
1052 
1053  /* search clear bits from the hint block */
1054  Count = RtlFindNextForwardRunClear(&BlockBitmap, dwHint, &Index);
1055  if (dwHint != 0 && Count == 0) {
1056  /* search clear bits from the very beginning */
1057  Count = RtlFindNextForwardRunClear(&BlockBitmap, 0, &Index);
1058  }
1059 
1060  if (Count == 0) {
1061 
1062  RtlZeroMemory(&BlockBitmap, sizeof(RTL_BITMAP));
1063 
1064  /* no blocks found: set bg_free_blocks_count to 0 */
1065  ext4_free_blks_set(sb, gd, 0);
1066  Ext2SaveGroup(IrpContext, Vcb, Group);
1067 
1068  /* will try next group */
1069  goto Again;
1070 
1071  } else {
1072 
1073  /* we got free blocks */
1074  if (Count <= *Number) {
1075  *Number = Count;
1076  }
1077  }
1078  }
1079 
1080  } else {
1081 
1082  /* try next group */
1083  dwHint = 0;
1084  Group = (Group + 1) % Vcb->sbi.s_groups_count;
1085  if (Group != GroupHint) {
1086  goto Again;
1087  }
1088 
1089  Index = 0xFFFFFFFF;
1090  }
1091 
1092  if (Index < Length) {
1093 
1094  /* mark block bits as allocated */
1095  RtlSetBits(&BlockBitmap, Index, *Number);
1096 
1097  /* set block bitmap dirty in cache */
1098  mark_buffer_dirty(bh);
1099 
1100  /* update group description */
1101  ext4_free_blks_set(sb, gd, RtlNumberOfClearBits(&BlockBitmap));
1102  Ext2SaveGroup(IrpContext, Vcb, Group);
1103 
1104  /* update Vcb free blocks */
1105  Ext2UpdateVcbStat(IrpContext, Vcb);
1106 
1107  /* validate the new allocated block number */
1109  if (*Block >= TOTAL_BLOCKS || *Block + *Number > TOTAL_BLOCKS) {
1110  DbgBreak();
1111  dwHint = 0;
1112  goto Again;
1113  }
1114 
1115  if (ext4_block_bitmap(sb, gd) == *Block ||
1116  ext4_inode_bitmap(sb, gd) == *Block ||
1117  ext4_inode_table(sb, gd) == *Block ) {
1118  DbgBreak();
1119  dwHint = 0;
1120  goto Again;
1121  }
1122 
1123  /* Always remove dirty MCB to prevent Volume's lazy writing.
1124  Metadata blocks will be re-added during modifications.*/
1125  if (Ext2RemoveBlockExtent(Vcb, NULL, *Block, *Number)) {
1126  } else {
1127  DbgBreak();
1128  Ext2RemoveBlockExtent(Vcb, NULL, *Block, *Number);
1129  }
1130 
1131  DEBUG(DL_INF, ("Ext2NewBlock: Block %xh - %x allocated.\n",
1132  *Block, *Block + *Number));
1134  }
1135 
1136 errorout:
1137 
1138  ExReleaseResourceLite(&Vcb->MetaBlock);
1139 
1140  if (bh)
1141  fini_bh(&bh);
1142 
1143  if (gb)
1144  fini_bh(&gb);
1145 
1146  return Status;
1147 }
1148 
1149 NTSTATUS
1151  IN PEXT2_IRP_CONTEXT IrpContext,
1152  IN PEXT2_VCB Vcb,
1153  IN ULONG Block,
1154  IN ULONG Number
1155 )
1156 {
1157  struct super_block *sb = &Vcb->sb;
1158  PEXT2_GROUP_DESC gd;
1159  struct buffer_head *gb = NULL;
1160  ext4_fsblk_t bitmap_blk;
1161 
1162  RTL_BITMAP BlockBitmap;
1164 
1165  PBCB BitmapBcb;
1166  PVOID BitmapCache;
1167 
1168  ULONG Group;
1169  ULONG Index;
1170  ULONG Length;
1171  ULONG Count;
1172 
1174 
1175  ExAcquireResourceExclusiveLite(&Vcb->MetaBlock, TRUE);
1176 
1177  DEBUG(DL_INF, ("Ext2FreeBlock: Block %xh - %x to be freed.\n",
1178  Block, Block + Number));
1179 
1182 
1183 Again:
1184 
1185  if (gb)
1186  fini_bh(&gb);
1187 
1188  if ( Block < EXT2_FIRST_DATA_BLOCK ||
1189  Block >= TOTAL_BLOCKS ||
1190  Group >= Vcb->sbi.s_groups_count) {
1191 
1192  DbgBreak();
1194 
1195  } else {
1196 
1197  gd = ext4_get_group_desc(sb, Group, &gb);
1198  if (!gd) {
1199  DbgBreak();
1201  goto errorout;
1202  }
1203  bitmap_blk = ext4_block_bitmap(sb, gd);
1204 
1205  /* check the block is valid or not */
1206  if (bitmap_blk >= TOTAL_BLOCKS) {
1207  DbgBreak();
1209  goto errorout;
1210  }
1211 
1212  /* get bitmap block offset and length */
1213  Offset.QuadPart = bitmap_blk;
1214  Offset.QuadPart = Offset.QuadPart << BLOCK_BITS;
1215 
1216  if (Group == Vcb->sbi.s_groups_count - 1) {
1217 
1219 
1220  /* s_blocks_count is integer multiple of s_blocks_per_group */
1221  if (Length == 0) {
1223  }
1224 
1225  } else {
1227  }
1228 
1229  /* read and initialize bitmap */
1230  if (!CcPinRead( Vcb->Volume,
1231  &Offset,
1232  Vcb->BlockSize,
1233  PIN_WAIT,
1234  &BitmapBcb,
1235  &BitmapCache ) ) {
1236 
1237  DEBUG(DL_ERR, ("Ext2FreeBlock: failed to PinLock bitmap block %xh.\n",
1238  bitmap_blk));
1240  DbgBreak();
1241  goto errorout;
1242  }
1243 
1244  /* clear usused bits */
1245  RtlInitializeBitMap(&BlockBitmap, BitmapCache, Length);
1246  Count = min(Length - Index, Number);
1247  RtlClearBits(&BlockBitmap, Index, Count);
1248 
1249  /* update group description table */
1250  ext4_free_blks_set(sb, gd, RtlNumberOfClearBits(&BlockBitmap));
1251 
1252  /* indict the cache range is dirty */
1253  CcSetDirtyPinnedData(BitmapBcb, NULL );
1254  Ext2AddVcbExtent(Vcb, Offset.QuadPart, (LONGLONG)Vcb->BlockSize);
1255  CcUnpinData(BitmapBcb);
1256  BitmapBcb = NULL;
1257  BitmapCache = NULL;
1258  Ext2SaveGroup(IrpContext, Vcb, Group);
1259 
1260  /* remove dirty MCB to prevent Volume's lazy writing. */
1261  if (Ext2RemoveBlockExtent(Vcb, NULL, Block, Count)) {
1262  } else {
1263  DbgBreak();
1264  Ext2RemoveBlockExtent(Vcb, NULL, Block, Count);
1265  }
1266 
1267  /* save super block (used/unused blocks statics) */
1268  Ext2UpdateVcbStat(IrpContext, Vcb);
1269 
1270  /* try next group to clear all remaining */
1271  Number -= Count;
1272  if (Number) {
1273  Group += 1;
1274  if (Group < Vcb->sbi.s_groups_count) {
1275  Index = 0;
1276  Block += Count;
1277  goto Again;
1278  } else {
1279  DEBUG(DL_ERR, ("Ext2FreeBlock: block number beyonds max group.\n"));
1280  goto errorout;
1281  }
1282  }
1283  }
1284 
1286 
1287 errorout:
1288 
1289  if (gb)
1290  fini_bh(&gb);
1291 
1292  ExReleaseResourceLite(&Vcb->MetaBlock);
1293 
1294  return Status;
1295 }
1296 
1297 
1298 NTSTATUS
1300  IN PEXT2_IRP_CONTEXT IrpContext,
1301  IN PEXT2_VCB Vcb,
1302  IN ULONG GroupHint,
1303  IN ULONG Type,
1304  OUT PULONG Inode
1305 )
1306 {
1307  struct super_block *sb = &Vcb->sb;
1308  PEXT2_GROUP_DESC gd;
1309  struct buffer_head *gb = NULL;
1310  struct buffer_head *bh = NULL;
1311  ext4_fsblk_t bitmap_blk;
1312 
1313  RTL_BITMAP InodeBitmap;
1314 
1315  ULONG Group, i, j;
1316  ULONG Average, Length;
1317 
1318  ULONG dwInode;
1319 
1321 
1322  *Inode = dwInode = 0XFFFFFFFF;
1323 
1324  ExAcquireResourceExclusiveLite(&Vcb->MetaInode, TRUE);
1325 
1326  if (GroupHint >= Vcb->sbi.s_groups_count)
1327  GroupHint = GroupHint % Vcb->sbi.s_groups_count;
1328 
1329 repeat:
1330 
1331  if (bh)
1332  fini_bh(&bh);
1333 
1334  if (gb)
1335  fini_bh(&gb);
1336 
1337  Group = i = 0;
1338  gd = NULL;
1339 
1340  if (Type == EXT2_FT_DIR) {
1341 
1342  Average = Vcb->SuperBlock->s_free_inodes_count / Vcb->sbi.s_groups_count;
1343 
1344  for (j = 0; j < Vcb->sbi.s_groups_count; j++) {
1345 
1346  i = (j + GroupHint) % (Vcb->sbi.s_groups_count);
1347  gd = ext4_get_group_desc(sb, i, &gb);
1348  if (!gd) {
1349  DbgBreak();
1351  goto errorout;
1352  }
1353 
1354  if ((gd->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT)) ||
1355  (ext4_used_dirs_count(sb, gd) << 8 <
1356  ext4_free_inodes_count(sb, gd)) ) {
1357  Group = i + 1;
1358  break;
1359  }
1360  fini_bh(&gb);
1361  }
1362 
1363  if (!Group) {
1364 
1366 
1367  gd = NULL;
1368 
1369  /* get the group with the biggest vacancy */
1370  for (j = 0; j < Vcb->sbi.s_groups_count; j++) {
1371 
1372  struct buffer_head *gt = NULL;
1373  desc = ext4_get_group_desc(sb, j, &gt);
1374  if (!desc) {
1375  DbgBreak();
1377  goto errorout;
1378  }
1379 
1380  /* return the group if it's not initialized yet */
1381  if (desc->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT)) {
1382  Group = j + 1;
1383  gd = desc;
1384 
1385  if (gb)
1386  fini_bh(&gb);
1387  gb = gt;
1388  gt = NULL;
1389  break;
1390  }
1391 
1392  if (!gd) {
1393  if (ext4_free_inodes_count(sb, desc) > 0) {
1394  Group = j + 1;
1395  gd = desc;
1396  if (gb)
1397  fini_bh(&gb);
1398  gb = gt;
1399  gt = NULL;
1400  }
1401  } else {
1403  ext4_free_inodes_count(sb, gd)) {
1404  Group = j + 1;
1405  gd = desc;
1406  if (gb)
1407  fini_bh(&gb);
1408  gb = gt;
1409  gt = NULL;
1410  break;
1411  }
1412  }
1413  if (gt)
1414  fini_bh(&gt);
1415  }
1416  }
1417 
1418  } else {
1419 
1420  /*
1421  * Try to place the inode in its parent directory (GroupHint)
1422  */
1423 
1424  gd = ext4_get_group_desc(sb, GroupHint, &gb);
1425  if (!gb) {
1426  DbgBreak();
1428  goto errorout;
1429  }
1430 
1431  if (gd->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT) ||
1432  ext4_free_inodes_count(sb, gd)) {
1433 
1434  Group = GroupHint + 1;
1435 
1436  } else {
1437 
1438  /* this group is 100% cocucpied */
1439  fini_bh(&gb);
1440 
1441  i = GroupHint;
1442 
1443  /*
1444  * Use a quadratic hash to find a group with a free inode
1445  */
1446 
1447  for (j = 1; j < Vcb->sbi.s_groups_count; j <<= 1) {
1448 
1449 
1450  i = (i + j) % Vcb->sbi.s_groups_count;
1451  gd = ext4_get_group_desc(sb, i, &gb);
1452  if (!gd) {
1453  DbgBreak();
1455  goto errorout;
1456  }
1457 
1458  if (gd->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT) ||
1459  ext4_free_inodes_count(sb, gd)) {
1460  Group = i + 1;
1461  break;
1462  }
1463 
1464  fini_bh(&gb);
1465  }
1466  }
1467 
1468  if (!Group) {
1469  /*
1470  * That failed: try linear search for a free inode
1471  */
1472  i = GroupHint;
1473  for (j = 2; j < Vcb->sbi.s_groups_count; j++) {
1474 
1475  i = (i + 1) % Vcb->sbi.s_groups_count;
1476  gd = ext4_get_group_desc(sb, i, &gb);
1477  if (!gd) {
1478  DbgBreak();
1480  goto errorout;
1481  }
1482 
1483  if (gd->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT) ||
1484  ext4_free_inodes_count(sb, gd)) {
1485  Group = i + 1;
1486  break;
1487  }
1488 
1489  fini_bh(&gb);
1490  }
1491  }
1492  }
1493 
1494  if (gd == NULL || Group == 0) {
1495  goto errorout;
1496  }
1497 
1498  /* finally we got the group, but is it valid ? */
1499  if (Group > Vcb->sbi.s_groups_count) {
1500  DbgBreak();
1501  goto errorout;
1502  }
1503 
1504  /* valid group number starts from 1, not 0 */
1505  Group -= 1;
1506 
1507  ASSERT(gd);
1508  bitmap_blk = ext4_inode_bitmap(sb, gd);
1509  /* check the block is valid or not */
1510  if (bitmap_blk == 0 || bitmap_blk >= TOTAL_BLOCKS) {
1511  DbgBreak();
1513  goto errorout;
1514  }
1515 
1516  if (gd->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT)) {
1517  bh = sb_getblk_zero(sb, bitmap_blk);
1518  if (!bh) {
1519  DbgBreak();
1521  goto errorout;
1522  }
1523  gd->bg_checksum = ext4_group_desc_csum(EXT3_SB(sb), Group, gd);
1524  ext4_init_inode_bitmap(sb, bh, Group, gd);
1525  set_buffer_uptodate(bh);
1526  gd->bg_flags &= cpu_to_le16(~EXT4_BG_INODE_UNINIT);
1527  Ext2SaveGroup(IrpContext, Vcb, Group);
1528  } else {
1529  bh = sb_getblk(sb, bitmap_blk);
1530  if (!bh) {
1531  DbgBreak();
1533  goto errorout;
1534  }
1535  }
1536 
1537  if (!buffer_uptodate(bh)) {
1538  int err = bh_submit_read(bh);
1539  if (err < 0) {
1540  DbgPrint("bh_submit_read error! err: %d\n", err);
1542  goto errorout;
1543  }
1544  }
1545 
1546  if (Vcb->sbi.s_groups_count == 1) {
1547  Length = INODES_COUNT;
1548  } else {
1549  if (Group + 1 == Vcb->sbi.s_groups_count) {
1551  if (!Length) {
1552  /* INODES_COUNT is integer multiple of INODES_PER_GROUP */
1554  }
1555  } else {
1557  }
1558  }
1559 
1560  RtlInitializeBitMap(&InodeBitmap, (PULONG)bh->b_data, Length);
1561  dwInode = RtlFindClearBits(&InodeBitmap, 1, 0);
1562 
1563  if (dwInode == 0xFFFFFFFF || dwInode >= Length) {
1564 
1565  RtlZeroMemory(&InodeBitmap, sizeof(RTL_BITMAP));
1566  if (ext4_free_inodes_count(sb, gd) > 0) {
1567  ext4_free_inodes_set(sb, gd, 0);
1568  Ext2SaveGroup(IrpContext, Vcb, Group);
1569  }
1570  goto repeat;
1571 
1572  } else {
1573 
1574  __u32 count = 0;
1575 
1576  /* update unused inodes count */
1577  count = ext4_free_inodes_count(sb, gd) - 1;
1579 
1580  RtlSetBits(&InodeBitmap, dwInode, 1);
1581 
1582  /* set block bitmap dirty in cache */
1583  mark_buffer_dirty(bh);
1584 
1585  /* If we didn't allocate from within the initialized part of the inode
1586  * table then we need to initialize up to this inode. */
1588 
1589  __u32 free;
1590 
1591  if (gd->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT)) {
1592  gd->bg_flags &= cpu_to_le16(~EXT4_BG_INODE_UNINIT);
1593  /* When marking the block group with
1594  * ~EXT4_BG_INODE_UNINIT we don't want to depend
1595  * on the value of bg_itable_unused even though
1596  * mke2fs could have initialized the same for us.
1597  * Instead we calculated the value below
1598  */
1599 
1600  free = 0;
1601  } else {
1603  }
1604 
1605  /*
1606  * Check the relative inode number against the last used
1607  * relative inode number in this group. if it is greater
1608  * we need to update the bg_itable_unused count
1609  *
1610  */
1611  if (dwInode + 1 > free) {
1613  (EXT3_INODES_PER_GROUP(sb) - 1 - dwInode));
1614  }
1615 
1616  /* We may have to initialize the block bitmap if it isn't already */
1617  if (gd->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
1618 
1619  struct buffer_head *block_bitmap_bh = NULL;
1620 
1621  /* recheck and clear flag under lock if we still need to */
1622  block_bitmap_bh = sb_getblk_zero(sb, ext4_block_bitmap(sb, gd));
1623  if (block_bitmap_bh) {
1624  gd->bg_checksum = ext4_group_desc_csum(EXT3_SB(sb), Group, gd);
1625  free = ext4_init_block_bitmap(sb, block_bitmap_bh, Group, gd);
1626  set_buffer_uptodate(block_bitmap_bh);
1627  brelse(block_bitmap_bh);
1628  gd->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT);
1629  ext4_free_blks_set(sb, gd, free);
1630  Ext2SaveGroup(IrpContext, Vcb, Group);
1631  }
1632  }
1633  }
1634 
1635  *Inode = dwInode + 1 + Group * INODES_PER_GROUP;
1636 
1637  /* update group_desc / super_block */
1638  if (Type == EXT2_FT_DIR) {
1640  }
1641  Ext2SaveGroup(IrpContext, Vcb, Group);
1642  Ext2UpdateVcbStat(IrpContext, Vcb);
1644  }
1645 
1646 errorout:
1647 
1648  ExReleaseResourceLite(&Vcb->MetaInode);
1649 
1650  if (bh)
1651  fini_bh(&bh);
1652 
1653  if (gb)
1654  fini_bh(&gb);
1655 
1656 
1657  return Status;
1658 }
1659 
1660 NTSTATUS
1662  IN PEXT2_IRP_CONTEXT IrpContext,
1663  IN PEXT2_VCB Vcb,
1664  IN ULONG group
1665  )
1666 {
1667  struct super_block *sb = &Vcb->sb;
1668  PEXT2_GROUP_DESC gd;
1669  struct buffer_head *gb = NULL;
1670  NTSTATUS status;
1671 
1672  ExAcquireResourceExclusiveLite(&Vcb->MetaInode, TRUE);
1673 
1674  /* get group desc */
1675  gd = ext4_get_group_desc(sb, group, &gb);
1676  if (!gd) {
1678  goto errorout;
1679  }
1680 
1681  /* update group_desc and super_block */
1683  Ext2SaveGroup(IrpContext, Vcb, group);
1684  Ext2UpdateVcbStat(IrpContext, Vcb);
1686 
1687 errorout:
1688 
1689  ExReleaseResourceLite(&Vcb->MetaInode);
1690 
1691  if (gb)
1692  fini_bh(&gb);
1693 
1694  return status;
1695 }
1696 
1697 
1698 NTSTATUS
1700  IN PEXT2_IRP_CONTEXT IrpContext,
1701  IN PEXT2_VCB Vcb,
1702  IN ULONG Inode,
1703  IN ULONG Type
1704 )
1705 {
1706  struct super_block *sb = &Vcb->sb;
1707  PEXT2_GROUP_DESC gd;
1708  struct buffer_head *gb = NULL;
1709  struct buffer_head *bh = NULL;
1710  ext4_fsblk_t bitmap_blk;
1711 
1712  RTL_BITMAP InodeBitmap;
1713  ULONG Group;
1714  ULONG Length;
1716 
1717  ULONG dwIno;
1718  BOOLEAN bModified = FALSE;
1719 
1721 
1722  ExAcquireResourceExclusiveLite(&Vcb->MetaInode, TRUE);
1723 
1724  Group = (Inode - 1) / INODES_PER_GROUP;
1725  dwIno = (Inode - 1) % INODES_PER_GROUP;
1726 
1727  DEBUG(DL_INF, ( "Ext2FreeInode: Inode: %xh (Group/Off = %xh/%xh)\n",
1728  Inode, Group, dwIno));
1729 
1730  if (Group >= Vcb->sbi.s_groups_count) {
1731  DbgBreak();
1732  goto errorout;
1733  }
1734 
1735  gd = ext4_get_group_desc(sb, Group, &gb);
1736  if (!gd) {
1737  DbgBreak();
1739  goto errorout;
1740  }
1741 
1742  bitmap_blk = ext4_inode_bitmap(sb, gd);
1743  bh = sb_getblk(sb, bitmap_blk);
1744  if (!bh) {
1745  DbgBreak();
1747  goto errorout;
1748  }
1749  if (!buffer_uptodate(bh)) {
1750  int err = bh_submit_read(bh);
1751  if (err < 0) {
1752  DbgPrint("bh_submit_read error! err: %d\n", err);
1754  goto errorout;
1755  }
1756  }
1757 
1758  if (Group == Vcb->sbi.s_groups_count - 1) {
1759 
1761  if (!Length) {
1762  /* s_inodes_count is integer multiple of s_inodes_per_group */
1764  }
1765  } else {
1767  }
1768 
1769  RtlInitializeBitMap(&InodeBitmap, (PULONG)bh->b_data, Length);
1770 
1771  if (RtlCheckBit(&InodeBitmap, dwIno) == 0) {
1772  DbgBreak();
1774  } else {
1775  RtlClearBits(&InodeBitmap, dwIno, 1);
1776  bModified = TRUE;
1777  }
1778 
1779  if (bModified) {
1780  /* update group free inodes */
1782  RtlNumberOfClearBits(&InodeBitmap));
1783 
1784  /* set inode block dirty and add to vcb dirty range */
1785  mark_buffer_dirty(bh);
1786 
1787  /* update group_desc and super_block */
1788  if (Type == EXT2_FT_DIR) {
1789  ext4_used_dirs_set(sb, gd,
1790  ext4_used_dirs_count(sb, gd) - 1);
1791  }
1792  Ext2SaveGroup(IrpContext, Vcb, Group);
1793  Ext2UpdateVcbStat(IrpContext, Vcb);
1795  }
1796 
1797 errorout:
1798 
1799  ExReleaseResourceLite(&Vcb->MetaInode);
1800 
1801  if (bh)
1802  fini_bh(&bh);
1803 
1804  if (gb)
1805  fini_bh(&gb);
1806 
1807  return Status;
1808 }
1809 
1810 
1811 NTSTATUS
1813  IN PEXT2_IRP_CONTEXT IrpContext,
1814  IN PEXT2_VCB Vcb,
1815  IN PEXT2_FCB Dcb,
1816  IN struct inode *Inode,
1818  struct dentry **Dentry
1819 )
1820 {
1821  struct dentry *de = NULL;
1822 
1824  OEM_STRING oem;
1825  int rc;
1826 
1827  BOOLEAN MainResourceAcquired = FALSE;
1828 
1829  if (!IsDirectory(Dcb)) {
1830  DbgBreak();
1831  return STATUS_NOT_A_DIRECTORY;
1832  }
1833 
1834  ExAcquireResourceExclusiveLite(&Dcb->MainResource, TRUE);
1835  MainResourceAcquired = TRUE;
1836 
1837  _SEH2_TRY {
1838 
1839  Ext2ReferXcb(&Dcb->ReferenceCount);
1840  de = Ext2BuildEntry(Vcb, Dcb->Mcb, FileName);
1841  if (!de) {
1843  _SEH2_LEAVE;
1844  }
1845  de->d_inode = Inode;
1846 
1847  rc = ext3_add_entry(IrpContext, de, Inode);
1848  status = Ext2WinntError(rc);
1849  if (NT_SUCCESS(status)) {
1850 
1851  /* increase dir inode's nlink for .. */
1852  if (S_ISDIR(Inode->i_mode)) {
1853  ext3_inc_count(Dcb->Inode);
1854  ext3_mark_inode_dirty(IrpContext, Dcb->Inode);
1855  }
1856 
1857  /* increase inode nlink reference */
1858  ext3_inc_count(Inode);
1859  ext3_mark_inode_dirty(IrpContext, Inode);
1860 
1861  if (Dentry) {
1862  *Dentry = de;
1863  de = NULL;
1864  }
1865  }
1866 
1867  } _SEH2_FINALLY {
1868 
1869  Ext2DerefXcb(&Dcb->ReferenceCount);
1870 
1871  if (MainResourceAcquired) {
1872  ExReleaseResourceLite(&Dcb->MainResource);
1873  }
1874 
1875  if (de)
1876  Ext2FreeEntry(de);
1877  } _SEH2_END;
1878 
1879  return status;
1880 }
1881 
1882 
1883 NTSTATUS
1885  IN PEXT2_IRP_CONTEXT IrpContext,
1886  IN PEXT2_VCB Vcb,
1887  IN PEXT2_FCB Dcb,
1888  IN PEXT2_MCB Mcb,
1889  IN umode_t mode
1890  )
1891 {
1892  struct inode *dir = Dcb->Inode;
1893  struct buffer_head *bh = NULL;
1894  struct ext3_dir_entry_2 *de;
1895  struct inode *inode;
1897  BOOLEAN MainResourceAcquired = FALSE;
1898 
1900  return STATUS_SUCCESS;
1901  }
1902 
1903  if (!IsDirectory(Dcb)) {
1904  return STATUS_NOT_A_DIRECTORY;
1905  }
1906 
1907  ExAcquireResourceExclusiveLite(&Dcb->MainResource, TRUE);
1908  MainResourceAcquired = TRUE;
1909 
1910  _SEH2_TRY {
1911 
1912  Ext2ReferXcb(&Dcb->ReferenceCount);
1913 
1914  bh = ext3_find_entry(IrpContext, Mcb->de, &de);
1915  if (!bh)
1916  _SEH2_LEAVE;
1917 
1918  inode = &Mcb->Inode;
1919  if (le32_to_cpu(de->inode) != inode->i_ino)
1920  _SEH2_LEAVE;
1921 
1923  mark_buffer_dirty(bh);
1924 
1925  if (S_ISDIR(inode->i_mode) == S_ISDIR(mode)) {
1926  } else if (S_ISDIR(inode->i_mode)) {
1928  } else if (S_ISDIR(mode)) {
1930  }
1931  dir->i_ctime = dir->i_mtime = ext3_current_time(dir);
1932  ext3_mark_inode_dirty(IrpContext, dir);
1933 
1934  inode->i_mode = mode;
1935  ext3_mark_inode_dirty(IrpContext, inode);
1936 
1938 
1939  } _SEH2_FINALLY {
1940 
1941  Ext2DerefXcb(&Dcb->ReferenceCount);
1942 
1943  if (MainResourceAcquired)
1944  ExReleaseResourceLite(&Dcb->MainResource);
1945 
1946  if (bh)
1947  brelse(bh);
1948  } _SEH2_END;
1949 
1950  return Status;
1951 }
1952 
1953 NTSTATUS
1955  IN PEXT2_IRP_CONTEXT IrpContext,
1956  IN PEXT2_VCB Vcb,
1957  IN PEXT2_FCB Dcb,
1958  IN PEXT2_MCB Mcb
1959 )
1960 {
1961  struct inode *dir = Dcb->Inode;
1962  struct buffer_head *bh = NULL;
1963  struct ext3_dir_entry_2 *de;
1964  struct inode *inode;
1965  int rc = -ENOENT;
1967  BOOLEAN MainResourceAcquired = FALSE;
1968 
1969  if (!IsDirectory(Dcb)) {
1970  return STATUS_NOT_A_DIRECTORY;
1971  }
1972 
1973  ExAcquireResourceExclusiveLite(&Dcb->MainResource, TRUE);
1974  MainResourceAcquired = TRUE;
1975 
1976  _SEH2_TRY {
1977 
1978  Ext2ReferXcb(&Dcb->ReferenceCount);
1979 
1980  bh = ext3_find_entry(IrpContext, Mcb->de, &de);
1981  if (!bh)
1982  _SEH2_LEAVE;
1983 
1984  inode = &Mcb->Inode;
1985  if (le32_to_cpu(de->inode) != inode->i_ino)
1986  _SEH2_LEAVE;
1987 
1988  if (!inode->i_nlink) {
1989  ext3_warning (inode->i_sb, "ext3_unlink",
1990  "Deleting nonexistent file (%lu), %d",
1991  inode->i_ino, inode->i_nlink);
1992  inode->i_nlink = 1;
1993  }
1994  rc = ext3_delete_entry(IrpContext, dir, de, bh);
1995  if (rc) {
1996  Status = Ext2WinntError(rc);
1997  _SEH2_LEAVE;
1998  }
1999  /*
2000  if (!inode->i_nlink)
2001  ext3_orphan_add(handle, inode);
2002  */
2003  inode->i_ctime = dir->i_ctime = dir->i_mtime = ext3_current_time(dir);
2005  ext3_mark_inode_dirty(IrpContext, inode);
2006 
2007  /* decrease dir inode's nlink for .. */
2008  if (S_ISDIR(inode->i_mode)) {
2011  ext3_mark_inode_dirty(IrpContext, dir);
2012  }
2013 
2015 
2016  } _SEH2_FINALLY {
2017 
2018  Ext2DerefXcb(&Dcb->ReferenceCount);
2019 
2020  if (MainResourceAcquired)
2021  ExReleaseResourceLite(&Dcb->MainResource);
2022 
2023  if (bh)
2024  brelse(bh);
2025  } _SEH2_END;
2026 
2027  return Status;
2028 }
2029 
2030 NTSTATUS
2032  IN PEXT2_IRP_CONTEXT IrpContext,
2033  IN PEXT2_VCB Vcb,
2034  IN PEXT2_FCB Dcb,
2035  IN ULONG OldParent,
2036  IN ULONG NewParent )
2037 {
2039 
2040  PEXT2_DIR_ENTRY2 pSelf = NULL;
2041  PEXT2_DIR_ENTRY2 pParent = NULL;
2042 
2043  ULONG dwBytes = 0;
2044 
2045  BOOLEAN MainResourceAcquired = FALSE;
2046 
2047  ULONG Offset = 0;
2048 
2049  if (!IsDirectory(Dcb)) {
2050  return STATUS_NOT_A_DIRECTORY;
2051  }
2052 
2053  if (OldParent == NewParent) {
2054  return STATUS_SUCCESS;
2055  }
2056 
2057  MainResourceAcquired =
2058  ExAcquireResourceExclusiveLite(&Dcb->MainResource, TRUE);
2059 
2060  _SEH2_TRY {
2061 
2062  Ext2ReferXcb(&Dcb->ReferenceCount);
2063 
2064  pSelf = (PEXT2_DIR_ENTRY2)
2066  PagedPool,
2069  );
2070  if (!pSelf) {
2071  DEBUG(DL_ERR, ( "Ex2SetParentEntry: failed to allocate pSelf.\n"));
2073  _SEH2_LEAVE;
2074  }
2075 
2076  dwBytes = 0;
2077 
2078  //
2079  // Reading the DCB contents
2080  //
2081 
2083  IrpContext,
2084  Vcb,
2085  Dcb->Mcb,
2086  (ULONGLONG)Offset,
2087  (PVOID)pSelf,
2089  FALSE,
2090  &dwBytes );
2091 
2092  if (!NT_SUCCESS(Status)) {
2093  DEBUG(DL_ERR, ( "Ext2SetParentEntry: failed to read directory.\n"));
2094  _SEH2_LEAVE;
2095  }
2096 
2097  ASSERT(dwBytes == EXT2_DIR_REC_LEN(1) + EXT2_DIR_REC_LEN(2));
2098 
2099  pParent = (PEXT2_DIR_ENTRY2)((PUCHAR)pSelf + pSelf->rec_len);
2100 
2101  if (pSelf->name_len == 1 && pSelf->name[0] == '.' &&
2102  pParent->name_len == 2 && pParent->name[0] == '.' &&
2103  pParent->name[1] == '.') {
2104 
2105  if (pParent->inode != OldParent) {
2106  DbgBreak();
2107  }
2108  pParent->inode = NewParent;
2109 
2111  IrpContext,
2112  Vcb,
2113  Dcb->Mcb,
2114  (ULONGLONG)Offset,
2115  pSelf,
2116  dwBytes,
2117  FALSE,
2118  &dwBytes );
2119  } else {
2120  DbgBreak();
2121  }
2122 
2123  } _SEH2_FINALLY {
2124 
2125 
2126  if (Ext2DerefXcb(&Dcb->ReferenceCount) == 0) {
2127  DEBUG(DL_ERR, ( "Ext2SetParentEntry: Dcb reference goes to ZERO.\n"));
2128  }
2129 
2130  if (MainResourceAcquired) {
2131  ExReleaseResourceLite(&Dcb->MainResource);
2132  }
2133 
2134  if (pSelf) {
2136  }
2137  } _SEH2_END;
2138 
2139  return Status;
2140 }
2141 
2142 int ext3_check_dir_entry (const char * function, struct inode * dir,
2143  struct ext3_dir_entry_2 * de,
2144  struct buffer_head * bh,
2145  unsigned long offset)
2146 {
2147  const char * error_msg = NULL;
2148  const int rlen = ext3_rec_len_from_disk(de->rec_len);
2149 
2150  if (rlen < EXT3_DIR_REC_LEN(1))
2151  error_msg = "rec_len is smaller than minimal";
2152  else if (rlen % 4 != 0)
2153  error_msg = "rec_len % 4 != 0";
2154  else if (rlen < EXT3_DIR_REC_LEN(de->name_len))
2155  error_msg = "rec_len is too small for name_len";
2156  else if ((char *) de + rlen > bh->b_data + dir->i_sb->s_blocksize)
2157  error_msg = "directory entry across blocks";
2158  else if (le32_to_cpu(de->inode) >
2159  le32_to_cpu(EXT3_SB(dir->i_sb)->s_es->s_inodes_count))
2160  error_msg = "inode out of bounds";
2161 
2162  if (error_msg != NULL) {
2163  DEBUG(DL_ERR, ("%s: bad entry in directory %u: %s - "
2164  "offset=%u, inode=%u, rec_len=%d, name_len=%d\n",
2165  function, dir->i_ino, error_msg, offset,
2166  (unsigned long) le32_to_cpu(de->inode),
2167  rlen, de->name_len));
2168  }
2169  return error_msg == NULL ? 1 : 0;
2170 }
2171 
2172 
2173 /*
2174  * p is at least 6 bytes before the end of page
2175  */
2176 struct ext3_dir_entry_2 *
2178 {
2179  return (struct ext3_dir_entry_2 *)((char *)p +
2180  ext3_rec_len_from_disk(p->rec_len));
2181 }
2182 
2183 #define MAX_LFS_FILESIZE 0x7fffffffffffffff
2184 
2185 /*
2186  * Maximal extent format file size.
2187  * Resulting logical blkno at s_maxbytes must fit in our on-disk
2188  * extent format containers, within a sector_t, and within i_blocks
2189  * in the vfs. ext4 inode has 48 bits of i_block in fsblock units,
2190  * so that won't be a limiting factor.
2191  *
2192  * Note, this does *not* consider any metadata overhead for vfs i_blocks.
2193  */
2194 static loff_t ext4_max_size(int blkbits, int has_huge_files)
2195 {
2196  loff_t res;
2198 
2199  /* small i_blocks in vfs inode? */
2200  if (!has_huge_files || sizeof(blkcnt_t) < sizeof(u64)) {
2201  /*
2202  * CONFIG_LBD is not enabled implies the inode
2203  * i_block represent total blocks in 512 bytes
2204  * 32 == size of vfs inode i_blocks * 8
2205  */
2206  upper_limit = (1LL << 32) - 1;
2207 
2208  /* total blocks in file system block size */
2209  upper_limit >>= (blkbits - 9);
2210  upper_limit <<= blkbits;
2211  }
2212 
2213  /* 32-bit extent-start container, ee_block */
2214  res = 1LL << 32;
2215  res <<= blkbits;
2216  res -= 1;
2217 
2218  /* Sanity check against vm- & vfs- imposed limits */
2219  if (res > upper_limit)
2220  res = upper_limit;
2221 
2222  return res;
2223 }
2224 
2225 /*
2226  * Maximal extent format file size.
2227  * Resulting logical blkno at s_maxbytes must fit in our on-disk
2228  * extent format containers, within a sector_t, and within i_blocks
2229  * in the vfs. ext4 inode has 48 bits of i_block in fsblock units,
2230  * so that won't be a limiting factor.
2231  *
2232  * Note, this does *not* consider any metadata overhead for vfs i_blocks.
2233  */
2234 loff_t ext3_max_size(int blkbits, int has_huge_files)
2235 {
2236  loff_t res;
2238 
2239  /* small i_blocks in vfs inode? */
2240  if (!has_huge_files) {
2241  /*
2242  * CONFIG_LBD is not enabled implies the inode
2243  * i_block represent total blocks in 512 bytes
2244  * 32 == size of vfs inode i_blocks * 8
2245  */
2246  upper_limit = ((loff_t)1 << 32) - 1;
2247 
2248  /* total blocks in file system block size */
2249  upper_limit >>= (blkbits - 9);
2250  upper_limit <<= blkbits;
2251  }
2252 
2253  /* 32-bit extent-start container, ee_block */
2254  res = (loff_t)1 << 32;
2255  res <<= blkbits;
2256  res -= 1;
2257 
2258  /* Sanity check against vm- & vfs- imposed limits */
2259  if (res > upper_limit)
2260  res = upper_limit;
2261 
2262  return res;
2263 }
2264 
2265 /*
2266  * Maximal bitmap file size. There is a direct, and {,double-,triple-}indirect
2267  * block limit, and also a limit of (2^48 - 1) 512-byte sectors in i_blocks.
2268  * We need to be 1 filesystem block less than the 2^48 sector limit.
2269  */
2270 loff_t ext3_max_bitmap_size(int bits, int has_huge_files)
2271 {
2273  int meta_blocks;
2275  /* This is calculated to be the largest file size for a
2276  * dense, bitmapped file such that the total number of
2277  * sectors in the file, including data and all indirect blocks,
2278  * does not exceed 2^48 -1
2279  * __u32 i_blocks_lo and _u16 i_blocks_high representing the
2280  * total number of 512 bytes blocks of the file
2281  */
2282 
2283  if (!has_huge_files) {
2284  /*
2285  * !has_huge_files or CONFIG_LBD is not enabled
2286  * implies the inode i_block represent total blocks in
2287  * 512 bytes 32 == size of vfs inode i_blocks * 8
2288  */
2289  upper_limit = ((loff_t)1 << 32) - 1;
2290 
2291  /* total blocks in file system block size */
2292  upper_limit >>= (bits - 9);
2293 
2294  } else {
2295  /*
2296  * We use 48 bit ext4_inode i_blocks
2297  * With EXT4_HUGE_FILE_FL set the i_blocks
2298  * represent total number of blocks in
2299  * file system block size
2300  */
2301  upper_limit = ((loff_t)1 << 48) - 1;
2302 
2303  }
2304 
2305  /* indirect blocks */
2306  meta_blocks = 1;
2307  /* double indirect blocks */
2308  meta_blocks += 1 + ((loff_t)1 << (bits-2));
2309  /* tripple indirect blocks */
2310  meta_blocks += 1 + ((loff_t)1 << (bits-2)) + ((loff_t)1 << (2*(bits-2)));
2311 
2312  upper_limit -= meta_blocks;
2313  upper_limit <<= bits;
2314 
2315  res += (loff_t)1 << (bits-2);
2316  res += (loff_t)1 << (2*(bits-2));
2317  res += (loff_t)1 << (3*(bits-2));
2318  res <<= bits;
2319  if (res > upper_limit)
2320  res = upper_limit;
2321 
2322  if (res > MAX_LFS_FILESIZE)
2324 
2325  return res;
2326 }
2327 
2329  struct inode *inode)
2330 {
2331  blkcnt_t i_blocks ;
2332  struct super_block *sb = inode->i_sb;
2333  PEXT2_VCB Vcb = (PEXT2_VCB)sb->s_priv;
2334 
2337  /* we are using combined 48 bit field */
2338  i_blocks = ((u64)le16_to_cpu(raw_inode->i_blocks_high)) << 32 |
2339  le32_to_cpu(raw_inode->i_blocks);
2340  if (inode->i_flags & EXT4_HUGE_FILE_FL) {
2341  /* i_blocks represent file system block size */
2342  return i_blocks << (BLOCK_BITS - 9);
2343  } else {
2344  return i_blocks;
2345  }
2346  } else {
2347  return le32_to_cpu(raw_inode->i_blocks);
2348  }
2349 }
2350 
2351 int ext3_inode_blocks_set(struct ext3_inode *raw_inode,
2352  struct inode * inode)
2353 {
2354  u64 i_blocks = inode->i_blocks;
2355  struct super_block *sb = inode->i_sb;
2356  PEXT2_VCB Vcb = (PEXT2_VCB)sb->s_priv;
2357 
2358  if (i_blocks < 0x100000000) {
2359  /*
2360  * i_blocks can be represnted in a 32 bit variable
2361  * as multiple of 512 bytes
2362  */
2363  raw_inode->i_blocks = cpu_to_le32(i_blocks);
2364  raw_inode->i_blocks_high = 0;
2366  return 0;
2367  }
2368 
2372  }
2373 
2374  if (i_blocks <= 0xffffffffffff) {
2375  /*
2376  * i_blocks can be represented in a 48 bit variable
2377  * as multiple of 512 bytes
2378  */
2379  raw_inode->i_blocks = (__u32)cpu_to_le32(i_blocks);
2380  raw_inode->i_blocks_high = (__u16)cpu_to_le16(i_blocks >> 32);
2382  } else {
2384  /* i_block is stored in file system block size */
2385  i_blocks = i_blocks >> (BLOCK_BITS - 9);
2386  raw_inode->i_blocks = (__u32)cpu_to_le32(i_blocks);
2387  raw_inode->i_blocks_high = (__u16)cpu_to_le16(i_blocks >> 32);
2388  }
2389  return 0;
2390 }
2391 
2393  struct ext4_group_desc *bg)
2394 {
2395  return le32_to_cpu(bg->bg_block_bitmap) |
2397  (ext4_fsblk_t)le32_to_cpu(bg->bg_block_bitmap_hi) << 32 : 0);
2398 }
2399 
2401  struct ext4_group_desc *bg)
2402 {
2403  return le32_to_cpu(bg->bg_inode_bitmap) |
2405  (ext4_fsblk_t)le32_to_cpu(bg->bg_inode_bitmap_hi) << 32 : 0);
2406 }
2407 
2409  struct ext4_group_desc *bg)
2410 {
2411  return le32_to_cpu(bg->bg_inode_table) |
2413  (ext4_fsblk_t)le32_to_cpu(bg->bg_inode_table_hi) << 32 : 0);
2414 }
2415 
2417  struct ext4_group_desc *bg)
2418 {
2419  return le16_to_cpu(bg->bg_free_blocks_count) |
2421  (__u32)le16_to_cpu(bg->bg_free_blocks_count_hi) << 16 : 0);
2422 }
2423 
2425  struct ext4_group_desc *bg)
2426 {
2427  return le16_to_cpu(bg->bg_free_inodes_count) |
2429  (__u32)le16_to_cpu(bg->bg_free_inodes_count_hi) << 16 : 0);
2430 }
2431 
2433  struct ext4_group_desc *bg)
2434 {
2435  return le16_to_cpu(bg->bg_used_dirs_count) |
2437  (__u32)le16_to_cpu(bg->bg_used_dirs_count_hi) << 16 : 0);
2438 }
2439 
2441  struct ext4_group_desc *bg)
2442 {
2443  return le16_to_cpu(bg->bg_itable_unused) |
2445  (__u32)le16_to_cpu(bg->bg_itable_unused_hi) << 16 : 0);
2446 }
2447 
2449  struct ext4_group_desc *bg, ext4_fsblk_t blk)
2450 {
2453  bg->bg_block_bitmap_hi = cpu_to_le32(blk >> 32);
2454 }
2455 
2457  struct ext4_group_desc *bg, ext4_fsblk_t blk)
2458 {
2461  bg->bg_inode_bitmap_hi = cpu_to_le32(blk >> 32);
2462 }
2463 
2465  struct ext4_group_desc *bg, ext4_fsblk_t blk)
2466 {
2469  bg->bg_inode_table_hi = cpu_to_le32(blk >> 32);
2470 }
2471 
2473  struct ext4_group_desc *bg, __u32 count)
2474 {
2478 }
2479 
2481  struct ext4_group_desc *bg, __u32 count)
2482 {
2486 }
2487 
2489  struct ext4_group_desc *bg, __u32 count)
2490 {
2494 }
2495 
2497  struct ext4_group_desc *bg, __u32 count)
2498 {
2501  bg->bg_itable_unused_hi = cpu_to_le16(count >> 16);
2502 }
2503 
2505 __u16 const crc16_table[256] = {
2506  0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
2507  0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
2508  0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
2509  0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
2510  0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
2511  0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
2512  0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
2513  0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
2514  0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
2515  0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
2516  0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
2517  0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
2518  0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
2519  0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
2520  0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
2521  0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
2522  0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
2523  0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
2524  0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
2525  0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
2526  0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
2527  0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
2528  0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
2529  0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
2530  0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
2531  0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
2532  0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
2533  0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
2534  0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
2535  0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
2536  0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
2537  0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
2538 };
2539 
2540 static inline __u16 crc16_byte(__u16 crc, const __u8 data)
2541 {
2542  return (crc >> 8) ^ crc16_table[(crc ^ data) & 0xff];
2543 }
2544 
2545 __u16 crc16(__u16 crc, __u8 const *buffer, size_t len)
2546 {
2547  while (len--)
2548  crc = crc16_byte(crc, *buffer++);
2549  return crc;
2550 }
2551 
2553  struct ext4_group_desc *gdp)
2554 {
2555  int offset;
2556  __u16 crc = 0;
2557  __le32 le_group = cpu_to_le32(block_group);
2558 
2559  /* old crc16 code */
2560  if (!(sbi->s_es->s_feature_ro_compat &
2562  return 0;
2563 
2564  offset = offsetof(struct ext4_group_desc, bg_checksum);
2565 
2566  crc = crc16(~0, sbi->s_es->s_uuid, sizeof(sbi->s_es->s_uuid));
2567  crc = crc16(crc, (__u8 *)&le_group, sizeof(le_group));
2568  crc = crc16(crc, (__u8 *)gdp, offset);
2569  offset += sizeof(gdp->bg_checksum); /* skip checksum */
2570  /* for checksum of struct ext4_group_desc do the rest...*/
2571  if ((sbi->s_es->s_feature_incompat &
2573  offset < le16_to_cpu(sbi->s_es->s_desc_size))
2574  crc = crc16(crc, (__u8 *)gdp + offset,
2575  le16_to_cpu(sbi->s_es->s_desc_size) -
2576  offset);
2577 
2578  return cpu_to_le16(crc);
2579 }
2580 
2581 int ext4_group_desc_csum_verify(struct ext3_sb_info *sbi, __u32 block_group,
2582  struct ext4_group_desc *gdp)
2583 {
2584  if ((sbi->s_es->s_feature_ro_compat & cpu_to_le32(EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) &&
2585  (gdp->bg_checksum != ext4_group_desc_csum(sbi, block_group, gdp)))
2586  return 0;
2587 
2588  return 1;
2589 }
2590 
2591 
2593 {
2594  ext3_group_t num = b;
2595 
2596  while (a > num)
2597  num *= b;
2598  return num == a;
2599 }
2600 
2602 {
2603  if (group <= 1)
2604  return 1;
2605  if (!(group & 1))
2606  return 0;
2607  return (test_root(group, 7) || test_root(group, 5) ||
2608  test_root(group, 3));
2609 }
2610 
2620 {
2624  return 0;
2625  return 1;
2626 }
2627 
2628 static unsigned long ext4_bg_num_gdb_meta(struct super_block *sb,
2630 {
2631  unsigned long metagroup = group / EXT4_DESC_PER_BLOCK(sb);
2632  ext4_group_t first = metagroup * EXT4_DESC_PER_BLOCK(sb);
2633  ext4_group_t last = first + EXT4_DESC_PER_BLOCK(sb) - 1;
2634 
2635  if (group == first || group == first + 1 || group == last)
2636  return 1;
2637  return 0;
2638 }
2639 
2640 static unsigned long ext4_bg_num_gdb_nometa(struct super_block *sb,
2642 {
2643  return ext3_bg_has_super(sb, group) ? EXT3_SB(sb)->s_gdb_count : 0;
2644 }
2645 
2656 {
2657  unsigned long first_meta_bg =
2658  le32_to_cpu(EXT3_SB(sb)->s_es->s_first_meta_bg);
2659  unsigned long metagroup = group / EXT4_DESC_PER_BLOCK(sb);
2660 
2662  metagroup < first_meta_bg)
2663  return ext4_bg_num_gdb_nometa(sb, group);
2664 
2665  return ext4_bg_num_gdb_meta(sb,group);
2666 
2667 }
2668 
2670  ext3_fsblk_t logical_sb_block, unsigned int nr)
2671 {
2672  struct ext3_sb_info *sbi = EXT3_SB(sb);
2673  ext3_group_t bg, first_meta_bg;
2674  int has_super = 0;
2675 
2676  first_meta_bg = le32_to_cpu(sbi->s_es->s_first_meta_bg);
2677 
2679  nr < first_meta_bg)
2680  return logical_sb_block + nr + 1;
2681  bg = sbi->s_desc_per_block * nr;
2682  if (ext3_bg_has_super(sb, bg))
2683  has_super = 1;
2684  return (has_super + ext3_group_first_block_no(sb, bg));
2685 }
2686 
2687 #define ext4_set_bit(n, p) set_bit((int)(n), (unsigned long *)(p))
2688 
2689 /*
2690  * The free inodes are managed by bitmaps. A file system contains several
2691  * blocks groups. Each group contains 1 bitmap block for blocks, 1 bitmap
2692  * block for inodes, N blocks for the inode table and data blocks.
2693  *
2694  * The file system contains group descriptors which are located after the
2695  * super block. Each descriptor contains the number of the bitmap block and
2696  * the free blocks count in the block.
2697  */
2698 
2699 /*
2700  * To avoid calling the atomic setbit hundreds or thousands of times, we only
2701  * need to use it within a single byte (to ensure we get endianness right).
2702  * We can use memset for the rest of the bitmap as there are no other users.
2703  */
2704 void mark_bitmap_end(int start_bit, int end_bit, char *bitmap)
2705 {
2706  int i;
2707 
2708  if (start_bit >= end_bit)
2709  return;
2710 
2711  DEBUG(DL_INF, ("mark end bits +%d through +%d used\n", start_bit, end_bit));
2712  for (i = start_bit; (unsigned)i < ((start_bit + 7) & ~7UL); i++)
2713  ext4_set_bit(i, bitmap);
2714  if (i < end_bit)
2715  memset(bitmap + (i >> 3), 0xff, (end_bit - i) >> 3);
2716 }
2717 
2718 /* Initializes an uninitialized inode bitmap */
2719 unsigned ext4_init_inode_bitmap(struct super_block *sb, struct buffer_head *bh,
2720  ext4_group_t block_group,
2721  struct ext4_group_desc *gdp)
2722 {
2723  struct ext3_sb_info *sbi = EXT3_SB(sb);
2724 
2725  mark_buffer_dirty(bh);
2726 
2727  /* If checksum is bad mark all blocks and inodes use to prevent
2728  * allocation, essentially implementing a per-group read-only flag. */
2729  if (!ext4_group_desc_csum_verify(sbi, block_group, gdp)) {
2730  ext4_error(sb, __FUNCTION__, "Checksum bad for group %u",
2731  block_group);
2732  ext4_free_blks_set(sb, gdp, 0);
2733  ext4_free_inodes_set(sb, gdp, 0);
2734  ext4_itable_unused_set(sb, gdp, 0);
2735  memset(bh->b_data, 0xff, sb->s_blocksize);
2736  return 0;
2737  }
2738 
2739  memset(bh->b_data, 0, (EXT4_INODES_PER_GROUP(sb) + 7) / 8);
2740  mark_bitmap_end(EXT4_INODES_PER_GROUP(sb), sb->s_blocksize * 8,
2741  bh->b_data);
2742  ext4_itable_unused_set(sb, gdp, EXT4_INODES_PER_GROUP(sb));
2743 
2744  return EXT4_INODES_PER_GROUP(sb);
2745 }
2746 
2747 /*
2748  * Calculate the block group number and offset, given a block number
2749  */
2751  ext4_group_t *blockgrpp, ext4_grpblk_t *offsetp)
2752 {
2753  struct ext3_super_block *es = EXT3_SB(sb)->s_es;
2755 
2756  blocknr = blocknr - le32_to_cpu(es->s_first_data_block);
2757  offset = do_div(blocknr, EXT4_BLOCKS_PER_GROUP(sb));
2758  if (offsetp)
2759  *offsetp = offset;
2760  if (blockgrpp)
2761  *blockgrpp = (ext4_grpblk_t)blocknr;
2762 
2763 }
2764 
2766  ext4_group_t block_group)
2767 {
2768  ext4_group_t actual_group;
2769  ext4_get_group_no_and_offset(sb, block, &actual_group, NULL);
2770  if (actual_group == block_group)
2771  return 1;
2772  return 0;
2773 }
2774 
2776  ext4_group_t block_group)
2777 {
2778  ext4_fsblk_t tmp;
2779  struct ext3_sb_info *sbi = EXT3_SB(sb);
2780  /* block bitmap, inode bitmap, and inode table blocks */
2781  int used_blocks = sbi->s_itb_per_group + 2;
2782 
2784  struct ext4_group_desc *gdp;
2785  struct buffer_head *bh = NULL;
2786 
2787  gdp = ext4_get_group_desc(sb, block_group, &bh);
2789  block_group))
2790  used_blocks--;
2791 
2793  block_group))
2794  used_blocks--;
2795 
2796  tmp = ext4_inode_table(sb, gdp);
2797  for (; tmp < ext4_inode_table(sb, gdp) +
2798  sbi->s_itb_per_group; tmp++) {
2799  if (!ext4_block_in_group(sb, tmp, block_group))
2800  used_blocks -= 1;
2801  }
2802  if (bh)
2803  fini_bh(&bh);
2804  }
2805  return used_blocks;
2806 }
2807 
2808 /* Initializes an uninitialized block bitmap if given, and returns the
2809  * number of blocks free in the group. */
2810 unsigned ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh,
2811  ext4_group_t block_group, struct ext4_group_desc *gdp)
2812 {
2813  int bit, bit_max;
2814  unsigned free_blocks, group_blocks;
2815  struct ext3_sb_info *sbi = EXT3_SB(sb);
2816 
2817  if (bh) {
2818  mark_buffer_dirty(bh);
2819  /* If checksum is bad mark all blocks used to prevent allocation
2820  * essentially implementing a per-group read-only flag. */
2821  if (!ext4_group_desc_csum_verify(sbi, block_group, gdp)) {
2823  "Checksum bad for group %u", block_group);
2824  ext4_free_blks_set(sb, gdp, 0);
2825  ext4_free_inodes_set(sb, gdp, 0);
2826  ext4_itable_unused_set(sb, gdp, 0);
2827  memset(bh->b_data, 0xff, sb->s_blocksize);
2828  return 0;
2829  }
2830  memset(bh->b_data, 0, sb->s_blocksize);
2831  }
2832 
2833  /* Check for superblock and gdt backups in this group */
2834  bit_max = ext3_bg_has_super(sb, block_group);
2835 
2837  block_group < le32_to_cpu(sbi->s_es->s_first_meta_bg) *
2838  sbi->s_desc_per_block) {
2839  if (bit_max) {
2840  bit_max += ext4_bg_num_gdb(sb, block_group);
2841  bit_max +=
2842  le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks);
2843  }
2844  } else { /* For META_BG_BLOCK_GROUPS */
2845  bit_max += ext4_bg_num_gdb(sb, block_group);
2846  }
2847 
2848  if (block_group == sbi->s_groups_count - 1) {
2849  /*
2850  * Even though mke2fs always initialize first and last group
2851  * if some other tool enabled the EXT4_BG_BLOCK_UNINIT we need
2852  * to make sure we calculate the right free blocks
2853  */
2854  group_blocks = (unsigned int)(ext3_blocks_count(sbi->s_es) -
2855  le32_to_cpu(sbi->s_es->s_first_data_block) -
2856  (EXT4_BLOCKS_PER_GROUP(sb) * (sbi->s_groups_count - 1)));
2857  } else {
2858  group_blocks = EXT4_BLOCKS_PER_GROUP(sb);
2859  }
2860 
2861  free_blocks = group_blocks - bit_max;
2862 
2863  if (bh) {
2864  ext4_fsblk_t start, tmp;
2865  int flex_bg = 0;
2866 
2867  for (bit = 0; bit < bit_max; bit++)
2868  ext4_set_bit(bit, bh->b_data);
2869 
2870  start = ext3_group_first_block_no(sb, block_group);
2871 
2874  flex_bg = 1;
2875 
2876  /* Set bits for block and inode bitmaps, and inode table */
2877  tmp = ext4_block_bitmap(sb, gdp);
2878  if (!flex_bg || ext4_block_in_group(sb, tmp, block_group))
2879  ext4_set_bit(tmp - start, bh->b_data);
2880 
2881  tmp = ext4_inode_bitmap(sb, gdp);
2882  if (!flex_bg || ext4_block_in_group(sb, tmp, block_group))
2883  ext4_set_bit(tmp - start, bh->b_data);
2884 
2885  tmp = ext4_inode_table(sb, gdp);
2886  for (; tmp < ext4_inode_table(sb, gdp) +
2887  sbi->s_itb_per_group; tmp++) {
2888  if (!flex_bg ||
2889  ext4_block_in_group(sb, tmp, block_group))
2890  ext4_set_bit(tmp - start, bh->b_data);
2891  }
2892  /*
2893  * Also if the number of blocks within the group is
2894  * less than the blocksize * 8 ( which is the size
2895  * of bitmap ), set rest of the block bitmap to 1
2896  */
2897  mark_bitmap_end(group_blocks, sb->s_blocksize * 8, bh->b_data);
2898  }
2899  return free_blocks - ext4_group_used_meta_blocks(sb, block_group);
2900 }
2901 
2910  ext4_group_t block_group, struct buffer_head **bh)
2911 {
2912  struct ext4_group_desc *desc = NULL;
2913  struct ext3_sb_info *sbi = EXT3_SB(sb);
2914  PEXT2_VCB vcb = sb->s_priv;
2917 
2918  if (bh)
2919  *bh = NULL;
2920 
2921  if (block_group >= sbi->s_groups_count) {
2922  ext4_error(sb, "ext4_get_group_desc",
2923  "block_group >= groups_count - "
2924  "block_group = %u, groups_count = %u",
2925  block_group, sbi->s_groups_count);
2926 
2927  return NULL;
2928  }
2929 
2930  _SEH2_TRY {
2931 
2932  group = block_group >> EXT4_DESC_PER_BLOCK_BITS(sb);
2933  offset = block_group & (EXT4_DESC_PER_BLOCK(sb) - 1);
2934 
2935  if (!sbi->s_gd) {
2936  if (!Ext2LoadGroup(vcb)) {
2937  _SEH2_LEAVE;
2938  }
2939  } else if ( !sbi->s_gd[group].block ||
2940  !sbi->s_gd[group].bh) {
2941  if (!Ext2LoadGroupBH(vcb)) {
2942  _SEH2_LEAVE;
2943  }
2944  }
2945 
2946  desc = (struct ext4_group_desc *)((PCHAR)sbi->s_gd[group].gd +
2947  offset * EXT4_DESC_SIZE(sb));
2948  if (bh) {
2949  atomic_inc(&sbi->s_gd[group].bh->b_count);
2950  *bh = sbi->s_gd[group].bh;
2951  }
2952  } _SEH2_FINALLY {
2953  /* do cleanup */
2954  } _SEH2_END;
2955 
2956  return desc;
2957 }
2958 
2959 
2967 {
2968  ext4_fsblk_t desc_count;
2969  struct ext4_group_desc *gdp;
2970  struct buffer_head *bh = NULL;
2971  ext4_group_t i;
2972  ext4_group_t ngroups = EXT3_SB(sb)->s_groups_count;
2973 
2974  desc_count = 0;
2975  smp_rmb();
2976  for (i = 0; i < ngroups; i++) {
2977  gdp = ext4_get_group_desc(sb, i, &bh);
2978  if (!bh)
2979  continue;
2980  desc_count += ext4_free_blks_count(sb, gdp);
2981  fini_bh(&bh);
2982  }
2983 
2984  return desc_count;
2985 }
2986 
2987 unsigned long ext4_count_free_inodes(struct super_block *sb)
2988 {
2989  unsigned long desc_count;
2990  struct ext4_group_desc *gdp;
2991  struct buffer_head *bh = NULL;
2992  ext4_group_t i;
2993 
2994  desc_count = 0;
2995  for (i = 0; i < EXT3_SB(sb)->s_groups_count; i++) {
2996  gdp = ext4_get_group_desc(sb, i, &bh);
2997  if (!bh)
2998  continue;
2999  desc_count += ext4_free_inodes_count(sb, gdp);
3000  fini_bh(&bh);
3001  }
3002  return desc_count;
3003 }
3004 
3005 /* Called at mount-time, super-block is locked */
3006 unsigned long ext4_count_dirs(struct super_block * sb)
3007 {
3008  struct ext4_group_desc *gdp;
3009  struct buffer_head *bh = NULL;
3010  unsigned long count = 0;
3011  ext4_group_t i;
3012 
3013  for (i = 0; i < EXT3_SB(sb)->s_groups_count; i++) {
3014  gdp = ext4_get_group_desc(sb, i, &bh);
3015  if (!bh)
3016  continue;
3017  count += ext4_used_dirs_count(sb, gdp);
3018  fini_bh(&bh);
3019  }
3020  return count;
3021 }
3022 
3023 /* Called at mount-time, super-block is locked */
3025 {
3026  PEXT2_VCB Vcb = sb->s_priv;
3027  struct ext3_sb_info *sbi = EXT3_SB(sb);
3028  ext4_fsblk_t first_block = le32_to_cpu(sbi->s_es->s_first_data_block);
3029  ext4_fsblk_t last_block;
3030  ext4_fsblk_t block_bitmap;
3031  ext4_fsblk_t inode_bitmap;
3032  ext4_fsblk_t inode_table;
3033  int flexbg_flag = 0;
3034  ext4_group_t i;
3035 
3037  flexbg_flag = 1;
3038 
3039  DEBUG(DL_INF, ("Checking group descriptors"));
3040 
3041  for (i = 0; i < sbi->s_groups_count; i++) {
3042 
3043  struct buffer_head *bh = NULL;
3044  struct ext4_group_desc *gdp = ext4_get_group_desc(sb, i, &bh);
3045 
3046  if (!bh)
3047  continue;
3048 
3049  if (i == sbi->s_groups_count - 1 || flexbg_flag)
3050  last_block = ext3_blocks_count(sbi->s_es) - 1;
3051  else
3052  last_block = first_block +
3053  (EXT3_BLOCKS_PER_GROUP(sb) - 1);
3054 
3055  block_bitmap = ext4_block_bitmap(sb, gdp);
3056  if (block_bitmap < first_block || block_bitmap > last_block) {
3057  printk(KERN_ERR "EXT4-fs: ext4_check_descriptors: "
3058  "Block bitmap for group %u not in group "
3059  "(block %llu)!\n", i, block_bitmap);
3060  __brelse(bh);
3061  return 0;
3062  }
3063  inode_bitmap = ext4_inode_bitmap(sb, gdp);
3064  if (inode_bitmap < first_block || inode_bitmap > last_block) {
3065  printk(KERN_ERR "EXT4-fs: ext4_check_descriptors: "
3066  "Inode bitmap for group %u not in group "
3067  "(block %llu)!\n", i, inode_bitmap);
3068  __brelse(bh);
3069  return 0;
3070  }
3071  inode_table = ext4_inode_table(sb, gdp);
3072  if (inode_table < first_block ||
3073  inode_table + sbi->s_itb_per_group - 1 > last_block) {
3074  printk(KERN_ERR "EXT4-fs: ext4_check_descriptors: "
3075  "Inode table for group %u not in group "
3076  "(block %llu)!\n", i, inode_table);
3077  __brelse(bh);
3078  return 0;
3079  }
3080 
3081  if (!ext4_group_desc_csum_verify(sbi, i, gdp)) {
3082  printk(KERN_ERR "EXT4-fs: ext4_check_descriptors: "
3083  "Checksum for group %u failed (%u!=%u)\n",
3085  gdp)),
3086  le16_to_cpu(gdp->bg_checksum));
3087  if (!IsVcbReadOnly(Vcb)) {
3088  __brelse(bh);
3089  return 0;
3090  }
3091  }
3092 
3093  if (!flexbg_flag)
3094  first_block += EXT4_BLOCKS_PER_GROUP(sb);
3095 
3096  __brelse(bh);
3097  }
3098 
3100  sbi->s_es->s_free_inodes_count = cpu_to_le32(ext4_count_free_inodes(sb));
3101  return 1;
3102 }
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
static PIO_STATUS_BLOCK iosb
Definition: file.c:98
VOID Ext2UpdateVcbStat(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb)
Definition: generic.c:930
VOID Ext2DropBH(IN PEXT2_VCB Vcb)
Definition: generic.c:262
#define IN
Definition: typedefs.h:38
NTSYSAPI void WINAPI RtlClearBits(PRTL_BITMAP, ULONG, ULONG)
__u32 ext4_used_dirs_count(struct super_block *sb, struct ext4_group_desc *bg)
Definition: generic.c:2432
__u16 const crc16_table[256]
Definition: generic.c:2505
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
int ext4_check_descriptors(struct super_block *sb)
Definition: generic.c:3024
#define LL
Definition: tui.h:72
NTSYSAPI void WINAPI RtlInitializeBitMap(PRTL_BITMAP, PULONG, ULONG)
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define EXT4_FEATURE_RO_COMPAT_HUGE_FILE
Definition: ext3_fs.h:699
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:63
Type
Definition: Type.h:6
#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:2480
unsigned long ext4_bg_num_gdb(struct super_block *sb, ext4_group_t group)
Definition: generic.c:2655
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:2488
#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 PLARGE_INTEGER IN ULONG IN BOOLEAN IN ULONG IN BOOLEAN OUT PIO_STATUS_BLOCK IoStatus
Definition: fatprocs.h:2650
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
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:3952
static struct buffer_head * sb_getblk(struct super_block *sb, sector_t block)
Definition: module.h:966
#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:2472
void ext4_itable_unused_set(struct super_block *sb, struct ext4_group_desc *bg, __u32 count)
Definition: generic.c:2496
static int ext3_group_sparse(ext3_group_t group)
Definition: generic.c:2601
Definition: ext3_fs.h:774
void free_buffer_head(struct buffer_head *bh)
Definition: linux.c:346
#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
GLuint GLuint GLsizei count
Definition: gl.h:1545
Definition: fs.h:64
_In_opt_ PSID Group
Definition: rtlfuncs.h:1606
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:3006
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
LONG NTSTATUS
Definition: precomp.h:26
#define MAX_LFS_FILESIZE
Definition: generic.c:2183
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:1699
GLintptr offset
Definition: glext.h:5920
#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:2581
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:2704
__u32 ext4_free_inodes_count(struct super_block *sb, struct ext4_group_desc *bg)
Definition: generic.c:2424
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
size_t b_size
Definition: module.h:724
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
#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:3154
#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:2810
#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:2177
STRING OEM_STRING
Definition: umtypes.h:203
#define EXT3_NDIR_BLOCKS
Definition: ext3_fs.h:197
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:2987
_SEH2_TRY
Definition: create.c:4250
ext4_fsblk_t ext4_inode_bitmap(struct super_block *sb, struct ext4_group_desc *bg)
Definition: generic.c:2400
#define EXT4_BG_BLOCK_UNINIT
Definition: ext3_fs.h:734
ext4_fsblk_t ext4_count_free_blocks(struct super_block *sb)
Definition: generic.c:2966
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:2775
void Ext2EncodeInode(struct ext3_inode *dst, struct inode *src)
Definition: generic.c:475
__GNU_EXTENSION typedef __int64 * PLONGLONG
Definition: ntbasedef.h:389
struct node node
VOID Ext2FreeEntry(IN struct dentry *de)
Definition: memory.c:432
#define EXT4_MIN_DESC_SIZE_64BIT
Definition: ext3_fs.h:171
void ext4_inode_bitmap_set(struct super_block *sb, struct ext4_group_desc *bg, ext4_fsblk_t blk)
Definition: generic.c:2456
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
#define STATUS_NOT_A_DIRECTORY
Definition: udferr_usr.h:169
char name[EXT3_NAME_LEN]
Definition: ext3_fs.h:779
BOOLEAN Ext2ReadInode(ULONG Inode, PEXT2_INODE InodeBuffer)
Definition: ext2.c:914
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
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 int test_root(ext3_group_t a, ext3_group_t b)
Definition: generic.c:2592
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:2234
#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
NTSYSAPI ULONG WINAPI RtlFindNextForwardRunClear(PCRTL_BITMAP, ULONG, PULONG)
const struct builtin_class_descr * desc
Definition: regcontrol.c:48
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:2194
smooth NULL
Definition: ftsmooth.c:416
NTSTATUS Ext2RemoveEntry(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN PEXT2_FCB Dcb, IN PEXT2_MCB Mcb)
Definition: generic.c:1954
#define offsetof(TYPE, MEMBER)
BOOLEAN NTAPI ExIsResourceAcquiredExclusiveLite(IN PERESOURCE Resource)
Definition: resource.c:1619
NTSYSAPI ULONG WINAPI RtlNumberOfClearBits(PCRTL_BITMAP)
__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
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:1661
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:2448
r l[0]
Definition: byte_order.h:167
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:1150
__le32 bg_block_bitmap
Definition: ext3_fs.h:136
Definition: uimain.c:88
int64_t LONGLONG
Definition: typedefs.h:66
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:1884
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
if(!(yy_init))
Definition: macro.lex.yy.c:714
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
#define IsVcbReadOnly(Vcb)
Definition: ext2fs.h:805
uint64_t ULONGLONG
Definition: typedefs.h:65
#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:2687
#define Vcb
Definition: cdprocs.h:1425
#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
static const UCHAR Index[8]
Definition: usbohci.c:18
unsigned long s_gdb_count
Definition: ext3_fs_sb.h:38
#define container_of(ptr, type, member)
Definition: glue.h:15
#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:2669
#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:2416
static unsigned long ext4_bg_num_gdb_meta(struct super_block *sb, ext4_group_t group)
Definition: generic.c:2628
__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:2408
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
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:941
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#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:1812
loff_t ext3_max_bitmap_size(int bits, int has_huge_files)
Definition: generic.c:2270
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:2552
#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:209
#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:117
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
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:2640
Status
Definition: gdiplustypes.h:24
#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
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
int ext3_inode_blocks_set(struct ext3_inode *raw_inode, struct inode *inode)
Definition: generic.c:2351
ext4_fsblk_t ext4_block_bitmap(struct super_block *sb, struct ext4_group_desc *bg)
Definition: generic.c:2392
__u32 ext4_itable_unused_count(struct super_block *sb, struct ext4_group_desc *bg)
Definition: generic.c:2440
unsigned int ext4_group_t
Definition: ext3_fs_i.h:35
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
_SEH2_END
Definition: create.c:4424
#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
blkcnt_t ext3_inode_blocks(struct ext3_inode *raw_inode, struct inode *inode)
Definition: generic.c:2328
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:334
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:2142
_SEH2_FINALLY
Definition: create.c:4395
#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:2464
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:2765
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:2619
#define EXT3_MIN_BLOCK_SIZE
Definition: ext3_fs.h:75
__u16 crc16(__u16 crc, __u8 const *buffer, size_t len)
Definition: generic.c:2545
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:2750
VOID Ext2PutGroup(IN PEXT2_VCB Vcb)
Definition: generic.c:146
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:2719
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:39
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
unsigned int ULONG
Definition: retypes.h:1
#define INODES_PER_GROUP
Definition: ext2fs.h:99
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:261
#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:2909
#define DbgBreak()
Definition: ext2fs.h:46
VOID Ext2FreePool(IN PVOID P, IN ULONG Tag)
Definition: debug.c:2697
__le16 rec_len
Definition: ext3_fs.h:776
unsigned long s_groups_count
Definition: ext3_fs_sb.h:43
NTSYSAPI void WINAPI RtlSetBits(PRTL_BITMAP, ULONG, ULONG)
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
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:1299
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
#define es
Definition: i386-dis.c:431
return STATUS_SUCCESS
Definition: btrfs.c:2777
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
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:2031
#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:4157
#define UL
Definition: tui.h:70
BOOLEAN Ext2GetInodeLba(IN PEXT2_VCB Vcb, IN ULONG inode, OUT PLONGLONG offset)
Definition: generic.c:414
NTSYSAPI ULONG WINAPI RtlFindClearBits(PCRTL_BITMAP, ULONG, ULONG)
#define ext4_error
Definition: ext2fs.h:2476
#define EXT3_SB(sb)
Definition: ext3_fs.h:615
BOOLEAN Ext2SaveBuffer(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN LONGLONG offset, IN ULONG size, IN PVOID buf)
Definition: generic.c:862
#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 __u16 crc16_byte(__u16 crc, const __u8 data)
Definition: generic.c:2540
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:438
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