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:
Darrick J. Wong 2015-10-17 16:18:43 -04:00 committed by Theodore Ts'o
parent 6a797d2737
commit e2b911c535
15 changed files with 252 additions and 184 deletions

View File

@ -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) {

View File

@ -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)))

View File

@ -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];
} }

View File

@ -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

View File

@ -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

View File

@ -1045,7 +1045,7 @@ got:
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 @@ got:
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);

View File

@ -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;

View File

@ -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);

View File

@ -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);
} }

View File

@ -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 @@ setversion_out:
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 @@ group_extend_out:
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 @@ mext_out:
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 @@ group_add_out:
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;

View File

@ -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;
/* /*

View File

@ -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 =

View File

@ -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 @@ exit_journal:
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 @@ retry:
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");

View File

@ -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 @@ failed:
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 @@ no_journal:
} }
} }
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 @@ no_journal:
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 @@ no_journal:
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 @@ no_journal:
#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;
} }

View File

@ -525,12 +525,12 @@ errout:
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);
} }
} }