ReactOS 0.4.16-dev-297-gc569aee
generic.c File Reference
#include "ext2fs.h"
#include "linux\ext4.h"
Include dependency graph for generic.c:

Go to the source code of this file.

Macros

#define MAX_LFS_FILESIZE   0x7fffffffffffffff
 
#define ext4_set_bit(n, p)   set_bit((int)(n), (unsigned long *)(p))
 

Functions

NTSTATUS Ext2LoadSuper (IN PEXT2_VCB Vcb, IN BOOLEAN bVerify, OUT PEXT2_SUPER_BLOCK *Sb)
 
BOOLEAN Ext2SaveSuper (IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb)
 
BOOLEAN Ext2RefreshSuper (IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb)
 
VOID Ext2DropGroupBH (IN PEXT2_VCB Vcb)
 
VOID Ext2PutGroup (IN PEXT2_VCB Vcb)
 
BOOLEAN Ext2LoadGroupBH (IN PEXT2_VCB Vcb)
 
BOOLEAN Ext2LoadGroup (IN PEXT2_VCB Vcb)
 
VOID Ext2DropBH (IN PEXT2_VCB Vcb)
 
VOID Ext2FlushRange (IN PEXT2_VCB Vcb, LARGE_INTEGER s, LARGE_INTEGER e)
 
NTSTATUS Ext2FlushVcb (IN PEXT2_VCB Vcb)
 
BOOLEAN Ext2SaveGroup (IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN ULONG Group)
 
BOOLEAN Ext2RefreshGroup (IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb)
 
BOOLEAN Ext2GetInodeLba (IN PEXT2_VCB Vcb, IN ULONG inode, OUT PLONGLONG offset)
 
void Ext2DecodeInode (struct inode *dst, struct ext3_inode *src)
 
void Ext2EncodeInode (struct ext3_inode *dst, struct inode *src)
 
BOOLEAN Ext2LoadInode (IN PEXT2_VCB Vcb, IN struct inode *Inode)
 
BOOLEAN Ext2ClearInode (IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN ULONG Inode)
 
BOOLEAN Ext2SaveInode (IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN struct inode *Inode)
 
BOOLEAN Ext2LoadInodeXattr (IN PEXT2_VCB Vcb, IN struct inode *Inode, IN PEXT2_INODE InodeXattr)
 
BOOLEAN Ext2SaveInodeXattr (IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN struct inode *Inode, IN PEXT2_INODE InodeXattr)
 
BOOLEAN Ext2LoadBlock (IN PEXT2_VCB Vcb, IN ULONG Index, IN PVOID Buffer)
 
BOOLEAN Ext2SaveBlock (IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN ULONG Index, IN PVOID Buf)
 
BOOLEAN Ext2LoadBuffer (IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN LONGLONG offset, IN ULONG size, IN PVOID buf)
 
BOOLEAN Ext2ZeroBuffer (IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN LONGLONG offset, IN ULONG size)
 
BOOLEAN Ext2SaveBuffer (IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN LONGLONG offset, IN ULONG size, IN PVOID buf)
 
VOID Ext2UpdateVcbStat (IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb)
 
NTSTATUS Ext2NewBlock (IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN ULONG GroupHint, IN ULONG BlockHint, OUT PULONG Block, IN OUT PULONG Number)
 
NTSTATUS Ext2FreeBlock (IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN ULONG Block, IN ULONG Number)
 
NTSTATUS Ext2NewInode (IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN ULONG GroupHint, IN ULONG Type, OUT PULONG Inode)
 
NTSTATUS Ext2UpdateGroupDirStat (IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN ULONG group)
 
NTSTATUS Ext2FreeInode (IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN ULONG Inode, IN ULONG Type)
 
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)
 
NTSTATUS Ext2SetFileType (IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN PEXT2_FCB Dcb, IN PEXT2_MCB Mcb, IN umode_t mode)
 
NTSTATUS Ext2RemoveEntry (IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN PEXT2_FCB Dcb, IN PEXT2_MCB Mcb)
 
NTSTATUS Ext2SetParentEntry (IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN PEXT2_FCB Dcb, IN ULONG OldParent, IN ULONG NewParent)
 
int ext3_check_dir_entry (const char *function, struct inode *dir, struct ext3_dir_entry_2 *de, struct buffer_head *bh, unsigned long offset)
 
struct ext3_dir_entry_2ext3_next_entry (struct ext3_dir_entry_2 *p)
 
static loff_t ext4_max_size (int blkbits, int has_huge_files)
 
loff_t ext3_max_size (int blkbits, int has_huge_files)
 
loff_t ext3_max_bitmap_size (int bits, int has_huge_files)
 
blkcnt_t ext3_inode_blocks (struct ext3_inode *raw_inode, struct inode *inode)
 
int ext3_inode_blocks_set (struct ext3_inode *raw_inode, struct inode *inode)
 
ext4_fsblk_t ext4_block_bitmap (struct super_block *sb, struct ext4_group_desc *bg)
 
ext4_fsblk_t ext4_inode_bitmap (struct super_block *sb, struct ext4_group_desc *bg)
 
ext4_fsblk_t ext4_inode_table (struct super_block *sb, struct ext4_group_desc *bg)
 
__u32 ext4_free_blks_count (struct super_block *sb, struct ext4_group_desc *bg)
 
__u32 ext4_free_inodes_count (struct super_block *sb, struct ext4_group_desc *bg)
 
__u32 ext4_used_dirs_count (struct super_block *sb, struct ext4_group_desc *bg)
 
__u32 ext4_itable_unused_count (struct super_block *sb, struct ext4_group_desc *bg)
 
void ext4_block_bitmap_set (struct super_block *sb, struct ext4_group_desc *bg, ext4_fsblk_t blk)
 
void ext4_inode_bitmap_set (struct super_block *sb, struct ext4_group_desc *bg, ext4_fsblk_t blk)
 
void ext4_inode_table_set (struct super_block *sb, struct ext4_group_desc *bg, ext4_fsblk_t blk)
 
void ext4_free_blks_set (struct super_block *sb, struct ext4_group_desc *bg, __u32 count)
 
void ext4_free_inodes_set (struct super_block *sb, struct ext4_group_desc *bg, __u32 count)
 
void ext4_used_dirs_set (struct super_block *sb, struct ext4_group_desc *bg, __u32 count)
 
void ext4_itable_unused_set (struct super_block *sb, struct ext4_group_desc *bg, __u32 count)
 
static __u16 crc16_byte (__u16 crc, const __u8 data)
 
__u16 crc16 (__u16 crc, __u8 const *buffer, size_t len)
 
__le16 ext4_group_desc_csum (struct ext3_sb_info *sbi, __u32 block_group, struct ext4_group_desc *gdp)
 
int ext4_group_desc_csum_verify (struct ext3_sb_info *sbi, __u32 block_group, struct ext4_group_desc *gdp)
 
static int test_root (ext3_group_t a, ext3_group_t b)
 
static int ext3_group_sparse (ext3_group_t group)
 
int ext3_bg_has_super (struct super_block *sb, ext3_group_t group)
 
static unsigned long ext4_bg_num_gdb_meta (struct super_block *sb, ext4_group_t group)
 
static unsigned long ext4_bg_num_gdb_nometa (struct super_block *sb, ext4_group_t group)
 
unsigned long ext4_bg_num_gdb (struct super_block *sb, ext4_group_t group)
 
ext3_fsblk_t descriptor_loc (struct super_block *sb, ext3_fsblk_t logical_sb_block, unsigned int nr)
 
void mark_bitmap_end (int start_bit, int end_bit, char *bitmap)
 
unsigned ext4_init_inode_bitmap (struct super_block *sb, struct buffer_head *bh, ext4_group_t block_group, struct ext4_group_desc *gdp)
 
void ext4_get_group_no_and_offset (struct super_block *sb, ext4_fsblk_t blocknr, ext4_group_t *blockgrpp, ext4_grpblk_t *offsetp)
 
static int ext4_block_in_group (struct super_block *sb, ext4_fsblk_t block, ext4_group_t block_group)
 
static int ext4_group_used_meta_blocks (struct super_block *sb, ext4_group_t block_group)
 
unsigned ext4_init_block_bitmap (struct super_block *sb, struct buffer_head *bh, ext4_group_t block_group, struct ext4_group_desc *gdp)
 
struct ext4_group_descext4_get_group_desc (struct super_block *sb, ext4_group_t block_group, struct buffer_head **bh)
 
ext4_fsblk_t ext4_count_free_blocks (struct super_block *sb)
 
unsigned long ext4_count_free_inodes (struct super_block *sb)
 
unsigned long ext4_count_dirs (struct super_block *sb)
 
int ext4_check_descriptors (struct super_block *sb)
 

Variables

PEXT2_GLOBAL Ext2Global
 
__u16 const crc16_table [256]
 

Macro Definition Documentation

◆ ext4_set_bit

#define ext4_set_bit (   n,
  p 
)    set_bit((int)(n), (unsigned long *)(p))

Definition at line 2754 of file generic.c.

◆ MAX_LFS_FILESIZE

#define MAX_LFS_FILESIZE   0x7fffffffffffffff

Definition at line 2250 of file generic.c.

Function Documentation

◆ crc16()

__u16 crc16 ( __u16  crc,
__u8 const buffer,
size_t  len 
)

Definition at line 2612 of file generic.c.

2613{
2614 while (len--)
2615 crc = crc16_byte(crc, *buffer++);
2616 return crc;
2617}
static __u16 crc16_byte(__u16 crc, const __u8 data)
Definition: generic.c:2607
GLuint buffer
Definition: glext.h:5915
GLenum GLsizei len
Definition: glext.h:6722

Referenced by ext4_group_desc_csum().

◆ crc16_byte()

static __u16 crc16_byte ( __u16  crc,
const __u8  data 
)
inlinestatic

Definition at line 2607 of file generic.c.

2608{
2609 return (crc >> 8) ^ crc16_table[(crc ^ data) & 0xff];
2610}
__u16 const crc16_table[256]
Definition: generic.c:2572
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950

Referenced by crc16().

◆ descriptor_loc()

ext3_fsblk_t descriptor_loc ( struct super_block sb,
ext3_fsblk_t  logical_sb_block,
unsigned int  nr 
)

Definition at line 2736 of file generic.c.

2738{
2739 struct ext3_sb_info *sbi = EXT3_SB(sb);
2740 ext3_group_t bg, first_meta_bg;
2741 int has_super = 0;
2742
2743 first_meta_bg = le32_to_cpu(sbi->s_es->s_first_meta_bg);
2744
2746 nr < first_meta_bg)
2747 return logical_sb_block + nr + 1;
2748 bg = sbi->s_desc_per_block * nr;
2749 if (ext3_bg_has_super(sb, bg))
2750 has_super = 1;
2751 return (has_super + ext3_group_first_block_no(sb, bg));
2752}
superblock * sb
Definition: btrfs.c:4261
#define EXT3_SB(sb)
Definition: ext3_fs.h:615
#define EXT3_HAS_INCOMPAT_FEATURE(sb, mask)
Definition: ext3_fs.h:649
#define EXT4_FEATURE_INCOMPAT_META_BG
Definition: ext3_fs.h:708
unsigned int ext3_group_t
Definition: ext3_fs_i.h:34
int ext3_bg_has_super(struct super_block *sb, ext3_group_t group)
Definition: generic.c:2686
#define le32_to_cpu
Definition: module.h:149
ULONG nr
Definition: thread.c:7
struct ext3_super_block * s_es
Definition: ext3_fs_sb.h:61
unsigned long s_desc_per_block
Definition: ext3_fs_sb.h:39

Referenced by Ext2LoadGroup().

◆ Ext2AddEntry()

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 at line 1879 of file generic.c.

1887{
1888 struct dentry *de = NULL;
1889
1891 OEM_STRING oem;
1892 int rc;
1893
1894 BOOLEAN MainResourceAcquired = FALSE;
1895
1896 if (!IsDirectory(Dcb)) {
1897 DbgBreak();
1899 }
1900
1901 ExAcquireResourceExclusiveLite(&Dcb->MainResource, TRUE);
1902 MainResourceAcquired = TRUE;
1903
1904 _SEH2_TRY {
1905
1906 Ext2ReferXcb(&Dcb->ReferenceCount);
1907 de = Ext2BuildEntry(Vcb, Dcb->Mcb, FileName);
1908 if (!de) {
1911 }
1912 de->d_inode = Inode;
1913
1914 rc = ext3_add_entry(IrpContext, de, Inode);
1915 status = Ext2WinntError(rc);
1916 if (NT_SUCCESS(status)) {
1917
1918 /* increase dir inode's nlink for .. */
1919 if (S_ISDIR(Inode->i_mode)) {
1920 ext3_inc_count(Dcb->Inode);
1921 ext3_mark_inode_dirty(IrpContext, Dcb->Inode);
1922 }
1923
1924 /* increase inode nlink reference */
1925 ext3_inc_count(Inode);
1926 ext3_mark_inode_dirty(IrpContext, Inode);
1927
1928 if (Dentry) {
1929 *Dentry = de;
1930 de = NULL;
1931 }
1932 }
1933
1934 } _SEH2_FINALLY {
1935
1936 Ext2DerefXcb(&Dcb->ReferenceCount);
1937
1938 if (MainResourceAcquired) {
1939 ExReleaseResourceLite(&Dcb->MainResource);
1940 }
1941
1942 if (de)
1943 Ext2FreeEntry(de);
1944 } _SEH2_END;
1945
1946 return status;
1947}
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
#define S_ISDIR(mode)
Definition: various.h:18
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB _Outptr_result_maybenull_ PDCB * Dcb
Definition: create.c:4140
#define ExAcquireResourceExclusiveLite(res, wait)
Definition: env_spec_w32.h:615
NTSTATUS Ext2WinntError(int rc)
Definition: misc.c:410
int ext3_mark_inode_dirty(struct ext2_icb *icb, struct inode *in)
Definition: htree.c:360
#define IsDirectory(Fcb)
Definition: ext2fs.h:283
#define Ext2ReferXcb(_C)
Definition: ext2fs.h:976
struct dentry * Ext2BuildEntry(PEXT2_VCB Vcb, PEXT2_MCB Dcb, PUNICODE_STRING FileName)
Definition: memory.c:444
int ext3_add_entry(struct ext2_icb *icb, struct dentry *dentry, struct inode *inode)
Definition: htree.c:1946
#define DbgBreak()
Definition: ext2fs.h:46
VOID Ext2FreeEntry(IN struct dentry *de)
Definition: memory.c:432
void ext3_inc_count(struct inode *inode)
Definition: htree.c:307
#define Ext2DerefXcb(_C)
Definition: ext2fs.h:977
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1822
#define Vcb
Definition: cdprocs.h:1415
#define _SEH2_FINALLY
Definition: pseh2_64.h:114
#define _SEH2_END
Definition: pseh2_64.h:155
#define _SEH2_TRY
Definition: pseh2_64.h:55
#define _SEH2_LEAVE
Definition: pseh2_64.h:167
Definition: fs.h:117
struct inode * d_inode
Definition: fs.h:123
Definition: ps.c:97
#define STATUS_NOT_A_DIRECTORY
Definition: udferr_usr.h:169
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
STRING OEM_STRING
Definition: umtypes.h:203

◆ Ext2ClearInode()

BOOLEAN Ext2ClearInode ( IN PEXT2_IRP_CONTEXT  IrpContext,
IN PEXT2_VCB  Vcb,
IN ULONG  Inode 
)

Definition at line 530 of file generic.c.

534{
535 LONGLONG Offset = 0;
536 BOOLEAN rc;
537
538 rc = Ext2GetInodeLba(Vcb, Inode, &Offset);
539 if (!rc) {
540 DEBUG(DL_ERR, ( "Ext2SaveInode: failed inode %u.\n", Inode));
541 goto errorout;
542 }
543
544 rc = Ext2ZeroBuffer(IrpContext, Vcb, Offset, Vcb->InodeSize);
545
546errorout:
547
548 return rc;
549}
#define DEBUG(args)
Definition: rdesktop.h:129
#define DL_ERR
Definition: ext2fs.h:1434
BOOLEAN Ext2ZeroBuffer(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN LONGLONG offset, IN ULONG size)
Definition: generic.c:795
BOOLEAN Ext2GetInodeLba(IN PEXT2_VCB Vcb, IN ULONG inode, OUT PLONGLONG offset)
Definition: generic.c:418
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
int64_t LONGLONG
Definition: typedefs.h:68

Referenced by Ext2CreateInode().

◆ Ext2DecodeInode()

void Ext2DecodeInode ( struct inode dst,
struct ext3_inode src 
)

Definition at line 452 of file generic.c.

