Bug fixes for the new ext4 fast commit feature, plus a fix for the
data=journal bug fix. Also use the generic casefolding support which has now landed in fs/libfs.c for 5.10. -----BEGIN PGP SIGNATURE----- iQEzBAABCAAdFiEEK2m5VNv+CHkogTfJ8vlZVpUNgaMFAl+aP/IACgkQ8vlZVpUN gaM62gf+JWHXh4d4RS4UcFlQWmT0JlMK8AGEdt90PGeJwO7MmAUC8KRFdMxCSdMQ yqJObRH9w7AFVZYCdroLIC2MyeXj4rASD7DxMgFhu/LYrKOTxCHiTt9gdx/slELM HQoKB77pYs4AZOMPgo+svqf9aHtHPu1Bk3M2C5WW4/BZHjKCxXDD7wONPFLHOq/0 qTcj2JS+1GAivNzwq8/ZFntmbz316FuKF3LNVUvCP+aTbOwD77NtyaBDGr8pnsnz duNyX4CYPo27FM9K/ywGQL9ISCIRxEwPN0GeILc3Cawu6bsr5z+ZBYKbt3DuUv18 hl+E7wrOG/+EMLd6TBfvRN1v5YvwPg== =0J5C -----END PGP SIGNATURE----- Merge tag 'ext4_for_linus_fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4 Pull ext4 fixes from Ted Ts'o: "Bug fixes for the new ext4 fast commit feature, plus a fix for the 'data=journal' bug fix. Also use the generic casefolding support which has now landed in fs/libfs.c for 5.10" * tag 'ext4_for_linus_fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4: ext4: indicate that fast_commit is available via /sys/fs/ext4/feature/... ext4: use generic casefolding support ext4: do not use extent after put_bh ext4: use IS_ERR() for error checking of path ext4: fix mmap write protection for data=journal mode jbd2: fix a kernel-doc markup ext4: use s_mount_flags instead of s_mount_state for fast commit state ext4: make num of fast commit blocks configurable ext4: properly check for dirty state in ext4_inode_datasync_dirty() ext4: fix double locking in ext4_fc_commit_dentry_updates()
This commit is contained in:
Коммит
58130a6cd0
|
@ -669,68 +669,8 @@ const struct file_operations ext4_dir_operations = {
|
|||
};
|
||||
|
||||
#ifdef CONFIG_UNICODE
|
||||
static int ext4_d_compare(const struct dentry *dentry, unsigned int len,
|
||||
const char *str, const struct qstr *name)
|
||||
{
|
||||
struct qstr qstr = {.name = str, .len = len };
|
||||
const struct dentry *parent = READ_ONCE(dentry->d_parent);
|
||||
const struct inode *inode = d_inode_rcu(parent);
|
||||
char strbuf[DNAME_INLINE_LEN];
|
||||
|
||||
if (!inode || !IS_CASEFOLDED(inode) ||
|
||||
!EXT4_SB(inode->i_sb)->s_encoding) {
|
||||
if (len != name->len)
|
||||
return -1;
|
||||
return memcmp(str, name->name, len);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the dentry name is stored in-line, then it may be concurrently
|
||||
* modified by a rename. If this happens, the VFS will eventually retry
|
||||
* the lookup, so it doesn't matter what ->d_compare() returns.
|
||||
* However, it's unsafe to call utf8_strncasecmp() with an unstable
|
||||
* string. Therefore, we have to copy the name into a temporary buffer.
|
||||
*/
|
||||
if (len <= DNAME_INLINE_LEN - 1) {
|
||||
memcpy(strbuf, str, len);
|
||||
strbuf[len] = 0;
|
||||
qstr.name = strbuf;
|
||||
/* prevent compiler from optimizing out the temporary buffer */
|
||||
barrier();
|
||||
}
|
||||
|
||||
return ext4_ci_compare(inode, name, &qstr, false);
|
||||
}
|
||||
|
||||
static int ext4_d_hash(const struct dentry *dentry, struct qstr *str)
|
||||
{
|
||||
const struct ext4_sb_info *sbi = EXT4_SB(dentry->d_sb);
|
||||
const struct unicode_map *um = sbi->s_encoding;
|
||||
const struct inode *inode = d_inode_rcu(dentry);
|
||||
unsigned char *norm;
|
||||
int len, ret = 0;
|
||||
|
||||
if (!inode || !IS_CASEFOLDED(inode) || !um)
|
||||
return 0;
|
||||
|
||||
norm = kmalloc(PATH_MAX, GFP_ATOMIC);
|
||||
if (!norm)
|
||||
return -ENOMEM;
|
||||
|
||||
len = utf8_casefold(um, str, norm, PATH_MAX);
|
||||
if (len < 0) {
|
||||
if (ext4_has_strict_mode(sbi))
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
str->hash = full_name_hash(dentry, norm, len);
|
||||
out:
|
||||
kfree(norm);
|
||||
return ret;
|
||||
}
|
||||
|
||||
const struct dentry_operations ext4_dentry_ops = {
|
||||
.d_hash = ext4_d_hash,
|
||||
.d_compare = ext4_d_compare,
|
||||
.d_hash = generic_ci_d_hash,
|
||||
.d_compare = generic_ci_d_compare,
|
||||
};
|
||||
#endif
|
||||
|
|
|
@ -1166,10 +1166,6 @@ struct ext4_inode_info {
|
|||
#define EXT4_VALID_FS 0x0001 /* Unmounted cleanly */
|
||||
#define EXT4_ERROR_FS 0x0002 /* Errors detected */
|
||||
#define EXT4_ORPHAN_FS 0x0004 /* Orphans being recovered */
|
||||
#define EXT4_FC_INELIGIBLE 0x0008 /* Fast commit ineligible */
|
||||
#define EXT4_FC_COMMITTING 0x0010 /* File system underoing a fast
|
||||
* commit.
|
||||
*/
|
||||
#define EXT4_FC_REPLAY 0x0020 /* Fast commit replay ongoing */
|
||||
|
||||
/*
|
||||
|
@ -1431,6 +1427,10 @@ struct ext4_super_block {
|
|||
*/
|
||||
#define EXT4_MF_MNTDIR_SAMPLED 0x0001
|
||||
#define EXT4_MF_FS_ABORTED 0x0002 /* Fatal error detected */
|
||||
#define EXT4_MF_FC_INELIGIBLE 0x0004 /* Fast commit ineligible */
|
||||
#define EXT4_MF_FC_COMMITTING 0x0008 /* File system underoing a fast
|
||||
* commit.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_FS_ENCRYPTION
|
||||
#define DUMMY_ENCRYPTION_ENABLED(sbi) ((sbi)->s_dummy_enc_policy.policy != NULL)
|
||||
|
@ -1443,14 +1443,6 @@ struct ext4_super_block {
|
|||
|
||||
#define EXT4_ENC_UTF8_12_1 1
|
||||
|
||||
/*
|
||||
* Flags for ext4_sb_info.s_encoding_flags.
|
||||
*/
|
||||
#define EXT4_ENC_STRICT_MODE_FL (1 << 0)
|
||||
|
||||
#define ext4_has_strict_mode(sbi) \
|
||||
(sbi->s_encoding_flags & EXT4_ENC_STRICT_MODE_FL)
|
||||
|
||||
/*
|
||||
* fourth extended-fs super-block data in memory
|
||||
*/
|
||||
|
@ -1500,10 +1492,6 @@ struct ext4_sb_info {
|
|||
struct kobject s_kobj;
|
||||
struct completion s_kobj_unregister;
|
||||
struct super_block *s_sb;
|
||||
#ifdef CONFIG_UNICODE
|
||||
struct unicode_map *s_encoding;
|
||||
__u16 s_encoding_flags;
|
||||
#endif
|
||||
|
||||
/* Journaling */
|
||||
struct journal_s *s_journal;
|
||||
|
|
|
@ -1471,16 +1471,16 @@ static int ext4_ext_search_left(struct inode *inode,
|
|||
}
|
||||
|
||||
/*
|
||||
* search the closest allocated block to the right for *logical
|
||||
* and returns it at @logical + it's physical address at @phys
|
||||
* if *logical is the largest allocated block, the function
|
||||
* returns 0 at @phys
|
||||
* return value contains 0 (success) or error code
|
||||
* Search the closest allocated block to the right for *logical
|
||||
* and returns it at @logical + it's physical address at @phys.
|
||||
* If not exists, return 0 and @phys is set to 0. We will return
|
||||
* 1 which means we found an allocated block and ret_ex is valid.
|
||||
* Or return a (< 0) error code.
|
||||
*/
|
||||
static int ext4_ext_search_right(struct inode *inode,
|
||||
struct ext4_ext_path *path,
|
||||
ext4_lblk_t *logical, ext4_fsblk_t *phys,
|
||||
struct ext4_extent **ret_ex)
|
||||
struct ext4_extent *ret_ex)
|
||||
{
|
||||
struct buffer_head *bh = NULL;
|
||||
struct ext4_extent_header *eh;
|
||||
|
@ -1574,10 +1574,11 @@ got_index:
|
|||
found_extent:
|
||||
*logical = le32_to_cpu(ex->ee_block);
|
||||
*phys = ext4_ext_pblock(ex);
|
||||
*ret_ex = ex;
|
||||
if (ret_ex)
|
||||
*ret_ex = *ex;
|
||||
if (bh)
|
||||
put_bh(bh);
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2868,8 +2869,8 @@ again:
|
|||
*/
|
||||
lblk = ex_end + 1;
|
||||
err = ext4_ext_search_right(inode, path, &lblk, &pblk,
|
||||
&ex);
|
||||
if (err)
|
||||
NULL);
|
||||
if (err < 0)
|
||||
goto out;
|
||||
if (pblk) {
|
||||
partial.pclu = EXT4_B2C(sbi, pblk);
|
||||
|
@ -4039,7 +4040,7 @@ int ext4_ext_map_blocks(handle_t *handle, struct inode *inode,
|
|||
struct ext4_map_blocks *map, int flags)
|
||||
{
|
||||
struct ext4_ext_path *path = NULL;
|
||||
struct ext4_extent newex, *ex, *ex2;
|
||||
struct ext4_extent newex, *ex, ex2;
|
||||
struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
|
||||
ext4_fsblk_t newblock = 0, pblk;
|
||||
int err = 0, depth, ret;
|
||||
|
@ -4175,15 +4176,14 @@ int ext4_ext_map_blocks(handle_t *handle, struct inode *inode,
|
|||
if (err)
|
||||
goto out;
|
||||
ar.lright = map->m_lblk;
|
||||
ex2 = NULL;
|
||||
err = ext4_ext_search_right(inode, path, &ar.lright, &ar.pright, &ex2);
|
||||
if (err)
|
||||
if (err < 0)
|
||||
goto out;
|
||||
|
||||
/* Check if the extent after searching to the right implies a
|
||||
* cluster we can use. */
|
||||
if ((sbi->s_cluster_ratio > 1) && ex2 &&
|
||||
get_implied_cluster_alloc(inode->i_sb, map, ex2, path)) {
|
||||
if ((sbi->s_cluster_ratio > 1) && err &&
|
||||
get_implied_cluster_alloc(inode->i_sb, map, &ex2, path)) {
|
||||
ar.len = allocated = map->m_len;
|
||||
newblock = map->m_pblk;
|
||||
goto got_allocated_blocks;
|
||||
|
|
|
@ -269,7 +269,7 @@ void ext4_fc_mark_ineligible(struct super_block *sb, int reason)
|
|||
(EXT4_SB(sb)->s_mount_state & EXT4_FC_REPLAY))
|
||||
return;
|
||||
|
||||
sbi->s_mount_state |= EXT4_FC_INELIGIBLE;
|
||||
sbi->s_mount_flags |= EXT4_MF_FC_INELIGIBLE;
|
||||
WARN_ON(reason >= EXT4_FC_REASON_MAX);
|
||||
sbi->s_fc_stats.fc_ineligible_reason_count[reason]++;
|
||||
}
|
||||
|
@ -292,7 +292,7 @@ void ext4_fc_start_ineligible(struct super_block *sb, int reason)
|
|||
}
|
||||
|
||||
/*
|
||||
* Stop a fast commit ineligible update. We set EXT4_FC_INELIGIBLE flag here
|
||||
* Stop a fast commit ineligible update. We set EXT4_MF_FC_INELIGIBLE flag here
|
||||
* to ensure that after stopping the ineligible update, at least one full
|
||||
* commit takes place.
|
||||
*/
|
||||
|
@ -302,13 +302,13 @@ void ext4_fc_stop_ineligible(struct super_block *sb)
|
|||
(EXT4_SB(sb)->s_mount_state & EXT4_FC_REPLAY))
|
||||
return;
|
||||
|
||||
EXT4_SB(sb)->s_mount_state |= EXT4_FC_INELIGIBLE;
|
||||
EXT4_SB(sb)->s_mount_flags |= EXT4_MF_FC_INELIGIBLE;
|
||||
atomic_dec(&EXT4_SB(sb)->s_fc_ineligible_updates);
|
||||
}
|
||||
|
||||
static inline int ext4_fc_is_ineligible(struct super_block *sb)
|
||||
{
|
||||
return (EXT4_SB(sb)->s_mount_state & EXT4_FC_INELIGIBLE) ||
|
||||
return (EXT4_SB(sb)->s_mount_flags & EXT4_MF_FC_INELIGIBLE) ||
|
||||
atomic_read(&EXT4_SB(sb)->s_fc_ineligible_updates);
|
||||
}
|
||||
|
||||
|
@ -358,7 +358,7 @@ static int ext4_fc_track_template(
|
|||
spin_lock(&sbi->s_fc_lock);
|
||||
if (list_empty(&EXT4_I(inode)->i_fc_list))
|
||||
list_add_tail(&EXT4_I(inode)->i_fc_list,
|
||||
(sbi->s_mount_state & EXT4_FC_COMMITTING) ?
|
||||
(sbi->s_mount_flags & EXT4_MF_FC_COMMITTING) ?
|
||||
&sbi->s_fc_q[FC_Q_STAGING] :
|
||||
&sbi->s_fc_q[FC_Q_MAIN]);
|
||||
spin_unlock(&sbi->s_fc_lock);
|
||||
|
@ -411,7 +411,7 @@ static int __track_dentry_update(struct inode *inode, void *arg, bool update)
|
|||
node->fcd_name.len = dentry->d_name.len;
|
||||
|
||||
spin_lock(&sbi->s_fc_lock);
|
||||
if (sbi->s_mount_state & EXT4_FC_COMMITTING)
|
||||
if (sbi->s_mount_flags & EXT4_MF_FC_COMMITTING)
|
||||
list_add_tail(&node->fcd_list,
|
||||
&sbi->s_fc_dentry_q[FC_Q_STAGING]);
|
||||
else
|
||||
|
@ -846,7 +846,7 @@ static int ext4_fc_submit_inode_data_all(journal_t *journal)
|
|||
int ret = 0;
|
||||
|
||||
spin_lock(&sbi->s_fc_lock);
|
||||
sbi->s_mount_state |= EXT4_FC_COMMITTING;
|
||||
sbi->s_mount_flags |= EXT4_MF_FC_COMMITTING;
|
||||
list_for_each(pos, &sbi->s_fc_q[FC_Q_MAIN]) {
|
||||
ei = list_entry(pos, struct ext4_inode_info, i_fc_list);
|
||||
ext4_set_inode_state(&ei->vfs_inode, EXT4_STATE_FC_COMMITTING);
|
||||
|
@ -964,7 +964,6 @@ static int ext4_fc_commit_dentry_updates(journal_t *journal, u32 *crc)
|
|||
fc_dentry->fcd_parent, fc_dentry->fcd_ino,
|
||||
fc_dentry->fcd_name.len,
|
||||
fc_dentry->fcd_name.name, crc)) {
|
||||
spin_lock(&sbi->s_fc_lock);
|
||||
ret = -ENOSPC;
|
||||
goto lock_and_exit;
|
||||
}
|
||||
|
@ -1191,8 +1190,8 @@ static void ext4_fc_cleanup(journal_t *journal, int full)
|
|||
list_splice_init(&sbi->s_fc_q[FC_Q_STAGING],
|
||||
&sbi->s_fc_q[FC_Q_STAGING]);
|
||||
|
||||
sbi->s_mount_state &= ~EXT4_FC_COMMITTING;
|
||||
sbi->s_mount_state &= ~EXT4_FC_INELIGIBLE;
|
||||
sbi->s_mount_flags &= ~EXT4_MF_FC_COMMITTING;
|
||||
sbi->s_mount_flags &= ~EXT4_MF_FC_INELIGIBLE;
|
||||
|
||||
if (full)
|
||||
sbi->s_fc_bytes = 0;
|
||||
|
@ -1617,8 +1616,10 @@ static int ext4_fc_replay_add_range(struct super_block *sb,
|
|||
if (ret == 0) {
|
||||
/* Range is not mapped */
|
||||
path = ext4_find_extent(inode, cur, NULL, 0);
|
||||
if (!path)
|
||||
continue;
|
||||
if (IS_ERR(path)) {
|
||||
iput(inode);
|
||||
return 0;
|
||||
}
|
||||
memset(&newex, 0, sizeof(newex));
|
||||
newex.ee_block = cpu_to_le32(cur);
|
||||
ext4_ext_store_pblock(
|
||||
|
@ -2078,6 +2079,8 @@ static int ext4_fc_replay(journal_t *journal, struct buffer_head *bh,
|
|||
|
||||
void ext4_fc_init(struct super_block *sb, journal_t *journal)
|
||||
{
|
||||
int num_fc_blocks;
|
||||
|
||||
/*
|
||||
* We set replay callback even if fast commit disabled because we may
|
||||
* could still have fast commit blocks that need to be replayed even if
|
||||
|
@ -2087,7 +2090,15 @@ void ext4_fc_init(struct super_block *sb, journal_t *journal)
|
|||
if (!test_opt2(sb, JOURNAL_FAST_COMMIT))
|
||||
return;
|
||||
journal->j_fc_cleanup_callback = ext4_fc_cleanup;
|
||||
if (jbd2_fc_init(journal, EXT4_NUM_FC_BLKS)) {
|
||||
if (!buffer_uptodate(journal->j_sb_buffer)
|
||||
&& ext4_read_bh_lock(journal->j_sb_buffer, REQ_META | REQ_PRIO,
|
||||
true)) {
|
||||
ext4_msg(sb, KERN_ERR, "I/O error on journal");
|
||||
return;
|
||||
}
|
||||
num_fc_blocks = be32_to_cpu(journal->j_superblock->s_num_fc_blks);
|
||||
if (jbd2_fc_init(journal, num_fc_blocks ? num_fc_blocks :
|
||||
EXT4_NUM_FC_BLKS)) {
|
||||
pr_warn("Error while enabling fast commits, turning off.");
|
||||
ext4_clear_feature_fast_commit(sb);
|
||||
}
|
||||
|
|
|
@ -275,7 +275,7 @@ int ext4fs_dirhash(const struct inode *dir, const char *name, int len,
|
|||
struct dx_hash_info *hinfo)
|
||||
{
|
||||
#ifdef CONFIG_UNICODE
|
||||
const struct unicode_map *um = EXT4_SB(dir->i_sb)->s_encoding;
|
||||
const struct unicode_map *um = dir->i_sb->s_encoding;
|
||||
int r, dlen;
|
||||
unsigned char *buff;
|
||||
struct qstr qstr = {.name = name, .len = len };
|
||||
|
|
|
@ -1918,7 +1918,7 @@ static int __ext4_journalled_writepage(struct page *page,
|
|||
}
|
||||
if (ret == 0)
|
||||
ret = err;
|
||||
err = ext4_jbd2_inode_add_write(handle, inode, 0, len);
|
||||
err = ext4_jbd2_inode_add_write(handle, inode, page_offset(page), len);
|
||||
if (ret == 0)
|
||||
ret = err;
|
||||
EXT4_I(inode)->i_datasync_tid = handle->h_transaction->t_tid;
|
||||
|
@ -3307,10 +3307,12 @@ static bool ext4_inode_datasync_dirty(struct inode *inode)
|
|||
|
||||
if (journal) {
|
||||
if (jbd2_transaction_committed(journal,
|
||||
EXT4_I(inode)->i_datasync_tid))
|
||||
return true;
|
||||
return atomic_read(&EXT4_SB(inode->i_sb)->s_fc_subtid) >=
|
||||
EXT4_I(inode)->i_fc_committed_subtid;
|
||||
EXT4_I(inode)->i_datasync_tid))
|
||||
return false;
|
||||
if (test_opt2(inode->i_sb, JOURNAL_FAST_COMMIT))
|
||||
return atomic_read(&EXT4_SB(inode->i_sb)->s_fc_subtid) <
|
||||
EXT4_I(inode)->i_fc_committed_subtid;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Any metadata buffers to write? */
|
||||
|
@ -6157,7 +6159,8 @@ retry_alloc:
|
|||
if (ext4_walk_page_buffers(handle, page_buffers(page),
|
||||
0, len, NULL, write_end_fn))
|
||||
goto out_error;
|
||||
if (ext4_jbd2_inode_add_write(handle, inode, 0, len))
|
||||
if (ext4_jbd2_inode_add_write(handle, inode,
|
||||
page_offset(page), len))
|
||||
goto out_error;
|
||||
ext4_set_inode_state(inode, EXT4_STATE_JDATA);
|
||||
} else {
|
||||
|
|
|
@ -1285,8 +1285,8 @@ static void dx_insert_block(struct dx_frame *frame, u32 hash, ext4_lblk_t block)
|
|||
int ext4_ci_compare(const struct inode *parent, const struct qstr *name,
|
||||
const struct qstr *entry, bool quick)
|
||||
{
|
||||
const struct ext4_sb_info *sbi = EXT4_SB(parent->i_sb);
|
||||
const struct unicode_map *um = sbi->s_encoding;
|
||||
const struct super_block *sb = parent->i_sb;
|
||||
const struct unicode_map *um = sb->s_encoding;
|
||||
int ret;
|
||||
|
||||
if (quick)
|
||||
|
@ -1298,7 +1298,7 @@ int ext4_ci_compare(const struct inode *parent, const struct qstr *name,
|
|||
/* Handle invalid character sequence as either an error
|
||||
* or as an opaque byte sequence.
|
||||
*/
|
||||
if (ext4_has_strict_mode(sbi))
|
||||
if (sb_has_strict_encoding(sb))
|
||||
return -EINVAL;
|
||||
|
||||
if (name->len != entry->len)
|
||||
|
@ -1315,7 +1315,7 @@ void ext4_fname_setup_ci_filename(struct inode *dir, const struct qstr *iname,
|
|||
{
|
||||
int len;
|
||||
|
||||
if (!IS_CASEFOLDED(dir) || !EXT4_SB(dir->i_sb)->s_encoding) {
|
||||
if (!IS_CASEFOLDED(dir) || !dir->i_sb->s_encoding) {
|
||||
cf_name->name = NULL;
|
||||
return;
|
||||
}
|
||||
|
@ -1324,7 +1324,7 @@ void ext4_fname_setup_ci_filename(struct inode *dir, const struct qstr *iname,
|
|||
if (!cf_name->name)
|
||||
return;
|
||||
|
||||
len = utf8_casefold(EXT4_SB(dir->i_sb)->s_encoding,
|
||||
len = utf8_casefold(dir->i_sb->s_encoding,
|
||||
iname, cf_name->name,
|
||||
EXT4_NAME_LEN);
|
||||
if (len <= 0) {
|
||||
|
@ -1361,7 +1361,7 @@ static inline bool ext4_match(const struct inode *parent,
|
|||
#endif
|
||||
|
||||
#ifdef CONFIG_UNICODE
|
||||
if (EXT4_SB(parent->i_sb)->s_encoding && IS_CASEFOLDED(parent)) {
|
||||
if (parent->i_sb->s_encoding && IS_CASEFOLDED(parent)) {
|
||||
if (fname->cf_name.name) {
|
||||
struct qstr cf = {.name = fname->cf_name.name,
|
||||
.len = fname->cf_name.len};
|
||||
|
@ -2180,9 +2180,6 @@ static int ext4_add_entry(handle_t *handle, struct dentry *dentry,
|
|||
struct buffer_head *bh = NULL;
|
||||
struct ext4_dir_entry_2 *de;
|
||||
struct super_block *sb;
|
||||
#ifdef CONFIG_UNICODE
|
||||
struct ext4_sb_info *sbi;
|
||||
#endif
|
||||
struct ext4_filename fname;
|
||||
int retval;
|
||||
int dx_fallback=0;
|
||||
|
@ -2199,9 +2196,8 @@ static int ext4_add_entry(handle_t *handle, struct dentry *dentry,
|
|||
return -EINVAL;
|
||||
|
||||
#ifdef CONFIG_UNICODE
|
||||
sbi = EXT4_SB(sb);
|
||||
if (ext4_has_strict_mode(sbi) && IS_CASEFOLDED(dir) &&
|
||||
sbi->s_encoding && utf8_validate(sbi->s_encoding, &dentry->d_name))
|
||||
if (sb_has_strict_encoding(sb) && IS_CASEFOLDED(dir) &&
|
||||
sb->s_encoding && utf8_validate(sb->s_encoding, &dentry->d_name))
|
||||
return -EINVAL;
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1288,7 +1288,7 @@ static void ext4_put_super(struct super_block *sb)
|
|||
fs_put_dax(sbi->s_daxdev);
|
||||
fscrypt_free_dummy_policy(&sbi->s_dummy_enc_policy);
|
||||
#ifdef CONFIG_UNICODE
|
||||
utf8_unload(sbi->s_encoding);
|
||||
utf8_unload(sb->s_encoding);
|
||||
#endif
|
||||
kfree(sbi);
|
||||
}
|
||||
|
@ -4303,7 +4303,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
|
|||
goto failed_mount;
|
||||
|
||||
#ifdef CONFIG_UNICODE
|
||||
if (ext4_has_feature_casefold(sb) && !sbi->s_encoding) {
|
||||
if (ext4_has_feature_casefold(sb) && !sb->s_encoding) {
|
||||
const struct ext4_sb_encodings *encoding_info;
|
||||
struct unicode_map *encoding;
|
||||
__u16 encoding_flags;
|
||||
|
@ -4334,8 +4334,8 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
|
|||
"%s-%s with flags 0x%hx", encoding_info->name,
|
||||
encoding_info->version?:"\b", encoding_flags);
|
||||
|
||||
sbi->s_encoding = encoding;
|
||||
sbi->s_encoding_flags = encoding_flags;
|
||||
sb->s_encoding = encoding;
|
||||
sb->s_encoding_flags = encoding_flags;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -4777,8 +4777,8 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
|
|||
INIT_LIST_HEAD(&sbi->s_fc_dentry_q[FC_Q_MAIN]);
|
||||
INIT_LIST_HEAD(&sbi->s_fc_dentry_q[FC_Q_STAGING]);
|
||||
sbi->s_fc_bytes = 0;
|
||||
sbi->s_mount_state &= ~EXT4_FC_INELIGIBLE;
|
||||
sbi->s_mount_state &= ~EXT4_FC_COMMITTING;
|
||||
sbi->s_mount_flags &= ~EXT4_MF_FC_INELIGIBLE;
|
||||
sbi->s_mount_flags &= ~EXT4_MF_FC_COMMITTING;
|
||||
spin_lock_init(&sbi->s_fc_lock);
|
||||
memset(&sbi->s_fc_stats, 0, sizeof(sbi->s_fc_stats));
|
||||
sbi->s_fc_replay_state.fc_regions = NULL;
|
||||
|
@ -4975,7 +4975,7 @@ no_journal:
|
|||
}
|
||||
|
||||
#ifdef CONFIG_UNICODE
|
||||
if (sbi->s_encoding)
|
||||
if (sb->s_encoding)
|
||||
sb->s_d_op = &ext4_dentry_ops;
|
||||
#endif
|
||||
|
||||
|
@ -5184,7 +5184,7 @@ failed_mount:
|
|||
crypto_free_shash(sbi->s_chksum_driver);
|
||||
|
||||
#ifdef CONFIG_UNICODE
|
||||
utf8_unload(sbi->s_encoding);
|
||||
utf8_unload(sb->s_encoding);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_QUOTA
|
||||
|
|
|
@ -315,6 +315,7 @@ EXT4_ATTR_FEATURE(casefold);
|
|||
EXT4_ATTR_FEATURE(verity);
|
||||
#endif
|
||||
EXT4_ATTR_FEATURE(metadata_csum_seed);
|
||||
EXT4_ATTR_FEATURE(fast_commit);
|
||||
|
||||
static struct attribute *ext4_feat_attrs[] = {
|
||||
ATTR_LIST(lazy_itable_init),
|
||||
|
@ -331,6 +332,7 @@ static struct attribute *ext4_feat_attrs[] = {
|
|||
ATTR_LIST(verity),
|
||||
#endif
|
||||
ATTR_LIST(metadata_csum_seed),
|
||||
ATTR_LIST(fast_commit),
|
||||
NULL,
|
||||
};
|
||||
ATTRIBUTE_GROUPS(ext4_feat);
|
||||
|
|
|
@ -263,7 +263,10 @@ typedef struct journal_superblock_s
|
|||
/* 0x0050 */
|
||||
__u8 s_checksum_type; /* checksum type */
|
||||
__u8 s_padding2[3];
|
||||
__u32 s_padding[42];
|
||||
/* 0x0054 */
|
||||
__be32 s_num_fc_blks; /* Number of fast commit blocks */
|
||||
/* 0x0058 */
|
||||
__u32 s_padding[41];
|
||||
__be32 s_checksum; /* crc32c(superblock) */
|
||||
|
||||
/* 0x0100 */
|
||||
|
@ -1253,7 +1256,7 @@ struct journal_s
|
|||
*/
|
||||
void (*j_fc_cleanup_callback)(struct journal_s *journal, int);
|
||||
|
||||
/*
|
||||
/**
|
||||
* @j_fc_replay_callback:
|
||||
*
|
||||
* File-system specific function that performs replay of a fast
|
||||
|
|
Загрузка…
Ссылка в новой задаче