mirror of
				https://github.com/bobranten/Ext4Fsd.git
				synced 2025-10-29 21:18:30 -05:00 
			
		
		
		
	suport for metadata checksums
This commit is contained in:
		| @@ -208,6 +208,7 @@ | ||||
|     <ClCompile Include="ext3\indirect.c" /> | ||||
|     <ClCompile Include="ext3\recover.c" /> | ||||
|     <ClCompile Include="ext4\ext4_bh.c" /> | ||||
|     <ClCompile Include="ext4\ext4_csum.c" /> | ||||
|     <ClCompile Include="ext4\ext4_extents.c" /> | ||||
|     <ClCompile Include="ext4\ext4_jbd2.c" /> | ||||
|     <ClCompile Include="ext4\ext4_xattr.c" /> | ||||
|   | ||||
| @@ -274,6 +274,9 @@ | ||||
|     <ClCompile Include="nls\nls_utf8.c"> | ||||
|       <Filter>Source Files\nls</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="ext4\ext4_csum.c"> | ||||
|       <Filter>Source Files\ext4</Filter> | ||||
|     </ClCompile> | ||||
|   </ItemGroup> | ||||
|   <ItemGroup> | ||||
|     <ClInclude Include="include\ext2fs.h"> | ||||
|   | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -758,7 +758,7 @@ static int call_filldir(struct file * filp, void * cookie, | ||||
|     } | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| #if 0 | ||||
| struct fake_dirent | ||||
| { | ||||
|     __le32 inode; | ||||
| @@ -823,7 +823,7 @@ struct dx_map_entry | ||||
|     __u16 offs; | ||||
|     __u16 size; | ||||
| }; | ||||
|  | ||||
| #endif | ||||
| /* | ||||
|  * Future: use high four bits of block for coalesce-on-delete flags | ||||
|  * Mask them off for now. | ||||
|   | ||||
| @@ -11,7 +11,6 @@ | ||||
|  | ||||
| #include <ext2fs.h> | ||||
| #include <linux/jbd.h> | ||||
| #include <linux/ext3_fs.h> | ||||
|  | ||||
| /* GLOBALS ***************************************************************/ | ||||
|  | ||||
|   | ||||
| @@ -25,5 +25,5 @@ DRIVERTYPE=FS | ||||
| INCLUDES=.;..;..\include;$(DRIVER_INC_PATH); | ||||
|  | ||||
| # The source code: | ||||
| SOURCES= ext4_bh.c ext4_extents.c ext4_jbd2.c extents.c \ | ||||
|          ext4_xattr.c | ||||
| SOURCES= ext4_bh.c ext4_csum.c ext4_extents.c ext4_jbd2.c ext4_xattr.c \ | ||||
|          extents.c | ||||
|   | ||||
							
								
								
									
										757
									
								
								Ext4Fsd/ext4/ext4_csum.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										757
									
								
								Ext4Fsd/ext4/ext4_csum.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,757 @@ | ||||