453{
454 dst->i_mode = src->i_mode;
455 dst->i_flags = src->i_flags;
456 dst->i_uid = src->i_uid;
457 dst->i_gid = src->i_gid;
458 dst->i_nlink = src->i_links_count;
459 dst->i_generation = src->i_generation;
460 dst->i_size = src->i_size;
461 if (S_ISREG(src->i_mode)) {
462 dst->i_size |= (loff_t)src->i_size_high << 32;
463 }
464 dst->i_file_acl = src->i_file_acl_lo;
465 dst->i_file_acl |= (ext4_fsblk_t)src->osd2.linux2.l_i_file_acl_high << 32;
466 dst->i_atime = src->i_atime;
467 dst->i_ctime = src->i_ctime;
468 dst->i_mtime = src->i_mtime;
469 dst->i_dtime = src->i_dtime;
470 dst->i_blocks = ext3_inode_blocks(src, dst);
471 memcpy(&dst->i_block[0], &src->i_block[0], sizeof(__u32) * 15);
474 dst->i_extra_isize = src->i_extra_isize;
475 else
476 dst->i_extra_isize = 0;
477}
#define S_ISREG(mode)
Definition: various.h:17
u32 __u32
Definition: btrfs.h:19
unsigned __int64 loff_t
Definition: types.h:84
#define EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE
Definition: ext3_fs.h:702
#define EXT3_HAS_RO_COMPAT_FEATURE(sb, mask)
Definition: ext3_fs.h:647
unsigned long long ext4_fsblk_t
Definition: ext3_fs_i.h:27
blkcnt_t ext3_inode_blocks(struct ext3_inode *raw_inode, struct inode *inode)
Definition: generic.c:2395
GLenum src
Definition: glext.h:6340
GLenum GLenum dst
Definition: glext.h:6340
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878

Referenced by Ext2LoadInode().

◆ Ext2DropBH()

VOID Ext2DropBH ( IN PEXT2_VCB  Vcb)

Definition at line 266 of file generic.c.

267{
268 struct ext3_sb_info *sbi = &Vcb->sbi;
269
270 /* do nothing if Vcb is not initialized yet */
271 if (!IsFlagOn(Vcb->Flags, VCB_INITIALIZED))
272 return;
273
274 _SEH2_TRY {
275
276 /* acquire bd lock to avoid bh creation */
277 ExAcquireResourceExclusiveLite(&Vcb->bd.bd_bh_lock, TRUE);
278
281
282 while (!IsListEmpty(&Vcb->bd.bd_bh_free)) {
283 struct buffer_head *bh;
285 l = RemoveHeadList(&Vcb->bd.bd_bh_free);
286 bh = CONTAINING_RECORD(l, struct buffer_head, b_link);
288 if (0 == atomic_read(&bh->b_count)) {
289 buffer_head_remove(&Vcb->bd, bh);
291 }
292 }
293
294 } _SEH2_FINALLY {
295 ExReleaseResourceLite(&Vcb->bd.bd_bh_lock);
296 } _SEH2_END;
297
299}
#define atomic_read(v)
Definition: atomic.h:23
r l[0]
Definition: byte_order.h:168
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define ClearFlag(_F, _SF)
Definition: ext2fs.h:191
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
#define VCB_INITIALIZED
Definition: ext2fs.h:788
#define VCB_BEING_DROPPED
Definition: ext2fs.h:798
#define IsFlagOn(a, b)
Definition: ext2fs.h:177
VOID Ext2DropGroupBH(IN PEXT2_VCB Vcb)
Definition: generic.c:132
void free_buffer_head(struct buffer_head *bh)
Definition: linux.c:346
void buffer_head_remove(struct block_device *bdev, struct buffer_head *bh)
Definition: linux.c:424
Definition: typedefs.h:120
LIST_ENTRY b_link
Definition: module.h:724
atomic_t b_count
Definition: module.h:740
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260

Referenced by Ext2DestroyVcb(), Ext2FlushVcb(), and Ext2PurgeVolume().

◆ Ext2DropGroupBH()

VOID Ext2DropGroupBH ( IN PEXT2_VCB  Vcb)

Definition at line 132 of file generic.c.

133{
134 struct ext3_sb_info *sbi = &Vcb->sbi;
135 unsigned long i;
136
137 if (NULL == Vcb->sbi.s_gd) {
138 return;
139 }
140
141 for (i = 0; i < Vcb->sbi.s_gdb_count; i++) {
142 if (Vcb->sbi.s_gd[i].bh) {
143 fini_bh(&sbi->s_gd[i].bh);
144 Vcb->sbi.s_gd[i].bh = NULL;
145 }
146 }
147}
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
static void fini_bh(struct buffer_head **bh)
Definition: module.h:961
struct ext3_gd * s_gd
Definition: ext3_fs_sb.h:35

Referenced by Ext2DropBH(), and Ext2PutGroup().

◆ Ext2EncodeInode()

void Ext2EncodeInode ( struct ext3_inode dst,
struct inode src 
)

Definition at line 479 of file generic.c.

480{
481 dst->i_mode = src->i_mode;
482 dst->i_flags = src->i_flags;
483 dst->i_uid = src->i_uid;
484 dst->i_gid = src->i_gid;
485 dst->i_links_count = src->i_nlink;
486 dst->i_generation = src->i_generation;
487 dst->i_size = (__u32)src->i_size;
488 if (S_ISREG(src->i_mode)) {
489 dst->i_size_high = (__u32)(src->i_size >> 32);
490 }
491 dst->i_file_acl_lo = (__u32)src->i_file_acl;
492 dst->osd2.linux2.l_i_file_acl_high |= (__u16)(src->i_file_acl >> 32);
493 dst->i_atime = src->i_atime;
494 dst->i_ctime = src->i_ctime;
495 dst->i_mtime = src->i_mtime;
496 dst->i_dtime = src->i_dtime;
497 dst->i_extra_isize = src->i_extra_isize;
498 ASSERT(src->i_sb);
500 memcpy(&dst->i_block[0], &src->i_block[0], sizeof(__u32) * 15);
503 dst->i_extra_isize = src->i_extra_isize;
504}
u16 __u16
Definition: btrfs.h:18
int ext3_inode_blocks_set(struct ext3_inode *raw_inode, struct inode *inode)
Definition: generic.c:2418
if(dx< 0)
Definition: linetemp.h:194
#define ASSERT(a)
Definition: mode.c:44
#define __u32
Definition: types.h:15

Referenced by Ext2LoadInodeXattr(), and Ext2SaveInode().

◆ Ext2FlushRange()

VOID Ext2FlushRange ( IN PEXT2_VCB  Vcb,
LARGE_INTEGER  s,
LARGE_INTEGER  e 
)

Definition at line 303 of file generic.c.

304{
305 ULONG len;
306
307 if (e.QuadPart <= s.QuadPart)
308 return;
309
310 /* loop per 2G */
311 while (s.QuadPart < e.QuadPart) {
312 if (e.QuadPart > s.QuadPart + 1024 * 1024 * 1024) {
313 len = 1024 * 1024 * 1024;
314 } else {
315 len = (ULONG) (e.QuadPart - s.QuadPart);
316 }
317 CcFlushCache(&Vcb->SectionObject, &s, len, NULL);
318 s.QuadPart += len;
319 }
320}
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
GLdouble s
Definition: gl.h:2039
#define e
Definition: ke_i.h:82
uint32_t ULONG
Definition: typedefs.h:59

Referenced by Ext2FlushVcb().

◆ Ext2FlushVcb()

NTSTATUS Ext2FlushVcb ( IN PEXT2_VCB  Vcb)

Definition at line 323 of file generic.c.

324{
325 LARGE_INTEGER s = {0}, o;
326 struct ext3_sb_info *sbi = &Vcb->sbi;
327 struct rb_node *node;
328 struct buffer_head *bh;
329
330 if (!IsFlagOn(Vcb->Flags, VCB_GD_LOADED)) {
331 CcFlushCache(&Vcb->SectionObject, NULL, 0, NULL);
332 goto errorout;
333 }
334
336
337 _SEH2_TRY {
338
339 /* acqurie gd block */
340 ExAcquireResourceExclusiveLite(&Vcb->sbi.s_gd_lock, TRUE);
341
342 /* acquire bd lock to avoid bh creation */
343 ExAcquireResourceExclusiveLite(&Vcb->bd.bd_bh_lock, TRUE);
344
345 /* drop unused bh */
347
348 /* flush volume with all outstanding bh skipped */
349
350 node = rb_first(&Vcb->bd.bd_bh_root);
351 while (node) {
352
353 bh = container_of(node, struct buffer_head, b_rb_node);
354 node = rb_next(node);
355
356 o.QuadPart = bh->b_blocknr << BLOCK_BITS;
357 ASSERT(o.QuadPart >= s.QuadPart);
358
359 if (o.QuadPart == s.QuadPart) {
360 s.QuadPart = s.QuadPart + bh->b_size;
361 continue;
362 }
363
364 if (o.QuadPart > s.QuadPart) {
365 Ext2FlushRange(Vcb, s, o);
366 s.QuadPart = (bh->b_blocknr << BLOCK_BITS) + bh->b_size;
367 continue;
368 }
369 }
370
371 o = Vcb->PartitionInformation.PartitionLength;
372 Ext2FlushRange(Vcb, s, o);
373
374 } _SEH2_FINALLY {
375
376 ExReleaseResourceLite(&Vcb->bd.bd_bh_lock);
377 ExReleaseResourceLite(&Vcb->sbi.s_gd_lock);
378 } _SEH2_END;
379
380errorout:
381 return STATUS_SUCCESS;
382}
#define BLOCK_BITS
Definition: stream.h:22
struct rb_node * rb_first(struct rb_root *)
Definition: rbtree.c:294
struct rb_node * rb_next(struct rb_node *)
Definition: rbtree.c:320
#define VCB_GD_LOADED
Definition: ext2fs.h:796
VOID Ext2FlushRange(IN PEXT2_VCB Vcb, LARGE_INTEGER s, LARGE_INTEGER e)
Definition: generic.c:303
VOID Ext2DropBH(IN PEXT2_VCB Vcb)
Definition: generic.c:266
#define container_of(ptr, type, member)
Definition: glue.h:15
BOOLEAN NTAPI ExIsResourceAcquiredExclusiveLite(IN PERESOURCE Resource)
Definition: resource.c:1624
#define STATUS_SUCCESS
Definition: shellext.h:65
struct rb_node b_rb_node
Definition: module.h:741
size_t b_size
Definition: module.h:734
blkcnt_t b_blocknr
Definition: module.h:733
Definition: rbtree.h:98
Definition: dlist.c:348

Referenced by Ext2FloppyFlush(), and Ext2FlushVolume().

◆ Ext2FreeBlock()

NTSTATUS Ext2FreeBlock ( IN PEXT2_IRP_CONTEXT  IrpContext,
IN PEXT2_VCB  Vcb,
IN ULONG  Block,
IN ULONG  Number 
)

Definition at line 1217 of file generic.c.

1223{
1224 struct super_block *sb = &Vcb->sb;
1226 struct buffer_head *gb = NULL;
1227 ext4_fsblk_t bitmap_blk;
1228
1229 RTL_BITMAP BlockBitmap;
1231
1232 PBCB BitmapBcb;
1233 PVOID BitmapCache;
1234
1235 ULONG Group;
1236 ULONG Index;
1237 ULONG Length;
1238 ULONG Count;
1239
1241
1243
1244 DEBUG(DL_INF, ("Ext2FreeBlock: Block %xh - %x to be freed.\n",
1245 Block, Block + Number));
1246
1249
1250Again:
1251
1252 if (gb)
1253 fini_bh(&gb);
1254
1255 if ( Block < EXT2_FIRST_DATA_BLOCK ||
1256 Block >= TOTAL_BLOCKS ||
1257 Group >= Vcb->sbi.s_groups_count) {
1258
1259 DbgBreak();
1261
1262 } else {
1263
1264 gd = ext4_get_group_desc(sb, Group, &gb);
1265 if (!gd) {
1266 DbgBreak();
1268 goto errorout;
1269 }
1270 bitmap_blk = ext4_block_bitmap(sb, gd);
1271
1272 /* check the block is valid or not */
1273 if (bitmap_blk >= TOTAL_BLOCKS) {
1274 DbgBreak();
1276 goto errorout;
1277 }
1278
1279 /* get bitmap block offset and length */
1280 Offset.QuadPart = bitmap_blk;
1281 Offset.QuadPart = Offset.QuadPart << BLOCK_BITS;
1282
1283 if (Group == Vcb->sbi.s_groups_count - 1) {
1284
1286
1287 /* s_blocks_count is integer multiple of s_blocks_per_group */
1288 if (Length == 0) {
1290 }
1291
1292 } else {
1294 }
1295
1296 /* read and initialize bitmap */
1297 if (!CcPinRead( Vcb->Volume,
1298 &Offset,
1299 Vcb->BlockSize,
1300 PIN_WAIT,
1301 &BitmapBcb,
1302 &BitmapCache ) ) {
1303
1304 DEBUG(DL_ERR, ("Ext2FreeBlock: failed to PinLock bitmap block %xh.\n",
1305 bitmap_blk));
1307 DbgBreak();
1308 goto errorout;
1309 }
1310
1311 /* clear usused bits */
1312 RtlInitializeBitMap(&BlockBitmap, BitmapCache, Length);
1313 Count = min(Length - Index, Number);
1314 RtlClearBits(&BlockBitmap, Index, Count);
1315
1316 /* update group description table */
1317 ext4_free_blks_set(sb, gd, RtlNumberOfClearBits(&BlockBitmap));
1318
1319 /* indict the cache range is dirty */
1320 CcSetDirtyPinnedData(BitmapBcb, NULL );
1321 Ext2AddVcbExtent(Vcb, Offset.QuadPart, (LONGLONG)Vcb->BlockSize);
1322 CcUnpinData(BitmapBcb);
1323 BitmapBcb = NULL;
1324 BitmapCache = NULL;
1325 Ext2SaveGroup(IrpContext, Vcb, Group);
1326
1327 /* remove dirty MCB to prevent Volume's lazy writing. */
1328 if (Ext2RemoveBlockExtent(Vcb, NULL, Block, Count)) {
1329 } else {
1330 DbgBreak();
1332 }
1333
1334 /* save super block (used/unused blocks statics) */
1335 Ext2UpdateVcbStat(IrpContext, Vcb);
1336
1337 /* try next group to clear all remaining */
1338 Number -= Count;
1339 if (Number) {
1340 Group += 1;
1341 if (Group < Vcb->sbi.s_groups_count) {
1342 Index = 0;
1343 Block += Count;
1344 goto Again;
1345 } else {
1346 DEBUG(DL_ERR, ("Ext2FreeBlock: block number beyonds max group.\n"));
1347 goto errorout;
1348 }
1349 }
1350 }
1351
1353
1354errorout:
1355
1356 if (gb)
1357 fini_bh(&gb);
1358
1359 ExReleaseResourceLite(&Vcb->MetaBlock);
1360
1361 return Status;
1362}
VOID NTAPI CcSetDirtyPinnedData(IN PVOID BcbVoid, IN OPTIONAL PLARGE_INTEGER Lsn)
Definition: cachesub.c:121
#define RtlClearBits
Definition: dbgbitmap.h:331
#define RtlInitializeBitMap
Definition: dbgbitmap.h:326
#define RtlNumberOfClearBits
Definition: dbgbitmap.h:342
#define EXT2_FIRST_DATA_BLOCK
Definition: ext2fs.h:103
#define TOTAL_BLOCKS
Definition: ext2fs.h:101
#define DL_INF
Definition: ext2fs.h:1436
BOOLEAN Ext2RemoveBlockExtent(IN PEXT2_VCB Vcb, IN PEXT2_MCB Mcb, IN ULONG Start, IN ULONG Number)
Definition: memory.c:1097
#define BLOCKS_PER_GROUP
Definition: ext2fs.h:100
BOOLEAN Ext2AddVcbExtent(IN PEXT2_VCB Vcb, IN LONGLONG Vbn, IN LONGLONG Length)
Definition: memory.c:648
Status
Definition: gdiplustypes.h:25
ext4_fsblk_t ext4_block_bitmap(struct super_block *sb, struct ext4_group_desc *bg)
Definition: generic.c:2459
struct ext4_group_desc * ext4_get_group_desc(struct super_block *sb, ext4_group_t block_group, struct buffer_head **bh)
Definition: generic.c:2976
void ext4_free_blks_set(struct super_block *sb, struct ext4_group_desc *bg, __u32 count)
Definition: generic.c:2539
VOID Ext2UpdateVcbStat(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb)
Definition: generic.c:997
BOOLEAN Ext2SaveGroup(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN ULONG Group)
Definition: generic.c:386
#define min(a, b)
Definition: monoChain.cc:55
_In_opt_ PSID Group
Definition: rtlfuncs.h:1658
int Count
Definition: noreturn.cpp:7
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define PIN_WAIT
_In_opt_ PENTER_STATE_SYSTEM_HANDLER _In_opt_ PVOID _In_ LONG _In_opt_ LONG volatile * Number
Definition: ntpoapi.h:207
#define STATUS_CANT_WAIT
Definition: ntstatus.h:452
VOID NTAPI CcUnpinData(IN PVOID Bcb)
Definition: pinsup.c:955
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
Definition: fs.h:64
#define STATUS_DISK_CORRUPT_ERROR
Definition: udferr_usr.h:147
_In_ WDFCOLLECTION _In_ ULONG Index

