2 * COPYRIGHT: See COPYRIGHT.TXT
3 * PROJECT: Ext2 File System Driver for WinNT/2K/XP
5 * PROGRAMMER: Matt Wu <mattwu@163.com>
6 * HOMEPAGE: http://www.ext2fsd.com
10 /* INCLUDES *****************************************************************/
13 #include <linux/ext4.h>
15 /* GLOBALS ***************************************************************/
17 extern PEXT2_GLOBAL Ext2Global
;
19 /* DEFINITIONS *************************************************************/
22 /* FUNCTIONS ***************************************************************/
25 Ext2LoadSuper(IN PEXT2_VCB Vcb
,
27 OUT PEXT2_SUPER_BLOCK
* Sb
)
30 PEXT2_SUPER_BLOCK Ext2Sb
= NULL
;
32 Ext2Sb
= (PEXT2_SUPER_BLOCK
)
39 Status
= STATUS_INSUFFICIENT_RESOURCES
;
43 Status
= Ext2ReadDisk(
45 (ULONGLONG
) SUPER_BLOCK_OFFSET
,
50 if (!NT_SUCCESS(Status
)) {
52 DEBUG(DL_ERR
, ( "Ext2ReadDisk: disk device error.\n"));
54 Ext2FreePool(Ext2Sb
, EXT2_SB_MAGIC
);
67 IN PEXT2_IRP_CONTEXT IrpContext
,
74 offset
= (LONGLONG
) SUPER_BLOCK_OFFSET
;
75 rc
= Ext2SaveBuffer( IrpContext
,
82 if (IsFlagOn(Vcb
->Flags
, VCB_FLOPPY_DISK
)) {
83 Ext2StartFloppyFlushDpc(Vcb
, NULL
, NULL
);
92 IN PEXT2_IRP_CONTEXT IrpContext
,
99 offset
= (LONGLONG
) SUPER_BLOCK_OFFSET
;
102 (PLARGE_INTEGER
)&offset
,
105 (PVOID
)Vcb
->SuperBlock
,
110 if (!NT_SUCCESS(iosb
.Status
)) {
114 /* reload root inode */
117 if (!Ext2LoadInode(Vcb
, &Vcb
->McbTree
->Inode
))
120 /* initializeroot node */
121 Vcb
->McbTree
->CreationTime
= Ext2NtTime(Vcb
->McbTree
->Inode
.i_ctime
);
122 Vcb
->McbTree
->LastAccessTime
= Ext2NtTime(Vcb
->McbTree
->Inode
.i_atime
);
123 Vcb
->McbTree
->LastWriteTime
= Ext2NtTime(Vcb
->McbTree
->Inode
.i_mtime
);
124 Vcb
->McbTree
->ChangeTime
= Ext2NtTime(Vcb
->McbTree
->Inode
.i_mtime
);
131 Ext2LoadGroup(IN PEXT2_VCB Vcb
)
133 struct super_block
*sb
= &Vcb
->sb
;
134 struct ext3_sb_info
*sbi
= &Vcb
->sbi
;
135 ext3_fsblk_t sb_block
= 1;
138 if (BLOCK_SIZE
!= EXT3_MIN_BLOCK_SIZE
) {
139 sb_block
= EXT4_MIN_BLOCK_SIZE
/ BLOCK_SIZE
;
142 if (NULL
== sbi
->s_group_desc
) {
143 sbi
->s_group_desc
= kzalloc(sbi
->s_gdb_count
* sizeof(ext3_fsblk_t
),
146 if (sbi
->s_group_desc
== NULL
) {
147 DEBUG(DL_ERR
, ("Ext2LoadGroup: not enough memory.\n"));
151 for (i
= 0; i
< sbi
->s_gdb_count
; i
++) {
152 sbi
->s_group_desc
[i
] = descriptor_loc(sb
, sb_block
, i
);
153 if (!sbi
->s_group_desc
[i
]) {
154 DEBUG(DL_ERR
, ("Ext2LoadGroup: can't read group descriptor %d\n", i
));
159 if (!ext4_check_descriptors(sb
)) {
160 DEBUG(DL_ERR
, ("Ext2LoadGroup: group descriptors corrupted!\n"));
169 Ext2DropGroup(IN PEXT2_VCB Vcb
)
171 struct ext3_sb_info
*sbi
= &Vcb
->sbi
;
174 if (NULL
== sbi
->s_group_desc
) {
178 kfree(sbi
->s_group_desc
);
179 sbi
->s_group_desc
= NULL
;
184 IN PEXT2_IRP_CONTEXT IrpContext
,
189 struct ext4_group_desc
*gd
;
190 struct buffer_head
*gb
= NULL
;
193 gd
= ext4_get_group_desc(&Vcb
->sb
, Group
, &gb
);
197 gd
->bg_checksum
= ext4_group_desc_csum(&Vcb
->sbi
, Group
, gd
);
198 mark_buffer_dirty(gb
);
207 IN PEXT2_IRP_CONTEXT IrpContext
,
222 struct buffer_head
*bh
= NULL
;
226 if (inode
< 1 || inode
> INODES_COUNT
) {
227 DEBUG(DL_ERR
, ( "Ext2GetInodeLba: Inode value %xh is invalid.\n",inode
));
232 group
= (inode
- 1) / INODES_PER_GROUP
;
233 gd
= ext4_get_group_desc(&Vcb
->sb
, group
, &bh
);
239 loc
= (LONGLONG
)ext4_inode_table(&Vcb
->sb
, gd
);
240 loc
= loc
<< BLOCK_BITS
;
241 loc
= loc
+ ((inode
- 1) % INODES_PER_GROUP
) * Vcb
->InodeSize
;
249 void Ext2DecodeInode(struct inode
*dst
, struct ext3_inode
*src
)
251 dst
->i_mode
= src
->i_mode
;
252 dst
->i_flags
= src
->i_flags
;
253 dst
->i_uid
= src
->i_uid
;
254 dst
->i_gid
= src
->i_gid
;
255 dst
->i_nlink
= src
->i_links_count
;
256 dst
->i_generation
= src
->i_generation
;
257 dst
->i_size
= src
->i_size
;
258 if (S_ISREG(src
->i_mode
)) {
259 dst
->i_size
|= (loff_t
)src
->i_size_high
<< 32;
261 dst
->i_file_acl
= src
->i_file_acl_lo
;
262 dst
->i_file_acl
|= (ext4_fsblk_t
)src
->osd2
.linux2
.l_i_file_acl_high
<< 32;
263 dst
->i_atime
= src
->i_atime
;
264 dst
->i_ctime
= src
->i_ctime
;
265 dst
->i_mtime
= src
->i_mtime
;
266 dst
->i_dtime
= src
->i_dtime
;
267 dst
->i_blocks
= ext3_inode_blocks(src
, dst
);
268 dst
->i_extra_isize
= src
->i_extra_isize
;
269 memcpy(&dst
->i_block
[0], &src
->i_block
[0], sizeof(__u32
) * 15);
272 void Ext2EncodeInode(struct ext3_inode
*dst
, struct inode
*src
)
274 dst
->i_mode
= src
->i_mode
;
275 dst
->i_flags
= src
->i_flags
;
276 dst
->i_uid
= src
->i_uid
;
277 dst
->i_gid
= src
->i_gid
;
278 dst
->i_links_count
= src
->i_nlink
;
279 dst
->i_generation
= src
->i_generation
;
280 dst
->i_size
= (__u32
)src
->i_size
;
281 if (S_ISREG(src
->i_mode
)) {
282 dst
->i_size_high
= (__u32
)(src
->i_size
>> 32);
284 dst
->i_file_acl_lo
= (__u32
)src
->i_file_acl
;
285 dst
->osd2
.linux2
.l_i_file_acl_high
|= (__u16
)(src
->i_file_acl
>> 32);
286 dst
->i_atime
= src
->i_atime
;
287 dst
->i_ctime
= src
->i_ctime
;
288 dst
->i_mtime
= src
->i_mtime
;
289 dst
->i_dtime
= src
->i_dtime
;
290 dst
->i_extra_isize
= src
->i_extra_isize
;
292 ext3_inode_blocks_set(dst
, src
);
293 memcpy(&dst
->i_block
[0], &src
->i_block
[0], sizeof(__u32
) * 15);
298 Ext2LoadInode (IN PEXT2_VCB Vcb
,
299 IN
struct inode
*Inode
)
301 struct ext3_inode ext3i
;
303 IO_STATUS_BLOCK IoStatus
;
306 if (!Ext2GetInodeLba(Vcb
, Inode
->i_ino
, &Offset
)) {
307 DEBUG(DL_ERR
, ( "Ext2LoadInode: error get inode(%xh)'s addr.\n", Inode
->i_ino
));
313 (PLARGE_INTEGER
)&Offset
,
314 sizeof(struct ext3_inode
),
321 if (!NT_SUCCESS(IoStatus
.Status
)) {
325 Ext2DecodeInode(Inode
, &ext3i
);
333 IN PEXT2_IRP_CONTEXT IrpContext
,
340 rc
= Ext2GetInodeLba(Vcb
, Inode
, &Offset
);
342 DEBUG(DL_ERR
, ( "Ext2SaveInode: error get inode(%xh)'s addr.\n", Inode
));
346 rc
= Ext2ZeroBuffer(IrpContext
, Vcb
, Offset
, Vcb
->InodeSize
);
354 Ext2SaveInode ( IN PEXT2_IRP_CONTEXT IrpContext
,
356 IN
struct inode
*Inode
)
358 struct ext3_inode ext3i
;
360 IO_STATUS_BLOCK IoStatus
;
362 ULONG InodeSize
= sizeof(ext3i
);
365 DEBUG(DL_INF
, ( "Ext2SaveInode: Saving Inode %xh: Mode=%xh Size=%xh\n",
366 Inode
->i_ino
, Inode
->i_mode
, Inode
->i_size
));
367 rc
= Ext2GetInodeLba(Vcb
, Inode
->i_ino
, &Offset
);
369 DEBUG(DL_ERR
, ( "Ext2SaveInode: error get inode(%xh)'s addr.\n", Inode
->i_ino
));
375 (PLARGE_INTEGER
)&Offset
,
376 sizeof(struct ext3_inode
),
384 if (!NT_SUCCESS(IoStatus
.Status
)) {
389 Ext2EncodeInode(&ext3i
, Inode
);
390 if (InodeSize
> Vcb
->InodeSize
)
391 InodeSize
= Vcb
->InodeSize
;
392 rc
= Ext2SaveBuffer(IrpContext
, Vcb
, Offset
, InodeSize
, &ext3i
);
394 if (rc
&& IsFlagOn(Vcb
->Flags
, VCB_FLOPPY_DISK
)) {
395 Ext2StartFloppyFlushDpc(Vcb
, NULL
, NULL
);
404 Ext2LoadBlock (IN PEXT2_VCB Vcb
,
408 IO_STATUS_BLOCK IoStatus
;
411 Offset
= (LONGLONG
) Index
;
412 Offset
= Offset
* Vcb
->BlockSize
;
416 (PLARGE_INTEGER
)&Offset
,
422 if (!NT_SUCCESS(IoStatus
.Status
)) {
431 Ext2SaveBlock ( IN PEXT2_IRP_CONTEXT IrpContext
,
439 Offset
= (LONGLONG
) Index
;
440 Offset
= Offset
* Vcb
->BlockSize
;
442 rc
= Ext2SaveBuffer(IrpContext
, Vcb
, Offset
, Vcb
->BlockSize
, Buf
);
444 if (IsFlagOn(Vcb
->Flags
, VCB_FLOPPY_DISK
)) {
445 Ext2StartFloppyFlushDpc(Vcb
, NULL
, NULL
);
452 Ext2ZeroBuffer( IN PEXT2_IRP_CONTEXT IrpContext
,
461 if ( !CcPreparePinWrite(
463 (PLARGE_INTEGER
) (&Offset
),
466 PIN_WAIT
| PIN_EXCLUSIVE
,
470 DEBUG(DL_ERR
, ( "Ext2SaveBuffer: failed to PinLock offset %I64xh ...\n", Offset
));
476 RtlZeroMemory(Buffer
, Size
);
477 CcSetDirtyPinnedData(Bcb
, NULL
);
478 SetFlag(Vcb
->Volume
->Flags
, FO_FILE_MODIFIED
);
480 rc
= Ext2AddVcbExtent(Vcb
, Offset
, (LONGLONG
)Size
);
484 rc
= Ext2AddVcbExtent(Vcb
, Offset
, (LONGLONG
)Size
);
495 #define SIZE_256K 0x40000
498 Ext2SaveBuffer( IN PEXT2_IRP_CONTEXT IrpContext
,
512 Length
= (ULONG
)Offset
& (SIZE_256K
- 1);
513 Length
= SIZE_256K
- Length
;
517 if ( !CcPreparePinWrite(
519 (PLARGE_INTEGER
) (&Offset
),
522 PIN_WAIT
| PIN_EXCLUSIVE
,
526 DEBUG(DL_ERR
, ( "Ext2SaveBuffer: failed to PinLock offset %I64xh ...\n", Offset
));
532 RtlCopyMemory(Buffer
, Buf
, Length
);
533 CcSetDirtyPinnedData(Bcb
, NULL
);
534 SetFlag(Vcb
->Volume
->Flags
, FO_FILE_MODIFIED
);
536 rc
= Ext2AddVcbExtent(Vcb
, Offset
, (LONGLONG
)Length
);
540 rc
= Ext2AddVcbExtent(Vcb
, Offset
, (LONGLONG
)Length
);
547 Buf
= (PUCHAR
)Buf
+ Length
;
548 Offset
= Offset
+ Length
;
549 Size
= Size
- Length
;
558 IN PEXT2_IRP_CONTEXT IrpContext
,
562 Vcb
->SuperBlock
->s_free_inodes_count
= ext4_count_free_inodes(&Vcb
->sb
);
563 ext3_free_blocks_count_set(SUPER_BLOCK
, ext4_count_free_blocks(&Vcb
->sb
));
564 Ext2SaveSuper(IrpContext
, Vcb
);
569 IN PEXT2_IRP_CONTEXT IrpContext
,
577 struct super_block
*sb
= &Vcb
->sb
;
579 struct buffer_head
*gb
= NULL
;
580 struct buffer_head
*bh
= NULL
;
581 ext4_fsblk_t bitmap_blk
;
583 RTL_BITMAP BlockBitmap
;
586 ULONG Index
= 0xFFFFFFFF;
591 NTSTATUS Status
= STATUS_DISK_FULL
;
595 ExAcquireResourceExclusiveLite(&Vcb
->MetaLock
, TRUE
);
597 /* validate the hint group and hint block */
598 if (GroupHint
>= Vcb
->sbi
.s_groups_count
) {
600 GroupHint
= Vcb
->sbi
.s_groups_count
- 1;
603 if (BlockHint
!= 0) {
604 GroupHint
= (BlockHint
- EXT2_FIRST_DATA_BLOCK
) / BLOCKS_PER_GROUP
;
605 dwHint
= (BlockHint
- EXT2_FIRST_DATA_BLOCK
) % BLOCKS_PER_GROUP
;
618 gd
= ext4_get_group_desc(sb
, Group
, &gb
);
621 Status
= STATUS_INSUFFICIENT_RESOURCES
;
625 bitmap_blk
= ext4_block_bitmap(sb
, gd
);
627 if (gd
->bg_flags
& cpu_to_le16(EXT4_BG_BLOCK_UNINIT
)) {
628 bh
= sb_getblk_zero(sb
, bitmap_blk
);
631 Status
= STATUS_INSUFFICIENT_RESOURCES
;
634 gd
->bg_checksum
= ext4_group_desc_csum(EXT3_SB(sb
), Group
, gd
);
635 ext4_init_block_bitmap(sb
, bh
, Group
, gd
);
636 set_buffer_uptodate(bh
);
637 gd
->bg_flags
&= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT
);
638 Ext2SaveGroup(IrpContext
, Vcb
, Group
);
640 bh
= sb_getblk(sb
, bitmap_blk
);
643 Status
= STATUS_INSUFFICIENT_RESOURCES
;
648 if (!buffer_uptodate(bh
)) {
649 int err
= bh_submit_read(bh
);
651 DbgPrint("bh_submit_read error! err: %d\n", err
);
652 Status
= Ext2WinntError(err
);
657 if (ext4_free_blks_count(sb
, gd
)) {
659 if (Group
== Vcb
->sbi
.s_groups_count
- 1) {
661 Length
= (ULONG
)(TOTAL_BLOCKS
% BLOCKS_PER_GROUP
);
663 /* s_blocks_count is integer multiple of s_blocks_per_group */
665 Length
= BLOCKS_PER_GROUP
;
668 Length
= BLOCKS_PER_GROUP
;
671 /* initialize bitmap buffer */
672 RtlInitializeBitMap(&BlockBitmap
, (PULONG
)bh
->b_data
, Length
);
674 /* try to find a clear bit range */
675 Index
= RtlFindClearBits(&BlockBitmap
, *Number
, dwHint
);
677 /* We could not get new block in the prefered group */
678 if (Index
== 0xFFFFFFFF) {
680 /* search clear bits from the hint block */
681 Count
= RtlFindNextForwardRunClear(&BlockBitmap
, dwHint
, &Index
);
682 if (dwHint
!= 0 && Count
== 0) {
683 /* search clear bits from the very beginning */
684 Count
= RtlFindNextForwardRunClear(&BlockBitmap
, 0, &Index
);
689 RtlZeroMemory(&BlockBitmap
, sizeof(RTL_BITMAP
));
691 /* no blocks found: set bg_free_blocks_count to 0 */
692 ext4_free_blks_set(sb
, gd
, 0);
693 Ext2SaveGroup(IrpContext
, Vcb
, Group
);
695 /* will try next group */
700 /* we got free blocks */
701 if (Count
<= *Number
) {
711 Group
= (Group
+ 1) % Vcb
->sbi
.s_groups_count
;
712 if (Group
!= GroupHint
) {
719 if (Index
< Length
) {
721 /* mark block bits as allocated */
722 RtlSetBits(&BlockBitmap
, Index
, *Number
);
724 /* set block bitmap dirty in cache */
725 mark_buffer_dirty(bh
);
727 /* update group description */
728 ext4_free_blks_set(sb
, gd
, RtlNumberOfClearBits(&BlockBitmap
));
729 Ext2SaveGroup(IrpContext
, Vcb
, Group
);
731 /* update Vcb free blocks */
732 Ext2UpdateVcbStat(IrpContext
, Vcb
);
734 /* validate the new allocated block number */
735 *Block
= Index
+ EXT2_FIRST_DATA_BLOCK
+ Group
* BLOCKS_PER_GROUP
;
736 if (*Block
>= TOTAL_BLOCKS
|| *Block
+ *Number
> TOTAL_BLOCKS
) {
742 if (ext4_block_bitmap(sb
, gd
) == *Block
||
743 ext4_inode_bitmap(sb
, gd
) == *Block
||
744 ext4_inode_table(sb
, gd
) == *Block
) {
750 /* Always remove dirty MCB to prevent Volume's lazy writing.
751 Metadata blocks will be re-added during modifications.*/
752 if (Ext2RemoveBlockExtent(Vcb
, NULL
, *Block
, *Number
)) {
755 Ext2RemoveBlockExtent(Vcb
, NULL
, *Block
, *Number
);
758 DEBUG(DL_INF
, ("Ext2NewBlock: Block %xh - %x allocated.\n",
759 *Block
, *Block
+ *Number
));
760 Status
= STATUS_SUCCESS
;
765 ExReleaseResourceLite(&Vcb
->MetaLock
);
778 IN PEXT2_IRP_CONTEXT IrpContext
,
784 struct super_block
*sb
= &Vcb
->sb
;
786 struct buffer_head
*gb
= NULL
;
787 ext4_fsblk_t bitmap_blk
;
789 RTL_BITMAP BlockBitmap
;
790 LARGE_INTEGER Offset
;
800 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
802 ExAcquireResourceExclusiveLite(&Vcb
->MetaLock
, TRUE
);
804 DEBUG(DL_INF
, ("Ext2FreeBlock: Block %xh - %x to be freed.\n",
805 Block
, Block
+ Number
));
807 Group
= (Block
- EXT2_FIRST_DATA_BLOCK
) / BLOCKS_PER_GROUP
;
808 Index
= (Block
- EXT2_FIRST_DATA_BLOCK
) % BLOCKS_PER_GROUP
;
815 if ( Block
< EXT2_FIRST_DATA_BLOCK
||
816 Block
>= TOTAL_BLOCKS
||
817 Group
>= Vcb
->sbi
.s_groups_count
) {
820 Status
= STATUS_SUCCESS
;
824 gd
= ext4_get_group_desc(sb
, Group
, &gb
);
827 Status
= STATUS_INSUFFICIENT_RESOURCES
;
830 bitmap_blk
= ext4_block_bitmap(sb
, gd
);
832 /* check the block is valid or not */
833 if (bitmap_blk
>= TOTAL_BLOCKS
) {
835 Status
= STATUS_DISK_CORRUPT_ERROR
;
839 /* get bitmap block offset and length */
840 Offset
.QuadPart
= bitmap_blk
;
841 Offset
.QuadPart
= Offset
.QuadPart
<< BLOCK_BITS
;
843 if (Group
== Vcb
->sbi
.s_groups_count
- 1) {
845 Length
= (ULONG
)(TOTAL_BLOCKS
% BLOCKS_PER_GROUP
);
847 /* s_blocks_count is integer multiple of s_blocks_per_group */
849 Length
= BLOCKS_PER_GROUP
;
853 Length
= BLOCKS_PER_GROUP
;
856 /* read and initialize bitmap */
857 if (!CcPinRead( Vcb
->Volume
,
864 DEBUG(DL_ERR
, ("Ext2FreeBlock: failed to PinLock bitmap block %xh.\n",
866 Status
= STATUS_CANT_WAIT
;
871 /* clear usused bits */
872 RtlInitializeBitMap(&BlockBitmap
, BitmapCache
, Length
);
873 Count
= min(Length
- Index
, Number
);
874 RtlClearBits(&BlockBitmap
, Index
, Count
);
876 /* update group description table */
877 ext4_free_blks_set(sb
, gd
, RtlNumberOfClearBits(&BlockBitmap
));
879 /* indict the cache range is dirty */
880 CcSetDirtyPinnedData(BitmapBcb
, NULL
);
881 Ext2AddVcbExtent(Vcb
, Offset
.QuadPart
, (LONGLONG
)Vcb
->BlockSize
);
882 CcUnpinData(BitmapBcb
);
885 Ext2SaveGroup(IrpContext
, Vcb
, Group
);
887 /* remove dirty MCB to prevent Volume's lazy writing. */
888 if (Ext2RemoveBlockExtent(Vcb
, NULL
, Block
, Count
)) {
891 Ext2RemoveBlockExtent(Vcb
, NULL
, Block
, Count
);
894 /* save super block (used/unused blocks statics) */
895 Ext2UpdateVcbStat(IrpContext
, Vcb
);
897 /* try next group to clear all remaining */
901 if (Group
< Vcb
->sbi
.s_groups_count
) {
906 DEBUG(DL_ERR
, ("Ext2FreeBlock: block number beyonds max group.\n"));
912 Status
= STATUS_SUCCESS
;
919 ExReleaseResourceLite(&Vcb
->MetaLock
);
927 IN PEXT2_IRP_CONTEXT IrpContext
,
934 struct super_block
*sb
= &Vcb
->sb
;
936 struct buffer_head
*gb
= NULL
;
937 struct buffer_head
*bh
= NULL
;
938 ext4_fsblk_t bitmap_blk
;
940 RTL_BITMAP InodeBitmap
;
943 ULONG Average
, Length
;
947 NTSTATUS Status
= STATUS_DISK_FULL
;
949 *Inode
= dwInode
= 0XFFFFFFFF;
951 ExAcquireResourceExclusiveLite(&Vcb
->MetaLock
, TRUE
);
953 if (GroupHint
>= Vcb
->sbi
.s_groups_count
)
954 GroupHint
= GroupHint
% Vcb
->sbi
.s_groups_count
;
967 if (Type
== EXT2_FT_DIR
) {
969 Average
= Vcb
->SuperBlock
->s_free_inodes_count
/ Vcb
->sbi
.s_groups_count
;
971 for (j
= 0; j
< Vcb
->sbi
.s_groups_count
; j
++) {
973 i
= (j
+ GroupHint
) % (Vcb
->sbi
.s_groups_count
);
974 gd
= ext4_get_group_desc(sb
, i
, &gb
);
977 Status
= STATUS_INSUFFICIENT_RESOURCES
;
981 if ((gd
->bg_flags
& cpu_to_le16(EXT4_BG_INODE_UNINIT
)) ||
982 (ext4_used_dirs_count(sb
, gd
) << 8 <
983 ext4_free_inodes_count(sb
, gd
)) ) {
992 PEXT2_GROUP_DESC desc
= NULL
;
996 /* get the group with the biggest vacancy */
997 for (j
= 0; j
< Vcb
->sbi
.s_groups_count
; j
++) {
999 struct buffer_head
*gt
= NULL
;
1000 desc
= ext4_get_group_desc(sb
, j
, >
);
1003 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1007 /* return the group if it's not initialized yet */
1008 if (desc
->bg_flags
& cpu_to_le16(EXT4_BG_INODE_UNINIT
)) {
1020 if (ext4_free_inodes_count(sb
, desc
) > 0) {
1029 if (ext4_free_inodes_count(sb
, desc
) >
1030 ext4_free_inodes_count(sb
, gd
)) {
1048 * Try to place the inode in its parent directory (GroupHint)
1051 gd
= ext4_get_group_desc(sb
, GroupHint
, &gb
);
1054 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1058 if (gd
->bg_flags
& cpu_to_le16(EXT4_BG_INODE_UNINIT
) ||
1059 ext4_free_inodes_count(sb
, gd
)) {
1061 Group
= GroupHint
+ 1;
1065 /* this group is 100% cocucpied */
1071 * Use a quadratic hash to find a group with a free inode
1074 for (j
= 1; j
< Vcb
->sbi
.s_groups_count
; j
<<= 1) {
1077 i
= (i
+ j
) % Vcb
->sbi
.s_groups_count
;
1078 gd
= ext4_get_group_desc(sb
, i
, &gb
);
1081 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1085 if (gd
->bg_flags
& cpu_to_le16(EXT4_BG_INODE_UNINIT
) ||
1086 ext4_free_inodes_count(sb
, gd
)) {
1097 * That failed: try linear search for a free inode
1100 for (j
= 2; j
< Vcb
->sbi
.s_groups_count
; j
++) {
1102 i
= (i
+ 1) % Vcb
->sbi
.s_groups_count
;
1103 gd
= ext4_get_group_desc(sb
, i
, &gb
);
1106 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1110 if (gd
->bg_flags
& cpu_to_le16(EXT4_BG_INODE_UNINIT
) ||
1111 ext4_free_inodes_count(sb
, gd
)) {
1121 if (gd
== NULL
|| Group
== 0) {
1125 /* finally we got the group, but is it valid ? */
1126 if (Group
> Vcb
->sbi
.s_groups_count
) {
1131 /* valid group number starts from 1, not 0 */
1135 bitmap_blk
= ext4_inode_bitmap(sb
, gd
);
1136 /* check the block is valid or not */
1137 if (bitmap_blk
== 0 || bitmap_blk
>= TOTAL_BLOCKS
) {
1139 Status
= STATUS_DISK_CORRUPT_ERROR
;
1143 if (gd
->bg_flags
& cpu_to_le16(EXT4_BG_INODE_UNINIT
)) {
1144 bh
= sb_getblk_zero(sb
, bitmap_blk
);
1147 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1150 gd
->bg_checksum
= ext4_group_desc_csum(EXT3_SB(sb
), Group
, gd
);
1151 ext4_init_inode_bitmap(sb
, bh
, Group
, gd
);
1152 set_buffer_uptodate(bh
);
1153 gd
->bg_flags
&= cpu_to_le16(~EXT4_BG_INODE_UNINIT
);
1154 Ext2SaveGroup(IrpContext
, Vcb
, Group
);
1156 bh
= sb_getblk(sb
, bitmap_blk
);
1159 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1164 if (!buffer_uptodate(bh
)) {
1165 int err
= bh_submit_read(bh
);
1167 DbgPrint("bh_submit_read error! err: %d\n", err
);
1168 Status
= Ext2WinntError(err
);
1173 if (Vcb
->sbi
.s_groups_count
== 1) {
1174 Length
= INODES_COUNT
;
1176 if (Group
+ 1 == Vcb
->sbi
.s_groups_count
) {
1177 Length
= INODES_COUNT
% INODES_PER_GROUP
;
1179 /* INODES_COUNT is integer multiple of INODES_PER_GROUP */
1180 Length
= INODES_PER_GROUP
;
1183 Length
= INODES_PER_GROUP
;
1187 RtlInitializeBitMap(&InodeBitmap
, (PULONG
)bh
->b_data
, Length
);
1188 dwInode
= RtlFindClearBits(&InodeBitmap
, 1, 0);
1190 if (dwInode
== 0xFFFFFFFF || dwInode
>= Length
) {
1192 RtlZeroMemory(&InodeBitmap
, sizeof(RTL_BITMAP
));
1193 if (ext4_free_inodes_count(sb
, gd
) > 0) {
1194 ext4_free_inodes_set(sb
, gd
, 0);
1195 Ext2SaveGroup(IrpContext
, Vcb
, Group
);
1203 /* update unused inodes count */
1204 count
= ext4_free_inodes_count(sb
, gd
) - 1;
1205 ext4_free_inodes_set(sb
, gd
, count
);
1207 RtlSetBits(&InodeBitmap
, dwInode
, 1);
1209 /* set block bitmap dirty in cache */
1210 mark_buffer_dirty(bh
);
1212 /* If we didn't allocate from within the initialized part of the inode
1213 * table then we need to initialize up to this inode. */
1214 if (EXT3_HAS_RO_COMPAT_FEATURE(sb
, EXT4_FEATURE_RO_COMPAT_GDT_CSUM
)) {
1218 if (gd
->bg_flags
& cpu_to_le16(EXT4_BG_INODE_UNINIT
)) {
1219 gd
->bg_flags
&= cpu_to_le16(~EXT4_BG_INODE_UNINIT
);
1220 /* When marking the block group with
1221 * ~EXT4_BG_INODE_UNINIT we don't want to depend
1222 * on the value of bg_itable_unused even though
1223 * mke2fs could have initialized the same for us.
1224 * Instead we calculated the value below
1229 free
= EXT3_INODES_PER_GROUP(sb
) - ext4_itable_unused_count(sb
, gd
);
1233 * Check the relative inode number against the last used
1234 * relative inode number in this group. if it is greater
1235 * we need to update the bg_itable_unused count
1238 if (dwInode
+ 1 > free
) {
1239 ext4_itable_unused_set(sb
, gd
,
1240 (EXT3_INODES_PER_GROUP(sb
) - 1 - dwInode
));
1243 /* We may have to initialize the block bitmap if it isn't already */
1244 if (gd
->bg_flags
& cpu_to_le16(EXT4_BG_BLOCK_UNINIT
)) {
1246 struct buffer_head
*block_bitmap_bh
= NULL
;
1248 /* recheck and clear flag under lock if we still need to */
1249 block_bitmap_bh
= sb_getblk_zero(sb
, ext4_block_bitmap(sb
, gd
));
1250 if (block_bitmap_bh
) {
1251 gd
->bg_checksum
= ext4_group_desc_csum(EXT3_SB(sb
), Group
, gd
);
1252 free
= ext4_init_block_bitmap(sb
, block_bitmap_bh
, Group
, gd
);
1253 set_buffer_uptodate(block_bitmap_bh
);
1254 brelse(block_bitmap_bh
);
1255 gd
->bg_flags
&= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT
);
1256 ext4_free_blks_set(sb
, gd
, free
);
1257 Ext2SaveGroup(IrpContext
, Vcb
, Group
);
1262 *Inode
= dwInode
+ 1 + Group
* INODES_PER_GROUP
;
1264 /* update group_desc / super_block */
1265 if (Type
== EXT2_FT_DIR
) {
1266 ext4_used_dirs_set(sb
, gd
, ext4_used_dirs_count(sb
, gd
) + 1);
1268 Ext2SaveGroup(IrpContext
, Vcb
, Group
);
1269 Ext2UpdateVcbStat(IrpContext
, Vcb
);
1270 Status
= STATUS_SUCCESS
;
1275 ExReleaseResourceLite(&Vcb
->MetaLock
);
1289 IN PEXT2_IRP_CONTEXT IrpContext
,
1295 struct super_block
*sb
= &Vcb
->sb
;
1296 PEXT2_GROUP_DESC gd
;
1297 struct buffer_head
*gb
= NULL
;
1298 struct buffer_head
*bh
= NULL
;
1299 ext4_fsblk_t bitmap_blk
;
1301 RTL_BITMAP InodeBitmap
;
1304 LARGE_INTEGER Offset
;
1307 BOOLEAN bModified
= FALSE
;
1309 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
1311 ExAcquireResourceExclusiveLite(&Vcb
->MetaLock
, TRUE
);
1313 Group
= (Inode
- 1) / INODES_PER_GROUP
;
1314 dwIno
= (Inode
- 1) % INODES_PER_GROUP
;
1316 DEBUG(DL_INF
, ( "Ext2FreeInode: Inode: %xh (Group/Off = %xh/%xh)\n",
1317 Inode
, Group
, dwIno
));
1319 if (Group
>= Vcb
->sbi
.s_groups_count
) {
1324 gd
= ext4_get_group_desc(sb
, Group
, &gb
);
1327 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1331 bitmap_blk
= ext4_inode_bitmap(sb
, gd
);
1332 bh
= sb_getblk(sb
, bitmap_blk
);
1335 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1338 if (!buffer_uptodate(bh
)) {
1339 int err
= bh_submit_read(bh
);
1341 DbgPrint("bh_submit_read error! err: %d\n", err
);
1342 Status
= Ext2WinntError(err
);
1347 if (Group
== Vcb
->sbi
.s_groups_count
- 1) {
1349 Length
= INODES_COUNT
% INODES_PER_GROUP
;
1351 /* s_inodes_count is integer multiple of s_inodes_per_group */
1352 Length
= INODES_PER_GROUP
;
1355 Length
= INODES_PER_GROUP
;
1358 RtlInitializeBitMap(&InodeBitmap
, (PULONG
)bh
->b_data
, Length
);
1360 if (RtlCheckBit(&InodeBitmap
, dwIno
) == 0) {
1362 Status
= STATUS_SUCCESS
;
1364 RtlClearBits(&InodeBitmap
, dwIno
, 1);
1369 /* update group free inodes */
1370 ext4_free_inodes_set(sb
, gd
,
1371 RtlNumberOfClearBits(&InodeBitmap
));
1373 /* set inode block dirty and add to vcb dirty range */
1374 mark_buffer_dirty(bh
);
1376 /* update group_desc and super_block */
1377 if (Type
== EXT2_FT_DIR
) {
1378 ext4_used_dirs_set(sb
, gd
,
1379 ext4_used_dirs_count(sb
, gd
) - 1);
1381 Ext2SaveGroup(IrpContext
, Vcb
, Group
);
1382 Ext2UpdateVcbStat(IrpContext
, Vcb
);
1383 Status
= STATUS_SUCCESS
;
1388 ExReleaseResourceLite(&Vcb
->MetaLock
);
1402 IN PEXT2_IRP_CONTEXT IrpContext
,
1405 IN
struct inode
*Inode
,
1406 IN PUNICODE_STRING FileName
,
1407 struct dentry
**Dentry
1410 struct dentry
*de
= NULL
;
1412 NTSTATUS status
= STATUS_UNSUCCESSFUL
;
1416 BOOLEAN MainResourceAcquired
= FALSE
;
1418 if (!IsDirectory(Dcb
)) {
1420 return STATUS_NOT_A_DIRECTORY
;
1423 ExAcquireResourceExclusiveLite(&Dcb
->MainResource
, TRUE
);
1424 MainResourceAcquired
= TRUE
;
1428 Ext2ReferXcb(&Dcb
->ReferenceCount
);
1429 de
= Ext2BuildEntry(Vcb
, Dcb
->Mcb
, FileName
);
1431 status
= STATUS_INSUFFICIENT_RESOURCES
;
1434 de
->d_inode
= Inode
;
1436 rc
= ext3_add_entry(IrpContext
, de
, Inode
);
1437 status
= Ext2WinntError(rc
);
1438 if (NT_SUCCESS(status
)) {
1440 /* increase dir inode's nlink for .. */
1441 if (S_ISDIR(Inode
->i_mode
)) {
1442 ext3_inc_count(Dcb
->Inode
);
1443 ext3_mark_inode_dirty(IrpContext
, Dcb
->Inode
);
1446 /* increase inode nlink reference */
1447 ext3_inc_count(Inode
);
1448 ext3_mark_inode_dirty(IrpContext
, Inode
);
1458 Ext2DerefXcb(&Dcb
->ReferenceCount
);
1460 if (MainResourceAcquired
) {
1461 ExReleaseResourceLite(&Dcb
->MainResource
);
1474 IN PEXT2_IRP_CONTEXT IrpContext
,
1480 struct inode
*dir
= Dcb
->Inode
;
1481 struct buffer_head
*bh
= NULL
;
1482 struct ext3_dir_entry_2
*de
;
1483 struct inode
*inode
;
1484 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
1485 BOOLEAN MainResourceAcquired
= FALSE
;
1487 if (!EXT3_HAS_INCOMPAT_FEATURE(dir
->i_sb
, EXT3_FEATURE_INCOMPAT_FILETYPE
)) {
1488 return STATUS_SUCCESS
;
1491 if (!IsDirectory(Dcb
)) {
1492 return STATUS_NOT_A_DIRECTORY
;
1495 ExAcquireResourceExclusiveLite(&Dcb
->MainResource
, TRUE
);
1496 MainResourceAcquired
= TRUE
;
1500 Ext2ReferXcb(&Dcb
->ReferenceCount
);
1502 bh
= ext3_find_entry(IrpContext
, Mcb
->de
, &de
);
1506 inode
= &Mcb
->Inode
;
1507 if (le32_to_cpu(de
->inode
) != inode
->i_ino
)
1510 ext3_set_de_type(inode
->i_sb
, de
, inode
->i_mode
);
1511 mark_buffer_dirty(bh
);
1513 //if (!inode->i_nlink)
1514 // ext3_orphan_add(handle, inode);
1516 dir
->i_ctime
= dir
->i_mtime
= ext3_current_time(dir
);
1517 ext3_mark_inode_dirty(IrpContext
, dir
);
1519 Status
= STATUS_SUCCESS
;
1523 Ext2DerefXcb(&Dcb
->ReferenceCount
);
1525 if (MainResourceAcquired
)
1526 ExReleaseResourceLite(&Dcb
->MainResource
);
1537 IN PEXT2_IRP_CONTEXT IrpContext
,
1543 struct inode
*dir
= Dcb
->Inode
;
1544 struct buffer_head
*bh
= NULL
;
1545 struct ext3_dir_entry_2
*de
;
1546 struct inode
*inode
;
1548 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
1549 BOOLEAN MainResourceAcquired
= FALSE
;
1551 if (!IsDirectory(Dcb
)) {
1552 return STATUS_NOT_A_DIRECTORY
;
1555 ExAcquireResourceExclusiveLite(&Dcb
->MainResource
, TRUE
);
1556 MainResourceAcquired
= TRUE
;
1560 Ext2ReferXcb(&Dcb
->ReferenceCount
);
1562 bh
= ext3_find_entry(IrpContext
, Mcb
->de
, &de
);
1566 inode
= &Mcb
->Inode
;
1567 if (le32_to_cpu(de
->inode
) != inode
->i_ino
)
1570 if (!inode
->i_nlink
) {
1571 ext3_warning (inode
->i_sb
, "ext3_unlink",
1572 "Deleting nonexistent file (%lu), %d",
1573 inode
->i_ino
, inode
->i_nlink
);
1576 rc
= ext3_delete_entry(IrpContext
, dir
, de
, bh
);
1578 Status
= Ext2WinntError(rc
);
1582 if (!inode->i_nlink)
1583 ext3_orphan_add(handle, inode);
1585 inode
->i_ctime
= dir
->i_ctime
= dir
->i_mtime
= ext3_current_time(dir
);
1586 ext3_dec_count(inode
);
1587 ext3_mark_inode_dirty(IrpContext
, inode
);
1589 /* decrease dir inode's nlink for .. */
1590 if (S_ISDIR(inode
->i_mode
)) {
1591 ext3_update_dx_flag(dir
);
1592 ext3_dec_count(dir
);
1593 ext3_mark_inode_dirty(IrpContext
, dir
);
1596 Status
= STATUS_SUCCESS
;
1600 Ext2DerefXcb(&Dcb
->ReferenceCount
);
1602 if (MainResourceAcquired
)
1603 ExReleaseResourceLite(&Dcb
->MainResource
);
1613 Ext2SetParentEntry (
1614 IN PEXT2_IRP_CONTEXT IrpContext
,
1618 IN ULONG NewParent
)
1620 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
1622 PEXT2_DIR_ENTRY2 pSelf
= NULL
;
1623 PEXT2_DIR_ENTRY2 pParent
= NULL
;
1627 BOOLEAN MainResourceAcquired
= FALSE
;
1631 if (!IsDirectory(Dcb
)) {
1632 return STATUS_NOT_A_DIRECTORY
;
1635 if (OldParent
== NewParent
) {
1636 return STATUS_SUCCESS
;
1639 MainResourceAcquired
=
1640 ExAcquireResourceExclusiveLite(&Dcb
->MainResource
, TRUE
);
1644 Ext2ReferXcb(&Dcb
->ReferenceCount
);
1646 pSelf
= (PEXT2_DIR_ENTRY2
)
1649 EXT2_DIR_REC_LEN(1) + EXT2_DIR_REC_LEN(2),
1653 DEBUG(DL_ERR
, ( "Ex2SetParentEntry: failed to allocate pSelf.\n"));
1654 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1661 // Reading the DCB contents
1664 Status
= Ext2ReadInode(
1670 EXT2_DIR_REC_LEN(1) + EXT2_DIR_REC_LEN(2),
1674 if (!NT_SUCCESS(Status
)) {
1675 DEBUG(DL_ERR
, ( "Ext2SetParentEntry: failed to read directory.\n"));
1679 ASSERT(dwBytes
== EXT2_DIR_REC_LEN(1) + EXT2_DIR_REC_LEN(2));
1681 pParent
= (PEXT2_DIR_ENTRY2
)((PUCHAR
)pSelf
+ pSelf
->rec_len
);
1683 if (pSelf
->name_len
== 1 && pSelf
->name
[0] == '.' &&
1684 pParent
->name_len
== 2 && pParent
->name
[0] == '.' &&
1685 pParent
->name
[1] == '.') {
1687 if (pParent
->inode
!= OldParent
) {
1690 pParent
->inode
= NewParent
;
1692 Status
= Ext2WriteInode(
1708 if (Ext2DerefXcb(&Dcb
->ReferenceCount
) == 0) {
1709 DEBUG(DL_ERR
, ( "Ext2SetParentEntry: Dcb reference goes to ZERO.\n"));
1712 if (MainResourceAcquired
) {
1713 ExReleaseResourceLite(&Dcb
->MainResource
);
1717 Ext2FreePool(pSelf
, EXT2_DENTRY_MAGIC
);
1724 int ext3_check_dir_entry (const char * function
, struct inode
* dir
,
1725 struct ext3_dir_entry_2
* de
,
1726 struct buffer_head
* bh
,
1727 unsigned long offset
)
1729 const char * error_msg
= NULL
;
1730 const int rlen
= ext3_rec_len_from_disk(de
->rec_len
);
1732 if (rlen
< EXT3_DIR_REC_LEN(1))
1733 error_msg
= "rec_len is smaller than minimal";
1734 else if (rlen
% 4 != 0)
1735 error_msg
= "rec_len % 4 != 0";
1736 else if (rlen
< EXT3_DIR_REC_LEN(de
->name_len
))
1737 error_msg
= "rec_len is too small for name_len";
1738 else if ((char *) de
+ rlen
> bh
->b_data
+ dir
->i_sb
->s_blocksize
)
1739 error_msg
= "directory entry across blocks";
1740 else if (le32_to_cpu(de
->inode
) >
1741 le32_to_cpu(EXT3_SB(dir
->i_sb
)->s_es
->s_inodes_count
))
1742 error_msg
= "inode out of bounds";
1744 if (error_msg
!= NULL
) {
1745 DEBUG(DL_ERR
, ("%s: bad entry in directory %u: %s - "
1746 "offset=%u, inode=%u, rec_len=%d, name_len=%d\n",
1747 function
, dir
->i_ino
, error_msg
, offset
,
1748 (unsigned long) le32_to_cpu(de
->inode
),
1749 rlen
, de
->name_len
));
1751 return error_msg
== NULL
? 1 : 0;
1756 * p is at least 6 bytes before the end of page
1758 struct ext3_dir_entry_2
*
1759 ext3_next_entry(struct ext3_dir_entry_2
*p
)
1761 return (struct ext3_dir_entry_2
*)((char *)p
+
1762 ext3_rec_len_from_disk(p
->rec_len
));
1765 #define MAX_LFS_FILESIZE 0x7fffffffffffffff
1768 * Maximal extent format file size.
1769 * Resulting logical blkno at s_maxbytes must fit in our on-disk
1770 * extent format containers, within a sector_t, and within i_blocks
1771 * in the vfs. ext4 inode has 48 bits of i_block in fsblock units,
1772 * so that won't be a limiting factor.
1774 * Note, this does *not* consider any metadata overhead for vfs i_blocks.
1776 static loff_t
ext4_max_size(int blkbits
, int has_huge_files
)
1779 loff_t upper_limit
= MAX_LFS_FILESIZE
;
1781 /* small i_blocks in vfs inode? */
1782 if (!has_huge_files
|| sizeof(blkcnt_t
) < sizeof(u64
)) {
1784 * CONFIG_LBD is not enabled implies the inode
1785 * i_block represent total blocks in 512 bytes
1786 * 32 == size of vfs inode i_blocks * 8
1788 upper_limit
= (1LL << 32) - 1;
1790 /* total blocks in file system block size */
1791 upper_limit
>>= (blkbits
- 9);
1792 upper_limit
<<= blkbits
;
1795 /* 32-bit extent-start container, ee_block */
1800 /* Sanity check against vm- & vfs- imposed limits */
1801 if (res
> upper_limit
)
1808 * Maximal extent format file size.
1809 * Resulting logical blkno at s_maxbytes must fit in our on-disk
1810 * extent format containers, within a sector_t, and within i_blocks
1811 * in the vfs. ext4 inode has 48 bits of i_block in fsblock units,
1812 * so that won't be a limiting factor.
1814 * Note, this does *not* consider any metadata overhead for vfs i_blocks.
1816 loff_t
ext3_max_size(int blkbits
, int has_huge_files
)
1819 loff_t upper_limit
= MAX_LFS_FILESIZE
;
1821 /* small i_blocks in vfs inode? */
1822 if (!has_huge_files
) {
1824 * CONFIG_LBD is not enabled implies the inode
1825 * i_block represent total blocks in 512 bytes
1826 * 32 == size of vfs inode i_blocks * 8
1828 upper_limit
= ((loff_t
)1 << 32) - 1;
1830 /* total blocks in file system block size */
1831 upper_limit
>>= (blkbits
- 9);
1832 upper_limit
<<= blkbits
;
1835 /* 32-bit extent-start container, ee_block */
1836 res
= (loff_t
)1 << 32;
1840 /* Sanity check against vm- & vfs- imposed limits */
1841 if (res
> upper_limit
)
1848 * Maximal bitmap file size. There is a direct, and {,double-,triple-}indirect
1849 * block limit, and also a limit of (2^48 - 1) 512-byte sectors in i_blocks.
1850 * We need to be 1 filesystem block less than the 2^48 sector limit.
1852 loff_t
ext3_max_bitmap_size(int bits
, int has_huge_files
)
1854 loff_t res
= EXT3_NDIR_BLOCKS
;
1857 /* This is calculated to be the largest file size for a
1858 * dense, bitmapped file such that the total number of
1859 * sectors in the file, including data and all indirect blocks,
1860 * does not exceed 2^48 -1
1861 * __u32 i_blocks_lo and _u16 i_blocks_high representing the
1862 * total number of 512 bytes blocks of the file
1865 if (!has_huge_files
) {
1867 * !has_huge_files or CONFIG_LBD is not enabled
1868 * implies the inode i_block represent total blocks in
1869 * 512 bytes 32 == size of vfs inode i_blocks * 8
1871 upper_limit
= ((loff_t
)1 << 32) - 1;
1873 /* total blocks in file system block size */
1874 upper_limit
>>= (bits
- 9);
1878 * We use 48 bit ext4_inode i_blocks
1879 * With EXT4_HUGE_FILE_FL set the i_blocks
1880 * represent total number of blocks in
1881 * file system block size
1883 upper_limit
= ((loff_t
)1 << 48) - 1;
1887 /* indirect blocks */
1889 /* double indirect blocks */
1890 meta_blocks
+= 1 + ((loff_t
)1 << (bits
-2));
1891 /* tripple indirect blocks */
1892 meta_blocks
+= 1 + ((loff_t
)1 << (bits
-2)) + ((loff_t
)1 << (2*(bits
-2)));
1894 upper_limit
-= meta_blocks
;
1895 upper_limit
<<= bits
;
1897 res
+= (loff_t
)1 << (bits
-2);
1898 res
+= (loff_t
)1 << (2*(bits
-2));
1899 res
+= (loff_t
)1 << (3*(bits
-2));
1901 if (res
> upper_limit
)
1904 if (res
> MAX_LFS_FILESIZE
)
1905 res
= MAX_LFS_FILESIZE
;
1910 blkcnt_t
ext3_inode_blocks(struct ext3_inode
*raw_inode
,
1911 struct inode
*inode
)
1914 struct super_block
*sb
= inode
->i_sb
;
1915 PEXT2_VCB Vcb
= (PEXT2_VCB
)sb
->s_priv
;
1917 if (EXT3_HAS_RO_COMPAT_FEATURE(sb
,
1918 EXT4_FEATURE_RO_COMPAT_HUGE_FILE
)) {
1919 /* we are using combined 48 bit field */
1920 i_blocks
= ((u64
)le16_to_cpu(raw_inode
->i_blocks_high
)) << 32 |
1921 le32_to_cpu(raw_inode
->i_blocks
);
1922 if (inode
->i_flags
& EXT4_HUGE_FILE_FL
) {
1923 /* i_blocks represent file system block size */
1924 return i_blocks
<< (BLOCK_BITS
- 9);
1929 return le32_to_cpu(raw_inode
->i_blocks
);
1933 int ext3_inode_blocks_set(struct ext3_inode
*raw_inode
,
1934 struct inode
* inode
)
1936 u64 i_blocks
= inode
->i_blocks
;
1937 struct super_block
*sb
= inode
->i_sb
;
1938 PEXT2_VCB Vcb
= (PEXT2_VCB
)sb
->s_priv
;
1940 if (i_blocks
< 0x100000000) {
1942 * i_blocks can be represnted in a 32 bit variable
1943 * as multiple of 512 bytes
1945 raw_inode
->i_blocks
= cpu_to_le32(i_blocks
);
1946 raw_inode
->i_blocks_high
= 0;
1947 inode
->i_flags
&= ~EXT4_HUGE_FILE_FL
;
1951 if (!EXT3_HAS_RO_COMPAT_FEATURE(sb
, EXT4_FEATURE_RO_COMPAT_HUGE_FILE
)) {
1952 EXT3_SET_RO_COMPAT_FEATURE(sb
, EXT4_FEATURE_RO_COMPAT_HUGE_FILE
);
1953 Ext2SaveSuper(NULL
, Vcb
);
1956 if (i_blocks
<= 0xffffffffffff) {
1958 * i_blocks can be represented in a 48 bit variable
1959 * as multiple of 512 bytes
1961 raw_inode
->i_blocks
= (__u32
)cpu_to_le32(i_blocks
);
1962 raw_inode
->i_blocks_high
= (__u16
)cpu_to_le16(i_blocks
>> 32);
1963 inode
->i_flags
&= ~EXT4_HUGE_FILE_FL
;
1965 inode
->i_flags
|= EXT4_HUGE_FILE_FL
;
1966 /* i_block is stored in file system block size */
1967 i_blocks
= i_blocks
>> (BLOCK_BITS
- 9);
1968 raw_inode
->i_blocks
= (__u32
)cpu_to_le32(i_blocks
);
1969 raw_inode
->i_blocks_high
= (__u16
)cpu_to_le16(i_blocks
>> 32);
1974 ext4_fsblk_t
ext4_block_bitmap(struct super_block
*sb
,
1975 struct ext4_group_desc
*bg
)
1977 return le32_to_cpu(bg
->bg_block_bitmap
) |
1978 (EXT4_DESC_SIZE(sb
) >= EXT4_MIN_DESC_SIZE_64BIT
?
1979 (ext4_fsblk_t
)le32_to_cpu(bg
->bg_block_bitmap_hi
) << 32 : 0);
1982 ext4_fsblk_t
ext4_inode_bitmap(struct super_block
*sb
,
1983 struct ext4_group_desc
*bg
)
1985 return le32_to_cpu(bg
->bg_inode_bitmap
) |
1986 (EXT4_DESC_SIZE(sb
) >= EXT4_MIN_DESC_SIZE_64BIT
?
1987 (ext4_fsblk_t
)le32_to_cpu(bg
->bg_inode_bitmap_hi
) << 32 : 0);
1990 ext4_fsblk_t
ext4_inode_table(struct super_block
*sb
,
1991 struct ext4_group_desc
*bg
)
1993 return le32_to_cpu(bg
->bg_inode_table
) |
1994 (EXT4_DESC_SIZE(sb
) >= EXT4_MIN_DESC_SIZE_64BIT
?
1995 (ext4_fsblk_t
)le32_to_cpu(bg
->bg_inode_table_hi
) << 32 : 0);
1998 __u32
ext4_free_blks_count(struct super_block
*sb
,
1999 struct ext4_group_desc
*bg
)
2001 return le16_to_cpu(bg
->bg_free_blocks_count
) |
2002 (EXT4_DESC_SIZE(sb
) >= EXT4_MIN_DESC_SIZE_64BIT
?
2003 (__u32
)le16_to_cpu(bg
->bg_free_blocks_count_hi
) << 16 : 0);
2006 __u32
ext4_free_inodes_count(struct super_block
*sb
,
2007 struct ext4_group_desc
*bg
)
2009 return le16_to_cpu(bg
->bg_free_inodes_count
) |
2010 (EXT4_DESC_SIZE(sb
) >= EXT4_MIN_DESC_SIZE_64BIT
?
2011 (__u32
)le16_to_cpu(bg
->bg_free_inodes_count_hi
) << 16 : 0);
2014 __u32
ext4_used_dirs_count(struct super_block
*sb
,
2015 struct ext4_group_desc
*bg
)
2017 return le16_to_cpu(bg
->bg_used_dirs_count
) |
2018 (EXT4_DESC_SIZE(sb
) >= EXT4_MIN_DESC_SIZE_64BIT
?
2019 (__u32
)le16_to_cpu(bg
->bg_used_dirs_count_hi
) << 16 : 0);
2022 __u32
ext4_itable_unused_count(struct super_block
*sb
,
2023 struct ext4_group_desc
*bg
)
2025 return le16_to_cpu(bg
->bg_itable_unused
) |
2026 (EXT4_DESC_SIZE(sb
) >= EXT4_MIN_DESC_SIZE_64BIT
?
2027 (__u32
)le16_to_cpu(bg
->bg_itable_unused_hi
) << 16 : 0);
2030 void ext4_block_bitmap_set(struct super_block
*sb
,
2031 struct ext4_group_desc
*bg
, ext4_fsblk_t blk
)
2033 bg
->bg_block_bitmap
= cpu_to_le32((u32
)blk
);
2034 if (EXT4_DESC_SIZE(sb
) >= EXT4_MIN_DESC_SIZE_64BIT
)
2035 bg
->bg_block_bitmap_hi
= cpu_to_le32(blk
>> 32);
2038 void ext4_inode_bitmap_set(struct super_block
*sb
,
2039 struct ext4_group_desc
*bg
, ext4_fsblk_t blk
)
2041 bg
->bg_inode_bitmap
= cpu_to_le32((u32
)blk
);
2042 if (EXT4_DESC_SIZE(sb
) >= EXT4_MIN_DESC_SIZE_64BIT
)
2043 bg
->bg_inode_bitmap_hi
= cpu_to_le32(blk
>> 32);
2046 void ext4_inode_table_set(struct super_block
*sb
,
2047 struct ext4_group_desc
*bg
, ext4_fsblk_t blk
)
2049 bg
->bg_inode_table
= cpu_to_le32((u32
)blk
);
2050 if (EXT4_DESC_SIZE(sb
) >= EXT4_MIN_DESC_SIZE_64BIT
)
2051 bg
->bg_inode_table_hi
= cpu_to_le32(blk
>> 32);
2054 void ext4_free_blks_set(struct super_block
*sb
,
2055 struct ext4_group_desc
*bg
, __u32 count
)
2057 bg
->bg_free_blocks_count
= cpu_to_le16((__u16
)count
);
2058 if (EXT4_DESC_SIZE(sb
) >= EXT4_MIN_DESC_SIZE_64BIT
)
2059 bg
->bg_free_blocks_count_hi
= cpu_to_le16(count
>> 16);
2062 void ext4_free_inodes_set(struct super_block
*sb
,
2063 struct ext4_group_desc
*bg
, __u32 count
)
2065 bg
->bg_free_inodes_count
= cpu_to_le16((__u16
)count
);
2066 if (EXT4_DESC_SIZE(sb
) >= EXT4_MIN_DESC_SIZE_64BIT
)
2067 bg
->bg_free_inodes_count_hi
= cpu_to_le16(count
>> 16);
2070 void ext4_used_dirs_set(struct super_block
*sb
,
2071 struct ext4_group_desc
*bg
, __u32 count
)
2073 bg
->bg_used_dirs_count
= cpu_to_le16((__u16
)count
);
2074 if (EXT4_DESC_SIZE(sb
) >= EXT4_MIN_DESC_SIZE_64BIT
)
2075 bg
->bg_used_dirs_count_hi
= cpu_to_le16(count
>> 16);
2078 void ext4_itable_unused_set(struct super_block
*sb
,
2079 struct ext4_group_desc
*bg
, __u32 count
)
2081 bg
->bg_itable_unused
= cpu_to_le16((__u16
)count
);
2082 if (EXT4_DESC_SIZE(sb
) >= EXT4_MIN_DESC_SIZE_64BIT
)
2083 bg
->bg_itable_unused_hi
= cpu_to_le16(count
>> 16);
2086 /** CRC table for the CRC-16. The poly is 0x8005 (x16 + x15 + x2 + 1) */
2087 __u16
const crc16_table
[256] = {
2088 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
2089 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
2090 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
2091 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
2092 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
2093 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
2094 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
2095 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
2096 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
2097 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
2098 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
2099 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
2100 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
2101 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
2102 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
2103 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
2104 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
2105 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
2106 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
2107 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
2108 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
2109 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
2110 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
2111 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
2112 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
2113 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
2114 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
2115 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
2116 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
2117 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
2118 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
2119 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
2122 static inline __u16
crc16_byte(__u16 crc
, const __u8 data
)
2124 return (crc
>> 8) ^ crc16_table
[(crc
^ data
) & 0xff];
2127 __u16
crc16(__u16 crc
, __u8
const *buffer
, size_t len
)
2130 crc
= crc16_byte(crc
, *buffer
++);
2134 __le16
ext4_group_desc_csum(struct ext3_sb_info
*sbi
, __u32 block_group
,
2135 struct ext4_group_desc
*gdp
)
2139 if (sbi
->s_es
->s_feature_ro_compat
&
2140 cpu_to_le32(EXT4_FEATURE_RO_COMPAT_GDT_CSUM
)) {
2141 int offset
= offsetof(struct ext4_group_desc
, bg_checksum
);
2142 __le32 le_group
= cpu_to_le32(block_group
);
2144 crc
= crc16(~0, sbi
->s_es
->s_uuid
, sizeof(sbi
->s_es
->s_uuid
));
2145 crc
= crc16(crc
, (__u8
*)&le_group
, sizeof(le_group
));
2146 crc
= crc16(crc
, (__u8
*)gdp
, offset
);
2147 offset
+= sizeof(gdp
->bg_checksum
); /* skip checksum */
2148 /* for checksum of struct ext4_group_desc do the rest...*/
2149 if ((sbi
->s_es
->s_feature_incompat
&
2150 cpu_to_le32(EXT4_FEATURE_INCOMPAT_64BIT
)) &&
2151 offset
< le16_to_cpu(sbi
->s_es
->s_desc_size
))
2152 crc
= crc16(crc
, (__u8
*)gdp
+ offset
,
2153 le16_to_cpu(sbi
->s_es
->s_desc_size
) -
2157 return cpu_to_le16(crc
);
2160 int ext4_group_desc_csum_verify(struct ext3_sb_info
*sbi
, __u32 block_group
,
2161 struct ext4_group_desc
*gdp
)
2163 if ((sbi
->s_es
->s_feature_ro_compat
& cpu_to_le32(EXT4_FEATURE_RO_COMPAT_GDT_CSUM
)) &&
2164 (gdp
->bg_checksum
!= ext4_group_desc_csum(sbi
, block_group
, gdp
)))
2171 static inline int test_root(ext3_group_t a
, ext3_group_t b
)
2173 ext3_group_t num
= b
;
2180 static int ext3_group_sparse(ext3_group_t group
)
2186 return (test_root(group
, 7) || test_root(group
, 5) ||
2187 test_root(group
, 3));
2191 * ext4_bg_has_super - number of blocks used by the superblock in group
2192 * @sb: superblock for filesystem
2193 * @group: group number to check
2195 * Return the number of blocks used by the superblock (primary or backup)
2196 * in this group. Currently this will be only 0 or 1.
2198 int ext3_bg_has_super(struct super_block
*sb
, ext3_group_t group
)
2200 if (EXT3_HAS_RO_COMPAT_FEATURE(sb
,
2201 EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER
) &&
2202 !ext3_group_sparse(group
))
2207 static unsigned long ext4_bg_num_gdb_meta(struct super_block
*sb
,
2210 unsigned long metagroup
= group
/ EXT4_DESC_PER_BLOCK(sb
);
2211 ext4_group_t first
= metagroup
* EXT4_DESC_PER_BLOCK(sb
);
2212 ext4_group_t last
= first
+ EXT4_DESC_PER_BLOCK(sb
) - 1;
2214 if (group
== first
|| group
== first
+ 1 || group
== last
)
2219 static unsigned long ext4_bg_num_gdb_nometa(struct super_block
*sb
,
2222 return ext3_bg_has_super(sb
, group
) ? EXT3_SB(sb
)->s_gdb_count
: 0;
2226 * ext4_bg_num_gdb - number of blocks used by the group table in group
2227 * @sb: superblock for filesystem
2228 * @group: group number to check
2230 * Return the number of blocks used by the group descriptor table
2231 * (primary or backup) in this group. In the future there may be a
2232 * different number of descriptor blocks in each group.
2234 unsigned long ext4_bg_num_gdb(struct super_block
*sb
, ext4_group_t group
)
2236 unsigned long first_meta_bg
=
2237 le32_to_cpu(EXT3_SB(sb
)->s_es
->s_first_meta_bg
);
2238 unsigned long metagroup
= group
/ EXT4_DESC_PER_BLOCK(sb
);
2240 if (!EXT3_HAS_INCOMPAT_FEATURE(sb
,EXT4_FEATURE_INCOMPAT_META_BG
) ||
2241 metagroup
< first_meta_bg
)
2242 return ext4_bg_num_gdb_nometa(sb
, group
);
2244 return ext4_bg_num_gdb_meta(sb
,group
);
2248 ext3_fsblk_t
descriptor_loc(struct super_block
*sb
,
2249 ext3_fsblk_t logical_sb_block
, unsigned int nr
)
2251 struct ext3_sb_info
*sbi
= EXT3_SB(sb
);
2252 ext3_group_t bg
, first_meta_bg
;
2255 first_meta_bg
= le32_to_cpu(sbi
->s_es
->s_first_meta_bg
);
2257 if (!EXT3_HAS_INCOMPAT_FEATURE(sb
, EXT4_FEATURE_INCOMPAT_META_BG
) ||
2259 return logical_sb_block
+ nr
+ 1;
2260 bg
= sbi
->s_desc_per_block
* nr
;
2261 if (ext3_bg_has_super(sb
, bg
))
2263 return (has_super
+ ext3_group_first_block_no(sb
, bg
));
2266 #define ext4_set_bit(n, p) set_bit((int)(n), (unsigned long *)(p))
2269 * The free inodes are managed by bitmaps. A file system contains several
2270 * blocks groups. Each group contains 1 bitmap block for blocks, 1 bitmap
2271 * block for inodes, N blocks for the inode table and data blocks.
2273 * The file system contains group descriptors which are located after the
2274 * super block. Each descriptor contains the number of the bitmap block and
2275 * the free blocks count in the block.
2279 * To avoid calling the atomic setbit hundreds or thousands of times, we only
2280 * need to use it within a single byte (to ensure we get endianness right).
2281 * We can use memset for the rest of the bitmap as there are no other users.
2283 void mark_bitmap_end(int start_bit
, int end_bit
, char *bitmap
)
2287 if (start_bit
>= end_bit
)
2290 DEBUG(DL_INF
, ("mark end bits +%d through +%d used\n", start_bit
, end_bit
));
2291 for (i
= start_bit
; (unsigned)i
< ((start_bit
+ 7) & ~7UL); i
++)
2292 ext4_set_bit(i
, bitmap
);
2294 memset(bitmap
+ (i
>> 3), 0xff, (end_bit
- i
) >> 3);
2297 /* Initializes an uninitialized inode bitmap */
2298 unsigned ext4_init_inode_bitmap(struct super_block
*sb
, struct buffer_head
*bh
,
2299 ext4_group_t block_group
,
2300 struct ext4_group_desc
*gdp
)
2302 struct ext3_sb_info
*sbi
= EXT3_SB(sb
);
2304 mark_buffer_dirty(bh
);
2306 /* If checksum is bad mark all blocks and inodes use to prevent
2307 * allocation, essentially implementing a per-group read-only flag. */
2308 if (!ext4_group_desc_csum_verify(sbi
, block_group
, gdp
)) {
2309 ext4_error(sb
, __FUNCTION__
, "Checksum bad for group %u",
2311 ext4_free_blks_set(sb
, gdp
, 0);
2312 ext4_free_inodes_set(sb
, gdp
, 0);
2313 ext4_itable_unused_set(sb
, gdp
, 0);
2314 memset(bh
->b_data
, 0xff, sb
->s_blocksize
);
2318 memset(bh
->b_data
, 0, (EXT4_INODES_PER_GROUP(sb
) + 7) / 8);
2319 mark_bitmap_end(EXT4_INODES_PER_GROUP(sb
), sb
->s_blocksize
* 8,
2321 ext4_itable_unused_set(sb
, gdp
, EXT4_INODES_PER_GROUP(sb
));
2323 return EXT4_INODES_PER_GROUP(sb
);
2327 * Calculate the block group number and offset, given a block number
2329 void ext4_get_group_no_and_offset(struct super_block
*sb
, ext4_fsblk_t blocknr
,
2330 ext4_group_t
*blockgrpp
, ext4_grpblk_t
*offsetp
)
2332 struct ext3_super_block
*es
= EXT3_SB(sb
)->s_es
;
2333 ext4_grpblk_t offset
;
2335 blocknr
= blocknr
- le32_to_cpu(es
->s_first_data_block
);
2336 offset
= do_div(blocknr
, EXT4_BLOCKS_PER_GROUP(sb
));
2340 *blockgrpp
= (ext4_grpblk_t
)blocknr
;
2344 static int ext4_block_in_group(struct super_block
*sb
, ext4_fsblk_t block
,
2345 ext4_group_t block_group
)
2347 ext4_group_t actual_group
;
2348 ext4_get_group_no_and_offset(sb
, block
, &actual_group
, NULL
);
2349 if (actual_group
== block_group
)
2354 static int ext4_group_used_meta_blocks(struct super_block
*sb
,
2355 ext4_group_t block_group
)
2358 struct ext3_sb_info
*sbi
= EXT3_SB(sb
);
2359 /* block bitmap, inode bitmap, and inode table blocks */
2360 int used_blocks
= sbi
->s_itb_per_group
+ 2;
2362 if (EXT3_HAS_INCOMPAT_FEATURE(sb
, EXT4_FEATURE_INCOMPAT_FLEX_BG
)) {
2363 struct ext4_group_desc
*gdp
;
2364 struct buffer_head
*bh
= NULL
;
2366 gdp
= ext4_get_group_desc(sb
, block_group
, &bh
);
2367 if (!ext4_block_in_group(sb
, ext4_block_bitmap(sb
, gdp
),
2371 if (!ext4_block_in_group(sb
, ext4_inode_bitmap(sb
, gdp
),
2375 tmp
= ext4_inode_table(sb
, gdp
);
2376 for (; tmp
< ext4_inode_table(sb
, gdp
) +
2377 sbi
->s_itb_per_group
; tmp
++) {
2378 if (!ext4_block_in_group(sb
, tmp
, block_group
))
2387 /* Initializes an uninitialized block bitmap if given, and returns the
2388 * number of blocks free in the group. */
2389 unsigned ext4_init_block_bitmap(struct super_block
*sb
, struct buffer_head
*bh
,
2390 ext4_group_t block_group
, struct ext4_group_desc
*gdp
)
2393 unsigned free_blocks
, group_blocks
;
2394 struct ext3_sb_info
*sbi
= EXT3_SB(sb
);
2397 mark_buffer_dirty(bh
);
2398 /* If checksum is bad mark all blocks used to prevent allocation
2399 * essentially implementing a per-group read-only flag. */
2400 if (!ext4_group_desc_csum_verify(sbi
, block_group
, gdp
)) {
2401 ext4_error(sb
, __FUNCTION__
,
2402 "Checksum bad for group %u", block_group
);
2403 ext4_free_blks_set(sb
, gdp
, 0);
2404 ext4_free_inodes_set(sb
, gdp
, 0);
2405 ext4_itable_unused_set(sb
, gdp
, 0);
2406 memset(bh
->b_data
, 0xff, sb
->s_blocksize
);
2409 memset(bh
->b_data
, 0, sb
->s_blocksize
);
2412 /* Check for superblock and gdt backups in this group */
2413 bit_max
= ext3_bg_has_super(sb
, block_group
);
2415 if (!EXT3_HAS_INCOMPAT_FEATURE(sb
, EXT4_FEATURE_INCOMPAT_META_BG
) ||
2416 block_group
< le32_to_cpu(sbi
->s_es
->s_first_meta_bg
) *
2417 sbi
->s_desc_per_block
) {
2419 bit_max
+= ext4_bg_num_gdb(sb
, block_group
);
2421 le16_to_cpu(sbi
->s_es
->s_reserved_gdt_blocks
);
2423 } else { /* For META_BG_BLOCK_GROUPS */
2424 bit_max
+= ext4_bg_num_gdb(sb
, block_group
);
2427 if (block_group
== sbi
->s_groups_count
- 1) {
2429 * Even though mke2fs always initialize first and last group
2430 * if some other tool enabled the EXT4_BG_BLOCK_UNINIT we need
2431 * to make sure we calculate the right free blocks
2433 group_blocks
= (unsigned int)(ext3_blocks_count(sbi
->s_es
) -
2434 le32_to_cpu(sbi
->s_es
->s_first_data_block
) -
2435 (EXT4_BLOCKS_PER_GROUP(sb
) * (sbi
->s_groups_count
- 1)));
2437 group_blocks
= EXT4_BLOCKS_PER_GROUP(sb
);
2440 free_blocks
= group_blocks
- bit_max
;
2443 ext4_fsblk_t start
, tmp
;
2446 for (bit
= 0; bit
< bit_max
; bit
++)
2447 ext4_set_bit(bit
, bh
->b_data
);
2449 start
= ext3_group_first_block_no(sb
, block_group
);
2451 if (EXT3_HAS_INCOMPAT_FEATURE(sb
,
2452 EXT4_FEATURE_INCOMPAT_FLEX_BG
))
2455 /* Set bits for block and inode bitmaps, and inode table */
2456 tmp
= ext4_block_bitmap(sb
, gdp
);
2457 if (!flex_bg
|| ext4_block_in_group(sb
, tmp
, block_group
))
2458 ext4_set_bit(tmp
- start
, bh
->b_data
);
2460 tmp
= ext4_inode_bitmap(sb
, gdp
);
2461 if (!flex_bg
|| ext4_block_in_group(sb
, tmp
, block_group
))
2462 ext4_set_bit(tmp
- start
, bh
->b_data
);
2464 tmp
= ext4_inode_table(sb
, gdp
);
2465 for (; tmp
< ext4_inode_table(sb
, gdp
) +
2466 sbi
->s_itb_per_group
; tmp
++) {
2468 ext4_block_in_group(sb
, tmp
, block_group
))
2469 ext4_set_bit(tmp
- start
, bh
->b_data
);
2472 * Also if the number of blocks within the group is
2473 * less than the blocksize * 8 ( which is the size
2474 * of bitmap ), set rest of the block bitmap to 1
2476 mark_bitmap_end(group_blocks
, sb
->s_blocksize
* 8, bh
->b_data
);
2478 return free_blocks
- ext4_group_used_meta_blocks(sb
, block_group
);
2482 * ext4_get_group_desc() -- load group descriptor from disk
2484 * @block_group: given block group
2485 * @bh: pointer to the buffer head to store the block
2488 struct ext4_group_desc
* ext4_get_group_desc(struct super_block
*sb
,
2489 ext4_group_t block_group
, struct buffer_head
**bh
)
2491 struct ext4_group_desc
*desc
= NULL
;
2492 struct buffer_head
*gb
= NULL
;
2493 struct ext3_sb_info
*sbi
= EXT3_SB(sb
);
2494 PEXT2_VCB vcb
= sb
->s_priv
;
2497 unsigned int offset
;
2502 if (block_group
>= sbi
->s_groups_count
) {
2503 ext4_error(sb
, "ext4_get_group_desc",
2504 "block_group >= groups_count - "
2505 "block_group = %u, groups_count = %u",
2506 block_group
, sbi
->s_groups_count
);
2512 group
= block_group
>> EXT4_DESC_PER_BLOCK_BITS(sb
);
2513 offset
= block_group
& (EXT4_DESC_PER_BLOCK(sb
) - 1);
2515 if (!sbi
->s_group_desc
|| !sbi
->s_group_desc
[group
]) {
2519 if (!sbi
->s_group_desc
[group
]) {
2520 ext4_error(sb
, "ext4_get_group_desc",
2521 "Group descriptor not loaded - "
2522 "block_group = %u, group = %u, desc = %u",
2523 block_group
, group
, offset
);
2527 gb
= sb_getblk(sb
, sbi
->s_group_desc
[group
]);
2529 ext4_error(sb
, "ext4_get_group_desc",
2530 "failed to load group - "
2531 "block_group = %u, group = %u, desc = %u",
2532 block_group
, group
, offset
);
2536 desc
= (struct ext4_group_desc
*)(gb
->b_data
+
2537 offset
* EXT4_DESC_SIZE(sb
));
2549 * ext4_count_free_blocks() -- count filesystem free blocks
2552 * Adds up the number of free blocks from each block group.
2554 ext4_fsblk_t
ext4_count_free_blocks(struct super_block
*sb
)
2556 ext4_fsblk_t desc_count
;
2557 struct ext4_group_desc
*gdp
;
2558 struct buffer_head
*bh
= NULL
;
2560 ext4_group_t ngroups
= EXT3_SB(sb
)->s_groups_count
;
2564 for (i
= 0; i
< ngroups
; i
++) {
2565 gdp
= ext4_get_group_desc(sb
, i
, &bh
);
2568 desc_count
+= ext4_free_blks_count(sb
, gdp
);
2575 unsigned long ext4_count_free_inodes(struct super_block
*sb
)
2577 unsigned long desc_count
;
2578 struct ext4_group_desc
*gdp
;
2579 struct buffer_head
*bh
= NULL
;
2583 for (i
= 0; i
< EXT3_SB(sb
)->s_groups_count
; i
++) {
2584 gdp
= ext4_get_group_desc(sb
, i
, &bh
);
2587 desc_count
+= ext4_free_inodes_count(sb
, gdp
);
2593 /* Called at mount-time, super-block is locked */
2594 unsigned long ext4_count_dirs(struct super_block
* sb
)
2596 struct ext4_group_desc
*gdp
;
2597 struct buffer_head
*bh
= NULL
;
2598 unsigned long count
= 0;
2601 for (i
= 0; i
< EXT3_SB(sb
)->s_groups_count
; i
++) {
2602 gdp
= ext4_get_group_desc(sb
, i
, &bh
);
2605 count
+= ext4_used_dirs_count(sb
, gdp
);
2611 /* Called at mount-time, super-block is locked */
2612 int ext4_check_descriptors(struct super_block
*sb
)
2614 PEXT2_VCB Vcb
= sb
->s_priv
;
2615 struct ext3_sb_info
*sbi
= EXT3_SB(sb
);
2616 ext4_fsblk_t first_block
= le32_to_cpu(sbi
->s_es
->s_first_data_block
);
2617 ext4_fsblk_t last_block
;
2618 ext4_fsblk_t block_bitmap
;
2619 ext4_fsblk_t inode_bitmap
;
2620 ext4_fsblk_t inode_table
;
2621 int flexbg_flag
= 0;
2624 if (EXT3_HAS_INCOMPAT_FEATURE(sb
, EXT4_FEATURE_INCOMPAT_FLEX_BG
))
2627 DEBUG(DL_INF
, ("Checking group descriptors"));
2629 for (i
= 0; i
< sbi
->s_groups_count
; i
++) {
2631 struct buffer_head
*bh
= NULL
;
2632 struct ext4_group_desc
*gdp
= ext4_get_group_desc(sb
, i
, &bh
);
2637 if (i
== sbi
->s_groups_count
- 1 || flexbg_flag
)
2638 last_block
= ext3_blocks_count(sbi
->s_es
) - 1;
2640 last_block
= first_block
+
2641 (EXT3_BLOCKS_PER_GROUP(sb
) - 1);
2643 block_bitmap
= ext4_block_bitmap(sb
, gdp
);
2644 if (block_bitmap
< first_block
|| block_bitmap
> last_block
) {
2645 printk(KERN_ERR
"EXT4-fs: ext4_check_descriptors: "
2646 "Block bitmap for group %u not in group "
2647 "(block %llu)!\n", i
, block_bitmap
);
2651 inode_bitmap
= ext4_inode_bitmap(sb
, gdp
);
2652 if (inode_bitmap
< first_block
|| inode_bitmap
> last_block
) {
2653 printk(KERN_ERR
"EXT4-fs: ext4_check_descriptors: "
2654 "Inode bitmap for group %u not in group "
2655 "(block %llu)!\n", i
, inode_bitmap
);
2659 inode_table
= ext4_inode_table(sb
, gdp
);
2660 if (inode_table
< first_block
||
2661 inode_table
+ sbi
->s_itb_per_group
- 1 > last_block
) {
2662 printk(KERN_ERR
"EXT4-fs: ext4_check_descriptors: "
2663 "Inode table for group %u not in group "
2664 "(block %llu)!\n", i
, inode_table
);
2669 if (!ext4_group_desc_csum_verify(sbi
, i
, gdp
)) {
2670 printk(KERN_ERR
"EXT4-fs: ext4_check_descriptors: "
2671 "Checksum for group %u failed (%u!=%u)\n",
2672 i
, le16_to_cpu(ext4_group_desc_csum(sbi
, i
,
2673 gdp
)), le16_to_cpu(gdp
->bg_checksum
));
2674 if (!IsVcbReadOnly(Vcb
)) {
2681 first_block
+= EXT4_BLOCKS_PER_GROUP(sb
);
2686 ext3_free_blocks_count_set(sbi
->s_es
, ext4_count_free_blocks(sb
));
2687 sbi
->s_es
->s_free_inodes_count
= cpu_to_le32(ext4_count_free_inodes(sb
));