| /* | ||||
|  * COPYRIGHT:        See COPYRIGHT.TXT | ||||
|  * PROJECT:          Ext2-Ext4 File System Driver for WinXP-Win10 | ||||
|  * FILE:             ext4_csum.c | ||||
|  * PROGRAMMER:       Bo Brant<6E>n <bosse@acc.umu.se> | ||||
|  * HOMEPAGE:         http://www.ext2fsd.com | ||||
|  * UPDATE HISTORY: | ||||
|  */ | ||||
|  | ||||
| /* INCLUDES *****************************************************************/ | ||||
|  | ||||
| #include "ext2fs.h" | ||||
| #include "linux\ext4.h" | ||||
| #include "linux\ext4_xattr.h" | ||||
|  | ||||
| /* GLOBALS ***************************************************************/ | ||||
|  | ||||
| extern PEXT2_GLOBAL Ext2Global; | ||||
|  | ||||
| /* DEFINITIONS *************************************************************/ | ||||
|  | ||||
|  | ||||
| /* FUNCTIONS ***************************************************************/ | ||||
|  | ||||
| /** CRC table for the CRC-16. The poly is 0x8005 (x16 + x15 + x2 + 1) */ | ||||
| __u16 const crc16_table[256] = { | ||||
|     0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241, | ||||
|     0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440, | ||||
|     0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40, | ||||
|     0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841, | ||||
|     0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40, | ||||
|     0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41, | ||||
|     0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641, | ||||
|     0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040, | ||||
|     0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240, | ||||
|     0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441, | ||||
|     0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41, | ||||
|     0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840, | ||||
|     0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41, | ||||
|     0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40, | ||||
|     0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640, | ||||
|     0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041, | ||||
|     0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240, | ||||
|     0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441, | ||||
|     0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41, | ||||
|     0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840, | ||||
|     0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41, | ||||
|     0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40, | ||||
|     0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640, | ||||
|     0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041, | ||||
|     0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241, | ||||
|     0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440, | ||||
|     0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40, | ||||
|     0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841, | ||||
|     0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40, | ||||
|     0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41, | ||||
|     0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641, | ||||
|     0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040 | ||||
| }; | ||||
|  | ||||
| static inline __u16 crc16_byte(__u16 crc, const __u8 data) | ||||
| { | ||||
|     return (crc >> 8) ^ crc16_table[(crc ^ data) & 0xff]; | ||||
| } | ||||
|  | ||||
| static __u16 crc16(__u16 crc, __u8 const *buffer, size_t len) | ||||
| { | ||||
|     while (len--) | ||||
|         crc = crc16_byte(crc, *buffer++); | ||||
|     return crc; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * This is the CRC-32C table | ||||
|  * Generated with: | ||||
|  * width = 32 bits | ||||
|  * poly = 0x1EDC6F41 | ||||
|  * reflect input bytes = true | ||||
|  * reflect output bytes = true | ||||
|  */ | ||||
|  | ||||
| static const __u32 crc32c_table[256] = { | ||||
| 	0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L, | ||||
| 	0xC79A971FL, 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL, | ||||
| 	0x8AD958CFL, 0x78B2DBCCL, 0x6BE22838L, 0x9989AB3BL, | ||||
| 	0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, 0x5E133C24L, | ||||
| 	0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL, | ||||
| 	0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L, | ||||
| 	0x9A879FA0L, 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L, | ||||
| 	0x5D1D08BFL, 0xAF768BBCL, 0xBC267848L, 0x4E4DFB4BL, | ||||
| 	0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, 0x33ED7D2AL, | ||||
| 	0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L, | ||||
| 	0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L, | ||||
| 	0x6DFE410EL, 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL, | ||||
| 	0x30E349B1L, 0xC288CAB2L, 0xD1D83946L, 0x23B3BA45L, | ||||
| 	0xF779DEAEL, 0x05125DADL, 0x1642AE59L, 0xE4292D5AL, | ||||
| 	0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL, | ||||
| 	0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L, | ||||
| 	0x417B1DBCL, 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L, | ||||
| 	0x86E18AA3L, 0x748A09A0L, 0x67DAFA54L, 0x95B17957L, | ||||
| 	0xCBA24573L, 0x39C9C670L, 0x2A993584L, 0xD8F2B687L, | ||||
| 	0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L, | ||||
| 	0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L, | ||||
| 	0x96BF4DCCL, 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L, | ||||
| 	0xDBFC821CL, 0x2997011FL, 0x3AC7F2EBL, 0xC8AC71E8L, | ||||
| 	0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, 0x0F36E6F7L, | ||||
| 	0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L, | ||||
| 	0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L, | ||||
| 	0xEB1FCBADL, 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L, | ||||
| 	0x2C855CB2L, 0xDEEEDFB1L, 0xCDBE2C45L, 0x3FD5AF46L, | ||||
| 	0x7198540DL, 0x83F3D70EL, 0x90A324FAL, 0x62C8A7F9L, | ||||
| 	0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L, | ||||
| 	0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L, | ||||
| 	0x3CDB9BDDL, 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L, | ||||
| 	0x82F63B78L, 0x709DB87BL, 0x63CD4B8FL, 0x91A6C88CL, | ||||
| 	0x456CAC67L, 0xB7072F64L, 0xA457DC90L, 0x563C5F93L, | ||||
| 	0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L, | ||||
| 	0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL, | ||||
| 	0x92A8FC17L, 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L, | ||||
| 	0x55326B08L, 0xA759E80BL, 0xB4091BFFL, 0x466298FCL, | ||||
| 	0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL, 0x0B21572CL, | ||||
| 	0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L, | ||||
| 	0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L, | ||||
| 	0x65D122B9L, 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL, | ||||
| 	0x2892ED69L, 0xDAF96E6AL, 0xC9A99D9EL, 0x3BC21E9DL, | ||||
| 	0xEF087A76L, 0x1D63F975L, 0x0E330A81L, 0xFC588982L, | ||||
| 	0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL, | ||||
| 	0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L, | ||||
| 	0x38CC2A06L, 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L, | ||||
| 	0xFF56BD19L, 0x0D3D3E1AL, 0x1E6DCDEEL, 0xEC064EEDL, | ||||
| 	0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, 0xD0DDD530L, | ||||
| 	0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL, | ||||
| 	0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL, | ||||
| 	0x8ECEE914L, 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L, | ||||
| 	0xD3D3E1ABL, 0x21B862A8L, 0x32E8915CL, 0xC083125FL, | ||||
| 	0x144976B4L, 0xE622F5B7L, 0xF5720643L, 0x07198540L, | ||||
| 	0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L, | ||||
| 	0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL, | ||||
| 	0xE330A81AL, 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL, | ||||
| 	0x24AA3F05L, 0xD6C1BC06L, 0xC5914FF2L, 0x37FACCF1L, | ||||
| 	0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L, 0x7AB90321L, | ||||
| 	0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL, | ||||
| 	0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L, | ||||
| 	0x34F4F86AL, 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL, | ||||
| 	0x79B737BAL, 0x8BDCB4B9L, 0x988C474DL, 0x6AE7C44EL, | ||||
| 	0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L | ||||
| }; | ||||
|  | ||||
| /* | ||||
|  * Steps through buffer one byte at at time, calculates reflected | ||||
|  * crc using table. | ||||
|  */ | ||||
|  | ||||
| static __u32 crc32c(__u32 crc, const __u8 *data, unsigned int length) | ||||
| { | ||||
| 	while (length--) | ||||
| 		crc = crc32c_table[(crc ^ *data++) & 0xFFL] ^ (crc >> 8); | ||||
|  | ||||
| 	return crc; | ||||
| } | ||||
|  | ||||
| __u32 ext4_chksum(struct ext4_sb_info *sbi, __u32 crc, | ||||
| 			      const void *buffer, unsigned int length) | ||||
| { | ||||
|     return crc32c(crc, buffer, length); | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Metadata checksum functions for the superblock. | ||||
|  */ | ||||
|  | ||||
| static __le32 ext4_superblock_csum(struct super_block *sb, | ||||
| 				   struct ext4_super_block *es) | ||||
| { | ||||
| 	struct ext4_sb_info *sbi = EXT4_SB(sb); | ||||
| 	int offset = offsetof(struct ext4_super_block, s_checksum); | ||||
| 	__u32 csum; | ||||
|  | ||||
| 	csum = ext4_chksum(sbi, ~0, (char *)es, offset); | ||||
|  | ||||
| 	return cpu_to_le32(csum); | ||||
| } | ||||
|  | ||||
| int ext4_superblock_csum_verify(struct super_block *sb, | ||||
| 				       struct ext4_super_block *es) | ||||
| { | ||||
| 	if (!ext4_has_feature_metadata_csum(sb)) | ||||
| 		return 1; | ||||
|  | ||||
| 	return es->s_checksum == ext4_superblock_csum(sb, es); | ||||
| } | ||||
|  | ||||
| void ext4_superblock_csum_set(struct super_block *sb) | ||||
| { | ||||
| 	struct ext4_super_block *es = EXT4_SB(sb)->s_es; | ||||
|  | ||||
| 	if (!ext4_has_feature_metadata_csum(sb)) | ||||
| 		return; | ||||
|  | ||||
| 	es->s_checksum = ext4_superblock_csum(sb, es); | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Metadata checksum functions for the group descriptors. | ||||
|  */ | ||||
|  | ||||
| static __le16 ext4_group_desc_csum(struct super_block *sb, __u32 block_group, | ||||
| 				   struct ext4_group_desc *gdp) | ||||
| { | ||||
| 	unsigned int offset = offsetof(struct ext4_group_desc, bg_checksum); | ||||
| 	__u16 crc; | ||||
| 	__le32 le_group = cpu_to_le32(block_group); | ||||
| 	struct ext4_sb_info *sbi = EXT4_SB(sb); | ||||
|  | ||||
| 	if (ext4_has_feature_metadata_csum(sb)) { | ||||
| 		/* Use new metadata_csum algorithm */ | ||||
| 		__u32 csum32; | ||||
| 		__u16 dummy_csum = 0; | ||||
|  | ||||
| 		csum32 = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)&le_group, | ||||
| 				     sizeof(le_group)); | ||||
| 		csum32 = ext4_chksum(sbi, csum32, (__u8 *)gdp, offset); | ||||
| 		csum32 = ext4_chksum(sbi, csum32, (__u8 *)&dummy_csum, | ||||
| 				     sizeof(dummy_csum)); | ||||
| 		offset += sizeof(dummy_csum); | ||||
| 		if (offset < sbi->s_desc_size) | ||||
| 			csum32 = ext4_chksum(sbi, csum32, (__u8 *)gdp + offset, | ||||
| 					     sbi->s_desc_size - offset); | ||||
|  | ||||
| 		crc = csum32 & 0xFFFF; | ||||
| 	} else if (ext4_has_feature_gdt_csum(sb)) { | ||||
|         /* old crc16 code */ | ||||
| 	    crc = crc16(~0, sbi->s_es->s_uuid, sizeof(sbi->s_es->s_uuid)); | ||||
| 	    crc = crc16(crc, (__u8 *)&le_group, sizeof(le_group)); | ||||
| 	    crc = crc16(crc, (__u8 *)gdp, offset); | ||||
| 	    offset += sizeof(gdp->bg_checksum); /* skip checksum */ | ||||
| 	    /* for checksum of struct ext4_group_desc do the rest...*/ | ||||
| 	    if (ext4_has_feature_64bit(sb) && | ||||
| 	        offset < le16_to_cpu(sbi->s_es->s_desc_size)) | ||||
| 		    crc = crc16(crc, (__u8 *)gdp + offset, | ||||
| 			        le16_to_cpu(sbi->s_es->s_desc_size) - | ||||
| 				    offset); | ||||
|     } else { | ||||
|         crc = 0; | ||||
|     } | ||||
|  | ||||
| 	return cpu_to_le16(crc); | ||||
| } | ||||
|  | ||||
| int ext4_group_desc_csum_verify(struct super_block *sb, __u32 block_group, | ||||
| 				struct ext4_group_desc *gdp) | ||||
| { | ||||
| 	if (!ext4_has_feature_metadata_csum(sb)) | ||||
| 		return 1; | ||||
|  | ||||
|     return gdp->bg_checksum == ext4_group_desc_csum(sb, block_group, gdp); | ||||
| } | ||||
|  | ||||
| void ext4_group_desc_csum_set(struct super_block *sb, __u32 block_group, | ||||
| 			      struct ext4_group_desc *gdp) | ||||
| { | ||||
| 	if (!ext4_has_group_desc_csum(sb)) | ||||
| 		return; | ||||
|  | ||||
| 	gdp->bg_checksum = ext4_group_desc_csum(sb, block_group, gdp); | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Metadata checksum functions for the inode bitmap. | ||||
|  */ | ||||
|  | ||||
| int ext4_inode_bitmap_csum_verify(struct super_block *sb, ext4_group_t group, | ||||
| 				  struct ext4_group_desc *gdp, | ||||
| 				  struct buffer_head *bh, int sz) | ||||
| { | ||||
| 	__u32 hi; | ||||
| 	__u32 provided, calculated; | ||||
| 	struct ext4_sb_info *sbi = EXT4_SB(sb); | ||||
|  | ||||
| 	if (!ext4_has_feature_metadata_csum(sb)) | ||||
| 		return 1; | ||||
|  | ||||
| 	provided = le16_to_cpu(gdp->bg_inode_bitmap_csum_lo); | ||||
| 	calculated = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)bh->b_data, sz); | ||||
| 	if (sbi->s_desc_size >= EXT4_BG_INODE_BITMAP_CSUM_HI_END) { | ||||
| 		hi = le16_to_cpu(gdp->bg_inode_bitmap_csum_hi); | ||||
| 		provided |= (hi << 16); | ||||
| 	} else | ||||
| 		calculated &= 0xFFFF; | ||||
|  | ||||
| 	return provided == calculated; | ||||
| } | ||||
|  | ||||
| void ext4_inode_bitmap_csum_set(struct super_block *sb, ext4_group_t group, | ||||
| 				struct ext4_group_desc *gdp, | ||||
| 				struct buffer_head *bh, int sz) | ||||
| { | ||||
| 	__u32 csum; | ||||
| 	struct ext4_sb_info *sbi = EXT4_SB(sb); | ||||
|  | ||||
| 	if (!ext4_has_feature_metadata_csum(sb)) | ||||
| 		return; | ||||
|  | ||||
| 	csum = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)bh->b_data, sz); | ||||
| 	gdp->bg_inode_bitmap_csum_lo = cpu_to_le16(csum & 0xFFFF); | ||||
| 	if (sbi->s_desc_size >= EXT4_BG_INODE_BITMAP_CSUM_HI_END) | ||||
| 		gdp->bg_inode_bitmap_csum_hi = cpu_to_le16(csum >> 16); | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Metadata checksum functions for the block bitmap. | ||||
|  */ | ||||
|  | ||||
| int ext4_block_bitmap_csum_verify(struct super_block *sb, ext4_group_t group, | ||||
| 				  struct ext4_group_desc *gdp, | ||||
| 				  struct buffer_head *bh) | ||||
| { | ||||
| 	__u32 hi; | ||||
| 	__u32 provided, calculated; | ||||
| 	struct ext4_sb_info *sbi = EXT4_SB(sb); | ||||
| 	int sz = EXT4_CLUSTERS_PER_GROUP(sb) / 8; | ||||
|  | ||||
| 	if (!ext4_has_feature_metadata_csum(sb)) | ||||
| 		return 1; | ||||
|  | ||||
| 	provided = le16_to_cpu(gdp->bg_block_bitmap_csum_lo); | ||||
| 	calculated = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)bh->b_data, sz); | ||||
| 	if (sbi->s_desc_size >= EXT4_BG_BLOCK_BITMAP_CSUM_HI_END) { | ||||
| 		hi = le16_to_cpu(gdp->bg_block_bitmap_csum_hi); | ||||
| 		provided |= (hi << 16); | ||||
| 	} else | ||||
| 		calculated &= 0xFFFF; | ||||
|  | ||||
| 	return provided == calculated; | ||||
| } | ||||
|  | ||||
| void ext4_block_bitmap_csum_set(struct super_block *sb, ext4_group_t group, | ||||
| 				struct ext4_group_desc *gdp, | ||||
| 				struct buffer_head *bh) | ||||
| { | ||||
| 	int sz = EXT4_CLUSTERS_PER_GROUP(sb) / 8; | ||||
| 	__u32 csum; | ||||
| 	struct ext4_sb_info *sbi = EXT4_SB(sb); | ||||
|  | ||||
| 	if (!ext4_has_feature_metadata_csum(sb)) | ||||
| 		return; | ||||
|  | ||||
| 	csum = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)bh->b_data, sz); | ||||
| 	gdp->bg_block_bitmap_csum_lo = cpu_to_le16(csum & 0xFFFF); | ||||
| 	if (sbi->s_desc_size >= EXT4_BG_BLOCK_BITMAP_CSUM_HI_END) | ||||
| 		gdp->bg_block_bitmap_csum_hi = cpu_to_le16(csum >> 16); | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Metadata checksum functions for the inodes. | ||||
|  */ | ||||
|  | ||||
| static __le32 ext4_inode_csum_seed(struct inode *inode) | ||||
| { | ||||
| 	/* Precompute checksum seed for inode metadata */ | ||||
| 	if (ext4_has_feature_metadata_csum(inode->i_sb)) { | ||||
| 		struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); | ||||
| 		__u32 csum; | ||||
| 		__le32 inum = cpu_to_le32(inode->i_ino); | ||||
| 		__le32 gen = inode->i_generation; | ||||
| 		csum = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)&inum, sizeof(inum)); | ||||
| 		return ext4_chksum(sbi, csum, (__u8 *)&gen, sizeof(gen)); | ||||
| 	} | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| static __u32 ext4_inode_csum(struct inode *inode, struct ext4_inode *raw, | ||||
| 			      struct ext4_inode_info *ei) | ||||
| { | ||||
| 	struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); | ||||
| 	__u32 csum; | ||||
| 	__u16 dummy_csum = 0; | ||||
| 	int offset = offsetof(struct ext4_inode, i_checksum_lo); | ||||
| 	unsigned int csum_size = sizeof(dummy_csum); | ||||
|  | ||||
| 	csum = ext4_chksum(sbi, ext4_inode_csum_seed(inode), (__u8 *)raw, offset); | ||||
| 	csum = ext4_chksum(sbi, csum, (__u8 *)&dummy_csum, csum_size); | ||||
| 	offset += csum_size; | ||||
| 	csum = ext4_chksum(sbi, csum, (__u8 *)raw + offset, | ||||
| 			   EXT4_GOOD_OLD_INODE_SIZE - offset); | ||||
|  | ||||
| 	if (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE) { | ||||
| 		offset = offsetof(struct ext4_inode, i_checksum_hi); | ||||
| 		csum = ext4_chksum(sbi, csum, (__u8 *)raw + | ||||
| 				   EXT4_GOOD_OLD_INODE_SIZE, | ||||
| 				   offset - EXT4_GOOD_OLD_INODE_SIZE); | ||||
| 		if (EXT4_FITS_IN_INODE(raw, ei, i_checksum_hi)) { | ||||
| 			csum = ext4_chksum(sbi, csum, (__u8 *)&dummy_csum, | ||||
| 					   csum_size); | ||||
| 			offset += csum_size; | ||||
| 		} | ||||
| 		csum = ext4_chksum(sbi, csum, (__u8 *)raw + offset, | ||||
| 				   EXT4_INODE_SIZE(inode->i_sb) - offset); | ||||
| 	} | ||||
|  | ||||
| 	return csum; | ||||
| } | ||||
|  | ||||
| int ext4_inode_csum_verify(struct inode *inode, struct ext4_inode *raw, | ||||
| 				  struct ext4_inode_info *ei) | ||||
| { | ||||
| 	__u32 provided, calculated, isz; | ||||
|  | ||||
| 	if (EXT4_SB(inode->i_sb)->s_es->s_creator_os != | ||||
| 	    cpu_to_le32(EXT4_OS_LINUX) || | ||||
| 	    !ext4_has_feature_metadata_csum(inode->i_sb)) | ||||
| 		return 1; | ||||
|  | ||||
| 	provided = le16_to_cpu(raw->i_checksum_lo); | ||||
| 	calculated = ext4_inode_csum(inode, raw, ei); | ||||
| 	if (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE && | ||||
| 	    EXT4_FITS_IN_INODE(raw, ei, i_checksum_hi)) | ||||
| 		{provided |= ((__u32)le16_to_cpu(raw->i_checksum_hi)) << 16;isz=EXT4_INODE_SIZE(inode->i_sb);} | ||||
| 	else | ||||
| 		{calculated &= 0xFFFF;isz=EXT4_GOOD_OLD_INODE_SIZE;} | ||||
|  | ||||
|     if (provided != calculated) { | ||||
|         DbgPrint("inod %d checksum invalid: %lx!=%lx, isz=%u\n", inode->i_ino, provided, calculated, isz); | ||||
|     } | ||||
|  | ||||
| 	return provided == calculated; | ||||
| } | ||||
|  | ||||
| void ext4_inode_csum_set(struct inode *inode, struct ext4_inode *raw, | ||||
| 				struct ext4_inode_info *ei) | ||||
| { | ||||
| 	__u32 csum; | ||||
|  | ||||
| 	if (EXT4_SB(inode->i_sb)->s_es->s_creator_os != | ||||
| 	    cpu_to_le32(EXT4_OS_LINUX) || | ||||
| 	    !ext4_has_feature_metadata_csum(inode->i_sb)) | ||||
| 		return; | ||||
|  | ||||
| 	csum = ext4_inode_csum(inode, raw, ei); | ||||
| 	raw->i_checksum_lo = cpu_to_le16(csum & 0xFFFF); | ||||
| 	if (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE && | ||||
| 	    EXT4_FITS_IN_INODE(raw, ei, i_checksum_hi)) | ||||
| 		raw->i_checksum_hi = cpu_to_le16(csum >> 16); | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Metadata checksum functions for the extent blocks. | ||||
|  */ | ||||
|  | ||||
| static __le32 ext4_extent_block_csum(struct inode *inode, | ||||
| 				     struct ext4_extent_header *eh) | ||||
| { | ||||
| 	struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); | ||||
| 	__u32 csum; | ||||
|  | ||||
| 	csum = ext4_chksum(sbi, ext4_inode_csum_seed(inode), (__u8 *)eh, EXT4_EXTENT_TAIL_OFFSET(eh)); | ||||
|  | ||||
|     return cpu_to_le32(csum); | ||||
| } | ||||
|  | ||||
| int ext4_extent_block_csum_verify(struct inode *inode, | ||||
| 					 struct ext4_extent_header *eh) | ||||
| { | ||||
| 	struct ext4_extent_tail *et; | ||||
|  | ||||
| 	if (!ext4_has_feature_metadata_csum(inode->i_sb)) | ||||
| 		return 1; | ||||
|  | ||||
| 	et = find_ext4_extent_tail(eh); | ||||
| 	return et->et_checksum == ext4_extent_block_csum(inode, eh); | ||||
| } | ||||
|  | ||||
| void ext4_extent_block_csum_set(struct inode *inode, | ||||
| 				       struct ext4_extent_header *eh) | ||||
| { | ||||
| 	struct ext4_extent_tail *et; | ||||
|  | ||||
| 	if (!ext4_has_feature_metadata_csum(inode->i_sb)) | ||||
| 		return; | ||||
|  | ||||
| 	et = find_ext4_extent_tail(eh); | ||||
| 	et->et_checksum = ext4_extent_block_csum(inode, eh); | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Metadata checksum functions for the directory entrys. | ||||
|  */ | ||||
|  | ||||
| static void initialize_dirent_tail(struct ext4_dir_entry_tail *t, | ||||
| 			    unsigned int blocksize) | ||||
| { | ||||
| 	memset(t, 0, sizeof(struct ext4_dir_entry_tail)); | ||||
| 	t->det_rec_len = ext4_rec_len_to_disk( | ||||
| 			sizeof(struct ext4_dir_entry_tail), blocksize); | ||||
| 	t->det_reserved_ft = EXT4_FT_DIR_CSUM; | ||||
| } | ||||
|  | ||||
| /* Walk through a dirent block to find a checksum "dirent" at the tail */ | ||||
| static struct ext4_dir_entry_tail *get_dirent_tail(struct inode *inode, | ||||
| 						   struct ext4_dir_entry *de) | ||||
| { | ||||
| 	struct ext4_dir_entry_tail *t; | ||||
|  | ||||
| #ifdef PARANOID | ||||
| 	struct ext4_dir_entry *d, *top; | ||||
|  | ||||
| 	d = de; | ||||
| 	top = (struct ext4_dir_entry *)(((void *)de) + | ||||
| 		(EXT4_BLOCK_SIZE(inode->i_sb) - | ||||
| 		sizeof(struct ext4_dir_entry_tail))); | ||||
| 	while (d < top && d->rec_len) | ||||
| 		d = (struct ext4_dir_entry *)(((void *)d) + | ||||
| 		    le16_to_cpu(d->rec_len)); | ||||
|  | ||||
| 	if (d != top) | ||||
| 		return NULL; | ||||
|  | ||||
| 	t = (struct ext4_dir_entry_tail *)d; | ||||
| #else | ||||
| 	t = EXT4_DIRENT_TAIL(de, EXT4_BLOCK_SIZE(inode->i_sb)); | ||||
| #endif | ||||
|  | ||||
| 	if (t->det_reserved_zero1 || | ||||
| 	    le16_to_cpu(t->det_rec_len) != sizeof(struct ext4_dir_entry_tail) || | ||||
| 	    t->det_reserved_zero2 || | ||||
| 	    t->det_reserved_ft != EXT4_FT_DIR_CSUM) | ||||
| 		return NULL; | ||||
|  | ||||
| 	return t; | ||||
| } | ||||
|  | ||||
| static __le32 ext4_dirent_csum(struct inode *inode, | ||||
| 			       struct ext4_dir_entry *dirent, int size) | ||||
| { | ||||
| 	struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); | ||||
| 	__u32 csum; | ||||
|  | ||||
| 	csum = ext4_chksum(sbi, ext4_inode_csum_seed(inode), (__u8 *)dirent, size); | ||||
|  | ||||
|     return cpu_to_le32(csum); | ||||
| } | ||||
|  | ||||
| int ext4_dirent_csum_verify(struct inode *inode, struct ext4_dir_entry *dirent) | ||||
| { | ||||
| 	struct ext4_dir_entry_tail *t; | ||||
|  | ||||
| 	if (!ext4_has_feature_metadata_csum(inode->i_sb)) | ||||
| 		return 1; | ||||
|  | ||||
| 	t = get_dirent_tail(inode, dirent); | ||||
| 	if (!t) { | ||||
|         DbgPrint("No space for directory leaf checksum. Please run e2fsck -D.\n"); | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	if (t->det_checksum != ext4_dirent_csum(inode, dirent, | ||||
| 						(unsigned int)((unsigned char *)t - (unsigned char *)dirent))) | ||||
| 		return 0; | ||||
|  | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| void ext4_dirent_csum_set(struct inode *inode, | ||||
| 				 struct ext4_dir_entry *dirent) | ||||
| { | ||||
| 	struct ext4_dir_entry_tail *t; | ||||
|  | ||||
| 	if (!ext4_has_feature_metadata_csum(inode->i_sb)) | ||||
| 		return; | ||||
|  | ||||
| 	t = get_dirent_tail(inode, dirent); | ||||
| 	if (!t) { | ||||
|         DbgPrint("No space for directory leaf checksum. Please run e2fsck -D.\n"); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	t->det_checksum = ext4_dirent_csum(inode, dirent, | ||||
| 					   (unsigned int)((unsigned char *)t - (unsigned char *)dirent)); | ||||
| } | ||||
|  | ||||
| static struct dx_countlimit *get_dx_countlimit(struct inode *inode, | ||||
| 					       struct ext4_dir_entry *dirent, | ||||
| 					       int *offset) | ||||
| { | ||||
| 	struct ext4_dir_entry *dp; | ||||
| 	struct dx_root_info *root; | ||||
| 	int count_offset; | ||||
|  | ||||
| 	if (le16_to_cpu(dirent->rec_len) == EXT4_BLOCK_SIZE(inode->i_sb)) | ||||
| 		count_offset = 8; | ||||
| 	else if (le16_to_cpu(dirent->rec_len) == 12) { | ||||
| 		dp = (struct ext4_dir_entry *)(((unsigned char *)dirent) + 12); | ||||
| 		if (le16_to_cpu(dp->rec_len) != | ||||
| 		    EXT4_BLOCK_SIZE(inode->i_sb) - 12) | ||||
| 			return NULL; | ||||
| 		root = (struct dx_root_info *)(((unsigned char *)dp + 12)); | ||||
| 		if (root->reserved_zero || | ||||
| 		    root->info_length != sizeof(struct dx_root_info)) | ||||
| 			return NULL; | ||||
| 		count_offset = 32; | ||||
| 	} else | ||||
| 		return NULL; | ||||
|  | ||||
| 	if (offset) | ||||
| 		*offset = count_offset; | ||||
| 	return (struct dx_countlimit *)(((unsigned char *)dirent) + count_offset); | ||||
| } | ||||
|  | ||||
| static __le32 ext4_dx_csum(struct inode *inode, struct ext4_dir_entry *dirent, | ||||
| 			   int count_offset, int count, struct dx_tail *t) | ||||
| { | ||||
| 	struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); | ||||
| 	__u32 csum; | ||||
| 	int size; | ||||
| 	__u32 dummy_csum = 0; | ||||
| 	int offset = offsetof(struct dx_tail, dt_checksum); | ||||
|  | ||||
| 	size = count_offset + (count * sizeof(struct dx_entry)); | ||||
| 	csum = ext4_chksum(sbi, ext4_inode_csum_seed(inode), (__u8 *)dirent, size); | ||||
| 	csum = ext4_chksum(sbi, csum, (__u8 *)t, offset); | ||||
| 	csum = ext4_chksum(sbi, csum, (__u8 *)&dummy_csum, sizeof(dummy_csum)); | ||||
|  | ||||
| 	return cpu_to_le32(csum); | ||||
| } | ||||
|  | ||||
| int ext4_dx_csum_verify(struct inode *inode, | ||||
| 			       struct ext4_dir_entry *dirent) | ||||
| { | ||||
| 	struct dx_countlimit *c; | ||||
| 	struct dx_tail *t; | ||||
| 	int count_offset, limit, count; | ||||
|  | ||||
| 	if (!ext4_has_feature_metadata_csum(inode->i_sb)) | ||||
| 		return 1; | ||||
|  | ||||
| 	c = get_dx_countlimit(inode, dirent, &count_offset); | ||||
| 	if (!c) { | ||||
| 		DbgPrint("dir seems corrupt?  Run e2fsck -D."); | ||||
| 		return 0; | ||||
| 	} | ||||
| 	limit = le16_to_cpu(c->limit); | ||||
| 	count = le16_to_cpu(c->count); | ||||
| 	if (count_offset + (limit * sizeof(struct dx_entry)) > | ||||
| 	    EXT4_BLOCK_SIZE(inode->i_sb) - sizeof(struct dx_tail)) { | ||||
| 		DbgPrint("warn_no_space_for_csum in inode\n"); | ||||
| 		return 0; | ||||
| 	} | ||||
| 	t = (struct dx_tail *)(((struct dx_entry *)c) + limit); | ||||
|  | ||||
| 	return t->dt_checksum == ext4_dx_csum(inode, dirent, count_offset, count, t); | ||||
| } | ||||
|  | ||||
| void ext4_dx_csum_set(struct inode *inode, struct ext4_dir_entry *dirent) | ||||
| { | ||||
| 	struct dx_countlimit *c; | ||||
| 	struct dx_tail *t; | ||||
| 	int count_offset, limit, count; | ||||
|  | ||||
| 	if (!ext4_has_feature_metadata_csum(inode->i_sb)) | ||||
| 		return; | ||||
|  | ||||
| 	c = get_dx_countlimit(inode, dirent, &count_offset); | ||||
| 	if (!c) { | ||||
| 		DbgPrint("dir seems corrupt?  Run e2fsck -D."); | ||||
| 		return; | ||||
| 	} | ||||
| 	limit = le16_to_cpu(c->limit); | ||||
| 	count = le16_to_cpu(c->count); | ||||
| 	if (count_offset + (limit * sizeof(struct dx_entry)) > | ||||
| 	    EXT4_BLOCK_SIZE(inode->i_sb) - sizeof(struct dx_tail)) { | ||||
| 		DbgPrint("warn_no_space_for_csum in inode\n"); | ||||
| 		return; | ||||
| 	} | ||||
| 	t = (struct dx_tail *)(((struct dx_entry *)c) + limit); | ||||
|  | ||||
| 	t->dt_checksum = ext4_dx_csum(inode, dirent, count_offset, count, t); | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Metadata checksum functions for the multiple mount point structure. | ||||
|  */ | ||||
|  | ||||
| static __le32 ext4_mmp_csum(struct super_block *sb, struct mmp_struct *mmp) | ||||
| { | ||||
| 	struct ext4_sb_info *sbi = EXT4_SB(sb); | ||||
| 	int offset = offsetof(struct mmp_struct, mmp_checksum); | ||||
| 	__u32 csum; | ||||
|  | ||||
| 	csum = ext4_chksum(sbi, sbi->s_csum_seed, (char *)mmp, offset); | ||||
|  | ||||
| 	return cpu_to_le32(csum); | ||||
| } | ||||
|  | ||||
| int ext4_mmp_csum_verify(struct super_block *sb, struct mmp_struct *mmp) | ||||
| { | ||||
| 	if (!ext4_has_feature_metadata_csum(sb)) | ||||
| 		return 1; | ||||
|  | ||||
| 	return mmp->mmp_checksum == ext4_mmp_csum(sb, mmp); | ||||
| } | ||||
|  | ||||
| void ext4_mmp_csum_set(struct super_block *sb, struct mmp_struct *mmp) | ||||
| { | ||||
| 	if (!ext4_has_feature_metadata_csum(sb)) | ||||
| 		return; | ||||
|  | ||||
| 	mmp->mmp_checksum = ext4_mmp_csum(sb, mmp); | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Metadata checksum functions for the extended attributes. | ||||
|  */ | ||||
|  | ||||
| static __le32 ext4_xattr_block_csum(struct inode *inode, | ||||
| 				    sector_t block_nr, | ||||
| 				    struct ext4_xattr_header *hdr) | ||||
| { | ||||
| 	struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); | ||||
| 	__u32 csum; | ||||
| 	__le64 dsk_block_nr = cpu_to_le64(block_nr); | ||||
| 	__u32 dummy_csum = 0; | ||||
| 	int offset = offsetof(struct ext4_xattr_header, h_checksum); | ||||
|  | ||||
| 	csum = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)&dsk_block_nr, | ||||
| 			   sizeof(dsk_block_nr)); | ||||
| 	csum = ext4_chksum(sbi, csum, (__u8 *)hdr, offset); | ||||
| 	csum = ext4_chksum(sbi, csum, (__u8 *)&dummy_csum, sizeof(dummy_csum)); | ||||
| 	offset += sizeof(dummy_csum); | ||||
| 	csum = ext4_chksum(sbi, csum, (__u8 *)hdr + offset, | ||||
| 			   EXT4_BLOCK_SIZE(inode->i_sb) - offset); | ||||
|  | ||||
| 	return cpu_to_le32(csum); | ||||
| } | ||||
|  | ||||
| int ext4_xattr_block_csum_verify(struct inode *inode, | ||||
| 					struct buffer_head *bh) | ||||
| { | ||||
| 	struct ext4_xattr_header *hdr = EXT4_XATTR_BHDR(bh); | ||||
| 	int ret = 1; | ||||
|  | ||||
| 	if (ext4_has_feature_metadata_csum(inode->i_sb)) { | ||||
| 		lock_buffer(bh); | ||||
| 		ret = (hdr->h_checksum == ext4_xattr_block_csum(inode, | ||||
| 							bh->b_blocknr, hdr)); | ||||
| 		unlock_buffer(bh); | ||||
| 	} | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| void ext4_xattr_block_csum_set(struct inode *inode, | ||||
| 				      struct buffer_head *bh) | ||||
| { | ||||
| 	if (ext4_has_feature_metadata_csum(inode->i_sb)) | ||||
| 		EXT4_XATTR_BHDR(bh)->h_checksum = ext4_xattr_block_csum(inode, | ||||
| 						bh->b_blocknr, EXT4_XATTR_BHDR(bh)); | ||||
| } | ||||
| @@ -1,71 +1,72 @@ | ||||
| #include "ext2fs.h" | ||||
| #include "linux\ext4.h" | ||||
|  | ||||
| static handle_t no_journal; | ||||
|  | ||||
| handle_t *__ext4_journal_start_sb(void *icb, struct super_block *sb, unsigned int line, | ||||
| 				  int type, int blocks, int rsv_blocks) | ||||
| { | ||||
| 	return &no_journal; | ||||
| } | ||||
|  | ||||
| int __ext4_journal_stop(const char *where, unsigned int line, void *icb, handle_t *handle) | ||||
| { | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| void ext4_journal_abort_handle(const char *caller, unsigned int line, | ||||
| 			       const char *err_fn, struct buffer_head *bh, | ||||
| 			       handle_t *handle, int err) | ||||
| { | ||||
| } | ||||
|  | ||||
| int __ext4_journal_get_write_access(const char *where, unsigned int line, | ||||
| 				    void *icb, handle_t *handle, struct buffer_head *bh) | ||||
| { | ||||
| 	int err = 0; | ||||
| 	return err; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * The ext4 forget function must perform a revoke if we are freeing data | ||||
|  * which has been journaled.  Metadata (eg. indirect blocks) must be | ||||
|  * revoked in all cases. | ||||
|  * | ||||
|  * "bh" may be NULL: a metadata block may have been freed from memory | ||||
|  * but there may still be a record of it in the journal, and that record | ||||
|  * still needs to be revoked. | ||||
|  * | ||||
|  * If the handle isn't valid we're not journaling, but we still need to | ||||
|  * call into ext4_journal_revoke() to put the buffer head. | ||||
|  */ | ||||
| int __ext4_forget(const char *where, unsigned int line, void *icb, handle_t *handle, | ||||
| 		  int is_metadata, struct inode *inode, | ||||
| 		  struct buffer_head *bh, ext4_fsblk_t blocknr) | ||||
| { | ||||
| 	int err = 0; | ||||
| 	return err; | ||||
| } | ||||
|  | ||||
| int __ext4_journal_get_create_access(const char *where, unsigned int line, | ||||
| 				void *icb, handle_t *handle, struct buffer_head *bh) | ||||
| { | ||||
| 	int err = 0; | ||||
| 	return err; | ||||
| } | ||||
|  | ||||
| int __ext4_handle_dirty_metadata(const char *where, unsigned int line, | ||||
| 				 void *icb, handle_t *handle, struct inode *inode, | ||||
| 				 struct buffer_head *bh) | ||||
| { | ||||
| 	int err = 0; | ||||
|  | ||||
| 	extents_mark_buffer_dirty(bh); | ||||
| 	return err; | ||||
| } | ||||
|  | ||||
| int __ext4_handle_dirty_super(const char *where, unsigned int line, | ||||
| 			      handle_t *handle, struct super_block *sb) | ||||
| { | ||||
|     return 0; | ||||
| } | ||||
| #include "ext2fs.h" | ||||
| #include "linux\ext4.h" | ||||
| #include "linux\jbd.h" | ||||
|  | ||||
| static handle_t no_journal; | ||||
|  | ||||
| handle_t *__ext4_journal_start_sb(void *icb, struct super_block *sb, unsigned int line, | ||||
| 				  int type, int blocks, int rsv_blocks) | ||||
| { | ||||
| 	return &no_journal; | ||||
| } | ||||
|  | ||||
| int __ext4_journal_stop(const char *where, unsigned int line, void *icb, handle_t *handle) | ||||
| { | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| void ext4_journal_abort_handle(const char *caller, unsigned int line, | ||||
| 			       const char *err_fn, struct buffer_head *bh, | ||||
| 			       handle_t *handle, int err) | ||||
| { | ||||
| } | ||||
|  | ||||
| int __ext4_journal_get_write_access(const char *where, unsigned int line, | ||||
| 				    void *icb, handle_t *handle, struct buffer_head *bh) | ||||
| { | ||||
| 	int err = 0; | ||||
| 	return err; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * The ext4 forget function must perform a revoke if we are freeing data | ||||
|  * which has been journaled.  Metadata (eg. indirect blocks) must be | ||||
|  * revoked in all cases. | ||||
|  * | ||||
|  * "bh" may be NULL: a metadata block may have been freed from memory | ||||
|  * but there may still be a record of it in the journal, and that record | ||||
|  * still needs to be revoked. | ||||
|  * | ||||
|  * If the handle isn't valid we're not journaling, but we still need to | ||||
|  * call into ext4_journal_revoke() to put the buffer head. | ||||
|  */ | ||||
| int __ext4_forget(const char *where, unsigned int line, void *icb, handle_t *handle, | ||||
| 		  int is_metadata, struct inode *inode, | ||||
| 		  struct buffer_head *bh, ext4_fsblk_t blocknr) | ||||
| { | ||||
| 	int err = 0; | ||||
| 	return err; | ||||
| } | ||||
|  | ||||
| int __ext4_journal_get_create_access(const char *where, unsigned int line, | ||||
| 				void *icb, handle_t *handle, struct buffer_head *bh) | ||||
| { | ||||
| 	int err = 0; | ||||
| 	return err; | ||||
| } | ||||
|  | ||||
| int __ext4_handle_dirty_metadata(const char *where, unsigned int line, | ||||
| 				 void *icb, handle_t *handle, struct inode *inode, | ||||
| 				 struct buffer_head *bh) | ||||
| { | ||||
| 	int err = 0; | ||||
|  | ||||
| 	extents_mark_buffer_dirty(bh); | ||||
| 	return err; | ||||
| } | ||||
|  | ||||
| int __ext4_handle_dirty_super(const char *where, unsigned int line, | ||||
| 			      handle_t *handle, struct super_block *sb) | ||||
| { | ||||
|     return 0; | ||||
| } | ||||
|   | ||||
							
								
								
									
										5758
									
								
								Ext4Fsd/fsctl.c
									
									
									
									
									
								
							
							
						
						
									
										5758
									
								
								Ext4Fsd/fsctl.c
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -17,9 +17,6 @@ | ||||
| #include <stdio.h> | ||||
| #include <time.h> | ||||
| #include <string.h> | ||||
| #include <linux/ext2_fs.h> | ||||
| #include <linux/ext3_fs.h> | ||||
| #include <linux/ext3_fs_i.h> | ||||
| #include <linux/ext4.h> | ||||
|  | ||||
| /* DEBUG ****************************************************************/ | ||||
| @@ -2021,10 +2018,10 @@ loff_t ext3_max_size(int blkbits, int has_huge_files); | ||||
| loff_t ext3_max_bitmap_size(int bits, int has_huge_files); | ||||
|  | ||||
|  | ||||
| __le16 ext4_group_desc_csum(struct ext3_sb_info *sbi, __u32 block_group, | ||||
| /*__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); | ||||
|                                 struct ext4_group_desc *gdp);*/ | ||||
|  | ||||
| ext3_fsblk_t descriptor_loc(struct super_block *sb, | ||||
|                             ext3_fsblk_t logical_sb_block, unsigned int nr); | ||||
|   | ||||
| @@ -17,7 +17,6 @@ | ||||
|  | ||||
| #include <linux/fs.h> | ||||
| #include <linux/jbd.h> | ||||
| #include <linux/ext3_fs.h> | ||||
|  | ||||
| #define EXT3_JOURNAL(inode)	(EXT3_SB((inode)->i_sb)->s_journal) | ||||
|  | ||||
|   | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -86,7 +86,7 @@ struct ext4_xattr_entry { | ||||
|  | ||||
| #pragma pack(pop) | ||||
|  | ||||
| #define EXT4_GOOD_OLD_INODE_SIZE	EXT2_GOOD_OLD_INODE_SIZE | ||||
| //#define EXT4_GOOD_OLD_INODE_SIZE	EXT2_GOOD_OLD_INODE_SIZE | ||||
|  | ||||
| #define EXT4_XATTR_PAD_BITS		2 | ||||
| #define EXT4_XATTR_PAD		(1<<EXT4_XATTR_PAD_BITS) | ||||
|   | ||||
							
								
								
									
										7048
									
								
								Ext4Fsd/memory.c
									
									
									
									
									
								
							
							
						
						
									
										7048
									
								
								Ext4Fsd/memory.c
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Reference in New Issue
	
	Block a user