Referenced by Ext2ExpandLast(), Ext2TruncateBlock(), Ext2TruncateIndirectFast(), and ext4_free_blocks().

◆ Ext2FreeInode()

NTSTATUS Ext2FreeInode ( IN PEXT2_IRP_CONTEXT  IrpContext,
IN PEXT2_VCB  Vcb,
IN ULONG  Inode,
IN ULONG  Type 
)

Definition at line 1766 of file generic.c.

1772{
1773 struct super_block *sb = &Vcb->sb;
1775 struct buffer_head *gb = NULL;
1776 struct buffer_head *bh = NULL;
1777 ext4_fsblk_t bitmap_blk;
1778
1779 RTL_BITMAP InodeBitmap;
1780 ULONG Group;
1781 ULONG Length;
1783
1784 ULONG dwIno;
1785 BOOLEAN bModified = FALSE;
1786
1788
1790
1791 Group = (Inode - 1) / INODES_PER_GROUP;
1792 dwIno = (Inode - 1) % INODES_PER_GROUP;
1793
1794 DEBUG(DL_INF, ( "Ext2FreeInode: Inode: %xh (Group/Off = %xh/%xh)\n",
1795 Inode, Group, dwIno));
1796
1797 if (Group >= Vcb->sbi.s_groups_count) {
1798 DbgBreak();
1799 goto errorout;
1800 }
1801
1802 gd = ext4_get_group_desc(sb, Group, &gb);
1803 if (!gd) {
1804 DbgBreak();
1806 goto errorout;
1807 }
1808
1809 bitmap_blk = ext4_inode_bitmap(sb, gd);
1810 bh = sb_getblk(sb, bitmap_blk);
1811 if (!bh) {
1812 DbgBreak();
1814 goto errorout;
1815 }
1816 if (!buffer_uptodate(bh)) {
1817 int err = bh_submit_read(bh);
1818 if (err < 0) {
1819 DbgPrint("bh_submit_read error! err: %d\n", err);
1821 goto errorout;
1822 }
1823 }
1824
1825 if (Group == Vcb->sbi.s_groups_count - 1) {
1826
1828 if (!Length) {
1829 /* s_inodes_count is integer multiple of s_inodes_per_group */
1831 }
1832 } else {
1834 }
1835
1836 RtlInitializeBitMap(&InodeBitmap, (PULONG)bh->b_data, Length);
1837
1838 if (RtlCheckBit(&InodeBitmap, dwIno) == 0) {
1839 DbgBreak();
1841 } else {
1842 RtlClearBits(&InodeBitmap, dwIno, 1);
1843 bModified = TRUE;
1844 }
1845
1846 if (bModified) {
1847 /* update group free inodes */
1849 RtlNumberOfClearBits(&InodeBitmap));
1850
1851 /* set inode block dirty and add to vcb dirty range */
1853
1854 /* update group_desc and super_block */
1855 if (Type == EXT2_FT_DIR) {
1857 ext4_used_dirs_count(sb, gd) - 1);
1858 }
1859 Ext2SaveGroup(IrpContext, Vcb, Group);
1860 Ext2UpdateVcbStat(IrpContext, Vcb);
1862 }
1863
1864errorout:
1865
1866 ExReleaseResourceLite(&Vcb->MetaInode);
1867
1868 if (bh)
1869 fini_bh(&bh);
1870
1871 if (gb)
1872 fini_bh(&gb);
1873
1874 return Status;
1875}
Type
Definition: Type.h:7
#define RtlCheckBit
Definition: dbgbitmap.h:349
#define INODES_PER_GROUP
Definition: ext2fs.h:99
#define INODES_COUNT
Definition: ext2fs.h:97
void ext4_used_dirs_set(struct super_block *sb, struct ext4_group_desc *bg, __u32 count)
Definition: generic.c:2555
ext4_fsblk_t ext4_inode_bitmap(struct super_block *sb, struct ext4_group_desc *bg)
Definition: generic.c:2467
__u32 ext4_used_dirs_count(struct super_block *sb, struct ext4_group_desc *bg)
Definition: generic.c:2499
void ext4_free_inodes_set(struct super_block *sb, struct ext4_group_desc *bg, __u32 count)
Definition: generic.c:2547
#define DbgPrint
Definition: hal.h:12
int bh_submit_read(struct buffer_head *bh)
Definition: linux.c:892
static struct buffer_head * sb_getblk(struct super_block *sb, sector_t block)
Definition: module.h:976
void mark_buffer_dirty(struct buffer_head *bh)
Definition: linux.c:914
#define err(...)
#define EXT2_FT_DIR
Definition: ext2_fs.h:531
char * b_data
Definition: module.h:735
uint32_t * PULONG
Definition: typedefs.h:59

Referenced by Ext2CreateInode(), and Ext2DeleteFile().

◆ Ext2GetInodeLba()

BOOLEAN Ext2GetInodeLba ( IN PEXT2_VCB  Vcb,
IN ULONG  inode,
OUT PLONGLONG  offset 
)

Definition at line 418 of file generic.c.

423{
425 struct buffer_head *bh = NULL;
426 ext4_fsblk_t loc;
427 int group;
428
429 if (inode < 1 || inode > INODES_COUNT) {
430 DEBUG(DL_ERR, ( "Ext2GetInodeLba: Inode value %xh is invalid.\n",inode));
431 *offset = 0;
432 return FALSE;
433 }
434
435 group = (inode - 1) / INODES_PER_GROUP ;
436 gd = ext4_get_group_desc(&Vcb->sb, group, &bh);
437 if (!bh) {
438 *offset = 0;
439 DbgBreak();
440 return FALSE;
441 }
442 loc = (LONGLONG)ext4_inode_table(&Vcb->sb, gd);
443 loc = loc << BLOCK_BITS;
444 loc = loc + ((inode - 1) % INODES_PER_GROUP) * Vcb->InodeSize;
445
446 *offset = loc;
447 __brelse(bh);
448
449 return TRUE;
450}
ext4_fsblk_t ext4_inode_table(struct super_block *sb, struct ext4_group_desc *bg)
Definition: generic.c:2475
GLboolean GLuint group
Definition: glext.h:11120
GLintptr offset
Definition: glext.h:5920
void __brelse(struct buffer_head *)
Definition: linux.c:808
Definition: fs.h:78

Referenced by Ext2ClearInode(), Ext2LoadInode(), Ext2LoadInodeXattr(), Ext2SaveInode(), and Ext2SaveInodeXattr().

◆ Ext2LoadBlock()

BOOLEAN Ext2LoadBlock ( IN PEXT2_VCB  Vcb,
IN ULONG  Index,
IN PVOID  Buffer 
)

Definition at line 659 of file generic.c.

662{
663 struct buffer_head *bh = NULL;
664 BOOLEAN rc = 0;
665
666 _SEH2_TRY {
667
668 bh = sb_getblk(&Vcb->sb, (sector_t)Index);
669
670 if (!bh) {
671 DEBUG(DL_ERR, ("Ext2Loadblock: can't load block %u\n", Index));
672 DbgBreak();
674 }
675
676 if (!buffer_uptodate(bh)) {
677 int err = bh_submit_read(bh);
678 if (err < 0) {
679 DEBUG(DL_ERR, ("Ext2LoadBlock: reading failed %d\n", err));
681 }
682 }
683
685 rc = TRUE;
686
687 } _SEH2_FINALLY {
688
689 if (bh)
690 fini_bh(&bh);
691 } _SEH2_END;
692
693 return rc;
694}
Definition: bufpool.h:45
#define BLOCK_SIZE
Definition: dlist.c:220
unsigned __int64 sector_t
Definition: types.h:82
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263

◆ Ext2LoadBuffer()

BOOLEAN Ext2LoadBuffer ( IN PEXT2_IRP_CONTEXT  IrpContext,
IN PEXT2_VCB  Vcb,
IN LONGLONG  offset,
IN ULONG  size,
IN PVOID  buf 
)

Definition at line 733 of file generic.c.

738{
739 struct buffer_head *bh = NULL;
740 BOOLEAN rc;
741
742 _SEH2_TRY {
743
744 while (size) {
745
747 ULONG len = 0, delta = 0;
748
750 delta = (ULONG)offset & (BLOCK_SIZE - 1);
751 len = BLOCK_SIZE - delta;
752 if (size < len)
753 len = size;
754
755 bh = sb_getblk(&Vcb->sb, block);
756 if (!bh) {
757 DEBUG(DL_ERR, ("Ext2SaveBuffer: can't load block %I64u\n", block));
758 DbgBreak();
760 }
761
762 if (!buffer_uptodate(bh)) {
763 int err = bh_submit_read(bh);
764 if (err < 0) {
765 DEBUG(DL_ERR, ("Ext2SaveBuffer: bh_submit_read failed: %d\n", err));
767 }
768 }
769
770 _SEH2_TRY {
771 RtlCopyMemory(buf, bh->b_data + delta, len);
772 } _SEH2_FINALLY {
773 fini_bh(&bh);
774 } _SEH2_END;
775
776 buf = (PUCHAR)buf + len;
777 offset = offset + len;
778 size = size - len;
779 }
780
781 rc = TRUE;
782
783 } _SEH2_FINALLY {
784
785 if (bh)
786 fini_bh(&bh);
787
788 } _SEH2_END;
789
790 return rc;
791}
GLsizeiptr size
Definition: glext.h:5919
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
unsigned char * PUCHAR
Definition: typedefs.h:53
static unsigned int block
Definition: xmlmemory.c:101

Referenced by Ext2LoadInode(), and Ext2SaveInode().

◆ Ext2LoadGroup()

BOOLEAN Ext2LoadGroup ( IN PEXT2_VCB  Vcb)

Definition at line 207 of file generic.c.

208{
209 struct super_block *sb = &Vcb->sb;
210 struct ext3_sb_info *sbi = &Vcb->sbi;
211 ext3_fsblk_t sb_block = 1;
212 unsigned long i;
213 BOOLEAN rc = FALSE;
214
215 _SEH2_TRY {
216
217 ExAcquireResourceExclusiveLite(&Vcb->sbi.s_gd_lock, TRUE);
218
219 if (NULL == sbi->s_gd) {
220 sbi->s_gd = kzalloc(sbi->s_gdb_count * sizeof(struct ext3_gd),
221 GFP_KERNEL);
222 }
223 if (sbi->s_gd == NULL) {
224 DEBUG(DL_ERR, ("Ext2LoadGroup: not enough memory.\n"));
226 }
227
229 sb_block = EXT4_MIN_BLOCK_SIZE / BLOCK_SIZE;
230 }
231
232 for (i = 0; i < sbi->s_gdb_count; i++) {
233 sbi->s_gd[i].block = descriptor_loc(sb, sb_block, i);
234 if (!sbi->s_gd[i].block) {
235 DEBUG(DL_ERR, ("Ext2LoadGroup: can't locate group descriptor %d\n", i));
237 }
238 }
239
240 if (!Ext2LoadGroupBH(Vcb)) {
241 DEBUG(DL_ERR, ("Ext2LoadGroup: Failed to load group descriptions !\n"));
243 }
244
246 DbgBreak();
247 DEBUG(DL_ERR, ("Ext2LoadGroup: group descriptors corrupted !\n"));
249 }
250
251 SetFlag(Vcb->Flags, VCB_GD_LOADED);
252 rc = TRUE;
253
254 } _SEH2_FINALLY {
255
256 if (!rc)
258
259 ExReleaseResourceLite(&Vcb->sbi.s_gd_lock);
260 } _SEH2_END;
261
262 return rc;
263}
#define EXT4_MIN_BLOCK_SIZE
Definition: ext3_fs.h:169
#define EXT3_MIN_BLOCK_SIZE
Definition: ext3_fs.h:75
unsigned long long ext3_fsblk_t
Definition: ext3_fs_i.h:26
BOOLEAN Ext2LoadGroupBH(IN PEXT2_VCB Vcb)
Definition: generic.c:170
int ext4_check_descriptors(struct super_block *sb)
Definition: generic.c:3091
VOID Ext2PutGroup(IN PEXT2_VCB Vcb)
Definition: generic.c:150
ext3_fsblk_t descriptor_loc(struct super_block *sb, ext3_fsblk_t logical_sb_block, unsigned int nr)
Definition: generic.c:2736
#define GFP_KERNEL
Definition: module.h:668
void * kzalloc(int size, int flags)
Definition: linux.c:34
unsigned long s_gdb_count
Definition: ext3_fs_sb.h:38

Referenced by Ext2InitializeVcb(), and ext4_get_group_desc().

◆ Ext2LoadGroupBH()

BOOLEAN Ext2LoadGroupBH ( IN PEXT2_VCB  Vcb)

Definition at line 170 of file generic.c.

171{
172 struct super_block *sb = &Vcb->sb;
173 struct ext3_sb_info *sbi = &Vcb->sbi;
174 unsigned long i;
175 BOOLEAN rc = FALSE;
176
177 _SEH2_TRY {
178
179 ExAcquireResourceExclusiveLite(&Vcb->sbi.s_gd_lock, TRUE);
180 ASSERT (NULL != sbi->s_gd);
181
182 for (i = 0; i < sbi->s_gdb_count; i++) {
183 ASSERT (sbi->s_gd[i].block);
184 if (sbi->s_gd[i].bh)
185 continue;
186 sbi->s_gd[i].bh = sb_getblk(sb, sbi->s_gd[i].block);
187 if (!sbi->s_gd[i].bh) {
188 DEBUG(DL_ERR, ("Ext2LoadGroupBH: can't read group descriptor %d\n", i));
189 DbgBreak();
191 }
192 sbi->s_gd[i].gd = (struct ext4_group_desc *)sbi->s_gd[i].bh->b_data;
193 }
194
195 rc = TRUE;
196
197 } _SEH2_FINALLY {
198
199 ExReleaseResourceLite(&Vcb->sbi.s_gd_lock);
200 } _SEH2_END;
201
202 return rc;
203}

Referenced by Ext2LoadGroup(), and ext4_get_group_desc().

◆ Ext2LoadInode()

BOOLEAN Ext2LoadInode ( IN PEXT2_VCB  Vcb,
IN struct inode Inode 
)

Definition at line 508 of file generic.c.

510{
511 struct ext3_inode ext3i = {0};
513
514 if (!Ext2GetInodeLba(Vcb, Inode->i_ino, &offset)) {
515 DEBUG(DL_ERR, ("Ext2LoadInode: failed inode %u.\n", Inode->i_ino));
516 return FALSE;
517 }
518
519 if (!Ext2LoadBuffer(NULL, Vcb, offset, sizeof(ext3i), &ext3i)) {
520 return FALSE;
521 }
522
523 Ext2DecodeInode(Inode, &ext3i);
524
525 return TRUE;
526}
void Ext2DecodeInode(struct inode *dst, struct ext3_inode *src)
Definition: generic.c:452
BOOLEAN Ext2LoadBuffer(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN LONGLONG offset, IN ULONG size, IN PVOID buf)
Definition: generic.c:733

Referenced by Ext2InitializeVcb(), Ext2LoadInternalJournal(), Ext2LookupFile(), Ext2ProcessEntry(), and Ext2RefreshSuper().

◆ Ext2LoadInodeXattr()

BOOLEAN Ext2LoadInodeXattr ( IN PEXT2_VCB  Vcb,
IN struct inode Inode,
IN PEXT2_INODE  InodeXattr 
)

Definition at line 590 of file generic.c.

593{
596
597 if (!Ext2GetInodeLba(Vcb, Inode->i_ino, &Offset)) {
598 DEBUG(DL_ERR, ("Ext2LoadRawInode: error get inode(%xh)'s addr.\n", Inode->i_ino));
599 return FALSE;
600 }
601
602 if (!CcCopyRead(
603 Vcb->Volume,
605 Vcb->InodeSize,
606 PIN_WAIT,
607 (PVOID)InodeXattr,
608 &IoStatus)) {
609 return FALSE;
610 }
611
612 if (!NT_SUCCESS(IoStatus.Status)) {
613 return FALSE;
614 }
615
616 Ext2EncodeInode(InodeXattr, Inode);
617 return TRUE;
618}
void Ext2EncodeInode(struct ext3_inode *dst, struct inode *src)
Definition: generic.c:479
__in UCHAR __in POWER_STATE __in_opt PVOID __in PIO_STATUS_BLOCK IoStatus
Definition: mxum.h:159
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

Referenced by ext4_fs_get_xattr_ref().

◆ Ext2LoadSuper()

NTSTATUS Ext2LoadSuper ( IN PEXT2_VCB  Vcb,
IN BOOLEAN  bVerify,
OUT PEXT2_SUPER_BLOCK Sb 
)

Definition at line 29 of file generic.c.

