mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	ext4: clean up feature test macros with predicate functions
Create separate predicate functions to test/set/clear feature flags, thereby replacing the wordy old macros. Furthermore, clean out the places where we open-coded feature tests. Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
This commit is contained in:
		
							parent
							
								
									6a797d2737
								
							
						
					
					
						commit
						e2b911c535
					
				
					 15 changed files with 252 additions and 184 deletions
				
			
		| 
						 | 
					@ -213,7 +213,7 @@ static int ext4_init_block_bitmap(struct super_block *sb,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	start = ext4_group_first_block_no(sb, block_group);
 | 
						start = ext4_group_first_block_no(sb, block_group);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG))
 | 
						if (ext4_has_feature_flex_bg(sb))
 | 
				
			||||||
		flex_bg = 1;
 | 
							flex_bg = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Set bits for block and inode bitmaps, and inode table */
 | 
						/* Set bits for block and inode bitmaps, and inode table */
 | 
				
			||||||
| 
						 | 
					@ -322,7 +322,7 @@ static ext4_fsblk_t ext4_valid_block_bitmap(struct super_block *sb,
 | 
				
			||||||
	ext4_fsblk_t blk;
 | 
						ext4_fsblk_t blk;
 | 
				
			||||||
	ext4_fsblk_t group_first_block;
 | 
						ext4_fsblk_t group_first_block;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG)) {
 | 
						if (ext4_has_feature_flex_bg(sb)) {
 | 
				
			||||||
		/* with FLEX_BG, the inode/block bitmaps and itable
 | 
							/* with FLEX_BG, the inode/block bitmaps and itable
 | 
				
			||||||
		 * blocks may not be in the group at all
 | 
							 * blocks may not be in the group at all
 | 
				
			||||||
		 * so the bitmap validation will be skipped for those groups
 | 
							 * so the bitmap validation will be skipped for those groups
 | 
				
			||||||
| 
						 | 
					@ -740,14 +740,13 @@ int ext4_bg_has_super(struct super_block *sb, ext4_group_t group)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (group == 0)
 | 
						if (group == 0)
 | 
				
			||||||
		return 1;
 | 
							return 1;
 | 
				
			||||||
	if (EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_SPARSE_SUPER2)) {
 | 
						if (ext4_has_feature_sparse_super2(sb)) {
 | 
				
			||||||
		if (group == le32_to_cpu(es->s_backup_bgs[0]) ||
 | 
							if (group == le32_to_cpu(es->s_backup_bgs[0]) ||
 | 
				
			||||||
		    group == le32_to_cpu(es->s_backup_bgs[1]))
 | 
							    group == le32_to_cpu(es->s_backup_bgs[1]))
 | 
				
			||||||
			return 1;
 | 
								return 1;
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if ((group <= 1) || !EXT4_HAS_RO_COMPAT_FEATURE(sb,
 | 
						if ((group <= 1) || !ext4_has_feature_sparse_super(sb))
 | 
				
			||||||
					EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER))
 | 
					 | 
				
			||||||
		return 1;
 | 
							return 1;
 | 
				
			||||||
	if (!(group & 1))
 | 
						if (!(group & 1))
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
| 
						 | 
					@ -776,7 +775,7 @@ static unsigned long ext4_bg_num_gdb_nometa(struct super_block *sb,
 | 
				
			||||||
	if (!ext4_bg_has_super(sb, group))
 | 
						if (!ext4_bg_has_super(sb, group))
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (EXT4_HAS_INCOMPAT_FEATURE(sb,EXT4_FEATURE_INCOMPAT_META_BG))
 | 
						if (ext4_has_feature_meta_bg(sb))
 | 
				
			||||||
		return le32_to_cpu(EXT4_SB(sb)->s_es->s_first_meta_bg);
 | 
							return le32_to_cpu(EXT4_SB(sb)->s_es->s_first_meta_bg);
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		return EXT4_SB(sb)->s_gdb_count;
 | 
							return EXT4_SB(sb)->s_gdb_count;
 | 
				
			||||||
| 
						 | 
					@ -797,8 +796,7 @@ unsigned long ext4_bg_num_gdb(struct super_block *sb, ext4_group_t group)
 | 
				
			||||||
			le32_to_cpu(EXT4_SB(sb)->s_es->s_first_meta_bg);
 | 
								le32_to_cpu(EXT4_SB(sb)->s_es->s_first_meta_bg);
 | 
				
			||||||
	unsigned long metagroup = group / EXT4_DESC_PER_BLOCK(sb);
 | 
						unsigned long metagroup = group / EXT4_DESC_PER_BLOCK(sb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!EXT4_HAS_INCOMPAT_FEATURE(sb,EXT4_FEATURE_INCOMPAT_META_BG) ||
 | 
						if (!ext4_has_feature_meta_bg(sb) || metagroup < first_meta_bg)
 | 
				
			||||||
			metagroup < first_meta_bg)
 | 
					 | 
				
			||||||
		return ext4_bg_num_gdb_nometa(sb, group);
 | 
							return ext4_bg_num_gdb_nometa(sb, group);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return ext4_bg_num_gdb_meta(sb,group);
 | 
						return ext4_bg_num_gdb_meta(sb,group);
 | 
				
			||||||
| 
						 | 
					@ -818,7 +816,7 @@ static unsigned ext4_num_base_meta_clusters(struct super_block *sb,
 | 
				
			||||||
	/* Check for superblock and gdt backups in this group */
 | 
						/* Check for superblock and gdt backups in this group */
 | 
				
			||||||
	num = ext4_bg_has_super(sb, block_group);
 | 
						num = ext4_bg_has_super(sb, block_group);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_META_BG) ||
 | 
						if (!ext4_has_feature_meta_bg(sb) ||
 | 
				
			||||||
	    block_group < le32_to_cpu(sbi->s_es->s_first_meta_bg) *
 | 
						    block_group < le32_to_cpu(sbi->s_es->s_first_meta_bg) *
 | 
				
			||||||
			  sbi->s_desc_per_block) {
 | 
								  sbi->s_desc_per_block) {
 | 
				
			||||||
		if (num) {
 | 
							if (num) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -40,8 +40,7 @@ static int is_dx_dir(struct inode *inode)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct super_block *sb = inode->i_sb;
 | 
						struct super_block *sb = inode->i_sb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (EXT4_HAS_COMPAT_FEATURE(inode->i_sb,
 | 
						if (ext4_has_feature_dir_index(inode->i_sb) &&
 | 
				
			||||||
		     EXT4_FEATURE_COMPAT_DIR_INDEX) &&
 | 
					 | 
				
			||||||
	    ((ext4_test_inode_flag(inode, EXT4_INODE_INDEX)) ||
 | 
						    ((ext4_test_inode_flag(inode, EXT4_INODE_INDEX)) ||
 | 
				
			||||||
	     ((inode->i_size >> sb->s_blocksize_bits) == 1) ||
 | 
						     ((inode->i_size >> sb->s_blocksize_bits) == 1) ||
 | 
				
			||||||
	     ext4_has_inline_data(inode)))
 | 
						     ext4_has_inline_data(inode)))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										146
									
								
								fs/ext4/ext4.h
									
									
									
									
									
								
							
							
						
						
									
										146
									
								
								fs/ext4/ext4.h
									
									
									
									
									
								
							| 
						 | 
					@ -1528,6 +1528,7 @@ static inline int ext4_encrypted_inode(struct inode *inode)
 | 
				
			||||||
 * Feature set definitions
 | 
					 * Feature set definitions
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Use the ext4_{has,set,clear}_feature_* helpers; these will be removed */
 | 
				
			||||||
#define EXT4_HAS_COMPAT_FEATURE(sb,mask)			\
 | 
					#define EXT4_HAS_COMPAT_FEATURE(sb,mask)			\
 | 
				
			||||||
	((EXT4_SB(sb)->s_es->s_feature_compat & cpu_to_le32(mask)) != 0)
 | 
						((EXT4_SB(sb)->s_es->s_feature_compat & cpu_to_le32(mask)) != 0)
 | 
				
			||||||
#define EXT4_HAS_RO_COMPAT_FEATURE(sb,mask)			\
 | 
					#define EXT4_HAS_RO_COMPAT_FEATURE(sb,mask)			\
 | 
				
			||||||
| 
						 | 
					@ -1590,6 +1591,94 @@ static inline int ext4_encrypted_inode(struct inode *inode)
 | 
				
			||||||
#define EXT4_FEATURE_INCOMPAT_INLINE_DATA	0x8000 /* data in inode */
 | 
					#define EXT4_FEATURE_INCOMPAT_INLINE_DATA	0x8000 /* data in inode */
 | 
				
			||||||
#define EXT4_FEATURE_INCOMPAT_ENCRYPT		0x10000
 | 
					#define EXT4_FEATURE_INCOMPAT_ENCRYPT		0x10000
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define EXT4_FEATURE_COMPAT_FUNCS(name, flagname) \
 | 
				
			||||||
 | 
					static inline bool ext4_has_feature_##name(struct super_block *sb) \
 | 
				
			||||||
 | 
					{ \
 | 
				
			||||||
 | 
						return ((EXT4_SB(sb)->s_es->s_feature_compat & \
 | 
				
			||||||
 | 
							cpu_to_le32(EXT4_FEATURE_COMPAT_##flagname)) != 0); \
 | 
				
			||||||
 | 
					} \
 | 
				
			||||||
 | 
					static inline void ext4_set_feature_##name(struct super_block *sb) \
 | 
				
			||||||
 | 
					{ \
 | 
				
			||||||
 | 
						EXT4_SB(sb)->s_es->s_feature_compat |= \
 | 
				
			||||||
 | 
							cpu_to_le32(EXT4_FEATURE_COMPAT_##flagname); \
 | 
				
			||||||
 | 
					} \
 | 
				
			||||||
 | 
					static inline void ext4_clear_feature_##name(struct super_block *sb) \
 | 
				
			||||||
 | 
					{ \
 | 
				
			||||||
 | 
						EXT4_SB(sb)->s_es->s_feature_compat &= \
 | 
				
			||||||
 | 
							~cpu_to_le32(EXT4_FEATURE_COMPAT_##flagname); \
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define EXT4_FEATURE_RO_COMPAT_FUNCS(name, flagname) \
 | 
				
			||||||
 | 
					static inline bool ext4_has_feature_##name(struct super_block *sb) \
 | 
				
			||||||
 | 
					{ \
 | 
				
			||||||
 | 
						return ((EXT4_SB(sb)->s_es->s_feature_ro_compat & \
 | 
				
			||||||
 | 
							cpu_to_le32(EXT4_FEATURE_RO_COMPAT_##flagname)) != 0); \
 | 
				
			||||||
 | 
					} \
 | 
				
			||||||
 | 
					static inline void ext4_set_feature_##name(struct super_block *sb) \
 | 
				
			||||||
 | 
					{ \
 | 
				
			||||||
 | 
						EXT4_SB(sb)->s_es->s_feature_ro_compat |= \
 | 
				
			||||||
 | 
							cpu_to_le32(EXT4_FEATURE_RO_COMPAT_##flagname); \
 | 
				
			||||||
 | 
					} \
 | 
				
			||||||
 | 
					static inline void ext4_clear_feature_##name(struct super_block *sb) \
 | 
				
			||||||
 | 
					{ \
 | 
				
			||||||
 | 
						EXT4_SB(sb)->s_es->s_feature_ro_compat &= \
 | 
				
			||||||
 | 
							~cpu_to_le32(EXT4_FEATURE_RO_COMPAT_##flagname); \
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define EXT4_FEATURE_INCOMPAT_FUNCS(name, flagname) \
 | 
				
			||||||
 | 
					static inline bool ext4_has_feature_##name(struct super_block *sb) \
 | 
				
			||||||
 | 
					{ \
 | 
				
			||||||
 | 
						return ((EXT4_SB(sb)->s_es->s_feature_incompat & \
 | 
				
			||||||
 | 
							cpu_to_le32(EXT4_FEATURE_INCOMPAT_##flagname)) != 0); \
 | 
				
			||||||
 | 
					} \
 | 
				
			||||||
 | 
					static inline void ext4_set_feature_##name(struct super_block *sb) \
 | 
				
			||||||
 | 
					{ \
 | 
				
			||||||
 | 
						EXT4_SB(sb)->s_es->s_feature_incompat |= \
 | 
				
			||||||
 | 
							cpu_to_le32(EXT4_FEATURE_INCOMPAT_##flagname); \
 | 
				
			||||||
 | 
					} \
 | 
				
			||||||
 | 
					static inline void ext4_clear_feature_##name(struct super_block *sb) \
 | 
				
			||||||
 | 
					{ \
 | 
				
			||||||
 | 
						EXT4_SB(sb)->s_es->s_feature_incompat &= \
 | 
				
			||||||
 | 
							~cpu_to_le32(EXT4_FEATURE_INCOMPAT_##flagname); \
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EXT4_FEATURE_COMPAT_FUNCS(dir_prealloc,		DIR_PREALLOC)
 | 
				
			||||||
 | 
					EXT4_FEATURE_COMPAT_FUNCS(imagic_inodes,	IMAGIC_INODES)
 | 
				
			||||||
 | 
					EXT4_FEATURE_COMPAT_FUNCS(journal,		HAS_JOURNAL)
 | 
				
			||||||
 | 
					EXT4_FEATURE_COMPAT_FUNCS(xattr,		EXT_ATTR)
 | 
				
			||||||
 | 
					EXT4_FEATURE_COMPAT_FUNCS(resize_inode,		RESIZE_INODE)
 | 
				
			||||||
 | 
					EXT4_FEATURE_COMPAT_FUNCS(dir_index,		DIR_INDEX)
 | 
				
			||||||
 | 
					EXT4_FEATURE_COMPAT_FUNCS(sparse_super2,	SPARSE_SUPER2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EXT4_FEATURE_RO_COMPAT_FUNCS(sparse_super,	SPARSE_SUPER)
 | 
				
			||||||
 | 
					EXT4_FEATURE_RO_COMPAT_FUNCS(large_file,	LARGE_FILE)
 | 
				
			||||||
 | 
					EXT4_FEATURE_RO_COMPAT_FUNCS(btree_dir,		BTREE_DIR)
 | 
				
			||||||
 | 
					EXT4_FEATURE_RO_COMPAT_FUNCS(huge_file,		HUGE_FILE)
 | 
				
			||||||
 | 
					EXT4_FEATURE_RO_COMPAT_FUNCS(gdt_csum,		GDT_CSUM)
 | 
				
			||||||
 | 
					EXT4_FEATURE_RO_COMPAT_FUNCS(dir_nlink,		DIR_NLINK)
 | 
				
			||||||
 | 
					EXT4_FEATURE_RO_COMPAT_FUNCS(extra_isize,	EXTRA_ISIZE)
 | 
				
			||||||
 | 
					EXT4_FEATURE_RO_COMPAT_FUNCS(quota,		QUOTA)
 | 
				
			||||||
 | 
					EXT4_FEATURE_RO_COMPAT_FUNCS(bigalloc,		BIGALLOC)
 | 
				
			||||||
 | 
					EXT4_FEATURE_RO_COMPAT_FUNCS(metadata_csum,	METADATA_CSUM)
 | 
				
			||||||
 | 
					EXT4_FEATURE_RO_COMPAT_FUNCS(readonly,		READONLY)
 | 
				
			||||||
 | 
					EXT4_FEATURE_RO_COMPAT_FUNCS(project,		PROJECT)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EXT4_FEATURE_INCOMPAT_FUNCS(compression,	COMPRESSION)
 | 
				
			||||||
 | 
					EXT4_FEATURE_INCOMPAT_FUNCS(filetype,		FILETYPE)
 | 
				
			||||||
 | 
					EXT4_FEATURE_INCOMPAT_FUNCS(journal_needs_recovery,	RECOVER)
 | 
				
			||||||
 | 
					EXT4_FEATURE_INCOMPAT_FUNCS(journal_dev,	JOURNAL_DEV)
 | 
				
			||||||
 | 
					EXT4_FEATURE_INCOMPAT_FUNCS(meta_bg,		META_BG)
 | 
				
			||||||
 | 
					EXT4_FEATURE_INCOMPAT_FUNCS(extents,		EXTENTS)
 | 
				
			||||||
 | 
					EXT4_FEATURE_INCOMPAT_FUNCS(64bit,		64BIT)
 | 
				
			||||||
 | 
					EXT4_FEATURE_INCOMPAT_FUNCS(mmp,		MMP)
 | 
				
			||||||
 | 
					EXT4_FEATURE_INCOMPAT_FUNCS(flex_bg,		FLEX_BG)
 | 
				
			||||||
 | 
					EXT4_FEATURE_INCOMPAT_FUNCS(ea_inode,		EA_INODE)
 | 
				
			||||||
 | 
					EXT4_FEATURE_INCOMPAT_FUNCS(dirdata,		DIRDATA)
 | 
				
			||||||
 | 
					EXT4_FEATURE_INCOMPAT_FUNCS(csum_seed,		CSUM_SEED)
 | 
				
			||||||
 | 
					EXT4_FEATURE_INCOMPAT_FUNCS(largedir,		LARGEDIR)
 | 
				
			||||||
 | 
					EXT4_FEATURE_INCOMPAT_FUNCS(inline_data,	INLINE_DATA)
 | 
				
			||||||
 | 
					EXT4_FEATURE_INCOMPAT_FUNCS(encrypt,		ENCRYPT)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define EXT2_FEATURE_COMPAT_SUPP	EXT4_FEATURE_COMPAT_EXT_ATTR
 | 
					#define EXT2_FEATURE_COMPAT_SUPP	EXT4_FEATURE_COMPAT_EXT_ATTR
 | 
				
			||||||
#define EXT2_FEATURE_INCOMPAT_SUPP	(EXT4_FEATURE_INCOMPAT_FILETYPE| \
 | 
					#define EXT2_FEATURE_INCOMPAT_SUPP	(EXT4_FEATURE_INCOMPAT_FILETYPE| \
 | 
				
			||||||
					 EXT4_FEATURE_INCOMPAT_META_BG)
 | 
										 EXT4_FEATURE_INCOMPAT_META_BG)
 | 
				
			||||||
| 
						 | 
					@ -1605,7 +1694,7 @@ static inline int ext4_encrypted_inode(struct inode *inode)
 | 
				
			||||||
					 EXT4_FEATURE_RO_COMPAT_LARGE_FILE| \
 | 
										 EXT4_FEATURE_RO_COMPAT_LARGE_FILE| \
 | 
				
			||||||
					 EXT4_FEATURE_RO_COMPAT_BTREE_DIR)
 | 
										 EXT4_FEATURE_RO_COMPAT_BTREE_DIR)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define EXT4_FEATURE_COMPAT_SUPP	EXT2_FEATURE_COMPAT_EXT_ATTR
 | 
					#define EXT4_FEATURE_COMPAT_SUPP	EXT4_FEATURE_COMPAT_EXT_ATTR
 | 
				
			||||||
#define EXT4_FEATURE_INCOMPAT_SUPP	(EXT4_FEATURE_INCOMPAT_FILETYPE| \
 | 
					#define EXT4_FEATURE_INCOMPAT_SUPP	(EXT4_FEATURE_INCOMPAT_FILETYPE| \
 | 
				
			||||||
					 EXT4_FEATURE_INCOMPAT_RECOVER| \
 | 
										 EXT4_FEATURE_INCOMPAT_RECOVER| \
 | 
				
			||||||
					 EXT4_FEATURE_INCOMPAT_META_BG| \
 | 
										 EXT4_FEATURE_INCOMPAT_META_BG| \
 | 
				
			||||||
| 
						 | 
					@ -1627,6 +1716,40 @@ static inline int ext4_encrypted_inode(struct inode *inode)
 | 
				
			||||||
					 EXT4_FEATURE_RO_COMPAT_METADATA_CSUM|\
 | 
										 EXT4_FEATURE_RO_COMPAT_METADATA_CSUM|\
 | 
				
			||||||
					 EXT4_FEATURE_RO_COMPAT_QUOTA)
 | 
										 EXT4_FEATURE_RO_COMPAT_QUOTA)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define EXTN_FEATURE_FUNCS(ver) \
 | 
				
			||||||
 | 
					static inline bool ext4_has_unknown_ext##ver##_compat_features(struct super_block *sb) \
 | 
				
			||||||
 | 
					{ \
 | 
				
			||||||
 | 
						return ((EXT4_SB(sb)->s_es->s_feature_compat & \
 | 
				
			||||||
 | 
							cpu_to_le32(~EXT##ver##_FEATURE_COMPAT_SUPP)) != 0); \
 | 
				
			||||||
 | 
					} \
 | 
				
			||||||
 | 
					static inline bool ext4_has_unknown_ext##ver##_ro_compat_features(struct super_block *sb) \
 | 
				
			||||||
 | 
					{ \
 | 
				
			||||||
 | 
						return ((EXT4_SB(sb)->s_es->s_feature_ro_compat & \
 | 
				
			||||||
 | 
							cpu_to_le32(~EXT##ver##_FEATURE_RO_COMPAT_SUPP)) != 0); \
 | 
				
			||||||
 | 
					} \
 | 
				
			||||||
 | 
					static inline bool ext4_has_unknown_ext##ver##_incompat_features(struct super_block *sb) \
 | 
				
			||||||
 | 
					{ \
 | 
				
			||||||
 | 
						return ((EXT4_SB(sb)->s_es->s_feature_incompat & \
 | 
				
			||||||
 | 
							cpu_to_le32(~EXT##ver##_FEATURE_INCOMPAT_SUPP)) != 0); \
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EXTN_FEATURE_FUNCS(2)
 | 
				
			||||||
 | 
					EXTN_FEATURE_FUNCS(3)
 | 
				
			||||||
 | 
					EXTN_FEATURE_FUNCS(4)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline bool ext4_has_compat_features(struct super_block *sb)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return (EXT4_SB(sb)->s_es->s_feature_compat != 0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					static inline bool ext4_has_ro_compat_features(struct super_block *sb)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return (EXT4_SB(sb)->s_es->s_feature_ro_compat != 0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					static inline bool ext4_has_incompat_features(struct super_block *sb)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return (EXT4_SB(sb)->s_es->s_feature_incompat != 0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Default values for user and/or group using reserved blocks
 | 
					 * Default values for user and/or group using reserved blocks
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
| 
						 | 
					@ -1777,8 +1900,7 @@ static inline __le16 ext4_rec_len_to_disk(unsigned len, unsigned blocksize)
 | 
				
			||||||
 * (c) Daniel Phillips, 2001
 | 
					 * (c) Daniel Phillips, 2001
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define is_dx(dir) (EXT4_HAS_COMPAT_FEATURE(dir->i_sb, \
 | 
					#define is_dx(dir) (ext4_has_feature_dir_index((dir)->i_sb) && \
 | 
				
			||||||
				      EXT4_FEATURE_COMPAT_DIR_INDEX) && \
 | 
					 | 
				
			||||||
		    ext4_test_inode_flag((dir), EXT4_INODE_INDEX))
 | 
							    ext4_test_inode_flag((dir), EXT4_INODE_INDEX))
 | 
				
			||||||
#define EXT4_DIR_LINK_MAX(dir) (!is_dx(dir) && (dir)->i_nlink >= EXT4_LINK_MAX)
 | 
					#define EXT4_DIR_LINK_MAX(dir) (!is_dx(dir) && (dir)->i_nlink >= EXT4_LINK_MAX)
 | 
				
			||||||
#define EXT4_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2 || (dir)->i_nlink == 1)
 | 
					#define EXT4_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2 || (dir)->i_nlink == 1)
 | 
				
			||||||
| 
						 | 
					@ -2079,7 +2201,7 @@ int ext4_init_crypto(void);
 | 
				
			||||||
void ext4_exit_crypto(void);
 | 
					void ext4_exit_crypto(void);
 | 
				
			||||||
static inline int ext4_sb_has_crypto(struct super_block *sb)
 | 
					static inline int ext4_sb_has_crypto(struct super_block *sb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_ENCRYPT);
 | 
						return ext4_has_feature_encrypt(sb);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
static inline int ext4_init_crypto(void) { return 0; }
 | 
					static inline int ext4_init_crypto(void) { return 0; }
 | 
				
			||||||
| 
						 | 
					@ -2200,8 +2322,7 @@ int ext4_insert_dentry(struct inode *dir,
 | 
				
			||||||
		       struct ext4_filename *fname);
 | 
							       struct ext4_filename *fname);
 | 
				
			||||||
static inline void ext4_update_dx_flag(struct inode *inode)
 | 
					static inline void ext4_update_dx_flag(struct inode *inode)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (!EXT4_HAS_COMPAT_FEATURE(inode->i_sb,
 | 
						if (!ext4_has_feature_dir_index(inode->i_sb))
 | 
				
			||||||
				     EXT4_FEATURE_COMPAT_DIR_INDEX))
 | 
					 | 
				
			||||||
		ext4_clear_inode_flag(inode, EXT4_INODE_INDEX);
 | 
							ext4_clear_inode_flag(inode, EXT4_INODE_INDEX);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
static unsigned char ext4_filetype_table[] = {
 | 
					static unsigned char ext4_filetype_table[] = {
 | 
				
			||||||
| 
						 | 
					@ -2210,8 +2331,7 @@ static unsigned char ext4_filetype_table[] = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline  unsigned char get_dtype(struct super_block *sb, int filetype)
 | 
					static inline  unsigned char get_dtype(struct super_block *sb, int filetype)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (!EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FILETYPE) ||
 | 
						if (!ext4_has_feature_filetype(sb) || filetype >= EXT4_FT_MAX)
 | 
				
			||||||
	    (filetype >= EXT4_FT_MAX))
 | 
					 | 
				
			||||||
		return DT_UNKNOWN;
 | 
							return DT_UNKNOWN;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return ext4_filetype_table[filetype];
 | 
						return ext4_filetype_table[filetype];
 | 
				
			||||||
| 
						 | 
					@ -2543,15 +2663,13 @@ extern int ext4_register_li_request(struct super_block *sb,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline int ext4_has_group_desc_csum(struct super_block *sb)
 | 
					static inline int ext4_has_group_desc_csum(struct super_block *sb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return EXT4_HAS_RO_COMPAT_FEATURE(sb,
 | 
						return ext4_has_feature_gdt_csum(sb) ||
 | 
				
			||||||
					  EXT4_FEATURE_RO_COMPAT_GDT_CSUM) ||
 | 
						       EXT4_SB(sb)->s_chksum_driver != NULL;
 | 
				
			||||||
	       (EXT4_SB(sb)->s_chksum_driver != NULL);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline int ext4_has_metadata_csum(struct super_block *sb)
 | 
					static inline int ext4_has_metadata_csum(struct super_block *sb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	WARN_ON_ONCE(EXT4_HAS_RO_COMPAT_FEATURE(sb,
 | 
						WARN_ON_ONCE(ext4_has_feature_metadata_csum(sb) &&
 | 
				
			||||||
			EXT4_FEATURE_RO_COMPAT_METADATA_CSUM) &&
 | 
					 | 
				
			||||||
		     !EXT4_SB(sb)->s_chksum_driver);
 | 
							     !EXT4_SB(sb)->s_chksum_driver);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return (EXT4_SB(sb)->s_chksum_driver != NULL);
 | 
						return (EXT4_SB(sb)->s_chksum_driver != NULL);
 | 
				
			||||||
| 
						 | 
					@ -2898,7 +3016,7 @@ static unsigned char ext4_type_by_mode[S_IFMT >> S_SHIFT] = {
 | 
				
			||||||
static inline void ext4_set_de_type(struct super_block *sb,
 | 
					static inline void ext4_set_de_type(struct super_block *sb,
 | 
				
			||||||
				struct ext4_dir_entry_2 *de,
 | 
									struct ext4_dir_entry_2 *de,
 | 
				
			||||||
				umode_t mode) {
 | 
									umode_t mode) {
 | 
				
			||||||
	if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FILETYPE))
 | 
						if (ext4_has_feature_filetype(sb))
 | 
				
			||||||
		de->file_type = ext4_type_by_mode[(mode & S_IFMT)>>S_SHIFT];
 | 
							de->file_type = ext4_type_by_mode[(mode & S_IFMT)>>S_SHIFT];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -34,8 +34,7 @@
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define EXT4_SINGLEDATA_TRANS_BLOCKS(sb)				\
 | 
					#define EXT4_SINGLEDATA_TRANS_BLOCKS(sb)				\
 | 
				
			||||||
	(EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_EXTENTS)   \
 | 
						(ext4_has_feature_extents(sb) ? 20U : 8U)
 | 
				
			||||||
	 ? 20U : 8U)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Extended attribute operations touch at most two data buffers,
 | 
					/* Extended attribute operations touch at most two data buffers,
 | 
				
			||||||
 * two bitmap buffers, and two group summaries, in addition to the inode
 | 
					 * two bitmap buffers, and two group summaries, in addition to the inode
 | 
				
			||||||
| 
						 | 
					@ -84,17 +83,16 @@
 | 
				
			||||||
/* Amount of blocks needed for quota update - we know that the structure was
 | 
					/* Amount of blocks needed for quota update - we know that the structure was
 | 
				
			||||||
 * allocated so we need to update only data block */
 | 
					 * allocated so we need to update only data block */
 | 
				
			||||||
#define EXT4_QUOTA_TRANS_BLOCKS(sb) ((test_opt(sb, QUOTA) ||\
 | 
					#define EXT4_QUOTA_TRANS_BLOCKS(sb) ((test_opt(sb, QUOTA) ||\
 | 
				
			||||||
		EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_QUOTA)) ?\
 | 
							ext4_has_feature_quota(sb)) ? 1 : 0)
 | 
				
			||||||
		1 : 0)
 | 
					 | 
				
			||||||
/* Amount of blocks needed for quota insert/delete - we do some block writes
 | 
					/* Amount of blocks needed for quota insert/delete - we do some block writes
 | 
				
			||||||
 * but inode, sb and group updates are done only once */
 | 
					 * but inode, sb and group updates are done only once */
 | 
				
			||||||
#define EXT4_QUOTA_INIT_BLOCKS(sb) ((test_opt(sb, QUOTA) ||\
 | 
					#define EXT4_QUOTA_INIT_BLOCKS(sb) ((test_opt(sb, QUOTA) ||\
 | 
				
			||||||
		EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_QUOTA)) ?\
 | 
							ext4_has_feature_quota(sb)) ?\
 | 
				
			||||||
		(DQUOT_INIT_ALLOC*(EXT4_SINGLEDATA_TRANS_BLOCKS(sb)-3)\
 | 
							(DQUOT_INIT_ALLOC*(EXT4_SINGLEDATA_TRANS_BLOCKS(sb)-3)\
 | 
				
			||||||
		 +3+DQUOT_INIT_REWRITE) : 0)
 | 
							 +3+DQUOT_INIT_REWRITE) : 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define EXT4_QUOTA_DEL_BLOCKS(sb) ((test_opt(sb, QUOTA) ||\
 | 
					#define EXT4_QUOTA_DEL_BLOCKS(sb) ((test_opt(sb, QUOTA) ||\
 | 
				
			||||||
		EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_QUOTA)) ?\
 | 
							ext4_has_feature_quota(sb)) ?\
 | 
				
			||||||
		(DQUOT_DEL_ALLOC*(EXT4_SINGLEDATA_TRANS_BLOCKS(sb)-3)\
 | 
							(DQUOT_DEL_ALLOC*(EXT4_SINGLEDATA_TRANS_BLOCKS(sb)-3)\
 | 
				
			||||||
		 +3+DQUOT_DEL_REWRITE) : 0)
 | 
							 +3+DQUOT_DEL_REWRITE) : 0)
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3055,7 +3055,7 @@ void ext4_ext_init(struct super_block *sb)
 | 
				
			||||||
	 * possible initialization would be here
 | 
						 * possible initialization would be here
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_EXTENTS)) {
 | 
						if (ext4_has_feature_extents(sb)) {
 | 
				
			||||||
#if defined(AGGRESSIVE_TEST) || defined(CHECK_BINSEARCH) || defined(EXTENTS_STATS)
 | 
					#if defined(AGGRESSIVE_TEST) || defined(CHECK_BINSEARCH) || defined(EXTENTS_STATS)
 | 
				
			||||||
		printk(KERN_INFO "EXT4-fs: file extents enabled"
 | 
							printk(KERN_INFO "EXT4-fs: file extents enabled"
 | 
				
			||||||
#ifdef AGGRESSIVE_TEST
 | 
					#ifdef AGGRESSIVE_TEST
 | 
				
			||||||
| 
						 | 
					@ -3082,7 +3082,7 @@ void ext4_ext_init(struct super_block *sb)
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
void ext4_ext_release(struct super_block *sb)
 | 
					void ext4_ext_release(struct super_block *sb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (!EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_EXTENTS))
 | 
						if (!ext4_has_feature_extents(sb))
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef EXTENTS_STATS
 | 
					#ifdef EXTENTS_STATS
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1045,7 +1045,7 @@ struct inode *__ext4_new_inode(handle_t *handle, struct inode *dir,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ei->i_extra_isize = EXT4_SB(sb)->s_want_extra_isize;
 | 
						ei->i_extra_isize = EXT4_SB(sb)->s_want_extra_isize;
 | 
				
			||||||
	ei->i_inline_off = 0;
 | 
						ei->i_inline_off = 0;
 | 
				
			||||||
	if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_INLINE_DATA))
 | 
						if (ext4_has_feature_inline_data(sb))
 | 
				
			||||||
		ext4_set_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA);
 | 
							ext4_set_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA);
 | 
				
			||||||
	ret = inode;
 | 
						ret = inode;
 | 
				
			||||||
	err = dquot_alloc_inode(inode);
 | 
						err = dquot_alloc_inode(inode);
 | 
				
			||||||
| 
						 | 
					@ -1060,7 +1060,7 @@ struct inode *__ext4_new_inode(handle_t *handle, struct inode *dir,
 | 
				
			||||||
	if (err)
 | 
						if (err)
 | 
				
			||||||
		goto fail_free_drop;
 | 
							goto fail_free_drop;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_EXTENTS)) {
 | 
						if (ext4_has_feature_extents(sb)) {
 | 
				
			||||||
		/* set extent flag only for directory, file and normal symlink*/
 | 
							/* set extent flag only for directory, file and normal symlink*/
 | 
				
			||||||
		if (S_ISDIR(mode) || S_ISREG(mode) || S_ISLNK(mode)) {
 | 
							if (S_ISDIR(mode) || S_ISREG(mode) || S_ISLNK(mode)) {
 | 
				
			||||||
			ext4_set_inode_flag(inode, EXT4_INODE_EXTENTS);
 | 
								ext4_set_inode_flag(inode, EXT4_INODE_EXTENTS);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -562,8 +562,7 @@ int ext4_ind_map_blocks(handle_t *handle, struct inode *inode,
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * Okay, we need to do block allocation.
 | 
						 * Okay, we need to do block allocation.
 | 
				
			||||||
	*/
 | 
						*/
 | 
				
			||||||
	if (EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb,
 | 
						if (ext4_has_feature_bigalloc(inode->i_sb)) {
 | 
				
			||||||
				       EXT4_FEATURE_RO_COMPAT_BIGALLOC)) {
 | 
					 | 
				
			||||||
		EXT4_ERROR_INODE(inode, "Can't allocate blocks for "
 | 
							EXT4_ERROR_INODE(inode, "Can't allocate blocks for "
 | 
				
			||||||
				 "non-extent mapped inodes with bigalloc");
 | 
									 "non-extent mapped inodes with bigalloc");
 | 
				
			||||||
		return -EFSCORRUPTED;
 | 
							return -EFSCORRUPTED;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -434,8 +434,7 @@ static int ext4_destroy_inline_data_nolock(handle_t *handle,
 | 
				
			||||||
	memset((void *)ext4_raw_inode(&is.iloc)->i_block,
 | 
						memset((void *)ext4_raw_inode(&is.iloc)->i_block,
 | 
				
			||||||
		0, EXT4_MIN_INLINE_DATA_SIZE);
 | 
							0, EXT4_MIN_INLINE_DATA_SIZE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (EXT4_HAS_INCOMPAT_FEATURE(inode->i_sb,
 | 
						if (ext4_has_feature_extents(inode->i_sb)) {
 | 
				
			||||||
				      EXT4_FEATURE_INCOMPAT_EXTENTS)) {
 | 
					 | 
				
			||||||
		if (S_ISDIR(inode->i_mode) ||
 | 
							if (S_ISDIR(inode->i_mode) ||
 | 
				
			||||||
		    S_ISREG(inode->i_mode) || S_ISLNK(inode->i_mode)) {
 | 
							    S_ISREG(inode->i_mode) || S_ISLNK(inode->i_mode)) {
 | 
				
			||||||
			ext4_set_inode_flag(inode, EXT4_INODE_EXTENTS);
 | 
								ext4_set_inode_flag(inode, EXT4_INODE_EXTENTS);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2642,8 +2642,7 @@ static int ext4_nonda_switch(struct super_block *sb)
 | 
				
			||||||
/* We always reserve for an inode update; the superblock could be there too */
 | 
					/* We always reserve for an inode update; the superblock could be there too */
 | 
				
			||||||
static int ext4_da_write_credits(struct inode *inode, loff_t pos, unsigned len)
 | 
					static int ext4_da_write_credits(struct inode *inode, loff_t pos, unsigned len)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (likely(EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb,
 | 
						if (likely(ext4_has_feature_large_file(inode->i_sb)))
 | 
				
			||||||
				EXT4_FEATURE_RO_COMPAT_LARGE_FILE)))
 | 
					 | 
				
			||||||
		return 1;
 | 
							return 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (pos + len <= 0x7fffffffULL)
 | 
						if (pos + len <= 0x7fffffffULL)
 | 
				
			||||||
| 
						 | 
					@ -4049,8 +4048,7 @@ static blkcnt_t ext4_inode_blocks(struct ext4_inode *raw_inode,
 | 
				
			||||||
	struct inode *inode = &(ei->vfs_inode);
 | 
						struct inode *inode = &(ei->vfs_inode);
 | 
				
			||||||
	struct super_block *sb = inode->i_sb;
 | 
						struct super_block *sb = inode->i_sb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
 | 
						if (ext4_has_feature_huge_file(sb)) {
 | 
				
			||||||
				EXT4_FEATURE_RO_COMPAT_HUGE_FILE)) {
 | 
					 | 
				
			||||||
		/* we are using combined 48 bit field */
 | 
							/* we are using combined 48 bit field */
 | 
				
			||||||
		i_blocks = ((u64)le16_to_cpu(raw_inode->i_blocks_high)) << 32 |
 | 
							i_blocks = ((u64)le16_to_cpu(raw_inode->i_blocks_high)) << 32 |
 | 
				
			||||||
					le32_to_cpu(raw_inode->i_blocks_lo);
 | 
										le32_to_cpu(raw_inode->i_blocks_lo);
 | 
				
			||||||
| 
						 | 
					@ -4173,7 +4171,7 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
 | 
				
			||||||
	ei->i_flags = le32_to_cpu(raw_inode->i_flags);
 | 
						ei->i_flags = le32_to_cpu(raw_inode->i_flags);
 | 
				
			||||||
	inode->i_blocks = ext4_inode_blocks(raw_inode, ei);
 | 
						inode->i_blocks = ext4_inode_blocks(raw_inode, ei);
 | 
				
			||||||
	ei->i_file_acl = le32_to_cpu(raw_inode->i_file_acl_lo);
 | 
						ei->i_file_acl = le32_to_cpu(raw_inode->i_file_acl_lo);
 | 
				
			||||||
	if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_64BIT))
 | 
						if (ext4_has_feature_64bit(sb))
 | 
				
			||||||
		ei->i_file_acl |=
 | 
							ei->i_file_acl |=
 | 
				
			||||||
			((__u64)le16_to_cpu(raw_inode->i_file_acl_high)) << 32;
 | 
								((__u64)le16_to_cpu(raw_inode->i_file_acl_high)) << 32;
 | 
				
			||||||
	inode->i_size = ext4_isize(raw_inode);
 | 
						inode->i_size = ext4_isize(raw_inode);
 | 
				
			||||||
| 
						 | 
					@ -4337,7 +4335,7 @@ static int ext4_inode_blocks_set(handle_t *handle,
 | 
				
			||||||
		ext4_clear_inode_flag(inode, EXT4_INODE_HUGE_FILE);
 | 
							ext4_clear_inode_flag(inode, EXT4_INODE_HUGE_FILE);
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (!EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_HUGE_FILE))
 | 
						if (!ext4_has_feature_huge_file(sb))
 | 
				
			||||||
		return -EFBIG;
 | 
							return -EFBIG;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (i_blocks <= 0xffffffffffffULL) {
 | 
						if (i_blocks <= 0xffffffffffffULL) {
 | 
				
			||||||
| 
						 | 
					@ -4498,8 +4496,7 @@ static int ext4_do_update_inode(handle_t *handle,
 | 
				
			||||||
		need_datasync = 1;
 | 
							need_datasync = 1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (ei->i_disksize > 0x7fffffffULL) {
 | 
						if (ei->i_disksize > 0x7fffffffULL) {
 | 
				
			||||||
		if (!EXT4_HAS_RO_COMPAT_FEATURE(sb,
 | 
							if (!ext4_has_feature_large_file(sb) ||
 | 
				
			||||||
				EXT4_FEATURE_RO_COMPAT_LARGE_FILE) ||
 | 
					 | 
				
			||||||
				EXT4_SB(sb)->s_es->s_rev_level ==
 | 
									EXT4_SB(sb)->s_es->s_rev_level ==
 | 
				
			||||||
		    cpu_to_le32(EXT4_GOOD_OLD_REV))
 | 
							    cpu_to_le32(EXT4_GOOD_OLD_REV))
 | 
				
			||||||
			set_large_file = 1;
 | 
								set_large_file = 1;
 | 
				
			||||||
| 
						 | 
					@ -4548,8 +4545,7 @@ static int ext4_do_update_inode(handle_t *handle,
 | 
				
			||||||
		if (err)
 | 
							if (err)
 | 
				
			||||||
			goto out_brelse;
 | 
								goto out_brelse;
 | 
				
			||||||
		ext4_update_dynamic_rev(sb);
 | 
							ext4_update_dynamic_rev(sb);
 | 
				
			||||||
		EXT4_SET_RO_COMPAT_FEATURE(sb,
 | 
							ext4_set_feature_large_file(sb);
 | 
				
			||||||
					   EXT4_FEATURE_RO_COMPAT_LARGE_FILE);
 | 
					 | 
				
			||||||
		ext4_handle_sync(handle);
 | 
							ext4_handle_sync(handle);
 | 
				
			||||||
		err = ext4_handle_dirty_super(handle, sb);
 | 
							err = ext4_handle_dirty_super(handle, sb);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -145,8 +145,7 @@ static long swap_inode_boot_loader(struct super_block *sb,
 | 
				
			||||||
		inode_bl->i_version = 1;
 | 
							inode_bl->i_version = 1;
 | 
				
			||||||
		i_size_write(inode_bl, 0);
 | 
							i_size_write(inode_bl, 0);
 | 
				
			||||||
		inode_bl->i_mode = S_IFREG;
 | 
							inode_bl->i_mode = S_IFREG;
 | 
				
			||||||
		if (EXT4_HAS_INCOMPAT_FEATURE(sb,
 | 
							if (ext4_has_feature_extents(sb)) {
 | 
				
			||||||
					      EXT4_FEATURE_INCOMPAT_EXTENTS)) {
 | 
					 | 
				
			||||||
			ext4_set_inode_flag(inode_bl, EXT4_INODE_EXTENTS);
 | 
								ext4_set_inode_flag(inode_bl, EXT4_INODE_EXTENTS);
 | 
				
			||||||
			ext4_ext_tree_init(handle, inode_bl);
 | 
								ext4_ext_tree_init(handle, inode_bl);
 | 
				
			||||||
		} else
 | 
							} else
 | 
				
			||||||
| 
						 | 
					@ -383,8 +382,7 @@ long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 | 
				
			||||||
			goto group_extend_out;
 | 
								goto group_extend_out;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
 | 
							if (ext4_has_feature_bigalloc(sb)) {
 | 
				
			||||||
			       EXT4_FEATURE_RO_COMPAT_BIGALLOC)) {
 | 
					 | 
				
			||||||
			ext4_msg(sb, KERN_ERR,
 | 
								ext4_msg(sb, KERN_ERR,
 | 
				
			||||||
				 "Online resizing not supported with bigalloc");
 | 
									 "Online resizing not supported with bigalloc");
 | 
				
			||||||
			err = -EOPNOTSUPP;
 | 
								err = -EOPNOTSUPP;
 | 
				
			||||||
| 
						 | 
					@ -432,8 +430,7 @@ long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 | 
				
			||||||
			goto mext_out;
 | 
								goto mext_out;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
 | 
							if (ext4_has_feature_bigalloc(sb)) {
 | 
				
			||||||
			       EXT4_FEATURE_RO_COMPAT_BIGALLOC)) {
 | 
					 | 
				
			||||||
			ext4_msg(sb, KERN_ERR,
 | 
								ext4_msg(sb, KERN_ERR,
 | 
				
			||||||
				 "Online defrag not supported with bigalloc");
 | 
									 "Online defrag not supported with bigalloc");
 | 
				
			||||||
			err = -EOPNOTSUPP;
 | 
								err = -EOPNOTSUPP;
 | 
				
			||||||
| 
						 | 
					@ -470,8 +467,7 @@ long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 | 
				
			||||||
			goto group_add_out;
 | 
								goto group_add_out;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
 | 
							if (ext4_has_feature_bigalloc(sb)) {
 | 
				
			||||||
			       EXT4_FEATURE_RO_COMPAT_BIGALLOC)) {
 | 
					 | 
				
			||||||
			ext4_msg(sb, KERN_ERR,
 | 
								ext4_msg(sb, KERN_ERR,
 | 
				
			||||||
				 "Online resizing not supported with bigalloc");
 | 
									 "Online resizing not supported with bigalloc");
 | 
				
			||||||
			err = -EOPNOTSUPP;
 | 
								err = -EOPNOTSUPP;
 | 
				
			||||||
| 
						 | 
					@ -553,8 +549,7 @@ long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 | 
				
			||||||
		int err = 0, err2 = 0;
 | 
							int err = 0, err2 = 0;
 | 
				
			||||||
		ext4_group_t o_group = EXT4_SB(sb)->s_groups_count;
 | 
							ext4_group_t o_group = EXT4_SB(sb)->s_groups_count;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
 | 
							if (ext4_has_feature_bigalloc(sb)) {
 | 
				
			||||||
			       EXT4_FEATURE_RO_COMPAT_BIGALLOC)) {
 | 
					 | 
				
			||||||
			ext4_msg(sb, KERN_ERR,
 | 
								ext4_msg(sb, KERN_ERR,
 | 
				
			||||||
				 "Online resizing not (yet) supported with bigalloc");
 | 
									 "Online resizing not (yet) supported with bigalloc");
 | 
				
			||||||
			return -EOPNOTSUPP;
 | 
								return -EOPNOTSUPP;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -448,8 +448,7 @@ int ext4_ext_migrate(struct inode *inode)
 | 
				
			||||||
	 * If the filesystem does not support extents, or the inode
 | 
						 * If the filesystem does not support extents, or the inode
 | 
				
			||||||
	 * already is extent-based, error out.
 | 
						 * already is extent-based, error out.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	if (!EXT4_HAS_INCOMPAT_FEATURE(inode->i_sb,
 | 
						if (!ext4_has_feature_extents(inode->i_sb) ||
 | 
				
			||||||
				       EXT4_FEATURE_INCOMPAT_EXTENTS) ||
 | 
					 | 
				
			||||||
	    (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)))
 | 
						    (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)))
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -625,13 +624,11 @@ int ext4_ind_migrate(struct inode *inode)
 | 
				
			||||||
	handle_t			*handle;
 | 
						handle_t			*handle;
 | 
				
			||||||
	int				ret;
 | 
						int				ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!EXT4_HAS_INCOMPAT_FEATURE(inode->i_sb,
 | 
						if (!ext4_has_feature_extents(inode->i_sb) ||
 | 
				
			||||||
				       EXT4_FEATURE_INCOMPAT_EXTENTS) ||
 | 
					 | 
				
			||||||
	    (!ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)))
 | 
						    (!ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)))
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb,
 | 
						if (ext4_has_feature_bigalloc(inode->i_sb))
 | 
				
			||||||
				       EXT4_FEATURE_RO_COMPAT_BIGALLOC))
 | 
					 | 
				
			||||||
		return -EOPNOTSUPP;
 | 
							return -EOPNOTSUPP;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2118,7 +2118,7 @@ static int ext4_add_entry(handle_t *handle, struct dentry *dentry,
 | 
				
			||||||
			goto out;
 | 
								goto out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (blocks == 1 && !dx_fallback &&
 | 
							if (blocks == 1 && !dx_fallback &&
 | 
				
			||||||
		    EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_DIR_INDEX)) {
 | 
							    ext4_has_feature_dir_index(sb)) {
 | 
				
			||||||
			retval = make_indexed_dir(handle, &fname, dentry,
 | 
								retval = make_indexed_dir(handle, &fname, dentry,
 | 
				
			||||||
						  inode, bh);
 | 
											  inode, bh);
 | 
				
			||||||
			bh = NULL; /* make_indexed_dir releases bh */
 | 
								bh = NULL; /* make_indexed_dir releases bh */
 | 
				
			||||||
| 
						 | 
					@ -2388,8 +2388,7 @@ static void ext4_inc_count(handle_t *handle, struct inode *inode)
 | 
				
			||||||
		/* limit is 16-bit i_links_count */
 | 
							/* limit is 16-bit i_links_count */
 | 
				
			||||||
		if (inode->i_nlink >= EXT4_LINK_MAX || inode->i_nlink == 2) {
 | 
							if (inode->i_nlink >= EXT4_LINK_MAX || inode->i_nlink == 2) {
 | 
				
			||||||
			set_nlink(inode, 1);
 | 
								set_nlink(inode, 1);
 | 
				
			||||||
			EXT4_SET_RO_COMPAT_FEATURE(inode->i_sb,
 | 
								ext4_set_feature_dir_nlink(inode->i_sb);
 | 
				
			||||||
					      EXT4_FEATURE_RO_COMPAT_DIR_NLINK);
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -3352,8 +3351,7 @@ static int ext4_setent(handle_t *handle, struct ext4_renament *ent,
 | 
				
			||||||
	if (retval)
 | 
						if (retval)
 | 
				
			||||||
		return retval;
 | 
							return retval;
 | 
				
			||||||
	ent->de->inode = cpu_to_le32(ino);
 | 
						ent->de->inode = cpu_to_le32(ino);
 | 
				
			||||||
	if (EXT4_HAS_INCOMPAT_FEATURE(ent->dir->i_sb,
 | 
						if (ext4_has_feature_filetype(ent->dir->i_sb))
 | 
				
			||||||
				      EXT4_FEATURE_INCOMPAT_FILETYPE))
 | 
					 | 
				
			||||||
		ent->de->file_type = file_type;
 | 
							ent->de->file_type = file_type;
 | 
				
			||||||
	ent->dir->i_version++;
 | 
						ent->dir->i_version++;
 | 
				
			||||||
	ent->dir->i_ctime = ent->dir->i_mtime =
 | 
						ent->dir->i_ctime = ent->dir->i_mtime =
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -490,7 +490,7 @@ static int setup_new_flex_group_blocks(struct super_block *sb,
 | 
				
			||||||
	       group_data[0].group != sbi->s_groups_count);
 | 
						       group_data[0].group != sbi->s_groups_count);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	reserved_gdb = le16_to_cpu(es->s_reserved_gdt_blocks);
 | 
						reserved_gdb = le16_to_cpu(es->s_reserved_gdt_blocks);
 | 
				
			||||||
	meta_bg = EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_META_BG);
 | 
						meta_bg = ext4_has_feature_meta_bg(sb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* This transaction may be extended/restarted along the way */
 | 
						/* This transaction may be extended/restarted along the way */
 | 
				
			||||||
	handle = ext4_journal_start_sb(sb, EXT4_HT_RESIZE, EXT4_MAX_TRANS_DATA);
 | 
						handle = ext4_journal_start_sb(sb, EXT4_HT_RESIZE, EXT4_MAX_TRANS_DATA);
 | 
				
			||||||
| 
						 | 
					@ -680,8 +680,7 @@ static unsigned ext4_list_backups(struct super_block *sb, unsigned *three,
 | 
				
			||||||
	int mult = 3;
 | 
						int mult = 3;
 | 
				
			||||||
	unsigned ret;
 | 
						unsigned ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!EXT4_HAS_RO_COMPAT_FEATURE(sb,
 | 
						if (!ext4_has_feature_sparse_super(sb)) {
 | 
				
			||||||
					EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER)) {
 | 
					 | 
				
			||||||
		ret = *min;
 | 
							ret = *min;
 | 
				
			||||||
		*min += 1;
 | 
							*min += 1;
 | 
				
			||||||
		return ret;
 | 
							return ret;
 | 
				
			||||||
| 
						 | 
					@ -1158,7 +1157,7 @@ static int ext4_add_new_descs(handle_t *handle, struct super_block *sb,
 | 
				
			||||||
	int i, gdb_off, gdb_num, err = 0;
 | 
						int i, gdb_off, gdb_num, err = 0;
 | 
				
			||||||
	int meta_bg;
 | 
						int meta_bg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	meta_bg = EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_META_BG);
 | 
						meta_bg = ext4_has_feature_meta_bg(sb);
 | 
				
			||||||
	for (i = 0; i < count; i++, group++) {
 | 
						for (i = 0; i < count; i++, group++) {
 | 
				
			||||||
		int reserved_gdb = ext4_bg_has_super(sb, group) ?
 | 
							int reserved_gdb = ext4_bg_has_super(sb, group) ?
 | 
				
			||||||
			le16_to_cpu(es->s_reserved_gdt_blocks) : 0;
 | 
								le16_to_cpu(es->s_reserved_gdt_blocks) : 0;
 | 
				
			||||||
| 
						 | 
					@ -1381,9 +1380,7 @@ static void ext4_update_super(struct super_block *sb,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ext4_debug("free blocks count %llu",
 | 
						ext4_debug("free blocks count %llu",
 | 
				
			||||||
		   percpu_counter_read(&sbi->s_freeclusters_counter));
 | 
							   percpu_counter_read(&sbi->s_freeclusters_counter));
 | 
				
			||||||
	if (EXT4_HAS_INCOMPAT_FEATURE(sb,
 | 
						if (ext4_has_feature_flex_bg(sb) && sbi->s_log_groups_per_flex) {
 | 
				
			||||||
				      EXT4_FEATURE_INCOMPAT_FLEX_BG) &&
 | 
					 | 
				
			||||||
	    sbi->s_log_groups_per_flex) {
 | 
					 | 
				
			||||||
		ext4_group_t flex_group;
 | 
							ext4_group_t flex_group;
 | 
				
			||||||
		flex_group = ext4_flex_group(sbi, group_data[0].group);
 | 
							flex_group = ext4_flex_group(sbi, group_data[0].group);
 | 
				
			||||||
		atomic64_add(EXT4_NUM_B2C(sbi, free_blocks),
 | 
							atomic64_add(EXT4_NUM_B2C(sbi, free_blocks),
 | 
				
			||||||
| 
						 | 
					@ -1476,8 +1473,7 @@ static int ext4_flex_group_add(struct super_block *sb,
 | 
				
			||||||
		int gdb_num = group / EXT4_DESC_PER_BLOCK(sb);
 | 
							int gdb_num = group / EXT4_DESC_PER_BLOCK(sb);
 | 
				
			||||||
		int gdb_num_end = ((group + flex_gd->count - 1) /
 | 
							int gdb_num_end = ((group + flex_gd->count - 1) /
 | 
				
			||||||
				   EXT4_DESC_PER_BLOCK(sb));
 | 
									   EXT4_DESC_PER_BLOCK(sb));
 | 
				
			||||||
		int meta_bg = EXT4_HAS_INCOMPAT_FEATURE(sb,
 | 
							int meta_bg = ext4_has_feature_meta_bg(sb);
 | 
				
			||||||
				EXT4_FEATURE_INCOMPAT_META_BG);
 | 
					 | 
				
			||||||
		sector_t old_gdb = 0;
 | 
							sector_t old_gdb = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		update_backups(sb, sbi->s_sbh->b_blocknr, (char *)es,
 | 
							update_backups(sb, sbi->s_sbh->b_blocknr, (char *)es,
 | 
				
			||||||
| 
						 | 
					@ -1585,8 +1581,7 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	gdb_off = input->group % EXT4_DESC_PER_BLOCK(sb);
 | 
						gdb_off = input->group % EXT4_DESC_PER_BLOCK(sb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (gdb_off == 0 && !EXT4_HAS_RO_COMPAT_FEATURE(sb,
 | 
						if (gdb_off == 0 && !ext4_has_feature_sparse_super(sb)) {
 | 
				
			||||||
					EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER)) {
 | 
					 | 
				
			||||||
		ext4_warning(sb, "Can't resize non-sparse filesystem further");
 | 
							ext4_warning(sb, "Can't resize non-sparse filesystem further");
 | 
				
			||||||
		return -EPERM;
 | 
							return -EPERM;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -1604,9 +1599,8 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (reserved_gdb || gdb_off == 0) {
 | 
						if (reserved_gdb || gdb_off == 0) {
 | 
				
			||||||
		if (!EXT4_HAS_COMPAT_FEATURE(sb,
 | 
							if (ext4_has_feature_resize_inode(sb) ||
 | 
				
			||||||
					     EXT4_FEATURE_COMPAT_RESIZE_INODE)
 | 
							    !le16_to_cpu(es->s_reserved_gdt_blocks)) {
 | 
				
			||||||
		    || !le16_to_cpu(es->s_reserved_gdt_blocks)) {
 | 
					 | 
				
			||||||
			ext4_warning(sb,
 | 
								ext4_warning(sb,
 | 
				
			||||||
				     "No reserved GDT blocks, can't resize");
 | 
									     "No reserved GDT blocks, can't resize");
 | 
				
			||||||
			return -EPERM;
 | 
								return -EPERM;
 | 
				
			||||||
| 
						 | 
					@ -1825,8 +1819,8 @@ static int ext4_convert_meta_bg(struct super_block *sb, struct inode *inode)
 | 
				
			||||||
	if (err)
 | 
						if (err)
 | 
				
			||||||
		goto errout;
 | 
							goto errout;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	EXT4_CLEAR_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_RESIZE_INODE);
 | 
						ext4_clear_feature_resize_inode(sb);
 | 
				
			||||||
	EXT4_SET_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_META_BG);
 | 
						ext4_set_feature_meta_bg(sb);
 | 
				
			||||||
	sbi->s_es->s_first_meta_bg =
 | 
						sbi->s_es->s_first_meta_bg =
 | 
				
			||||||
		cpu_to_le32(num_desc_blocks(sb, sbi->s_groups_count));
 | 
							cpu_to_le32(num_desc_blocks(sb, sbi->s_groups_count));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1918,9 +1912,9 @@ int ext4_resize_fs(struct super_block *sb, ext4_fsblk_t n_blocks_count)
 | 
				
			||||||
	n_desc_blocks = num_desc_blocks(sb, n_group + 1);
 | 
						n_desc_blocks = num_desc_blocks(sb, n_group + 1);
 | 
				
			||||||
	o_desc_blocks = num_desc_blocks(sb, sbi->s_groups_count);
 | 
						o_desc_blocks = num_desc_blocks(sb, sbi->s_groups_count);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	meta_bg = EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_META_BG);
 | 
						meta_bg = ext4_has_feature_meta_bg(sb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_RESIZE_INODE)) {
 | 
						if (ext4_has_feature_resize_inode(sb)) {
 | 
				
			||||||
		if (meta_bg) {
 | 
							if (meta_bg) {
 | 
				
			||||||
			ext4_error(sb, "resize_inode and meta_bg enabled "
 | 
								ext4_error(sb, "resize_inode and meta_bg enabled "
 | 
				
			||||||
				   "simultaneously");
 | 
									   "simultaneously");
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										165
									
								
								fs/ext4/super.c
									
									
									
									
									
								
							
							
						
						
									
										165
									
								
								fs/ext4/super.c
									
									
									
									
									
								
							| 
						 | 
					@ -110,8 +110,7 @@ MODULE_ALIAS("ext3");
 | 
				
			||||||
static int ext4_verify_csum_type(struct super_block *sb,
 | 
					static int ext4_verify_csum_type(struct super_block *sb,
 | 
				
			||||||
				 struct ext4_super_block *es)
 | 
									 struct ext4_super_block *es)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (!EXT4_HAS_RO_COMPAT_FEATURE(sb,
 | 
						if (!ext4_has_feature_metadata_csum(sb))
 | 
				
			||||||
					EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
 | 
					 | 
				
			||||||
		return 1;
 | 
							return 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return es->s_checksum_type == EXT4_CRC32C_CHKSUM;
 | 
						return es->s_checksum_type == EXT4_CRC32C_CHKSUM;
 | 
				
			||||||
| 
						 | 
					@ -810,7 +809,7 @@ static void ext4_put_super(struct super_block *sb)
 | 
				
			||||||
	ext4_xattr_put_super(sb);
 | 
						ext4_xattr_put_super(sb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!(sb->s_flags & MS_RDONLY)) {
 | 
						if (!(sb->s_flags & MS_RDONLY)) {
 | 
				
			||||||
		EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
 | 
							ext4_clear_feature_journal_needs_recovery(sb);
 | 
				
			||||||
		es->s_state = cpu_to_le16(sbi->s_mount_state);
 | 
							es->s_state = cpu_to_le16(sbi->s_mount_state);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (!(sb->s_flags & MS_RDONLY))
 | 
						if (!(sb->s_flags & MS_RDONLY))
 | 
				
			||||||
| 
						 | 
					@ -1284,7 +1283,7 @@ static int set_qf_name(struct super_block *sb, int qtype, substring_t *args)
 | 
				
			||||||
			"quota options when quota turned on");
 | 
								"quota options when quota turned on");
 | 
				
			||||||
		return -1;
 | 
							return -1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_QUOTA)) {
 | 
						if (ext4_has_feature_quota(sb)) {
 | 
				
			||||||
		ext4_msg(sb, KERN_ERR, "Cannot set journaled quota options "
 | 
							ext4_msg(sb, KERN_ERR, "Cannot set journaled quota options "
 | 
				
			||||||
			 "when QUOTA feature is enabled");
 | 
								 "when QUOTA feature is enabled");
 | 
				
			||||||
		return -1;
 | 
							return -1;
 | 
				
			||||||
| 
						 | 
					@ -1643,8 +1642,7 @@ static int handle_mount_opt(struct super_block *sb, char *opt, int token,
 | 
				
			||||||
				 "quota options when quota turned on");
 | 
									 "quota options when quota turned on");
 | 
				
			||||||
			return -1;
 | 
								return -1;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
 | 
							if (ext4_has_feature_quota(sb)) {
 | 
				
			||||||
					       EXT4_FEATURE_RO_COMPAT_QUOTA)) {
 | 
					 | 
				
			||||||
			ext4_msg(sb, KERN_ERR,
 | 
								ext4_msg(sb, KERN_ERR,
 | 
				
			||||||
				 "Cannot set journaled quota options "
 | 
									 "Cannot set journaled quota options "
 | 
				
			||||||
				 "when QUOTA feature is enabled");
 | 
									 "when QUOTA feature is enabled");
 | 
				
			||||||
| 
						 | 
					@ -1703,7 +1701,7 @@ static int parse_options(char *options, struct super_block *sb,
 | 
				
			||||||
			return 0;
 | 
								return 0;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
#ifdef CONFIG_QUOTA
 | 
					#ifdef CONFIG_QUOTA
 | 
				
			||||||
	if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_QUOTA) &&
 | 
						if (ext4_has_feature_quota(sb) &&
 | 
				
			||||||
	    (test_opt(sb, USRQUOTA) || test_opt(sb, GRPQUOTA))) {
 | 
						    (test_opt(sb, USRQUOTA) || test_opt(sb, GRPQUOTA))) {
 | 
				
			||||||
		ext4_msg(sb, KERN_ERR, "Cannot set quota options when QUOTA "
 | 
							ext4_msg(sb, KERN_ERR, "Cannot set quota options when QUOTA "
 | 
				
			||||||
			 "feature is enabled");
 | 
								 "feature is enabled");
 | 
				
			||||||
| 
						 | 
					@ -1927,7 +1925,7 @@ static int ext4_setup_super(struct super_block *sb, struct ext4_super_block *es,
 | 
				
			||||||
	es->s_mtime = cpu_to_le32(get_seconds());
 | 
						es->s_mtime = cpu_to_le32(get_seconds());
 | 
				
			||||||
	ext4_update_dynamic_rev(sb);
 | 
						ext4_update_dynamic_rev(sb);
 | 
				
			||||||
	if (sbi->s_journal)
 | 
						if (sbi->s_journal)
 | 
				
			||||||
		EXT4_SET_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
 | 
							ext4_set_feature_journal_needs_recovery(sb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ext4_commit_super(sb, 1);
 | 
						ext4_commit_super(sb, 1);
 | 
				
			||||||
done:
 | 
					done:
 | 
				
			||||||
| 
						 | 
					@ -2010,12 +2008,13 @@ static int ext4_fill_flex_info(struct super_block *sb)
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static __le16 ext4_group_desc_csum(struct ext4_sb_info *sbi, __u32 block_group,
 | 
					static __le16 ext4_group_desc_csum(struct super_block *sb, __u32 block_group,
 | 
				
			||||||
				   struct ext4_group_desc *gdp)
 | 
									   struct ext4_group_desc *gdp)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int offset;
 | 
						int offset;
 | 
				
			||||||
	__u16 crc = 0;
 | 
						__u16 crc = 0;
 | 
				
			||||||
	__le32 le_group = cpu_to_le32(block_group);
 | 
						__le32 le_group = cpu_to_le32(block_group);
 | 
				
			||||||
 | 
						struct ext4_sb_info *sbi = EXT4_SB(sb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (ext4_has_metadata_csum(sbi->s_sb)) {
 | 
						if (ext4_has_metadata_csum(sbi->s_sb)) {
 | 
				
			||||||
		/* Use new metadata_csum algorithm */
 | 
							/* Use new metadata_csum algorithm */
 | 
				
			||||||
| 
						 | 
					@ -2035,8 +2034,7 @@ static __le16 ext4_group_desc_csum(struct ext4_sb_info *sbi, __u32 block_group,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* old crc16 code */
 | 
						/* old crc16 code */
 | 
				
			||||||
	if (!(sbi->s_es->s_feature_ro_compat &
 | 
						if (!ext4_has_feature_gdt_csum(sb))
 | 
				
			||||||
	      cpu_to_le32(EXT4_FEATURE_RO_COMPAT_GDT_CSUM)))
 | 
					 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	offset = offsetof(struct ext4_group_desc, bg_checksum);
 | 
						offset = offsetof(struct ext4_group_desc, bg_checksum);
 | 
				
			||||||
| 
						 | 
					@ -2046,8 +2044,7 @@ static __le16 ext4_group_desc_csum(struct ext4_sb_info *sbi, __u32 block_group,
 | 
				
			||||||
	crc = crc16(crc, (__u8 *)gdp, offset);
 | 
						crc = crc16(crc, (__u8 *)gdp, offset);
 | 
				
			||||||
	offset += sizeof(gdp->bg_checksum); /* skip checksum */
 | 
						offset += sizeof(gdp->bg_checksum); /* skip checksum */
 | 
				
			||||||
	/* for checksum of struct ext4_group_desc do the rest...*/
 | 
						/* for checksum of struct ext4_group_desc do the rest...*/
 | 
				
			||||||
	if ((sbi->s_es->s_feature_incompat &
 | 
						if (ext4_has_feature_64bit(sb) &&
 | 
				
			||||||
	     cpu_to_le32(EXT4_FEATURE_INCOMPAT_64BIT)) &&
 | 
					 | 
				
			||||||
	    offset < le16_to_cpu(sbi->s_es->s_desc_size))
 | 
						    offset < le16_to_cpu(sbi->s_es->s_desc_size))
 | 
				
			||||||
		crc = crc16(crc, (__u8 *)gdp + offset,
 | 
							crc = crc16(crc, (__u8 *)gdp + offset,
 | 
				
			||||||
			    le16_to_cpu(sbi->s_es->s_desc_size) -
 | 
								    le16_to_cpu(sbi->s_es->s_desc_size) -
 | 
				
			||||||
| 
						 | 
					@ -2061,8 +2058,7 @@ int ext4_group_desc_csum_verify(struct super_block *sb, __u32 block_group,
 | 
				
			||||||
				struct ext4_group_desc *gdp)
 | 
									struct ext4_group_desc *gdp)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (ext4_has_group_desc_csum(sb) &&
 | 
						if (ext4_has_group_desc_csum(sb) &&
 | 
				
			||||||
	    (gdp->bg_checksum != ext4_group_desc_csum(EXT4_SB(sb),
 | 
						    (gdp->bg_checksum != ext4_group_desc_csum(sb, block_group, gdp)))
 | 
				
			||||||
						      block_group, gdp)))
 | 
					 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 1;
 | 
						return 1;
 | 
				
			||||||
| 
						 | 
					@ -2073,7 +2069,7 @@ void ext4_group_desc_csum_set(struct super_block *sb, __u32 block_group,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (!ext4_has_group_desc_csum(sb))
 | 
						if (!ext4_has_group_desc_csum(sb))
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	gdp->bg_checksum = ext4_group_desc_csum(EXT4_SB(sb), block_group, gdp);
 | 
						gdp->bg_checksum = ext4_group_desc_csum(sb, block_group, gdp);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Called at mount-time, super-block is locked */
 | 
					/* Called at mount-time, super-block is locked */
 | 
				
			||||||
| 
						 | 
					@ -2089,7 +2085,7 @@ static int ext4_check_descriptors(struct super_block *sb,
 | 
				
			||||||
	int flexbg_flag = 0;
 | 
						int flexbg_flag = 0;
 | 
				
			||||||
	ext4_group_t i, grp = sbi->s_groups_count;
 | 
						ext4_group_t i, grp = sbi->s_groups_count;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG))
 | 
						if (ext4_has_feature_flex_bg(sb))
 | 
				
			||||||
		flexbg_flag = 1;
 | 
							flexbg_flag = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ext4_debug("Checking group descriptors");
 | 
						ext4_debug("Checking group descriptors");
 | 
				
			||||||
| 
						 | 
					@ -2133,7 +2129,7 @@ static int ext4_check_descriptors(struct super_block *sb,
 | 
				
			||||||
		if (!ext4_group_desc_csum_verify(sb, i, gdp)) {
 | 
							if (!ext4_group_desc_csum_verify(sb, i, gdp)) {
 | 
				
			||||||
			ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: "
 | 
								ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: "
 | 
				
			||||||
				 "Checksum for group %u failed (%u!=%u)",
 | 
									 "Checksum for group %u failed (%u!=%u)",
 | 
				
			||||||
				 i, le16_to_cpu(ext4_group_desc_csum(sbi, i,
 | 
									 i, le16_to_cpu(ext4_group_desc_csum(sb, i,
 | 
				
			||||||
				     gdp)), le16_to_cpu(gdp->bg_checksum));
 | 
									     gdp)), le16_to_cpu(gdp->bg_checksum));
 | 
				
			||||||
			if (!(sb->s_flags & MS_RDONLY)) {
 | 
								if (!(sb->s_flags & MS_RDONLY)) {
 | 
				
			||||||
				ext4_unlock_group(sb, i);
 | 
									ext4_unlock_group(sb, i);
 | 
				
			||||||
| 
						 | 
					@ -2396,8 +2392,7 @@ static ext4_fsblk_t descriptor_loc(struct super_block *sb,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	first_meta_bg = le32_to_cpu(sbi->s_es->s_first_meta_bg);
 | 
						first_meta_bg = le32_to_cpu(sbi->s_es->s_first_meta_bg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_META_BG) ||
 | 
						if (!ext4_has_feature_meta_bg(sb) || nr < first_meta_bg)
 | 
				
			||||||
	    nr < first_meta_bg)
 | 
					 | 
				
			||||||
		return logical_sb_block + nr + 1;
 | 
							return logical_sb_block + nr + 1;
 | 
				
			||||||
	bg = sbi->s_desc_per_block * nr;
 | 
						bg = sbi->s_desc_per_block * nr;
 | 
				
			||||||
	if (ext4_bg_has_super(sb, bg))
 | 
						if (ext4_bg_has_super(sb, bg))
 | 
				
			||||||
| 
						 | 
					@ -2461,7 +2456,7 @@ static unsigned long ext4_get_stripe_size(struct ext4_sb_info *sbi)
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static int ext4_feature_set_ok(struct super_block *sb, int readonly)
 | 
					static int ext4_feature_set_ok(struct super_block *sb, int readonly)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (EXT4_HAS_INCOMPAT_FEATURE(sb, ~EXT4_FEATURE_INCOMPAT_SUPP)) {
 | 
						if (ext4_has_unknown_ext4_incompat_features(sb)) {
 | 
				
			||||||
		ext4_msg(sb, KERN_ERR,
 | 
							ext4_msg(sb, KERN_ERR,
 | 
				
			||||||
			"Couldn't mount because of "
 | 
								"Couldn't mount because of "
 | 
				
			||||||
			"unsupported optional features (%x)",
 | 
								"unsupported optional features (%x)",
 | 
				
			||||||
| 
						 | 
					@ -2473,14 +2468,14 @@ static int ext4_feature_set_ok(struct super_block *sb, int readonly)
 | 
				
			||||||
	if (readonly)
 | 
						if (readonly)
 | 
				
			||||||
		return 1;
 | 
							return 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_READONLY)) {
 | 
						if (ext4_has_feature_readonly(sb)) {
 | 
				
			||||||
		ext4_msg(sb, KERN_INFO, "filesystem is read-only");
 | 
							ext4_msg(sb, KERN_INFO, "filesystem is read-only");
 | 
				
			||||||
		sb->s_flags |= MS_RDONLY;
 | 
							sb->s_flags |= MS_RDONLY;
 | 
				
			||||||
		return 1;
 | 
							return 1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Check that feature set is OK for a read-write mount */
 | 
						/* Check that feature set is OK for a read-write mount */
 | 
				
			||||||
	if (EXT4_HAS_RO_COMPAT_FEATURE(sb, ~EXT4_FEATURE_RO_COMPAT_SUPP)) {
 | 
						if (ext4_has_unknown_ext4_ro_compat_features(sb)) {
 | 
				
			||||||
		ext4_msg(sb, KERN_ERR, "couldn't mount RDWR because of "
 | 
							ext4_msg(sb, KERN_ERR, "couldn't mount RDWR because of "
 | 
				
			||||||
			 "unsupported optional features (%x)",
 | 
								 "unsupported optional features (%x)",
 | 
				
			||||||
			 (le32_to_cpu(EXT4_SB(sb)->s_es->s_feature_ro_compat) &
 | 
								 (le32_to_cpu(EXT4_SB(sb)->s_es->s_feature_ro_compat) &
 | 
				
			||||||
| 
						 | 
					@ -2491,7 +2486,7 @@ static int ext4_feature_set_ok(struct super_block *sb, int readonly)
 | 
				
			||||||
	 * Large file size enabled file system can only be mounted
 | 
						 * Large file size enabled file system can only be mounted
 | 
				
			||||||
	 * read-write on 32-bit systems if kernel is built with CONFIG_LBDAF
 | 
						 * read-write on 32-bit systems if kernel is built with CONFIG_LBDAF
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_HUGE_FILE)) {
 | 
						if (ext4_has_feature_huge_file(sb)) {
 | 
				
			||||||
		if (sizeof(blkcnt_t) < sizeof(u64)) {
 | 
							if (sizeof(blkcnt_t) < sizeof(u64)) {
 | 
				
			||||||
			ext4_msg(sb, KERN_ERR, "Filesystem with huge files "
 | 
								ext4_msg(sb, KERN_ERR, "Filesystem with huge files "
 | 
				
			||||||
				 "cannot be mounted RDWR without "
 | 
									 "cannot be mounted RDWR without "
 | 
				
			||||||
| 
						 | 
					@ -2499,8 +2494,7 @@ static int ext4_feature_set_ok(struct super_block *sb, int readonly)
 | 
				
			||||||
			return 0;
 | 
								return 0;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_BIGALLOC) &&
 | 
						if (ext4_has_feature_bigalloc(sb) && !ext4_has_feature_extents(sb)) {
 | 
				
			||||||
	    !EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_EXTENTS)) {
 | 
					 | 
				
			||||||
		ext4_msg(sb, KERN_ERR,
 | 
							ext4_msg(sb, KERN_ERR,
 | 
				
			||||||
			 "Can't support bigalloc feature without "
 | 
								 "Can't support bigalloc feature without "
 | 
				
			||||||
			 "extents feature\n");
 | 
								 "extents feature\n");
 | 
				
			||||||
| 
						 | 
					@ -2508,8 +2502,7 @@ static int ext4_feature_set_ok(struct super_block *sb, int readonly)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifndef CONFIG_QUOTA
 | 
					#ifndef CONFIG_QUOTA
 | 
				
			||||||
	if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_QUOTA) &&
 | 
						if (ext4_has_feature_quota(sb) && !readonly) {
 | 
				
			||||||
	    !readonly) {
 | 
					 | 
				
			||||||
		ext4_msg(sb, KERN_ERR,
 | 
							ext4_msg(sb, KERN_ERR,
 | 
				
			||||||
			 "Filesystem with quota feature cannot be mounted RDWR "
 | 
								 "Filesystem with quota feature cannot be mounted RDWR "
 | 
				
			||||||
			 "without CONFIG_QUOTA");
 | 
								 "without CONFIG_QUOTA");
 | 
				
			||||||
| 
						 | 
					@ -2966,7 +2959,7 @@ static int count_overhead(struct super_block *sb, ext4_group_t grp,
 | 
				
			||||||
	ext4_group_t		i, ngroups = ext4_get_groups_count(sb);
 | 
						ext4_group_t		i, ngroups = ext4_get_groups_count(sb);
 | 
				
			||||||
	int			s, j, count = 0;
 | 
						int			s, j, count = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_BIGALLOC))
 | 
						if (!ext4_has_feature_bigalloc(sb))
 | 
				
			||||||
		return (ext4_bg_has_super(sb, grp) + ext4_bg_num_gdb(sb, grp) +
 | 
							return (ext4_bg_has_super(sb, grp) + ext4_bg_num_gdb(sb, grp) +
 | 
				
			||||||
			sbi->s_itb_per_group + 2);
 | 
								sbi->s_itb_per_group + 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3068,7 +3061,7 @@ static void ext4_set_resv_clusters(struct super_block *sb)
 | 
				
			||||||
	 * hole punching doesn't need new metadata... This is needed especially
 | 
						 * hole punching doesn't need new metadata... This is needed especially
 | 
				
			||||||
	 * to keep ext2/3 backward compatibility.
 | 
						 * to keep ext2/3 backward compatibility.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	if (!EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_EXTENTS))
 | 
						if (!ext4_has_feature_extents(sb))
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * By default we reserve 2% or 4096 clusters, whichever is smaller.
 | 
						 * By default we reserve 2% or 4096 clusters, whichever is smaller.
 | 
				
			||||||
| 
						 | 
					@ -3167,9 +3160,8 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
 | 
				
			||||||
	sbi->s_kbytes_written = le64_to_cpu(es->s_kbytes_written);
 | 
						sbi->s_kbytes_written = le64_to_cpu(es->s_kbytes_written);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Warn if metadata_csum and gdt_csum are both set. */
 | 
						/* Warn if metadata_csum and gdt_csum are both set. */
 | 
				
			||||||
	if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
 | 
						if (ext4_has_feature_metadata_csum(sb) &&
 | 
				
			||||||
				       EXT4_FEATURE_RO_COMPAT_METADATA_CSUM) &&
 | 
						    ext4_has_feature_gdt_csum(sb))
 | 
				
			||||||
	    EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_GDT_CSUM))
 | 
					 | 
				
			||||||
		ext4_warning(sb, "metadata_csum and uninit_bg are "
 | 
							ext4_warning(sb, "metadata_csum and uninit_bg are "
 | 
				
			||||||
			     "redundant flags; please run fsck.");
 | 
								     "redundant flags; please run fsck.");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3182,8 +3174,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Load the checksum driver */
 | 
						/* Load the checksum driver */
 | 
				
			||||||
	if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
 | 
						if (ext4_has_feature_metadata_csum(sb)) {
 | 
				
			||||||
				       EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) {
 | 
					 | 
				
			||||||
		sbi->s_chksum_driver = crypto_alloc_shash("crc32c", 0, 0);
 | 
							sbi->s_chksum_driver = crypto_alloc_shash("crc32c", 0, 0);
 | 
				
			||||||
		if (IS_ERR(sbi->s_chksum_driver)) {
 | 
							if (IS_ERR(sbi->s_chksum_driver)) {
 | 
				
			||||||
			ext4_msg(sb, KERN_ERR, "Cannot load crc32c driver.");
 | 
								ext4_msg(sb, KERN_ERR, "Cannot load crc32c driver.");
 | 
				
			||||||
| 
						 | 
					@ -3203,7 +3194,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Precompute checksum seed for all metadata */
 | 
						/* Precompute checksum seed for all metadata */
 | 
				
			||||||
	if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_CSUM_SEED))
 | 
						if (ext4_has_feature_csum_seed(sb))
 | 
				
			||||||
		sbi->s_csum_seed = le32_to_cpu(es->s_checksum_seed);
 | 
							sbi->s_csum_seed = le32_to_cpu(es->s_checksum_seed);
 | 
				
			||||||
	else if (ext4_has_metadata_csum(sb))
 | 
						else if (ext4_has_metadata_csum(sb))
 | 
				
			||||||
		sbi->s_csum_seed = ext4_chksum(sbi, ~0, es->s_uuid,
 | 
							sbi->s_csum_seed = ext4_chksum(sbi, ~0, es->s_uuid,
 | 
				
			||||||
| 
						 | 
					@ -3308,17 +3299,16 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
 | 
				
			||||||
		(test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0);
 | 
							(test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (le32_to_cpu(es->s_rev_level) == EXT4_GOOD_OLD_REV &&
 | 
						if (le32_to_cpu(es->s_rev_level) == EXT4_GOOD_OLD_REV &&
 | 
				
			||||||
	    (EXT4_HAS_COMPAT_FEATURE(sb, ~0U) ||
 | 
						    (ext4_has_compat_features(sb) ||
 | 
				
			||||||
	     EXT4_HAS_RO_COMPAT_FEATURE(sb, ~0U) ||
 | 
						     ext4_has_ro_compat_features(sb) ||
 | 
				
			||||||
	     EXT4_HAS_INCOMPAT_FEATURE(sb, ~0U)))
 | 
						     ext4_has_incompat_features(sb)))
 | 
				
			||||||
		ext4_msg(sb, KERN_WARNING,
 | 
							ext4_msg(sb, KERN_WARNING,
 | 
				
			||||||
		       "feature flags set on rev 0 fs, "
 | 
							       "feature flags set on rev 0 fs, "
 | 
				
			||||||
		       "running e2fsck is recommended");
 | 
							       "running e2fsck is recommended");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (es->s_creator_os == cpu_to_le32(EXT4_OS_HURD)) {
 | 
						if (es->s_creator_os == cpu_to_le32(EXT4_OS_HURD)) {
 | 
				
			||||||
		set_opt2(sb, HURD_COMPAT);
 | 
							set_opt2(sb, HURD_COMPAT);
 | 
				
			||||||
		if (EXT4_HAS_INCOMPAT_FEATURE(sb,
 | 
							if (ext4_has_feature_64bit(sb)) {
 | 
				
			||||||
					      EXT4_FEATURE_INCOMPAT_64BIT)) {
 | 
					 | 
				
			||||||
			ext4_msg(sb, KERN_ERR,
 | 
								ext4_msg(sb, KERN_ERR,
 | 
				
			||||||
				 "The Hurd can't support 64-bit file systems");
 | 
									 "The Hurd can't support 64-bit file systems");
 | 
				
			||||||
			goto failed_mount;
 | 
								goto failed_mount;
 | 
				
			||||||
| 
						 | 
					@ -3376,8 +3366,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_ENCRYPT) &&
 | 
						if (ext4_has_feature_encrypt(sb) && es->s_encryption_level) {
 | 
				
			||||||
	    es->s_encryption_level) {
 | 
					 | 
				
			||||||
		ext4_msg(sb, KERN_ERR, "Unsupported encryption level %d",
 | 
							ext4_msg(sb, KERN_ERR, "Unsupported encryption level %d",
 | 
				
			||||||
			 es->s_encryption_level);
 | 
								 es->s_encryption_level);
 | 
				
			||||||
		goto failed_mount;
 | 
							goto failed_mount;
 | 
				
			||||||
| 
						 | 
					@ -3409,8 +3398,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	has_huge_files = EXT4_HAS_RO_COMPAT_FEATURE(sb,
 | 
						has_huge_files = ext4_has_feature_huge_file(sb);
 | 
				
			||||||
				EXT4_FEATURE_RO_COMPAT_HUGE_FILE);
 | 
					 | 
				
			||||||
	sbi->s_bitmap_maxbytes = ext4_max_bitmap_size(sb->s_blocksize_bits,
 | 
						sbi->s_bitmap_maxbytes = ext4_max_bitmap_size(sb->s_blocksize_bits,
 | 
				
			||||||
						      has_huge_files);
 | 
											      has_huge_files);
 | 
				
			||||||
	sb->s_maxbytes = ext4_max_size(sb->s_blocksize_bits, has_huge_files);
 | 
						sb->s_maxbytes = ext4_max_size(sb->s_blocksize_bits, has_huge_files);
 | 
				
			||||||
| 
						 | 
					@ -3434,7 +3422,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sbi->s_desc_size = le16_to_cpu(es->s_desc_size);
 | 
						sbi->s_desc_size = le16_to_cpu(es->s_desc_size);
 | 
				
			||||||
	if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_64BIT)) {
 | 
						if (ext4_has_feature_64bit(sb)) {
 | 
				
			||||||
		if (sbi->s_desc_size < EXT4_MIN_DESC_SIZE_64BIT ||
 | 
							if (sbi->s_desc_size < EXT4_MIN_DESC_SIZE_64BIT ||
 | 
				
			||||||
		    sbi->s_desc_size > EXT4_MAX_DESC_SIZE ||
 | 
							    sbi->s_desc_size > EXT4_MAX_DESC_SIZE ||
 | 
				
			||||||
		    !is_power_of_2(sbi->s_desc_size)) {
 | 
							    !is_power_of_2(sbi->s_desc_size)) {
 | 
				
			||||||
| 
						 | 
					@ -3465,7 +3453,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
 | 
				
			||||||
	for (i = 0; i < 4; i++)
 | 
						for (i = 0; i < 4; i++)
 | 
				
			||||||
		sbi->s_hash_seed[i] = le32_to_cpu(es->s_hash_seed[i]);
 | 
							sbi->s_hash_seed[i] = le32_to_cpu(es->s_hash_seed[i]);
 | 
				
			||||||
	sbi->s_def_hash_version = es->s_def_hash_version;
 | 
						sbi->s_def_hash_version = es->s_def_hash_version;
 | 
				
			||||||
	if (EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_DIR_INDEX)) {
 | 
						if (ext4_has_feature_dir_index(sb)) {
 | 
				
			||||||
		i = le32_to_cpu(es->s_flags);
 | 
							i = le32_to_cpu(es->s_flags);
 | 
				
			||||||
		if (i & EXT2_FLAGS_UNSIGNED_HASH)
 | 
							if (i & EXT2_FLAGS_UNSIGNED_HASH)
 | 
				
			||||||
			sbi->s_hash_unsigned = 3;
 | 
								sbi->s_hash_unsigned = 3;
 | 
				
			||||||
| 
						 | 
					@ -3485,8 +3473,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Handle clustersize */
 | 
						/* Handle clustersize */
 | 
				
			||||||
	clustersize = BLOCK_SIZE << le32_to_cpu(es->s_log_cluster_size);
 | 
						clustersize = BLOCK_SIZE << le32_to_cpu(es->s_log_cluster_size);
 | 
				
			||||||
	has_bigalloc = EXT4_HAS_RO_COMPAT_FEATURE(sb,
 | 
						has_bigalloc = ext4_has_feature_bigalloc(sb);
 | 
				
			||||||
				EXT4_FEATURE_RO_COMPAT_BIGALLOC);
 | 
					 | 
				
			||||||
	if (has_bigalloc) {
 | 
						if (has_bigalloc) {
 | 
				
			||||||
		if (clustersize < blocksize) {
 | 
							if (clustersize < blocksize) {
 | 
				
			||||||
			ext4_msg(sb, KERN_ERR,
 | 
								ext4_msg(sb, KERN_ERR,
 | 
				
			||||||
| 
						 | 
					@ -3645,7 +3632,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
 | 
				
			||||||
	sb->s_xattr = ext4_xattr_handlers;
 | 
						sb->s_xattr = ext4_xattr_handlers;
 | 
				
			||||||
#ifdef CONFIG_QUOTA
 | 
					#ifdef CONFIG_QUOTA
 | 
				
			||||||
	sb->dq_op = &ext4_quota_operations;
 | 
						sb->dq_op = &ext4_quota_operations;
 | 
				
			||||||
	if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_QUOTA))
 | 
						if (ext4_has_feature_quota(sb))
 | 
				
			||||||
		sb->s_qcop = &dquot_quotactl_sysfile_ops;
 | 
							sb->s_qcop = &dquot_quotactl_sysfile_ops;
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		sb->s_qcop = &ext4_qctl_operations;
 | 
							sb->s_qcop = &ext4_qctl_operations;
 | 
				
			||||||
| 
						 | 
					@ -3659,11 +3646,9 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
 | 
				
			||||||
	sb->s_root = NULL;
 | 
						sb->s_root = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	needs_recovery = (es->s_last_orphan != 0 ||
 | 
						needs_recovery = (es->s_last_orphan != 0 ||
 | 
				
			||||||
			  EXT4_HAS_INCOMPAT_FEATURE(sb,
 | 
								  ext4_has_feature_journal_needs_recovery(sb));
 | 
				
			||||||
				    EXT4_FEATURE_INCOMPAT_RECOVER));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_MMP) &&
 | 
						if (ext4_has_feature_mmp(sb) && !(sb->s_flags & MS_RDONLY))
 | 
				
			||||||
	    !(sb->s_flags & MS_RDONLY))
 | 
					 | 
				
			||||||
		if (ext4_multi_mount_protect(sb, le64_to_cpu(es->s_mmp_block)))
 | 
							if (ext4_multi_mount_protect(sb, le64_to_cpu(es->s_mmp_block)))
 | 
				
			||||||
			goto failed_mount3a;
 | 
								goto failed_mount3a;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3671,12 +3656,11 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
 | 
				
			||||||
	 * The first inode we look at is the journal inode.  Don't try
 | 
						 * The first inode we look at is the journal inode.  Don't try
 | 
				
			||||||
	 * root first: it may be modified in the journal!
 | 
						 * root first: it may be modified in the journal!
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	if (!test_opt(sb, NOLOAD) &&
 | 
						if (!test_opt(sb, NOLOAD) && ext4_has_feature_journal(sb)) {
 | 
				
			||||||
	    EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL)) {
 | 
					 | 
				
			||||||
		if (ext4_load_journal(sb, es, journal_devnum))
 | 
							if (ext4_load_journal(sb, es, journal_devnum))
 | 
				
			||||||
			goto failed_mount3a;
 | 
								goto failed_mount3a;
 | 
				
			||||||
	} else if (test_opt(sb, NOLOAD) && !(sb->s_flags & MS_RDONLY) &&
 | 
						} else if (test_opt(sb, NOLOAD) && !(sb->s_flags & MS_RDONLY) &&
 | 
				
			||||||
	      EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER)) {
 | 
							   ext4_has_feature_journal_needs_recovery(sb)) {
 | 
				
			||||||
		ext4_msg(sb, KERN_ERR, "required journal recovery "
 | 
							ext4_msg(sb, KERN_ERR, "required journal recovery "
 | 
				
			||||||
		       "suppressed and not mounted read-only");
 | 
							       "suppressed and not mounted read-only");
 | 
				
			||||||
		goto failed_mount_wq;
 | 
							goto failed_mount_wq;
 | 
				
			||||||
| 
						 | 
					@ -3687,7 +3671,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
 | 
				
			||||||
		goto no_journal;
 | 
							goto no_journal;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_64BIT) &&
 | 
						if (ext4_has_feature_64bit(sb) &&
 | 
				
			||||||
	    !jbd2_journal_set_features(EXT4_SB(sb)->s_journal, 0, 0,
 | 
						    !jbd2_journal_set_features(EXT4_SB(sb)->s_journal, 0, 0,
 | 
				
			||||||
				       JBD2_FEATURE_INCOMPAT_64BIT)) {
 | 
									       JBD2_FEATURE_INCOMPAT_64BIT)) {
 | 
				
			||||||
		ext4_msg(sb, KERN_ERR, "Failed to set 64-bit journal feature");
 | 
							ext4_msg(sb, KERN_ERR, "Failed to set 64-bit journal feature");
 | 
				
			||||||
| 
						 | 
					@ -3739,18 +3723,16 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((DUMMY_ENCRYPTION_ENABLED(sbi) ||
 | 
						if ((DUMMY_ENCRYPTION_ENABLED(sbi) || ext4_has_feature_encrypt(sb)) &&
 | 
				
			||||||
	     EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_ENCRYPT)) &&
 | 
					 | 
				
			||||||
	    (blocksize != PAGE_CACHE_SIZE)) {
 | 
						    (blocksize != PAGE_CACHE_SIZE)) {
 | 
				
			||||||
		ext4_msg(sb, KERN_ERR,
 | 
							ext4_msg(sb, KERN_ERR,
 | 
				
			||||||
			 "Unsupported blocksize for fs encryption");
 | 
								 "Unsupported blocksize for fs encryption");
 | 
				
			||||||
		goto failed_mount_wq;
 | 
							goto failed_mount_wq;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (DUMMY_ENCRYPTION_ENABLED(sbi) &&
 | 
						if (DUMMY_ENCRYPTION_ENABLED(sbi) && !(sb->s_flags & MS_RDONLY) &&
 | 
				
			||||||
	    !(sb->s_flags & MS_RDONLY) &&
 | 
						    !ext4_has_feature_encrypt(sb)) {
 | 
				
			||||||
	    !EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_ENCRYPT)) {
 | 
							ext4_set_feature_encrypt(sb);
 | 
				
			||||||
		EXT4_SET_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_ENCRYPT);
 | 
					 | 
				
			||||||
		ext4_commit_super(sb, 1);
 | 
							ext4_commit_super(sb, 1);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3809,8 +3791,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
 | 
				
			||||||
	if (sbi->s_inode_size > EXT4_GOOD_OLD_INODE_SIZE) {
 | 
						if (sbi->s_inode_size > EXT4_GOOD_OLD_INODE_SIZE) {
 | 
				
			||||||
		sbi->s_want_extra_isize = sizeof(struct ext4_inode) -
 | 
							sbi->s_want_extra_isize = sizeof(struct ext4_inode) -
 | 
				
			||||||
						     EXT4_GOOD_OLD_INODE_SIZE;
 | 
											     EXT4_GOOD_OLD_INODE_SIZE;
 | 
				
			||||||
		if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
 | 
							if (ext4_has_feature_extra_isize(sb)) {
 | 
				
			||||||
				       EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE)) {
 | 
					 | 
				
			||||||
			if (sbi->s_want_extra_isize <
 | 
								if (sbi->s_want_extra_isize <
 | 
				
			||||||
			    le16_to_cpu(es->s_want_extra_isize))
 | 
								    le16_to_cpu(es->s_want_extra_isize))
 | 
				
			||||||
				sbi->s_want_extra_isize =
 | 
									sbi->s_want_extra_isize =
 | 
				
			||||||
| 
						 | 
					@ -3869,7 +3850,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
 | 
				
			||||||
		goto failed_mount6;
 | 
							goto failed_mount6;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG))
 | 
						if (ext4_has_feature_flex_bg(sb))
 | 
				
			||||||
		if (!ext4_fill_flex_info(sb)) {
 | 
							if (!ext4_fill_flex_info(sb)) {
 | 
				
			||||||
			ext4_msg(sb, KERN_ERR,
 | 
								ext4_msg(sb, KERN_ERR,
 | 
				
			||||||
			       "unable to initialize "
 | 
								       "unable to initialize "
 | 
				
			||||||
| 
						 | 
					@ -3887,8 +3868,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_QUOTA
 | 
					#ifdef CONFIG_QUOTA
 | 
				
			||||||
	/* Enable quota usage during mount. */
 | 
						/* Enable quota usage during mount. */
 | 
				
			||||||
	if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_QUOTA) &&
 | 
						if (ext4_has_feature_quota(sb) && !(sb->s_flags & MS_RDONLY)) {
 | 
				
			||||||
	    !(sb->s_flags & MS_RDONLY)) {
 | 
					 | 
				
			||||||
		err = ext4_enable_quotas(sb);
 | 
							err = ext4_enable_quotas(sb);
 | 
				
			||||||
		if (err)
 | 
							if (err)
 | 
				
			||||||
			goto failed_mount8;
 | 
								goto failed_mount8;
 | 
				
			||||||
| 
						 | 
					@ -4029,7 +4009,7 @@ static journal_t *ext4_get_journal(struct super_block *sb,
 | 
				
			||||||
	struct inode *journal_inode;
 | 
						struct inode *journal_inode;
 | 
				
			||||||
	journal_t *journal;
 | 
						journal_t *journal;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	BUG_ON(!EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL));
 | 
						BUG_ON(!ext4_has_feature_journal(sb));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* First, test for the existence of a valid inode on disk.  Bad
 | 
						/* First, test for the existence of a valid inode on disk.  Bad
 | 
				
			||||||
	 * things happen if we iget() an unused inode, as the subsequent
 | 
						 * things happen if we iget() an unused inode, as the subsequent
 | 
				
			||||||
| 
						 | 
					@ -4079,7 +4059,7 @@ static journal_t *ext4_get_dev_journal(struct super_block *sb,
 | 
				
			||||||
	struct ext4_super_block *es;
 | 
						struct ext4_super_block *es;
 | 
				
			||||||
	struct block_device *bdev;
 | 
						struct block_device *bdev;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	BUG_ON(!EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL));
 | 
						BUG_ON(!ext4_has_feature_journal(sb));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bdev = ext4_blkdev_get(j_dev, sb);
 | 
						bdev = ext4_blkdev_get(j_dev, sb);
 | 
				
			||||||
	if (bdev == NULL)
 | 
						if (bdev == NULL)
 | 
				
			||||||
| 
						 | 
					@ -4171,7 +4151,7 @@ static int ext4_load_journal(struct super_block *sb,
 | 
				
			||||||
	int err = 0;
 | 
						int err = 0;
 | 
				
			||||||
	int really_read_only;
 | 
						int really_read_only;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	BUG_ON(!EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL));
 | 
						BUG_ON(!ext4_has_feature_journal(sb));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (journal_devnum &&
 | 
						if (journal_devnum &&
 | 
				
			||||||
	    journal_devnum != le32_to_cpu(es->s_journal_dev)) {
 | 
						    journal_devnum != le32_to_cpu(es->s_journal_dev)) {
 | 
				
			||||||
| 
						 | 
					@ -4188,7 +4168,7 @@ static int ext4_load_journal(struct super_block *sb,
 | 
				
			||||||
	 * crash?  For recovery, we need to check in advance whether we
 | 
						 * crash?  For recovery, we need to check in advance whether we
 | 
				
			||||||
	 * can get read-write access to the device.
 | 
						 * can get read-write access to the device.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER)) {
 | 
						if (ext4_has_feature_journal_needs_recovery(sb)) {
 | 
				
			||||||
		if (sb->s_flags & MS_RDONLY) {
 | 
							if (sb->s_flags & MS_RDONLY) {
 | 
				
			||||||
			ext4_msg(sb, KERN_INFO, "INFO: recovery "
 | 
								ext4_msg(sb, KERN_INFO, "INFO: recovery "
 | 
				
			||||||
					"required on readonly filesystem");
 | 
										"required on readonly filesystem");
 | 
				
			||||||
| 
						 | 
					@ -4219,7 +4199,7 @@ static int ext4_load_journal(struct super_block *sb,
 | 
				
			||||||
	if (!(journal->j_flags & JBD2_BARRIER))
 | 
						if (!(journal->j_flags & JBD2_BARRIER))
 | 
				
			||||||
		ext4_msg(sb, KERN_INFO, "barriers disabled");
 | 
							ext4_msg(sb, KERN_INFO, "barriers disabled");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER))
 | 
						if (!ext4_has_feature_journal_needs_recovery(sb))
 | 
				
			||||||
		err = jbd2_journal_wipe(journal, !really_read_only);
 | 
							err = jbd2_journal_wipe(journal, !really_read_only);
 | 
				
			||||||
	if (!err) {
 | 
						if (!err) {
 | 
				
			||||||
		char *save = kmalloc(EXT4_S_ERR_LEN, GFP_KERNEL);
 | 
							char *save = kmalloc(EXT4_S_ERR_LEN, GFP_KERNEL);
 | 
				
			||||||
| 
						 | 
					@ -4333,7 +4313,7 @@ static void ext4_mark_recovery_complete(struct super_block *sb,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	journal_t *journal = EXT4_SB(sb)->s_journal;
 | 
						journal_t *journal = EXT4_SB(sb)->s_journal;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL)) {
 | 
						if (!ext4_has_feature_journal(sb)) {
 | 
				
			||||||
		BUG_ON(journal != NULL);
 | 
							BUG_ON(journal != NULL);
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -4341,9 +4321,9 @@ static void ext4_mark_recovery_complete(struct super_block *sb,
 | 
				
			||||||
	if (jbd2_journal_flush(journal) < 0)
 | 
						if (jbd2_journal_flush(journal) < 0)
 | 
				
			||||||
		goto out;
 | 
							goto out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER) &&
 | 
						if (ext4_has_feature_journal_needs_recovery(sb) &&
 | 
				
			||||||
	    sb->s_flags & MS_RDONLY) {
 | 
						    sb->s_flags & MS_RDONLY) {
 | 
				
			||||||
		EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
 | 
							ext4_clear_feature_journal_needs_recovery(sb);
 | 
				
			||||||
		ext4_commit_super(sb, 1);
 | 
							ext4_commit_super(sb, 1);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4363,7 +4343,7 @@ static void ext4_clear_journal_err(struct super_block *sb,
 | 
				
			||||||
	int j_errno;
 | 
						int j_errno;
 | 
				
			||||||
	const char *errstr;
 | 
						const char *errstr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	BUG_ON(!EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL));
 | 
						BUG_ON(!ext4_has_feature_journal(sb));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	journal = EXT4_SB(sb)->s_journal;
 | 
						journal = EXT4_SB(sb)->s_journal;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4478,7 +4458,7 @@ static int ext4_freeze(struct super_block *sb)
 | 
				
			||||||
			goto out;
 | 
								goto out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* Journal blocked and flushed, clear needs_recovery flag. */
 | 
							/* Journal blocked and flushed, clear needs_recovery flag. */
 | 
				
			||||||
		EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
 | 
							ext4_clear_feature_journal_needs_recovery(sb);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	error = ext4_commit_super(sb, 1);
 | 
						error = ext4_commit_super(sb, 1);
 | 
				
			||||||
| 
						 | 
					@ -4500,7 +4480,7 @@ static int ext4_unfreeze(struct super_block *sb)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (EXT4_SB(sb)->s_journal) {
 | 
						if (EXT4_SB(sb)->s_journal) {
 | 
				
			||||||
		/* Reset the needs_recovery flag before the fs is unlocked. */
 | 
							/* Reset the needs_recovery flag before the fs is unlocked. */
 | 
				
			||||||
		EXT4_SET_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
 | 
							ext4_set_feature_journal_needs_recovery(sb);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ext4_commit_super(sb, 1);
 | 
						ext4_commit_super(sb, 1);
 | 
				
			||||||
| 
						 | 
					@ -4653,8 +4633,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
 | 
				
			||||||
				ext4_mark_recovery_complete(sb, es);
 | 
									ext4_mark_recovery_complete(sb, es);
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			/* Make sure we can mount this feature set readwrite */
 | 
								/* Make sure we can mount this feature set readwrite */
 | 
				
			||||||
			if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
 | 
								if (ext4_has_feature_readonly(sb) ||
 | 
				
			||||||
					EXT4_FEATURE_RO_COMPAT_READONLY) ||
 | 
					 | 
				
			||||||
			    !ext4_feature_set_ok(sb, 0)) {
 | 
								    !ext4_feature_set_ok(sb, 0)) {
 | 
				
			||||||
				err = -EROFS;
 | 
									err = -EROFS;
 | 
				
			||||||
				goto restore_opts;
 | 
									goto restore_opts;
 | 
				
			||||||
| 
						 | 
					@ -4670,7 +4649,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
 | 
				
			||||||
				if (!ext4_group_desc_csum_verify(sb, g, gdp)) {
 | 
									if (!ext4_group_desc_csum_verify(sb, g, gdp)) {
 | 
				
			||||||
					ext4_msg(sb, KERN_ERR,
 | 
										ext4_msg(sb, KERN_ERR,
 | 
				
			||||||
	       "ext4_remount: Checksum for group %u failed (%u!=%u)",
 | 
						       "ext4_remount: Checksum for group %u failed (%u!=%u)",
 | 
				
			||||||
		g, le16_to_cpu(ext4_group_desc_csum(sbi, g, gdp)),
 | 
							g, le16_to_cpu(ext4_group_desc_csum(sb, g, gdp)),
 | 
				
			||||||
					       le16_to_cpu(gdp->bg_checksum));
 | 
										       le16_to_cpu(gdp->bg_checksum));
 | 
				
			||||||
					err = -EFSBADCRC;
 | 
										err = -EFSBADCRC;
 | 
				
			||||||
					goto restore_opts;
 | 
										goto restore_opts;
 | 
				
			||||||
| 
						 | 
					@ -4702,8 +4681,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
 | 
				
			||||||
			sbi->s_mount_state = le16_to_cpu(es->s_state);
 | 
								sbi->s_mount_state = le16_to_cpu(es->s_state);
 | 
				
			||||||
			if (!ext4_setup_super(sb, es, 0))
 | 
								if (!ext4_setup_super(sb, es, 0))
 | 
				
			||||||
				sb->s_flags &= ~MS_RDONLY;
 | 
									sb->s_flags &= ~MS_RDONLY;
 | 
				
			||||||
			if (EXT4_HAS_INCOMPAT_FEATURE(sb,
 | 
								if (ext4_has_feature_mmp(sb))
 | 
				
			||||||
						     EXT4_FEATURE_INCOMPAT_MMP))
 | 
					 | 
				
			||||||
				if (ext4_multi_mount_protect(sb,
 | 
									if (ext4_multi_mount_protect(sb,
 | 
				
			||||||
						le64_to_cpu(es->s_mmp_block))) {
 | 
											le64_to_cpu(es->s_mmp_block))) {
 | 
				
			||||||
					err = -EROFS;
 | 
										err = -EROFS;
 | 
				
			||||||
| 
						 | 
					@ -4736,8 +4714,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
 | 
				
			||||||
	if (enable_quota) {
 | 
						if (enable_quota) {
 | 
				
			||||||
		if (sb_any_quota_suspended(sb))
 | 
							if (sb_any_quota_suspended(sb))
 | 
				
			||||||
			dquot_resume(sb, -1);
 | 
								dquot_resume(sb, -1);
 | 
				
			||||||
		else if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
 | 
							else if (ext4_has_feature_quota(sb)) {
 | 
				
			||||||
					EXT4_FEATURE_RO_COMPAT_QUOTA)) {
 | 
					 | 
				
			||||||
			err = ext4_enable_quotas(sb);
 | 
								err = ext4_enable_quotas(sb);
 | 
				
			||||||
			if (err)
 | 
								if (err)
 | 
				
			||||||
				goto restore_opts;
 | 
									goto restore_opts;
 | 
				
			||||||
| 
						 | 
					@ -4881,7 +4858,7 @@ static int ext4_mark_dquot_dirty(struct dquot *dquot)
 | 
				
			||||||
	struct ext4_sb_info *sbi = EXT4_SB(sb);
 | 
						struct ext4_sb_info *sbi = EXT4_SB(sb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Are we journaling quotas? */
 | 
						/* Are we journaling quotas? */
 | 
				
			||||||
	if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_QUOTA) ||
 | 
						if (ext4_has_feature_quota(sb) ||
 | 
				
			||||||
	    sbi->s_qf_names[USRQUOTA] || sbi->s_qf_names[GRPQUOTA]) {
 | 
						    sbi->s_qf_names[USRQUOTA] || sbi->s_qf_names[GRPQUOTA]) {
 | 
				
			||||||
		dquot_mark_dquot_dirty(dquot);
 | 
							dquot_mark_dquot_dirty(dquot);
 | 
				
			||||||
		return ext4_write_dquot(dquot);
 | 
							return ext4_write_dquot(dquot);
 | 
				
			||||||
| 
						 | 
					@ -4969,7 +4946,7 @@ static int ext4_quota_enable(struct super_block *sb, int type, int format_id,
 | 
				
			||||||
		le32_to_cpu(EXT4_SB(sb)->s_es->s_grp_quota_inum)
 | 
							le32_to_cpu(EXT4_SB(sb)->s_es->s_grp_quota_inum)
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	BUG_ON(!EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_QUOTA));
 | 
						BUG_ON(!ext4_has_feature_quota(sb));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!qf_inums[type])
 | 
						if (!qf_inums[type])
 | 
				
			||||||
		return -EPERM;
 | 
							return -EPERM;
 | 
				
			||||||
| 
						 | 
					@ -5163,11 +5140,11 @@ static inline void unregister_as_ext2(void)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline int ext2_feature_set_ok(struct super_block *sb)
 | 
					static inline int ext2_feature_set_ok(struct super_block *sb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (EXT4_HAS_INCOMPAT_FEATURE(sb, ~EXT2_FEATURE_INCOMPAT_SUPP))
 | 
						if (ext4_has_unknown_ext2_incompat_features(sb))
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
	if (sb->s_flags & MS_RDONLY)
 | 
						if (sb->s_flags & MS_RDONLY)
 | 
				
			||||||
		return 1;
 | 
							return 1;
 | 
				
			||||||
	if (EXT4_HAS_RO_COMPAT_FEATURE(sb, ~EXT2_FEATURE_RO_COMPAT_SUPP))
 | 
						if (ext4_has_unknown_ext2_ro_compat_features(sb))
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
	return 1;
 | 
						return 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -5192,13 +5169,13 @@ static inline void unregister_as_ext3(void)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline int ext3_feature_set_ok(struct super_block *sb)
 | 
					static inline int ext3_feature_set_ok(struct super_block *sb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (EXT4_HAS_INCOMPAT_FEATURE(sb, ~EXT3_FEATURE_INCOMPAT_SUPP))
 | 
						if (ext4_has_unknown_ext3_incompat_features(sb))
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
	if (!EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL))
 | 
						if (!ext4_has_feature_journal(sb))
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
	if (sb->s_flags & MS_RDONLY)
 | 
						if (sb->s_flags & MS_RDONLY)
 | 
				
			||||||
		return 1;
 | 
							return 1;
 | 
				
			||||||
	if (EXT4_HAS_RO_COMPAT_FEATURE(sb, ~EXT3_FEATURE_RO_COMPAT_SUPP))
 | 
						if (ext4_has_unknown_ext3_ro_compat_features(sb))
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
	return 1;
 | 
						return 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -525,12 +525,12 @@ ext4_xattr_list(struct dentry *dentry, char *buffer, size_t buffer_size)
 | 
				
			||||||
static void ext4_xattr_update_super_block(handle_t *handle,
 | 
					static void ext4_xattr_update_super_block(handle_t *handle,
 | 
				
			||||||
					  struct super_block *sb)
 | 
										  struct super_block *sb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_EXT_ATTR))
 | 
						if (ext4_has_feature_xattr(sb))
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	BUFFER_TRACE(EXT4_SB(sb)->s_sbh, "get_write_access");
 | 
						BUFFER_TRACE(EXT4_SB(sb)->s_sbh, "get_write_access");
 | 
				
			||||||
	if (ext4_journal_get_write_access(handle, EXT4_SB(sb)->s_sbh) == 0) {
 | 
						if (ext4_journal_get_write_access(handle, EXT4_SB(sb)->s_sbh) == 0) {
 | 
				
			||||||
		EXT4_SET_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_EXT_ATTR);
 | 
							ext4_set_feature_xattr(sb);
 | 
				
			||||||
		ext4_handle_dirty_super(handle, sb);
 | 
							ext4_handle_dirty_super(handle, sb);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue