ext4: only set S_DAX if DAX is really supported
Currently we have S_DAX set inode->i_flags for a regular file whenever ext4 is mounted with dax mount option. However in some cases we cannot really do DAX - e.g. when inode is marked to use data journalling, when inode data is being encrypted, or when inode is stored inline. Make sure S_DAX flag is appropriately set/cleared in these cases. Reviewed-by: Ross Zwisler <ross.zwisler@linux.intel.com> Signed-off-by: Jan Kara <jack@suse.cz> Signed-off-by: Theodore Ts'o <tytso@mit.edu>
This commit is contained in:
parent
213bcd9ccb
commit
a3caa24b70
|
@ -299,6 +299,11 @@ static int ext4_create_inline_data(handle_t *handle,
|
||||||
EXT4_I(inode)->i_inline_size = len + EXT4_MIN_INLINE_DATA_SIZE;
|
EXT4_I(inode)->i_inline_size = len + EXT4_MIN_INLINE_DATA_SIZE;
|
||||||
ext4_clear_inode_flag(inode, EXT4_INODE_EXTENTS);
|
ext4_clear_inode_flag(inode, EXT4_INODE_EXTENTS);
|
||||||
ext4_set_inode_flag(inode, EXT4_INODE_INLINE_DATA);
|
ext4_set_inode_flag(inode, EXT4_INODE_INLINE_DATA);
|
||||||
|
/*
|
||||||
|
* Propagate changes to inode->i_flags as well - e.g. S_DAX may
|
||||||
|
* get cleared
|
||||||
|
*/
|
||||||
|
ext4_set_inode_flags(inode);
|
||||||
get_bh(is.iloc.bh);
|
get_bh(is.iloc.bh);
|
||||||
error = ext4_mark_iloc_dirty(handle, inode, &is.iloc);
|
error = ext4_mark_iloc_dirty(handle, inode, &is.iloc);
|
||||||
|
|
||||||
|
@ -442,6 +447,11 @@ static int ext4_destroy_inline_data_nolock(handle_t *handle,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ext4_clear_inode_flag(inode, EXT4_INODE_INLINE_DATA);
|
ext4_clear_inode_flag(inode, EXT4_INODE_INLINE_DATA);
|
||||||
|
/*
|
||||||
|
* Propagate changes to inode->i_flags as well - e.g. S_DAX may
|
||||||
|
* get set.
|
||||||
|
*/
|
||||||
|
ext4_set_inode_flags(inode);
|
||||||
|
|
||||||
get_bh(is.iloc.bh);
|
get_bh(is.iloc.bh);
|
||||||
error = ext4_mark_iloc_dirty(handle, inode, &is.iloc);
|
error = ext4_mark_iloc_dirty(handle, inode, &is.iloc);
|
||||||
|
|
|
@ -4368,7 +4368,9 @@ void ext4_set_inode_flags(struct inode *inode)
|
||||||
new_fl |= S_NOATIME;
|
new_fl |= S_NOATIME;
|
||||||
if (flags & EXT4_DIRSYNC_FL)
|
if (flags & EXT4_DIRSYNC_FL)
|
||||||
new_fl |= S_DIRSYNC;
|
new_fl |= S_DIRSYNC;
|
||||||
if (test_opt(inode->i_sb, DAX) && S_ISREG(inode->i_mode))
|
if (test_opt(inode->i_sb, DAX) && S_ISREG(inode->i_mode) &&
|
||||||
|
!ext4_should_journal_data(inode) && !ext4_has_inline_data(inode) &&
|
||||||
|
!ext4_encrypted_inode(inode))
|
||||||
new_fl |= S_DAX;
|
new_fl |= S_DAX;
|
||||||
inode_set_flags(inode, new_fl,
|
inode_set_flags(inode, new_fl,
|
||||||
S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC|S_DAX);
|
S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC|S_DAX);
|
||||||
|
@ -5641,6 +5643,11 @@ int ext4_change_inode_journal_flag(struct inode *inode, int val)
|
||||||
ext4_clear_inode_flag(inode, EXT4_INODE_JOURNAL_DATA);
|
ext4_clear_inode_flag(inode, EXT4_INODE_JOURNAL_DATA);
|
||||||
}
|
}
|
||||||
ext4_set_aops(inode);
|
ext4_set_aops(inode);
|
||||||
|
/*
|
||||||
|
* Update inode->i_flags after EXT4_INODE_JOURNAL_DATA was updated.
|
||||||
|
* E.g. S_DAX may get cleared / set.
|
||||||
|
*/
|
||||||
|
ext4_set_inode_flags(inode);
|
||||||
|
|
||||||
jbd2_journal_unlock_updates(journal);
|
jbd2_journal_unlock_updates(journal);
|
||||||
percpu_up_write(&sbi->s_journal_flag_rwsem);
|
percpu_up_write(&sbi->s_journal_flag_rwsem);
|
||||||
|
|
|
@ -1126,6 +1126,10 @@ static int ext4_set_context(struct inode *inode, const void *ctx, size_t len,
|
||||||
ext4_set_inode_flag(inode, EXT4_INODE_ENCRYPT);
|
ext4_set_inode_flag(inode, EXT4_INODE_ENCRYPT);
|
||||||
ext4_clear_inode_state(inode,
|
ext4_clear_inode_state(inode,
|
||||||
EXT4_STATE_MAY_INLINE_DATA);
|
EXT4_STATE_MAY_INLINE_DATA);
|
||||||
|
/*
|
||||||
|
* Update inode->i_flags - e.g. S_DAX may get disabled
|
||||||
|
*/
|
||||||
|
ext4_set_inode_flags(inode);
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -1140,6 +1144,8 @@ static int ext4_set_context(struct inode *inode, const void *ctx, size_t len,
|
||||||
len, 0);
|
len, 0);
|
||||||
if (!res) {
|
if (!res) {
|
||||||
ext4_set_inode_flag(inode, EXT4_INODE_ENCRYPT);
|
ext4_set_inode_flag(inode, EXT4_INODE_ENCRYPT);
|
||||||
|
/* Update inode->i_flags - e.g. S_DAX may get disabled */
|
||||||
|
ext4_set_inode_flags(inode);
|
||||||
res = ext4_mark_inode_dirty(handle, inode);
|
res = ext4_mark_inode_dirty(handle, inode);
|
||||||
if (res)
|
if (res)
|
||||||
EXT4_ERROR_INODE(inode, "Failed to mark inode dirty");
|
EXT4_ERROR_INODE(inode, "Failed to mark inode dirty");
|
||||||
|
|
Loading…
Reference in New Issue