32{
34 PEXT2_SUPER_BLOCK Ext2Sb = NULL;
35
36 Ext2Sb = (PEXT2_SUPER_BLOCK)
41 );
42 if (!Ext2Sb) {
44 goto errorout;
45 }
46
48 Vcb,
51 (PVOID) Ext2Sb,
52 bVerify );
53
54 if (!NT_SUCCESS(Status)) {
56 Ext2Sb = NULL;
57 }
58
59errorout:
60
61 *Sb = Ext2Sb;
62 return Status;
63}
#define PagedPool
Definition: env_spec_w32.h:308
struct ext2_sblock * PEXT2_SUPER_BLOCK
Definition: ext2.h:171
VOID Ext2FreePool(IN PVOID P, IN ULONG Tag)
Definition: debug.c:2697
PVOID Ext2AllocatePool(IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes, IN ULONG Tag)
Definition: debug.c:2684
#define SUPER_BLOCK_SIZE
Definition: ext2fs.h:86
#define EXT2_SB_MAGIC
Definition: ext2fs.h:302
NTSTATUS Ext2ReadDisk(IN PEXT2_VCB Vcb, IN ULONGLONG Offset, IN ULONG Size, IN PVOID Buffer, IN BOOLEAN bVerify)
Definition: block.c:559
#define SUPER_BLOCK_OFFSET
Definition: ext2fs.h:85
uint64_t ULONGLONG
Definition: typedefs.h:67
static BOOL bVerify
Definition: verify.c:27

Referenced by Ext2MountVolume(), and Ext2VerifyVolume().

◆ Ext2NewBlock()

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 at line 1008 of file generic.c.

1016{
1017 struct super_block *sb = &Vcb->sb;
1019 struct buffer_head *gb = NULL;
1020 struct buffer_head *bh = NULL;
1021 ext4_fsblk_t bitmap_blk;
1022
1023 RTL_BITMAP BlockBitmap;
1024
1025 ULONG Group = 0;
1026 ULONG Index = 0xFFFFFFFF;
1027 ULONG dwHint = 0;
1028 ULONG Count = 0;
1029 ULONG Length = 0;
1030
1032
1033 *Block = 0;
1034
1036
1037 /* validate the hint group and hint block */
1038 if (GroupHint >= Vcb->sbi.s_groups_count) {
1039 DbgBreak();
1040 GroupHint = Vcb->sbi.s_groups_count - 1;
1041 }
1042
1043 if (BlockHint != 0) {
1044 GroupHint = (BlockHint - EXT2_FIRST_DATA_BLOCK) / BLOCKS_PER_GROUP;
1045 dwHint = (BlockHint - EXT2_FIRST_DATA_BLOCK) % BLOCKS_PER_GROUP;
1046 }
1047
1048 Group = GroupHint;
1049
1050Again:
1051
1052 if (bh)
1053 fini_bh(&bh);
1054
1055 if (gb)
1056 fini_bh(&gb);
1057
1058 gd = ext4_get_group_desc(sb, Group, &gb);
1059 if (!gd) {
1060 DbgBreak();
1062 goto errorout;
1063 }
1064
1065 bitmap_blk = ext4_block_bitmap(sb, gd);
1066
1067 if (gd->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
1068 bh = sb_getblk_zero(sb, bitmap_blk);
1069 if (!bh) {
1070 DbgBreak();
1072 goto errorout;
1073 }
1074 gd->bg_checksum = ext4_group_desc_csum(EXT3_SB(sb), Group, gd);
1076 set_buffer_uptodate(bh);
1077 gd->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT);
1078 Ext2SaveGroup(IrpContext, Vcb, Group);
1079 } else {
1080 bh = sb_getblk(sb, bitmap_blk);
1081 if (!bh) {
1082 DbgBreak();
1084 goto errorout;
1085 }
1086 }
1087
1088 if (!buffer_uptodate(bh)) {
1089 int err = bh_submit_read(bh);
1090 if (err < 0) {
1091 DbgPrint("bh_submit_read error! err: %d\n", err);
1093 goto errorout;
1094 }
1095 }
1096
1097 if (ext4_free_blks_count(sb, gd)) {
1098
1099 if (Group == Vcb->sbi.s_groups_count - 1) {
1100
1102
1103 /* s_blocks_count is integer multiple of s_blocks_per_group */
1104 if (Length == 0) {
1106 }
1107 } else {
1109 }
1110
1111 /* initialize bitmap buffer */
1112 RtlInitializeBitMap(&BlockBitmap, (PULONG)bh->b_data, Length);
1113
1114 /* try to find a clear bit range */
1115 Index = RtlFindClearBits(&BlockBitmap, *Number, dwHint);
1116
1117 /* We could not get new block in the prefered group */
1118 if (Index == 0xFFFFFFFF) {
1119
1120 /* search clear bits from the hint block */
1121 Count = RtlFindNextForwardRunClear(&BlockBitmap, dwHint, &Index);
1122 if (dwHint != 0 && Count == 0) {
1123 /* search clear bits from the very beginning */
1124 Count = RtlFindNextForwardRunClear(&BlockBitmap, 0, &Index);
1125 }
1126
1127 if (Count == 0) {
1128
1129 RtlZeroMemory(&BlockBitmap, sizeof(RTL_BITMAP));
1130
1131 /* no blocks found: set bg_free_blocks_count to 0 */
1132 ext4_free_blks_set(sb, gd, 0);
1133 Ext2SaveGroup(IrpContext, Vcb, Group);
1134
1135 /* will try next group */
1136 goto Again;
1137
1138 } else {
1139
1140 /* we got free blocks */
1141 if (Count <= *Number) {
1142 *Number = Count;
1143 }
1144 }
1145 }
1146
1147 } else {
1148
1149 /* try next group */
1150 dwHint = 0;
1151 Group = (Group + 1) % Vcb->sbi.s_groups_count;
1152 if (Group != GroupHint) {
1153 goto Again;
1154 }
1155
1156 Index = 0xFFFFFFFF;
1157 }
1158
1159 if (Index < Length) {
1160
1161 /* mark block bits as allocated */
1162 RtlSetBits(&BlockBitmap, Index, *Number);
1163
1164 /* set block bitmap dirty in cache */
1166
1167 /* update group description */
1168 ext4_free_blks_set(sb, gd, RtlNumberOfClearBits(&BlockBitmap));
1169 Ext2SaveGroup(IrpContext, Vcb, Group);
1170
1171 /* update Vcb free blocks */
1172 Ext2UpdateVcbStat(IrpContext, Vcb);
1173
1174 /* validate the new allocated block number */
1176 if (*Block >= TOTAL_BLOCKS || *Block + *Number > TOTAL_BLOCKS) {
1177 DbgBreak();
1178 dwHint = 0;
1179 goto Again;
1180 }
1181
1182 if (ext4_block_bitmap(sb, gd) == *Block ||
1183 ext4_inode_bitmap(sb, gd) == *Block ||
1184 ext4_inode_table(sb, gd) == *Block ) {
1185 DbgBreak();
1186 dwHint = 0;
1187 goto Again;
1188 }
1189
1190 /* Always remove dirty MCB to prevent Volume's lazy writing.
1191 Metadata blocks will be re-added during modifications.*/
1192 if (Ext2RemoveBlockExtent(Vcb, NULL, *Block, *Number)) {
1193 } else {
1194 DbgBreak();
1196 }
1197
1198 DEBUG(DL_INF, ("Ext2NewBlock: Block %xh - %x allocated.\n",
1199 *Block, *Block + *Number));
1201 }
1202
1203errorout:
1204
1205 ExReleaseResourceLite(&Vcb->MetaBlock);
1206
1207 if (bh)
1208 fini_bh(&bh);
1209
1210 if (gb)
1211 fini_bh(&gb);
1212
1213 return Status;
1214}
#define RtlFindClearBits
Definition: dbgbitmap.h:332
#define RtlFindNextForwardRunClear
Definition: dbgbitmap.h:338
#define RtlSetBits
Definition: dbgbitmap.h:345
#define EXT4_BG_BLOCK_UNINIT
Definition: ext3_fs.h:734
__le16 ext4_group_desc_csum(struct ext3_sb_info *sbi, __u32 block_group, struct ext4_group_desc *gdp)
Definition: generic.c:2619
__u32 ext4_free_blks_count(struct super_block *sb, struct ext4_group_desc *bg)
Definition: generic.c:2483
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:2877
static struct buffer_head * sb_getblk_zero(struct super_block *sb, sector_t block)
Definition: module.h:982
#define cpu_to_le16
Definition: module.h:150
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define STATUS_DISK_FULL
Definition: udferr_usr.h:155

Referenced by Ext2ExpandLast(), and ext4_new_meta_blocks().

◆ Ext2NewInode()

NTSTATUS Ext2NewInode ( IN PEXT2_IRP_CONTEXT  IrpContext,
IN PEXT2_VCB  Vcb,
IN ULONG  GroupHint,
IN ULONG  Type,
OUT PULONG  Inode 
)

Definition at line 1366 of file generic.c.

1373{
1374 struct super_block *sb = &Vcb->sb;
1376 struct buffer_head *gb = NULL;
1377 struct buffer_head *bh = NULL;
1378 ext4_fsblk_t bitmap_blk;
1379
1380 RTL_BITMAP InodeBitmap;
1381
1382 ULONG Group, i, j;
1383 ULONG Average, Length;
1384
1385 ULONG dwInode;
1386
1388
1389 *Inode = dwInode = 0XFFFFFFFF;
1390
1392
1393 if (GroupHint >= Vcb->sbi.s_groups_count)
1394 GroupHint = GroupHint % Vcb->sbi.s_groups_count;
1395
1396repeat:
1397
1398 if (bh)
1399 fini_bh(&bh);
1400
1401 if (gb)
1402 fini_bh(&gb);
1403
1404 Group = i = 0;
1405 gd = NULL;
1406
1407 if (Type == EXT2_FT_DIR) {
1408
1409 Average = Vcb->SuperBlock->s_free_inodes_count / Vcb->sbi.s_groups_count;
1410
1411 for (j = 0; j < Vcb->sbi.s_groups_count; j++) {
1412
1413 i = (j + GroupHint) % (Vcb->sbi.s_groups_count);
1414 gd = ext4_get_group_desc(sb, i, &gb);
1415 if (!gd) {
1416 DbgBreak();
1418 goto errorout;
1419 }
1420
1421 if ((gd->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT)) ||
1422 (ext4_used_dirs_count(sb, gd) << 8 <
1423 ext4_free_inodes_count(sb, gd)) ) {
1424 Group = i + 1;
1425 break;
1426 }
1427 fini_bh(&gb);
1428 }
1429
1430 if (!Group) {
1431
1433
1434 gd = NULL;
1435
1436 /* get the group with the biggest vacancy */
1437 for (j = 0; j < Vcb->sbi.s_groups_count; j++) {
1438
1439 struct buffer_head *gt = NULL;
1440 desc = ext4_get_group_desc(sb, j, &gt);
1441 if (!desc) {
1442 DbgBreak();
1444 goto errorout;
1445 }
1446
1447 /* return the group if it's not initialized yet */
1448 if (desc->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT)) {
1449 Group = j + 1;
1450 gd = desc;
1451
1452 if (gb)
1453 fini_bh(&gb);
1454 gb = gt;
1455 gt = NULL;
1456 break;
1457 }
1458
1459 if (!gd) {
1460 if (ext4_free_inodes_count(sb, desc) > 0) {
1461 Group = j + 1;
1462 gd = desc;
1463 if (gb)
1464 fini_bh(&gb);
1465 gb = gt;
1466 gt = NULL;
1467 }
1468 } else {
1471 Group = j + 1;
1472 gd = desc;
1473 if (gb)
1474 fini_bh(&gb);
1475 gb = gt;
1476 gt = NULL;
1477 break;
1478 }
1479 }
1480 if (gt)
1481 fini_bh(&gt);
1482 }
1483 }
1484
1485 } else {
1486
1487 /*
1488 * Try to place the inode in its parent directory (GroupHint)
1489 */
1490
1491 gd = ext4_get_group_desc(sb, GroupHint, &gb);
1492 if (!gb) {
1493 DbgBreak();
1495 goto errorout;
1496 }
1497
1498 if (gd->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT) ||
1500
1501 Group = GroupHint + 1;
1502
1503 } else {
1504
1505 /* this group is 100% cocucpied */
1506 fini_bh(&gb);
1507
1508 i = GroupHint;
1509
1510 /*
1511 * Use a quadratic hash to find a group with a free inode
1512 */
1513
1514 for (j = 1; j < Vcb->sbi.s_groups_count; j <<= 1) {
1515
1516
1517 i = (i + j) % Vcb->sbi.s_groups_count;
1518 gd = ext4_get_group_desc(sb, i, &gb);
1519 if (!gd) {
1520 DbgBreak();
1522 goto errorout;
1523 }
1524
1525 if (gd->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT) ||
1527 Group = i + 1;
1528 break;
1529 }
1530
1531 fini_bh(&gb);
1532 }
1533 }
1534
1535 if (!Group) {
1536 /*
1537 * That failed: try linear search for a free inode
1538 */
1539 i = GroupHint;
1540 for (j = 2; j < Vcb->sbi.s_groups_count; j++) {
1541
1542 i = (i + 1) % Vcb->sbi.s_groups_count;
1543 gd = ext4_get_group_desc(sb, i, &gb);
1544 if (!gd) {
1545 DbgBreak();
1547 goto errorout;
1548 }
1549
1550 if (gd->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT) ||
1552 Group = i + 1;
1553 break;
1554 }
1555
1556 fini_bh(&gb);
1557 }
1558 }
1559 }
1560
1561 if (gd == NULL || Group == 0) {
1562 goto errorout;
1563 }
1564
1565 /* finally we got the group, but is it valid ? */
1566 if (Group > Vcb->sbi.s_groups_count) {
1567 DbgBreak();
1568 goto errorout;
1569 }
1570
1571 /* valid group number starts from 1, not 0 */
1572 Group -= 1;
1573
1574 ASSERT(gd);
1575 bitmap_blk = ext4_inode_bitmap(sb, gd);
1576 /* check the block is valid or not */
1577 if (bitmap_blk == 0 || bitmap_blk >= TOTAL_BLOCKS) {
1578 DbgBreak();
1580 goto errorout;
1581 }
1582
1583 if (gd->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT)) {
1584 bh = sb_getblk_zero(sb, bitmap_blk);
1585 if (!bh) {
1586 DbgBreak();
1588 goto errorout;
1589 }
1590 gd->bg_checksum = ext4_group_desc_csum(EXT3_SB(sb), Group, gd);
1592 set_buffer_uptodate(bh);
1593 gd->bg_flags &= cpu_to_le16(~EXT4_BG_INODE_UNINIT);
1594 Ext2SaveGroup(IrpContext, Vcb, Group);
1595 } else {
1596 bh = sb_getblk(sb, bitmap_blk);
1597 if (!bh) {
1598 DbgBreak();
1600 goto errorout;
1601 }
1602 }
1603
1604 if (!buffer_uptodate(bh)) {
1605 int err = bh_submit_read(bh);
1606 if (err < 0) {
1607 DbgPrint("bh_submit_read error! err: %d\n", err);
1609 goto errorout;
1610 }
1611 }
1612
1613 if (Vcb->sbi.s_groups_count == 1) {
1615 } else {
1616 if (Group + 1 == Vcb->sbi.s_groups_count) {
1618 if (!Length) {
1619 /* INODES_COUNT is integer multiple of INODES_PER_GROUP */
1621 }
1622 } else {
1624 }
1625 }
1626
1627 RtlInitializeBitMap(&InodeBitmap, (PULONG)bh->b_data, Length);
1628 dwInode = RtlFindClearBits(&InodeBitmap, 1, 0);
1629
1630 if (dwInode == 0xFFFFFFFF || dwInode >= Length) {
1631
1632 RtlZeroMemory(&InodeBitmap, sizeof(RTL_BITMAP));
1633 if (ext4_free_inodes_count(sb, gd) > 0) {
1634 ext4_free_inodes_set(sb, gd, 0);
1635 Ext2SaveGroup(IrpContext, Vcb, Group);
1636 }
1637 goto repeat;
1638
1639 } else {
1640
1641 __u32 count = 0;
1642
1643 /* update unused inodes count */
1644 count = ext4_free_inodes_count(sb, gd) - 1;
1646
1647 RtlSetBits(&InodeBitmap, dwInode, 1);
1648
1649 /* set block bitmap dirty in cache */
1651
1652 /* If we didn't allocate from within the initialized part of the inode
1653 * table then we need to initialize up to this inode. */
1655
1656 __u32 free;
1657
1658 if (gd->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT)) {
1659 gd->bg_flags &= cpu_to_le16(~EXT4_BG_INODE_UNINIT);
1660 /* When marking the block group with
1661 * ~EXT4_BG_INODE_UNINIT we don't want to depend
1662 * on the value of bg_itable_unused even though
1663 * mke2fs could have initialized the same for us.
1664 * Instead we calculated the value below
1665 */
1666
1667 free = 0;
1668 } else {
1670 }
1671
1672 /*
1673 * Check the relative inode number against the last used
1674 * relative inode number in this group. if it is greater
1675 * we need to update the bg_itable_unused count
1676 *
1677 */
1678 if (dwInode + 1 > free) {
1680 (EXT3_INODES_PER_GROUP(sb) - 1 - dwInode));
1681 }
1682
1683 /* We may have to initialize the block bitmap if it isn't already */
1684 if (gd->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
1685
1686 struct buffer_head *block_bitmap_bh = NULL;
1687
1688 /* recheck and clear flag under lock if we still need to */
1689 block_bitmap_bh = sb_getblk_zero(sb, ext4_block_bitmap(sb, gd));
1690 if (block_bitmap_bh) {
1691 gd->bg_checksum = ext4_group_desc_csum(EXT3_SB(sb), Group, gd);
1692 free = ext4_init_block_bitmap(sb, block_bitmap_bh, Group, gd);
1693 set_buffer_uptodate(block_bitmap_bh);
1694 brelse(block_bitmap_bh);
1695 gd->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT);
1697 Ext2SaveGroup(IrpContext, Vcb, Group);
1698 }
1699 }
1700 }
1701
1702 *Inode = dwInode + 1 + Group * INODES_PER_GROUP;
1703
1704 /* update group_desc / super_block */
1705 if (Type == EXT2_FT_DIR) {
1707 }
1708 Ext2SaveGroup(IrpContext, Vcb, Group);
1709 Ext2UpdateVcbStat(IrpContext, Vcb);
1711 }
1712
1713errorout:
1714
1715 ExReleaseResourceLite(&Vcb->MetaInode);
1716
1717 if (bh)
1718 fini_bh(&bh);
1719
1720 if (gb)
1721 fini_bh(&gb);
1722
1723
1724 return Status;
1725}
#define free
Definition: debug_ros.c:5
#define EXT3_INODES_PER_GROUP(s)
Definition: ext3_fs.h:191
#define EXT4_FEATURE_RO_COMPAT_GDT_CSUM
Definition: ext3_fs.h:700
#define EXT4_BG_INODE_UNINIT
Definition: ext3_fs.h:733
__u32 ext4_free_inodes_count(struct super_block *sb, struct ext4_group_desc *bg)
Definition: generic.c:2491
__u32 ext4_itable_unused_count(struct super_block *sb, struct ext4_group_desc *bg)
Definition: generic.c:2507
void ext4_itable_unused_set(struct super_block *sb, struct ext4_group_desc *bg, __u32 count)
Definition: generic.c:2563
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:2786
GLuint GLuint GLsizei count
Definition: gl.h:1545
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
static void brelse(struct buffer_head *bh)
Definition: module.h:955
static const WCHAR desc[]
Definition: protectdata.c:36
static int repeat
Definition: xmllint.c:137

Referenced by Ext2CreateInode().

◆ Ext2PutGroup()

VOID Ext2PutGroup ( IN PEXT2_VCB  Vcb)

Definition at line 150 of file generic.c.

151{
152 struct ext3_sb_info *sbi = &Vcb->sbi;
153 unsigned long i;
154
155
156 if (NULL == Vcb->sbi.s_gd) {
157 return;
158 }
159
161
162 kfree(Vcb->sbi.s_gd);
163 Vcb->sbi.s_gd = NULL;
164
165 ClearFlag(Vcb->Flags, VCB_GD_LOADED);
166}
#define kfree(p)
Definition: module.h:1126

Referenced by Ext2InitializeVcb(), and Ext2LoadGroup().

◆ Ext2RefreshGroup()

BOOLEAN Ext2RefreshGroup ( IN PEXT2_IRP_CONTEXT  IrpContext,
IN PEXT2_VCB  Vcb 
)

Definition at line 409 of file generic.c.

413{
414 return TRUE;
415}

Referenced by Ext2RecoverJournal().

◆ Ext2RefreshSuper()

BOOLEAN Ext2RefreshSuper ( IN PEXT2_IRP_CONTEXT  IrpContext,
IN PEXT2_VCB  Vcb 
)

Definition at line 92 of file generic.c.

96{
99
101 if (!CcCopyRead(
102 Vcb->Volume,
105 TRUE,
106 (PVOID)Vcb->SuperBlock,
107 &iosb )) {
108 return FALSE;
109 }
110
111 if (!NT_SUCCESS(iosb.Status)) {
112 return FALSE;
113 }
114
115 /* reload root inode */
116 if (Vcb->McbTree) {
117
118 if (!Ext2LoadInode(Vcb, &Vcb->McbTree->Inode))
119 return FALSE;
120
121 /* initializeroot node */
122 Vcb->McbTree->CreationTime = Ext2NtTime(Vcb->McbTree->Inode.i_ctime);
123 Vcb->McbTree->LastAccessTime = Ext2NtTime(Vcb->McbTree->Inode.i_atime);
124 Vcb->McbTree->LastWriteTime = Ext2NtTime(Vcb->McbTree->Inode.i_mtime);
125 Vcb->McbTree->ChangeTime = Ext2NtTime(Vcb->McbTree->Inode.i_mtime);
126 }
127
128 return TRUE;
129}
LARGE_INTEGER Ext2NtTime(IN ULONG i_time)
Definition: misc.c:40
BOOLEAN Ext2LoadInode(IN PEXT2_VCB Vcb, IN struct inode *Inode)
Definition: generic.c:508
static PIO_STATUS_BLOCK iosb
Definition: file.c:98

Referenced by Ext2RecoverJournal().

◆ Ext2RemoveEntry()

NTSTATUS Ext2RemoveEntry ( IN PEXT2_IRP_CONTEXT  IrpContext,
IN PEXT2_VCB  Vcb,
IN PEXT2_FCB  Dcb,
IN PEXT2_MCB  Mcb 
)

Definition at line 2021 of file generic.c.

2027{
2028 struct inode *dir = Dcb->Inode;
2029 struct buffer_head *bh = NULL;
2030 struct ext3_dir_entry_2 *de;
2031 struct inode *inode;
2032 int rc = -ENOENT;
2034 BOOLEAN MainResourceAcquired = FALSE;
2035
2036 if (!IsDirectory(Dcb)) {
2038 }
2039
2040 ExAcquireResourceExclusiveLite(&Dcb->MainResource, TRUE);
2041 MainResourceAcquired = TRUE;
2042
2043 _SEH2_TRY {
2044
2045 Ext2ReferXcb(&Dcb->ReferenceCount);
2046
2047 bh = ext3_find_entry(IrpContext, Mcb->de, &de);
2048 if (!bh)
2050
2051 inode = &Mcb->Inode;
2052 if (le32_to_cpu(de->inode) != inode->i_ino)
2054
2055 if (!inode->i_nlink) {
2056 ext3_warning (inode->i_sb, "ext3_unlink",
2057 "Deleting nonexistent file (%lu), %d",
2059 inode->i_nlink = 1;
2060 }
2061 rc = ext3_delete_entry(IrpContext, dir, de, bh);
2062 if (rc) {
2063 Status = Ext2WinntError(rc);
2065 }
2066 /*
2067 if (!inode->i_nlink)
2068 ext3_orphan_add(handle, inode);
2069 */
2070 inode->i_ctime = dir->i_ctime = dir->i_mtime = ext3_current_time(dir);
2072 ext3_mark_inode_dirty(IrpContext, inode);
2073
2074 /* decrease dir inode's nlink for .. */
2075 if (S_ISDIR(inode->i_mode)) {
2078 ext3_mark_inode_dirty(IrpContext, dir);
2079 }
2080
2082
2083 } _SEH2_FINALLY {
2084
2085 Ext2DerefXcb(&Dcb->ReferenceCount);
2086
2087 if (MainResourceAcquired)
2088 ExReleaseResourceLite(&Dcb->MainResource);
2089
2090 if (bh)
2091 brelse(bh);
2092 } _SEH2_END;
2093
2094 return Status;
2095}
#define ENOENT
Definition: acclib.h:79
unsigned int dir
Definition: maze.c:112
__u32 ext3_current_time(struct inode *in)
Definition: htree.c:204
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_warning(struct super_block *sb, const char *function, char *fmt,...)
Definition: htree.c:212
void ext3_dec_count(struct inode *inode)
Definition: htree.c:312
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
void ext3_update_dx_flag(struct inode *inode)
Definition: htree.c:368
IN PVCB IN ULONG IN OUT PULONG IN BOOLEAN OUT PLARGE_MCB Mcb
Definition: fatprocs.h:349
Definition: ext3_fs.h:774
__le32 inode
Definition: ext3_fs.h:775
__u32 i_ino
Definition: fs.h:79
umode_t i_mode
Definition: fs.h:87
struct super_block * i_sb
Definition: fs.h:96
__u16 i_nlink
Definition: fs.h:91
__u32 i_ctime
Definition: fs.h:82

Referenced by Ext2DeleteFile(), and Ext2SetRenameInfo().

◆ Ext2SaveBlock()

BOOLEAN Ext2SaveBlock ( IN PEXT2_IRP_CONTEXT  IrpContext,
IN PEXT2_VCB  Vcb,
IN ULONG  Index,
IN PVOID  Buf 
)

Definition at line 698 of file generic.c.

702{
703 struct buffer_head *bh = NULL;
704 BOOLEAN rc = 0;
705
706 _SEH2_TRY {
707
708 bh = sb_getblk_zero(&Vcb->sb, (sector_t)Index);
709
710 if (!bh) {
711 DEBUG(DL_ERR, ("Ext2Saveblock: can't load block %u\n", Index));
712 DbgBreak();
714 }
715
716 if (!buffer_uptodate(bh)) {
717 }
718
721 rc = TRUE;
722
723 } _SEH2_FINALLY {
724
725 if (bh)
726 fini_bh(&bh);
727 } _SEH2_END;
728
729 return rc;
730}

Referenced by Ext2ExpandBlock(), and Ext2ExpandLast().

◆ Ext2SaveBuffer()

BOOLEAN Ext2SaveBuffer ( IN PEXT2_IRP_CONTEXT  IrpContext,
IN PEXT2_VCB  Vcb,
IN LONGLONG  offset,
IN ULONG  size,
IN PVOID  buf 
)

Definition at line 928 of file generic.c.

933{
934 struct buffer_head *bh = NULL;
935 BOOLEAN rc = 0;
936
937 __try {
938
939 while (size) {
940
942 ULONG len = 0, delta = 0;
943
945 delta = (ULONG)offset & (BLOCK_SIZE - 1);
946 len = BLOCK_SIZE - delta;
947 if (size < len)
948 len = size;
949
950 if (delta == 0 && len >= BLOCK_SIZE) {
951 bh = sb_getblk_zero(&Vcb->sb, block);
952 } else {
953 bh = sb_getblk(&Vcb->sb, block);
954 }
955
956 if (!bh) {
957 DEBUG(DL_ERR, ("Ext2SaveBuffer: can't load block %I64u\n", block));
958 DbgBreak();
959 __leave;
960 }
961
962 if (!buffer_uptodate(bh)) {
963 int err = bh_submit_read(bh);
964 if (err < 0) {
965 DEBUG(DL_ERR, ("Ext2SaveBuffer: bh_submit_read failed: %d\n", err));
966 __leave;
967 }
968 }
969
970 __try {
971 RtlCopyMemory(bh->b_data + delta, buf, len);
973 } __finally {
974 fini_bh(&bh);
975 }
976
977 buf = (PUCHAR)buf + len;
978 offset = offset + len;
979 size = size - len;
980 }
981
982 rc = TRUE;
983
984 } __finally {
985
986 if (bh)
987 fini_bh(&bh);
988
989 }
990
991 return rc;
992}

Referenced by Ext2SaveInode(), Ext2SaveInodeXattr(), Ext2SaveSuper(), and Ext2WriteInode().

◆ Ext2SaveGroup()

BOOLEAN Ext2SaveGroup ( IN PEXT2_IRP_CONTEXT  IrpContext,
IN PEXT2_VCB  Vcb,
IN ULONG  Group 
)

Definition at line 386 of file generic.c.

391{
392 struct ext4_group_desc *gd;
393 struct buffer_head *gb = NULL;
394 unsigned long i;
395
396 gd = ext4_get_group_desc(&Vcb->sb, Group, &gb);
397 if (!gd)
398 return 0;
399
400 gd->bg_checksum = ext4_group_desc_csum(&Vcb->sbi, Group, gd);
402 fini_bh(&gb);
403
404 return TRUE;
405}
__le16 bg_checksum
Definition: ext3_fs.h:145

Referenced by Ext2FreeBlock(), Ext2FreeInode(), Ext2NewBlock(), Ext2NewInode(), and Ext2UpdateGroupDirStat().

◆ Ext2SaveInode()

BOOLEAN Ext2SaveInode ( IN PEXT2_IRP_CONTEXT  IrpContext,
IN PEXT2_VCB  Vcb,
IN struct inode Inode 
)

Definition at line 552 of file generic.c.

555{
556 struct ext3_inode ext3i = {0};
557
558 LONGLONG Offset = 0;
559 ULONG InodeSize = sizeof(ext3i);
560 BOOLEAN rc = 0;
561
562 DEBUG(DL_INF, ( "Ext2SaveInode: Saving Inode %xh: Mode=%xh Size=%xh\n",
563 Inode->i_ino, Inode->i_mode, Inode->i_size));
564 rc = Ext2GetInodeLba(Vcb, Inode->i_ino, &Offset);
565 if (!rc) {
566 DEBUG(DL_ERR, ( "Ext2SaveInode: failed inode %u.\n", Inode->i_ino));
567 goto errorout;
568 }
569
570 rc = Ext2LoadBuffer(NULL, Vcb, Offset, InodeSize, &ext3i);
571 if (!rc) {
572 DEBUG(DL_ERR, ( "Ext2SaveInode: failed reading inode %u.\n", Inode->i_ino));
573 goto errorout;;
574 }
575
576 Ext2EncodeInode(&ext3i, Inode);
577 if (InodeSize > Vcb->InodeSize)
578 InodeSize = Vcb->InodeSize;
579 rc = Ext2SaveBuffer(IrpContext, Vcb, Offset, InodeSize, &ext3i);
580
581 if (rc && IsFlagOn(Vcb->Flags, VCB_FLOPPY_DISK)) {
583 }
584
585errorout:
586 return rc;
587}
VOID Ext2StartFloppyFlushDpc(PEXT2_VCB Vcb, PEXT2_FCB Fcb, PFILE_OBJECT FileObject)
Definition: write.c:139
#define VCB_FLOPPY_DISK
Definition: ext2fs.h:806
BOOLEAN Ext2SaveBuffer(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN LONGLONG offset, IN ULONG size, IN PVOID buf)
Definition: generic.c:928

Referenced by Ext2Cleanup(), Ext2CreateInode(), Ext2DeleteFile(), Ext2DoExtentExpand(), Ext2ExpandExtent(), Ext2ExpandIndirect(), Ext2FlushFile(), Ext2GetBlock(), Ext2MapExtent(), Ext2MapIndirect(), Ext2SetFileInformation(), Ext2SetReparsePoint(), Ext2SupersedeOrOverWriteFile(), Ext2TruncateExtent(), Ext2TruncateIndirect(), Ext2TruncateSymlink(), Ext2WriteFile(), Ext2WriteSymlink(), ext3_append(), ext3_mark_inode_dirty(), and ext4_fs_put_xattr_ref().

◆ Ext2SaveInodeXattr()

BOOLEAN Ext2SaveInodeXattr ( IN PEXT2_IRP_CONTEXT  IrpContext,
IN PEXT2_VCB  Vcb,
IN struct inode Inode,
IN PEXT2_INODE  InodeXattr 
)

Definition at line 621 of file generic.c.

625{
627 LONGLONG Offset = 0;
628 ULONG InodeSize = Vcb->InodeSize;
629 BOOLEAN rc = 0;
630
631 /* There is no way to put EA information in such a small inode */
632 if (InodeSize == EXT2_GOOD_OLD_INODE_SIZE)
633 return FALSE;
634
635 DEBUG(DL_INF, ("Ext2SaveInodeXattr: Saving Inode %xh: Mode=%xh Size=%xh\n",
636 Inode->i_ino, Inode->i_mode, Inode->i_size));
637 rc = Ext2GetInodeLba(Vcb, Inode->i_ino, &Offset);
638 if (!rc) {
639 DEBUG(DL_ERR, ("Ext2SaveInodeXattr: error get inode(%xh)'s addr.\n", Inode->i_ino));
640 goto errorout;
641 }
642
643 rc = Ext2SaveBuffer(IrpContext,
644 Vcb,
645 Offset + EXT2_GOOD_OLD_INODE_SIZE + Inode->i_extra_isize,
646 InodeSize - EXT2_GOOD_OLD_INODE_SIZE - Inode->i_extra_isize,
647 (char *)InodeXattr + EXT2_GOOD_OLD_INODE_SIZE + Inode->i_extra_isize);
648
649 if (rc && IsFlagOn(Vcb->Flags, VCB_FLOPPY_DISK)) {
651 }
652
653errorout:
654 return rc;
655}
#define EXT2_GOOD_OLD_INODE_SIZE
Definition: ext2.h:54

Referenced by ext4_fs_put_xattr_ref().

◆ Ext2SaveSuper()

BOOLEAN Ext2SaveSuper ( IN PEXT2_IRP_CONTEXT  IrpContext,
IN PEXT2_VCB  Vcb 
)

Definition at line 67 of file generic.c.

71{
73 BOOLEAN rc;
74
76 rc = Ext2SaveBuffer( IrpContext,
77 Vcb,
78 offset,
80 Vcb->SuperBlock
81 );
82
83 if (IsFlagOn(Vcb->Flags, VCB_FLOPPY_DISK)) {
85 }
86
87 return rc;
88}

Referenced by Ext2RecoverJournal(), Ext2SetFileInformation(), Ext2SetVolumeInformation(), Ext2ShutDown(), Ext2UpdateVcbStat(), Ext2WriteFile(), and ext3_inode_blocks_set().

◆ Ext2SetFileType()

NTSTATUS Ext2SetFileType ( IN PEXT2_IRP_CONTEXT  IrpContext,
IN PEXT2_VCB  Vcb,
IN PEXT2_FCB  Dcb,
IN PEXT2_MCB  Mcb,
IN umode_t  mode 
)

Definition at line 1951 of file generic.c.

1958{
1959 struct inode *dir = Dcb->Inode;
1960 struct buffer_head *bh = NULL;
1961 struct ext3_dir_entry_2 *de;
1962 struct inode *inode;
1964 BOOLEAN MainResourceAcquired = FALSE;
1965
1967 return STATUS_SUCCESS;
1968 }
1969
1970 if (!IsDirectory(Dcb)) {
1972 }
1973
1974 ExAcquireResourceExclusiveLite(&Dcb->MainResource, TRUE);
1975 MainResourceAcquired = TRUE;
1976
1977 _SEH2_TRY {
1978
1979 Ext2ReferXcb(&Dcb->ReferenceCount);
1980
1981 bh = ext3_find_entry(IrpContext, Mcb->de, &de);
1982 if (!bh)
1984
1985 inode = &Mcb->Inode;
1986 if (le32_to_cpu(de->inode) != inode->i_ino)
1988
1991
1992 if (S_ISDIR(inode->i_mode) == S_ISDIR(mode)) {
1993 } else if (S_ISDIR(inode->i_mode)) {
1995 } else if (S_ISDIR(mode)) {
1997 }
1998 dir->i_ctime = dir->i_mtime = ext3_current_time(dir);
1999 ext3_mark_inode_dirty(IrpContext, dir);
2000
2001 inode->i_mode = mode;
2002 ext3_mark_inode_dirty(IrpContext, inode);
2003
2005
2006 } _SEH2_FINALLY {
2007
2008 Ext2DerefXcb(&Dcb->ReferenceCount);
2009
2010 if (MainResourceAcquired)
2011 ExReleaseResourceLite(&Dcb->MainResource);
2012
2013 if (bh)
2014 brelse(bh);
2015 } _SEH2_END;
2016
2017 return Status;
2018}
void ext3_set_de_type(struct super_block *sb, struct ext3_dir_entry_2 *de, umode_t mode)
Definition: htree.c:347
#define EXT3_FEATURE_INCOMPAT_FILETYPE
Definition: ext3_fs.h:679
GLenum mode
Definition: glext.h:6217

Referenced by Ext2SetReparsePoint().

◆ Ext2SetParentEntry()

NTSTATUS Ext2SetParentEntry ( IN PEXT2_IRP_CONTEXT  IrpContext,
IN PEXT2_VCB  Vcb,
IN PEXT2_FCB  Dcb,
IN ULONG  OldParent,
IN ULONG  NewParent 
)

Definition at line 2098 of file generic.c.

2104{
2106
2107 PEXT2_DIR_ENTRY2 pSelf = NULL;
2109
2110 ULONG dwBytes = 0;
2111
2112 BOOLEAN MainResourceAcquired = FALSE;
2113
2114 ULONG Offset = 0;
2115
2116 if (!IsDirectory(Dcb)) {
2118 }
2119
2120 if (OldParent == NewParent) {
2121 return STATUS_SUCCESS;
2122 }
2123
2124 MainResourceAcquired =
2125 ExAcquireResourceExclusiveLite(&Dcb->MainResource, TRUE);
2126
2127 _SEH2_TRY {
2128
2129 Ext2ReferXcb(&Dcb->ReferenceCount);
2130
2131 pSelf = (PEXT2_DIR_ENTRY2)
2133 PagedPool,
2136 );
2137 if (!pSelf) {
2138 DEBUG(DL_ERR, ( "Ex2SetParentEntry: failed to allocate pSelf.\n"));
2141 }
2142
2143 dwBytes = 0;
2144
2145 //
2146 // Reading the DCB contents
2147 //
2148
2150 IrpContext,
2151 Vcb,
2152 Dcb->Mcb,
2154 (PVOID)pSelf,
2156 FALSE,
2157 &dwBytes );
2158
2159 if (!NT_SUCCESS(Status)) {
2160 DEBUG(DL_ERR, ( "Ext2SetParentEntry: failed to read directory.\n"));
2162 }
2163
2164 ASSERT(dwBytes == EXT2_DIR_REC_LEN(1) + EXT2_DIR_REC_LEN(2));
2165
2166 pParent = (PEXT2_DIR_ENTRY2)((PUCHAR)pSelf + pSelf->rec_len);
2167
2168 if (pSelf->name_len == 1 && pSelf->name[0] == '.' &&
2169 pParent->name_len == 2 && pParent->name[0] == '.' &&
2170 pParent->name[1] == '.') {
2171
2172 if (pParent->inode != OldParent) {
2173 DbgBreak();
2174 }
2175 pParent->inode = NewParent;
2176
2178 IrpContext,
2179 Vcb,
2180 Dcb->Mcb,
2182 pSelf,
2183 dwBytes,
2184 FALSE,
2185 &dwBytes );
2186 } else {
2187 DbgBreak();
2188 }
2189
2190 } _SEH2_FINALLY {
2191
2192
2193 if (Ext2DerefXcb(&Dcb->ReferenceCount) == 0) {
2194 DEBUG(DL_ERR, ( "Ext2SetParentEntry: Dcb reference goes to ZERO.\n"));
2195 }
2196
2197 if (MainResourceAcquired) {
2198 ExReleaseResourceLite(&Dcb->MainResource);
2199 }
2200
2201 if (pSelf) {
2203 }
2204 } _SEH2_END;
2205
2206 return Status;
2207}
#define EXT2_DIR_REC_LEN(name_len)
Definition: ext2_fs.h:536
BOOLEAN Ext2ReadInode(PEXT2_VOLUME_INFO Volume, ULONG Inode, PEXT2_INODE InodeBuffer)
Definition: ext2.c:910
struct ext3_dir_entry_2 * PEXT2_DIR_ENTRY2
Definition: ext2fs.h:109
#define EXT2_DENTRY_MAGIC
Definition: ext2fs.h:300
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:668
FxObject * pParent
Definition: fxdpcapi.cpp:86

Referenced by Ext2SetRenameInfo().

◆ Ext2UpdateGroupDirStat()

NTSTATUS Ext2UpdateGroupDirStat ( IN PEXT2_IRP_CONTEXT  IrpContext,
IN PEXT2_VCB  Vcb,
IN ULONG  group 
)

Definition at line 1728 of file generic.c.

1733{
1734 struct super_block *sb = &Vcb->sb;
1736 struct buffer_head *gb = NULL;
1738
1740
1741 /* get group desc */
1742 gd = ext4_get_group_desc(sb, group, &gb);
1743 if (!gd) {
1745 goto errorout;
1746 }
1747
1748 /* update group_desc and super_block */
1750 Ext2SaveGroup(IrpContext, Vcb, group);
1751 Ext2UpdateVcbStat(IrpContext, Vcb);
1753
1754errorout:
1755
1756 ExReleaseResourceLite(&Vcb->MetaInode);
1757
1758 if (gb)
1759 fini_bh(&gb);
1760
1761 return status;
1762}

Referenced by Ext2SetReparsePoint().

◆ Ext2UpdateVcbStat()

VOID Ext2UpdateVcbStat ( IN PEXT2_IRP_CONTEXT  IrpContext,
IN PEXT2_VCB  Vcb 
)

Definition at line 997 of file generic.c.

1001{
1002 Vcb->SuperBlock->s_free_inodes_count = ext4_count_free_inodes(&Vcb->sb);
1004 Ext2SaveSuper(IrpContext, Vcb);
1005}
#define SUPER_BLOCK
Definition: ext2fs.h:90
static void ext3_free_blocks_count_set(struct ext3_super_block *es, ext3_fsblk_t blk)
Definition: ext2fs.h:1770
ext4_fsblk_t ext4_count_free_blocks(struct super_block *sb)
Definition: generic.c:3033
unsigned long ext4_count_free_inodes(struct super_block *sb)
Definition: generic.c:3054
BOOLEAN Ext2SaveSuper(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb)
Definition: generic.c:67

Referenced by Ext2FreeBlock(), Ext2FreeInode(), Ext2NewBlock(), Ext2NewInode(), and Ext2UpdateGroupDirStat().

◆ Ext2ZeroBuffer()

BOOLEAN Ext2ZeroBuffer ( IN PEXT2_IRP_CONTEXT  IrpContext,
IN PEXT2_VCB  Vcb,
IN LONGLONG  offset,
IN ULONG  size 
)

Definition at line 795 of file generic.c.

800{
801 struct buffer_head *bh = NULL;
802 BOOLEAN rc = 0;
803
804 _SEH2_TRY {
805
806 while (size) {
807
809 ULONG len = 0, delta = 0;
810
812 delta = (ULONG)offset & (BLOCK_SIZE - 1);
813 len = BLOCK_SIZE - delta;
814 if (size < len)
815 len = size;
816
817 if (delta == 0 && len >= BLOCK_SIZE) {
818 bh = sb_getblk_zero(&Vcb->sb, block);
819 } else {
820 bh = sb_getblk(&Vcb->sb, block);
821 }
822
823 if (!bh) {
824 DEBUG(DL_ERR, ("Ext2SaveBuffer: can't load block %I64u\n", block));
825 DbgBreak();
827 }
828
829 if (!buffer_uptodate(bh)) {
830 int err = bh_submit_read(bh);
831 if (err < 0) {
832 DEBUG(DL_ERR, ("Ext2SaveBuffer: bh_submit_read failed: %d\n", err));
834 }
835 }
836
837 _SEH2_TRY {
838 if (delta == 0 && len >= BLOCK_SIZE) {
839 /* bh (cache) was already cleaned as zero */
840 } else {
841 RtlZeroMemory(bh->b_data + delta, len);
842 }
844 } _SEH2_FINALLY {
845 fini_bh(&bh);
846 } _SEH2_END;
847
848 offset = offset + len;
849 size = size - len;
850 }
851
852 rc = TRUE;
853
854 } _SEH2_FINALLY {
855
856 if (bh)
857 fini_bh(&bh);
858
859 } _SEH2_END;
860
861 return rc;
862}

Referenced by Ext2ClearInode().

◆ ext3_bg_has_super()

int ext3_bg_has_super ( struct super_block sb,
ext3_group_t  group 
)

ext4_bg_has_super - number of blocks used by the superblock in group @sb: superblock for filesystem @group: group number to check

Return the number of blocks used by the superblock (primary or backup) in this group. Currently this will be only 0 or 1.

Definition at line 2686 of file generic.c.

2687{
2691 return 0;
2692 return 1;
2693}
#define EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER
Definition: ext3_fs.h:671
static int ext3_group_sparse(ext3_group_t group)
Definition: generic.c:2668

Referenced by descriptor_loc(), ext4_bg_num_gdb_nometa(), and ext4_init_block_bitmap().

◆ ext3_check_dir_entry()

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 at line 2209 of file generic.c.

2213{
2214 const char * error_msg = NULL;
2215 const int rlen = ext3_rec_len_from_disk(de->rec_len);
2216
2217 if (rlen < EXT3_DIR_REC_LEN(1))
2218 error_msg = "rec_len is smaller than minimal";
2219 else if (rlen % 4 != 0)
2220 error_msg = "rec_len % 4 != 0";
2221 else if (rlen < EXT3_DIR_REC_LEN(de->name_len))
2222 error_msg = "rec_len is too small for name_len";
2223 else if ((char *) de + rlen > bh->b_data + dir->i_sb->s_blocksize)
2224 error_msg = "directory entry across blocks";
2225 else if (le32_to_cpu(de->inode) >
2226 le32_to_cpu(EXT3_SB(dir->i_sb)->s_es->s_inodes_count))
2227 error_msg = "inode out of bounds";
2228
2229 if (error_msg != NULL) {
2230 DEBUG(DL_ERR, ("%s: bad entry in directory %u: %s - "
2231 "offset=%u, inode=%u, rec_len=%d, name_len=%d\n",
2232 function, dir->i_ino, error_msg, offset,
2233 (unsigned long) le32_to_cpu(de->inode),
2234 rlen, de->name_len));
2235 }
2236 return error_msg == NULL ? 1 : 0;
2237}
#define EXT3_DIR_REC_LEN(len)
Definition: ext3_fs.h:867
static unsigned ext3_rec_len_from_disk(__le16 dlen)
Definition: ext3_fs.h:871
__u8 name_len
Definition: ext3_fs.h:777
__le16 rec_len
Definition: ext3_fs.h:776
static const WCHAR * error_msg[8]
Definition: odbccp32.c:62

Referenced by add_dirent_to_buf(), ext3_delete_entry(), ext3_is_dir_empty(), and search_dirblock().

◆ ext3_group_sparse()

static int ext3_group_sparse ( ext3_group_t  group)
static

Definition at line 2668 of file generic.c.

2669{
2670 if (group <= 1)
2671 return 1;
2672 if (!(group & 1))
2673 return 0;
2674 return (test_root(group, 7) || test_root(group, 5) ||
2675 test_root(group, 3));
2676}
static int test_root(ext3_group_t a, ext3_group_t b)
Definition: generic.c:2659

Referenced by ext3_bg_has_super().

◆ ext3_inode_blocks()

blkcnt_t ext3_inode_blocks ( struct ext3_inode raw_inode,
struct inode inode 
)

Definition at line 2395 of file generic.c.

2397{
2398 blkcnt_t i_blocks ;
2399 struct super_block *sb = inode->i_sb;
2400 PEXT2_VCB Vcb = (PEXT2_VCB)sb->s_priv;
2401
2404 /* we are using combined 48 bit field */
2405 i_blocks = ((u64)le16_to_cpu(raw_inode->i_blocks_high)) << 32 |
2406 le32_to_cpu(raw_inode->i_blocks);
2408 /* i_blocks represent file system block size */
2409 return i_blocks << (BLOCK_BITS - 9);
2410 } else {
2411 return i_blocks;
2412 }
2413 } else {
2414 return le32_to_cpu(raw_inode->i_blocks);
2415 }
2416}
unsigned __int64 blkcnt_t
Definition: types.h:83
struct _EXT2_VCB * PEXT2_VCB
#define EXT4_FEATURE_RO_COMPAT_HUGE_FILE
Definition: ext3_fs.h:699
#define EXT4_HUGE_FILE_FL
Definition: ext3_fs.h:262
#define le16_to_cpu
Definition: module.h:151
#define u64
Definition: types.h:10
__le32 i_blocks
Definition: ext3_fs.h:355
__u32 i_flags
Definition: fs.h:94

Referenced by Ext2DecodeInode().

◆ ext3_inode_blocks_set()

int ext3_inode_blocks_set ( struct ext3_inode raw_inode,
struct inode inode 
)

Definition at line 2418 of file generic.c.

2420{
2421 u64 i_blocks = inode->i_blocks;
2422 struct super_block *sb = inode->i_sb;
2423 PEXT2_VCB Vcb = (PEXT2_VCB)sb->s_priv;
2424
2425 if (i_blocks < 0x100000000) {
2426 /*
2427 * i_blocks can be represnted in a 32 bit variable
2428 * as multiple of 512 bytes
2429 */
2430 raw_inode->i_blocks = cpu_to_le32(i_blocks);
2431 raw_inode->i_blocks_high = 0;
2432 inode->i_flags &= ~EXT4_HUGE_FILE_FL;
2433 return 0;
2434 }
2435
2439 }
2440
2441 if (i_blocks <= 0xffffffffffff) {
2442 /*
2443 * i_blocks can be represented in a 48 bit variable
2444 * as multiple of 512 bytes
2445 */
2446 raw_inode->i_blocks = (__u32)cpu_to_le32(i_blocks);
2447 raw_inode->i_blocks_high = (__u16)cpu_to_le16(i_blocks >> 32);
2448 inode->i_flags &= ~EXT4_HUGE_FILE_FL;
2449 } else {
2451 /* i_block is stored in file system block size */
2452 i_blocks = i_blocks >> (BLOCK_BITS - 9);
2453 raw_inode->i_blocks = (__u32)cpu_to_le32(i_blocks);
2454 raw_inode->i_blocks_high = (__u16)cpu_to_le16(i_blocks >> 32);
2455 }
2456 return 0;
2457}
ULONG64 u64
Definition: btrfs.h:15
#define EXT3_SET_RO_COMPAT_FEATURE(sb, mask)
Definition: ext3_fs.h:653
#define cpu_to_le32
Definition: module.h:148
#define __u16
Definition: types.h:13
__u64 i_blocks
Definition: fs.h:85

Referenced by Ext2EncodeInode().

◆ ext3_max_bitmap_size()

loff_t ext3_max_bitmap_size ( int  bits,
int  has_huge_files 
)

Definition at line 2337 of file generic.c.

2338{
2340 int meta_blocks;
2342 /* This is calculated to be the largest file size for a
2343 * dense, bitmapped file such that the total number of
2344 * sectors in the file, including data and all indirect blocks,
2345 * does not exceed 2^48 -1
2346 * __u32 i_blocks_lo and _u16 i_blocks_high representing the
2347 * total number of 512 bytes blocks of the file
2348 */
2349
2350 if (!has_huge_files) {
2351 /*
2352 * !has_huge_files or CONFIG_LBD is not enabled
2353 * implies the inode i_block represent total blocks in
2354 * 512 bytes 32 == size of vfs inode i_blocks * 8
2355 */
2356 upper_limit = ((loff_t)1 << 32) - 1;
2357
2358 /* total blocks in file system block size */
2359 upper_limit >>= (bits - 9);
2360
2361 } else {
2362 /*
2363 * We use 48 bit ext4_inode i_blocks
2364 * With EXT4_HUGE_FILE_FL set the i_blocks
2365 * represent total number of blocks in
2366 * file system block size
2367 */
2368 upper_limit = ((loff_t)1 << 48) - 1;
2369
2370 }
2371
2372 /* indirect blocks */
2373 meta_blocks = 1;
2374 /* double indirect blocks */
2375 meta_blocks += 1 + ((loff_t)1 << (bits-2));
2376 /* tripple indirect blocks */
2377 meta_blocks += 1 + ((loff_t)1 << (bits-2)) + ((loff_t)1 << (2*(bits-2)));
2378
2379 upper_limit -= meta_blocks;
2380 upper_limit <<= bits;
2381
2382 res += (loff_t)1 << (bits-2);
2383 res += (loff_t)1 << (2*(bits-2));
2384 res += (loff_t)1 << (3*(bits-2));
2385 res <<= bits;
2386 if (res > upper_limit)
2387 res = upper_limit;
2388
2389 if (res > MAX_LFS_FILESIZE)
2391
2392 return res;
2393}
#define EXT3_NDIR_BLOCKS
Definition: ext3_fs.h:197
#define MAX_LFS_FILESIZE
Definition: generic.c:2250
GLuint res
Definition: glext.h:9613
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * bits
Definition: glext.h:10929
#define bits
Definition: infblock.c:15
DWORD upper_limit
Definition: apphelp.c:212

Referenced by Ext2InitializeVcb().

◆ ext3_max_size()

loff_t ext3_max_size ( int  blkbits,
int  has_huge_files 
)

Definition at line 2301 of file generic.c.

2302{
2303 loff_t res;
2305
2306 /* small i_blocks in vfs inode? */
2307 if (!has_huge_files) {
2308 /*
2309 * CONFIG_LBD is not enabled implies the inode
2310 * i_block represent total blocks in 512 bytes
2311 * 32 == size of vfs inode i_blocks * 8
2312 */
2313 upper_limit = ((loff_t)1 << 32) - 1;
2314
2315 /* total blocks in file system block size */
2316 upper_limit >>= (blkbits - 9);
2317 upper_limit <<= blkbits;
2318 }
2319
2320 /* 32-bit extent-start container, ee_block */
2321 res = (loff_t)1 << 32;
2322 res <<= blkbits;
2323 res -= 1;
2324
2325 /* Sanity check against vm- & vfs- imposed limits */
2326 if (res > upper_limit)
2327 res = upper_limit;
2328
2329 return res;
2330}

Referenced by Ext2InitializeVcb().

◆ ext3_next_entry()

struct ext3_dir_entry_2 * ext3_next_entry ( struct ext3_dir_entry_2 p)

Definition at line 2244 of file generic.c.

2245{
2246 return (struct ext3_dir_entry_2 *)((char *)p +
2247 ext3_rec_len_from_disk(p->rec_len));
2248}
GLfloat GLfloat p
Definition: glext.h:8902

Referenced by ext3_delete_entry(), and ext3_is_dir_empty().

◆ ext4_bg_num_gdb()

unsigned long ext4_bg_num_gdb ( struct super_block sb,
ext4_group_t  group 
)

ext4_bg_num_gdb - number of blocks used by the group table in group @sb: superblock for filesystem @group: group number to check

Return the number of blocks used by the group descriptor table (primary or backup) in this group. In the future there may be a different number of descriptor blocks in each group.

Definition at line 2722 of file generic.c.

2723{
2724 unsigned long first_meta_bg =
2725 le32_to_cpu(EXT3_SB(sb)->s_es->s_first_meta_bg);
2726 unsigned long metagroup = group / EXT4_DESC_PER_BLOCK(sb);
2727
2729 metagroup < first_meta_bg)
2731
2733
2734}
static unsigned long ext4_bg_num_gdb_nometa(struct super_block *sb, ext4_group_t group)
Definition: generic.c:2707
static unsigned long ext4_bg_num_gdb_meta(struct super_block *sb, ext4_group_t group)
Definition: generic.c:2695

Referenced by ext4_init_block_bitmap().

◆ ext4_bg_num_gdb_meta()

static unsigned long ext4_bg_num_gdb_meta ( struct super_block sb,
ext4_group_t  group 
)
static

Definition at line 2695 of file generic.c.

2697{
2698 unsigned long metagroup = group / EXT4_DESC_PER_BLOCK(sb);
2699 ext4_group_t first = metagroup * EXT4_DESC_PER_BLOCK(sb);
2700 ext4_group_t last = first + EXT4_DESC_PER_BLOCK(sb) - 1;
2701
2702 if (group == first || group == first + 1 || group == last)
2703 return 1;
2704 return 0;
2705}
unsigned int ext4_group_t
Definition: ext3_fs_i.h:35
const GLint * first
Definition: glext.h:5794
static UINT UINT last
Definition: font.c:45

Referenced by ext4_bg_num_gdb().

◆ ext4_bg_num_gdb_nometa()

static unsigned long ext4_bg_num_gdb_nometa ( struct super_block sb,
ext4_group_t  group 
)
static

Definition at line 2707 of file generic.c.

2709{
2710 return ext3_bg_has_super(sb, group) ? EXT3_SB(sb)->s_gdb_count : 0;
2711}

Referenced by ext4_bg_num_gdb().

◆ ext4_block_bitmap()

ext4_fsblk_t ext4_block_bitmap ( struct super_block sb,
struct ext4_group_desc bg 
)

◆ ext4_block_bitmap_set()

void ext4_block_bitmap_set ( struct super_block sb,
struct ext4_group_desc bg,
ext4_fsblk_t  blk 
)

Definition at line 2515 of file generic.c.

2517{
2520 bg->bg_block_bitmap_hi = cpu_to_le32(blk >> 32);
2521}
ULONG32 u32
Definition: btrfs.h:14
#define blk
Definition: linetest.c:70

◆ ext4_block_in_group()

static int ext4_block_in_group ( struct super_block sb,
ext4_fsblk_t  block,
ext4_group_t  block_group 
)
static

Definition at line 2832 of file generic.c.

2834{
2835 ext4_group_t actual_group;
2836 ext4_get_group_no_and_offset(sb, block, &actual_group, NULL);
2837 if (actual_group == block_group)
2838 return 1;
2839 return 0;
2840}
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:2817

Referenced by ext4_group_used_meta_blocks(), and ext4_init_block_bitmap().

◆ ext4_check_descriptors()

int ext4_check_descriptors ( struct super_block sb)

Definition at line 3091 of file generic.c.

3092{
3093 PEXT2_VCB Vcb = sb->s_priv;
3094 struct ext3_sb_info *sbi = EXT3_SB(sb);
3095 ext4_fsblk_t first_block = le32_to_cpu(sbi->s_es->s_first_data_block);
3096 ext4_fsblk_t last_block;
3097 ext4_fsblk_t block_bitmap;
3098 ext4_fsblk_t inode_bitmap;
3099 ext4_fsblk_t inode_table;
3100 int flexbg_flag = 0;
3102
3104 flexbg_flag = 1;
3105
3106 DEBUG(DL_INF, ("Checking group descriptors"));
3107
3108 for (i = 0; i < sbi->s_groups_count; i++) {
3109
3110 struct buffer_head *bh = NULL;
3111 struct ext4_group_desc *gdp = ext4_get_group_desc(sb, i, &bh);
3112
3113 if (!bh)
3114 continue;
3115
3116 if (i == sbi->s_groups_count - 1 || flexbg_flag)
3117 last_block = ext3_blocks_count(sbi->s_es) - 1;
3118 else
3119 last_block = first_block +
3121
3122 block_bitmap = ext4_block_bitmap(sb, gdp);
3123 if (block_bitmap < first_block || block_bitmap > last_block) {
3124 printk(KERN_ERR "EXT4-fs: ext4_check_descriptors: "
3125 "Block bitmap for group %u not in group "
3126 "(block %llu)!\n", i, block_bitmap);
3127 __brelse(bh);
3128 return 0;
3129 }
3130 inode_bitmap = ext4_inode_bitmap(sb, gdp);
3131 if (inode_bitmap < first_block || inode_bitmap > last_block) {
3132 printk(KERN_ERR "EXT4-fs: ext4_check_descriptors: "
3133 "Inode bitmap for group %u not in group "
3134 "(block %llu)!\n", i, inode_bitmap);
3135 __brelse(bh);
3136 return 0;
3137 }
3138 inode_table = ext4_inode_table(sb, gdp);
3139 if (inode_table < first_block ||
3140 inode_table + sbi->s_itb_per_group - 1 > last_block) {
3141 printk(KERN_ERR "EXT4-fs: ext4_check_descriptors: "
3142 "Inode table for group %u not in group "
3143 "(block %llu)!\n", i, inode_table);
3144 __brelse(bh);
3145 return 0;
3146 }
3147
3148 if (!ext4_group_desc_csum_verify(sbi, i, gdp)) {
3149 printk(KERN_ERR "EXT4-fs: ext4_check_descriptors: "
3150 "Checksum for group %u failed (%u!=%u)\n",
3152 gdp)),
3153 le16_to_cpu(gdp->bg_checksum));
3154 if (!IsVcbReadOnly(Vcb)) {
3155 __brelse(bh);
3156 return 0;
3157 }
3158 }
3159
3160 if (!flexbg_flag)
3161 first_block += EXT4_BLOCKS_PER_GROUP(sb);
3162
3163 __brelse(bh);
3164 }
3165
3167 sbi->s_es->s_free_inodes_count = cpu_to_le32(ext4_count_free_inodes(sb));
3168 return 1;
3169}
static ext3_fsblk_t ext3_blocks_count(struct ext3_super_block *es)
Definition: ext2fs.h:1745
#define IsVcbReadOnly(Vcb)
Definition: ext2fs.h:814
#define EXT3_BLOCKS_PER_GROUP(s)
Definition: ext3_fs.h:189
#define EXT4_FEATURE_INCOMPAT_FLEX_BG
Definition: ext3_fs.h:712
int ext4_group_desc_csum_verify(struct ext3_sb_info *sbi, __u32 block_group, struct ext4_group_desc *gdp)
Definition: generic.c:2648
#define printk
Definition: module.h:231
#define KERN_ERR
Definition: module.h:225
unsigned long s_itb_per_group
Definition: ext3_fs_sb.h:44
unsigned long s_groups_count
Definition: ext3_fs_sb.h:43

Referenced by Ext2LoadGroup().

◆ ext4_count_dirs()

unsigned long ext4_count_dirs ( struct super_block sb)

Definition at line 3073 of file generic.c.

3074{
3075 struct ext4_group_desc *gdp;
3076 struct buffer_head *bh = NULL;
3077 unsigned long count = 0;
3079
3080 for (i = 0; i < EXT3_SB(sb)->s_groups_count; i++) {
3081 gdp = ext4_get_group_desc(sb, i, &bh);
3082 if (!bh)
3083 continue;
3084 count += ext4_used_dirs_count(sb, gdp);
3085 fini_bh(&bh);
3086 }
3087 return count;
3088}

◆ ext4_count_free_blocks()

ext4_fsblk_t ext4_count_free_blocks ( struct super_block sb)

ext4_count_free_blocks() – count filesystem free blocks @sb: superblock

Adds up the number of free blocks from each block group.

Definition at line 3033 of file generic.c.

3034{
3035 ext4_fsblk_t desc_count;
3036 struct ext4_group_desc *gdp;
3037 struct buffer_head *bh = NULL;
3039 ext4_group_t ngroups = EXT3_SB(sb)->s_groups_count;
3040
3041 desc_count = 0;
3042 smp_rmb();
3043 for (i = 0; i < ngroups; i++) {
3044 gdp = ext4_get_group_desc(sb, i, &bh);
3045 if (!bh)
3046 continue;
3047 desc_count += ext4_free_blks_count(sb, gdp);
3048 fini_bh(&bh);
3049 }
3050
3051 return desc_count;
3052}
#define smp_rmb()
Definition: module.h:1219

Referenced by Ext2UpdateVcbStat(), and ext4_check_descriptors().

◆ ext4_count_free_inodes()

unsigned long ext4_count_free_inodes ( struct super_block sb)

Definition at line 3054 of file generic.c.

3055{
3056 unsigned long desc_count;
3057 struct ext4_group_desc *gdp;
3058 struct buffer_head *bh = NULL;
3060
3061 desc_count = 0;
3062 for (i = 0; i < EXT3_SB(sb)->s_groups_count; i++) {
3063 gdp = ext4_get_group_desc(sb, i, &bh);
3064 if (!bh)
3065 continue;
3066 desc_count += ext4_free_inodes_count(sb, gdp);
3067 fini_bh(&bh);
3068 }
3069 return desc_count;
3070}

Referenced by Ext2UpdateVcbStat(), and ext4_check_descriptors().

◆ ext4_free_blks_count()

__u32 ext4_free_blks_count ( struct super_block sb,
struct ext4_group_desc bg 
)

Definition at line 2483 of file generic.c.

2485{
2486 return le16_to_cpu(bg->bg_free_blocks_count) |
2488 (__u32)le16_to_cpu(bg->bg_free_blocks_count_hi) << 16 : 0);
2489}
__le16 bg_free_blocks_count
Definition: ext3_fs.h:139
__le16 bg_free_blocks_count_hi
Definition: ext3_fs.h:149

Referenced by Ext2NewBlock(), and ext4_count_free_blocks().

◆ ext4_free_blks_set()

void ext4_free_blks_set ( struct super_block sb,
struct ext4_group_desc bg,
__u32  count 
)

◆ ext4_free_inodes_count()

__u32 ext4_free_inodes_count ( struct super_block sb,
struct ext4_group_desc bg 
)

Definition at line 2491 of file generic.c.

2493{
2494 return le16_to_cpu(bg->bg_free_inodes_count) |
2496 (__u32)le16_to_cpu(bg->bg_free_inodes_count_hi) << 16 : 0);
2497}
__le16 bg_free_inodes_count
Definition: ext3_fs.h:140
__le16 bg_free_inodes_count_hi
Definition: ext3_fs.h:150

Referenced by Ext2NewInode(), and ext4_count_free_inodes().

◆ ext4_free_inodes_set()

void ext4_free_inodes_set ( struct super_block sb,
struct ext4_group_desc bg,
__u32  count 
)

◆ ext4_get_group_desc()

struct ext4_group_desc * ext4_get_group_desc ( struct super_block sb,
ext4_group_t  block_group,
struct buffer_head **  bh 
)

ext4_get_group_desc() – load group descriptor from disk @sb: super block @block_group: given block group @bh: pointer to the buffer head to store the block group descriptor

Definition at line 2976 of file generic.c.

2978{
2979 struct ext4_group_desc *desc = NULL;
2980 struct ext3_sb_info *sbi = EXT3_SB(sb);
2981 PEXT2_VCB vcb = sb->s_priv;
2984
2985 if (bh)
2986 *bh = NULL;
2987
2988 if (block_group >= sbi->s_groups_count) {
2989 ext4_error(sb, "ext4_get_group_desc",
2990 "block_group >= groups_count - "
2991 "block_group = %u, groups_count = %u",
2992 block_group, sbi->s_groups_count);
2993
2994 return NULL;
2995 }
2996
2997 _SEH2_TRY {
2998
2999 group = block_group >> EXT4_DESC_PER_BLOCK_BITS(sb);
3000 offset = block_group & (EXT4_DESC_PER_BLOCK(sb) - 1);
3001
3002 if (!sbi->s_gd) {
3003 if (!Ext2LoadGroup(vcb)) {
3005 }
3006 } else if ( !sbi->s_gd[group].block ||
3007 !sbi->s_gd[group].bh) {
3008 if (!Ext2LoadGroupBH(vcb)) {
3010 }
3011 }
3012
3013 desc = (struct ext4_group_desc *)((PCHAR)sbi->s_gd[group].gd +
3015 if (bh) {
3016 atomic_inc(&sbi->s_gd[group].bh->b_count);
3017 *bh = sbi->s_gd[group].bh;
3018 }
3019 } _SEH2_FINALLY {
3020 /* do cleanup */
3021 } _SEH2_END;
3022
3023 return desc;
3024}
static void atomic_inc(atomic_t volatile *v)
Definition: atomic.h:95
#define ext4_error
Definition: ext2fs.h:2594
BOOLEAN Ext2LoadGroup(IN PEXT2_VCB Vcb)
Definition: generic.c:207
char * PCHAR
Definition: typedefs.h:51

Referenced by Ext2CheckBitmapConsistency(), Ext2CheckSetBlock(), Ext2FreeBlock(), Ext2FreeInode(), Ext2GetInodeLba(), Ext2NewBlock(), Ext2NewInode(), Ext2SaveGroup(), Ext2UpdateGroupDirStat(), ext4_check_descriptors(), ext4_count_dirs(), ext4_count_free_blocks(), ext4_count_free_inodes(), and ext4_group_used_meta_blocks().

◆ ext4_get_group_no_and_offset()

void ext4_get_group_no_and_offset ( struct super_block sb,
ext4_fsblk_t  blocknr,
ext4_group_t blockgrpp,
ext4_grpblk_t offsetp 
)

Definition at line 2817 of file generic.c.

2819{
2820 struct ext3_super_block *es = EXT3_SB(sb)->s_es;
2822
2823 blocknr = blocknr - le32_to_cpu(es->s_first_data_block);
2824 offset = do_div(blocknr, EXT4_BLOCKS_PER_GROUP(sb));
2825 if (offsetp)
2826 *offsetp = offset;
2827 if (blockgrpp)
2828 *blockgrpp = (ext4_grpblk_t)blocknr;
2829
2830}
int ext4_grpblk_t
Definition: ext3_fs_i.h:23
#define es
Definition: i386-dis.c:440
#define do_div(n, b)
Definition: module.h:1230

Referenced by ext4_block_in_group().

◆ ext4_group_desc_csum()

__le16 ext4_group_desc_csum ( struct ext3_sb_info sbi,
__u32  block_group,
struct ext4_group_desc gdp 
)

Definition at line 2619 of file generic.c.

2621{
2622 int offset;
2623 __u16 crc = 0;
2624 __le32 le_group = cpu_to_le32(block_group);
2625
2626 /* old crc16 code */
2627 if (!(sbi->s_es->s_feature_ro_compat &
2629 return 0;
2630
2631 offset = offsetof(struct ext4_group_desc, bg_checksum);
2632
2633 crc = crc16(~0, sbi->s_es->s_uuid, sizeof(sbi->s_es->s_uuid));
2634 crc = crc16(crc, (__u8 *)&le_group, sizeof(le_group));
2635 crc = crc16(crc, (__u8 *)gdp, offset);
2636 offset += sizeof(gdp->bg_checksum); /* skip checksum */
2637 /* for checksum of struct ext4_group_desc do the rest...*/
2638 if ((sbi->s_es->s_feature_incompat &
2640 offset < le16_to_cpu(sbi->s_es->s_desc_size))
2641 crc = crc16(crc, (__u8 *)gdp + offset,
2642 le16_to_cpu(sbi->s_es->s_desc_size) -
2643 offset);
2644
2645 return cpu_to_le16(crc);
2646}
u8 __u8
Definition: btrfs.h:17
#define __le32
Definition: types.h:44
#define EXT4_FEATURE_INCOMPAT_64BIT
Definition: ext3_fs.h:710
__u16 crc16(__u16 crc, __u8 const *buffer, size_t len)
Definition: generic.c:2612
#define offsetof(TYPE, MEMBER)

Referenced by Ext2NewBlock(), Ext2NewInode(), Ext2SaveGroup(), ext4_check_descriptors(), and ext4_group_desc_csum_verify().

◆ ext4_group_desc_csum_verify()

int ext4_group_desc_csum_verify ( struct ext3_sb_info sbi,
__u32  block_group,
struct ext4_group_desc gdp 
)

Definition at line 2648 of file generic.c.

2650{
2651 if ((sbi->s_es->s_feature_ro_compat & cpu_to_le32(EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) &&
2652 (gdp->bg_checksum != ext4_group_desc_csum(sbi, block_group, gdp)))
2653 return 0;
2654
2655 return 1;
2656}

Referenced by ext4_check_descriptors(), ext4_init_block_bitmap(), and ext4_init_inode_bitmap().

◆ ext4_group_used_meta_blocks()

static int ext4_group_used_meta_blocks ( struct super_block sb,
ext4_group_t  block_group 
)
static

Definition at line 2842 of file generic.c.

2844{
2845 ext4_fsblk_t tmp;
2846 struct ext3_sb_info *sbi = EXT3_SB(sb);
2847 /* block bitmap, inode bitmap, and inode table blocks */
2848 int used_blocks = sbi->s_itb_per_group + 2;
2849
2851 struct ext4_group_desc *gdp;
2852 struct buffer_head *bh = NULL;
2853
2854 gdp = ext4_get_group_desc(sb, block_group, &bh);
2856 block_group))
2857 used_blocks--;
2858
2860 block_group))
2861 used_blocks--;
2862
2863 tmp = ext4_inode_table(sb, gdp);
2864 for (; tmp < ext4_inode_table(sb, gdp) +
2865 sbi->s_itb_per_group; tmp++) {
2866 if (!ext4_block_in_group(sb, tmp, block_group))
2867 used_blocks -= 1;
2868 }
2869 if (bh)
2870 fini_bh(&bh);
2871 }
2872 return used_blocks;
2873}
static int ext4_block_in_group(struct super_block *sb, ext4_fsblk_t block, ext4_group_t block_group)
Definition: generic.c:2832

Referenced by ext4_init_block_bitmap().

◆ ext4_init_block_bitmap()

unsigned ext4_init_block_bitmap ( struct super_block sb,
struct buffer_head bh,
ext4_group_t  block_group,
struct ext4_group_desc gdp 
)

Definition at line 2877 of file generic.c.

2879{
2880 int bit, bit_max;
2881 unsigned free_blocks, group_blocks;
2882 struct ext3_sb_info *sbi = EXT3_SB(sb);
2883
2884 if (bh) {
2886 /* If checksum is bad mark all blocks used to prevent allocation
2887 * essentially implementing a per-group read-only flag. */
2888 if (!ext4_group_desc_csum_verify(sbi, block_group, gdp)) {
2890 "Checksum bad for group %u", block_group);
2891 ext4_free_blks_set(sb, gdp, 0);
2892 ext4_free_inodes_set(sb, gdp, 0);
2893 ext4_itable_unused_set(sb, gdp, 0);
2894 memset(bh->b_data, 0xff, sb->s_blocksize);
2895 return 0;
2896 }
2897 memset(bh->b_data, 0, sb->s_blocksize);
2898 }
2899
2900 /* Check for superblock and gdt backups in this group */
2901 bit_max = ext3_bg_has_super(sb, block_group);
2902
2904 block_group < le32_to_cpu(sbi->s_es->s_first_meta_bg) *
2905 sbi->s_desc_per_block) {
2906 if (bit_max) {
2907 bit_max += ext4_bg_num_gdb(sb, block_group);
2908 bit_max +=
2909 le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks);
2910 }
2911 } else { /* For META_BG_BLOCK_GROUPS */
2912 bit_max += ext4_bg_num_gdb(sb, block_group);
2913 }
2914
2915 if (block_group == sbi->s_groups_count - 1) {
2916 /*
2917 * Even though mke2fs always initialize first and last group
2918 * if some other tool enabled the EXT4_BG_BLOCK_UNINIT we need
2919 * to make sure we calculate the right free blocks
2920 */
2921 group_blocks = (unsigned int)(ext3_blocks_count(sbi->s_es) -
2922 le32_to_cpu(sbi->s_es->s_first_data_block) -
2923 (EXT4_BLOCKS_PER_GROUP(sb) * (sbi->s_groups_count - 1)));
2924 } else {
2925 group_blocks = EXT4_BLOCKS_PER_GROUP(sb);
2926 }
2927
2928 free_blocks = group_blocks - bit_max;
2929
2930 if (bh) {
2931 ext4_fsblk_t start, tmp;
2932 int flex_bg = 0;
2933
2934 for (bit = 0; bit < bit_max; bit++)
2935 ext4_set_bit(bit, bh->b_data);
2936
2937 start = ext3_group_first_block_no(sb, block_group);
2938
2941 flex_bg = 1;
2942
2943 /* Set bits for block and inode bitmaps, and inode table */
2944 tmp = ext4_block_bitmap(sb, gdp);
2945 if (!flex_bg || ext4_block_in_group(sb, tmp, block_group))
2946 ext4_set_bit(tmp - start, bh->b_data);
2947
2948 tmp = ext4_inode_bitmap(sb, gdp);
2949 if (!flex_bg || ext4_block_in_group(sb, tmp, block_group))
2950 ext4_set_bit(tmp - start, bh->b_data);
2951
2952 tmp = ext4_inode_table(sb, gdp);
2953 for (; tmp < ext4_inode_table(sb, gdp) +
2954 sbi->s_itb_per_group; tmp++) {
2955 if (!flex_bg ||
2956 ext4_block_in_group(sb, tmp, block_group))
2957 ext4_set_bit(tmp - start, bh->b_data);
2958 }
2959 /*
2960 * Also if the number of blocks within the group is
2961 * less than the blocksize * 8 ( which is the size
2962 * of bitmap ), set rest of the block bitmap to 1
2963 */
2964 mark_bitmap_end(group_blocks, sb->s_blocksize * 8, bh->b_data);
2965 }
2966 return free_blocks - ext4_group_used_meta_blocks(sb, block_group);
2967}
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
#define __FUNCTION__
Definition: types.h:116
static int ext4_group_used_meta_blocks(struct super_block *sb, ext4_group_t block_group)
Definition: generic.c:2842
unsigned long ext4_bg_num_gdb(struct super_block *sb, ext4_group_t group)
Definition: generic.c:2722
void mark_bitmap_end(int start_bit, int end_bit, char *bitmap)
Definition: generic.c:2771
#define ext4_set_bit(n, p)
Definition: generic.c:2754
GLuint start
Definition: gl.h:1545
#define memset(x, y, z)
Definition: compat.h:39

Referenced by Ext2NewBlock(), and Ext2NewInode().

◆ ext4_init_inode_bitmap()

unsigned ext4_init_inode_bitmap ( struct super_block sb,
struct buffer_head bh,
ext4_group_t  block_group,
struct ext4_group_desc gdp 
)

Definition at line 2786 of file generic.c.

2789{
2790 struct ext3_sb_info *sbi = EXT3_SB(sb);
2791
2793
2794 /* If checksum is bad mark all blocks and inodes use to prevent
2795 * allocation, essentially implementing a per-group read-only flag. */
2796 if (!ext4_group_desc_csum_verify(sbi, block_group, gdp)) {
2797 ext4_error(sb, __FUNCTION__, "Checksum bad for group %u",
2798 block_group);
2799 ext4_free_blks_set(sb, gdp, 0);
2800 ext4_free_inodes_set(sb, gdp, 0);
2801 ext4_itable_unused_set(sb, gdp, 0);
2802 memset(bh->b_data, 0xff, sb->s_blocksize);
2803 return 0;
2804 }
2805
2806 memset(bh->b_data, 0, (EXT4_INODES_PER_GROUP(sb) + 7) / 8);
2807 mark_bitmap_end(EXT4_INODES_PER_GROUP(sb), sb->s_blocksize * 8,
2808 bh->b_data);
2809 ext4_itable_unused_set(sb, gdp, EXT4_INODES_PER_GROUP(sb));
2810
2811 return EXT4_INODES_PER_GROUP(sb);
2812}

Referenced by Ext2NewInode().

◆ ext4_inode_bitmap()

◆ ext4_inode_bitmap_set()

void ext4_inode_bitmap_set ( struct super_block sb,
struct ext4_group_desc bg,
ext4_fsblk_t  blk 
)

Definition at line 2523 of file generic.c.

2525{
2528 bg->bg_inode_bitmap_hi = cpu_to_le32(blk >> 32);
2529}

◆ ext4_inode_table()

◆ ext4_inode_table_set()

void ext4_inode_table_set ( struct super_block sb,
struct ext4_group_desc bg,
ext4_fsblk_t  blk 
)

Definition at line 2531 of file generic.c.

2533{
2536 bg->bg_inode_table_hi = cpu_to_le32(blk >> 32);
2537}

◆ ext4_itable_unused_count()

__u32 ext4_itable_unused_count ( struct super_block sb,
struct ext4_group_desc bg 
)

Definition at line 2507 of file generic.c.

2509{
2510 return le16_to_cpu(bg->bg_itable_unused) |
2512 (__u32)le16_to_cpu(bg->bg_itable_unused_hi) << 16 : 0);
2513}
__le16 bg_itable_unused
Definition: ext3_fs.h:144
__le16 bg_itable_unused_hi
Definition: ext3_fs.h:152

Referenced by Ext2NewInode().

◆ ext4_itable_unused_set()

void ext4_itable_unused_set ( struct super_block sb,
struct ext4_group_desc bg,
__u32  count 
)

◆ ext4_max_size()

static loff_t ext4_max_size ( int  blkbits,
int  has_huge_files 
)
static

Definition at line 2261 of file generic.c.

2262{
2263 loff_t res;
2265
2266 /* small i_blocks in vfs inode? */
2267 if (!has_huge_files || sizeof(blkcnt_t) < sizeof(u64)) {
2268 /*
2269 * CONFIG_LBD is not enabled implies the inode
2270 * i_block represent total blocks in 512 bytes
2271 * 32 == size of vfs inode i_blocks * 8
2272 */
2273 upper_limit = (1LL << 32) - 1;
2274
2275 /* total blocks in file system block size */
2276 upper_limit >>= (blkbits - 9);
2277 upper_limit <<= blkbits;
2278 }
2279
2280 /* 32-bit extent-start container, ee_block */
2281 res = 1LL << 32;
2282 res <<= blkbits;
2283 res -= 1;
2284
2285 /* Sanity check against vm- & vfs- imposed limits */
2286 if (res > upper_limit)
2287 res = upper_limit;
2288
2289 return res;
2290}

◆ ext4_used_dirs_count()

__u32 ext4_used_dirs_count ( struct super_block sb,
struct ext4_group_desc bg 
)

Definition at line 2499 of file generic.c.

2501{
2502 return le16_to_cpu(bg->bg_used_dirs_count) |
2504 (__u32)le16_to_cpu(bg->bg_used_dirs_count_hi) << 16 : 0);
2505}
__le16 bg_used_dirs_count
Definition: ext3_fs.h:141
__le16 bg_used_dirs_count_hi
Definition: ext3_fs.h:151

Referenced by Ext2FreeInode(), Ext2NewInode(), Ext2UpdateGroupDirStat(), and ext4_count_dirs().

◆ ext4_used_dirs_set()

void ext4_used_dirs_set ( struct super_block sb,
struct ext4_group_desc bg,
__u32  count 
)

Definition at line 2555 of file generic.c.

Referenced by Ext2FreeInode(), Ext2NewInode(), and Ext2UpdateGroupDirStat().

◆ mark_bitmap_end()

void mark_bitmap_end ( int  start_bit,
int  end_bit,
char bitmap 
)

Definition at line 2771 of file generic.c.

2772{
2773 int i;
2774
2775 if (start_bit >= end_bit)
2776 return;
2777
2778 DEBUG(DL_INF, ("mark end bits +%d through +%d used\n", start_bit, end_bit));
2779 for (i = start_bit; (unsigned)i < ((start_bit + 7) & ~7UL); i++)
2781 if (i < end_bit)
2782 memset(bitmap + (i >> 3), 0xff, (end_bit - i) >> 3);
2783}
static unsigned(__cdecl *hash_bstr)(bstr_t s)
Definition: uimain.c:89

Referenced by ext4_init_block_bitmap(), and ext4_init_inode_bitmap().

◆ test_root()

static int test_root ( ext3_group_t  a,
ext3_group_t  b 
)
inlinestatic

Definition at line 2659 of file generic.c.

2660{
2661 ext3_group_t num = b;
2662
2663 while (a > num)
2664 num *= b;
2665 return num == a;
2666}
GLuint GLuint num
Definition: glext.h:9618
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
#define a
Definition: ke_i.h:78
#define b
Definition: ke_i.h:79

Referenced by ext3_group_sparse().

Variable Documentation

◆ crc16_table

__u16 const crc16_table[256]

CRC table for the CRC-16. The poly is 0x8005 (x16 + x15 + x2 + 1)

Definition at line 2572 of file generic.c.

Referenced by crc16_byte().

◆ Ext2Global

PEXT2_GLOBAL Ext2Global
extern

Definition at line 16 of file init.c.