Skip to content

Commit d8ad2ce

Browse files
committed
Merge tag 'ext4_for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4
Pull ext4 fixes from Ted Ts'o: "Various bug fixes for ext4 fast commit and inline data handling. Also fix regression introduced as part of moving to the new mount API" * tag 'ext4_for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4: fs/ext4: fix comments mentioning i_mutex ext4: fix incorrect type issue during replay_del_range jbd2: fix kernel-doc descriptions for jbd2_journal_shrink_{scan,count}() ext4: fix potential NULL pointer dereference in ext4_fill_super() jbd2: refactor wait logic for transaction updates into a common function jbd2: cleanup unused functions declarations from jbd2.h ext4: fix error handling in ext4_fc_record_modified_inode() ext4: remove redundant max inline_size check in ext4_da_write_inline_data_begin() ext4: fix error handling in ext4_restore_inline_data() ext4: fast commit may miss file actions ext4: fast commit may not fallback for ineligible commit ext4: modify the logic of ext4_mb_new_blocks_simple ext4: prevent used blocks from being allocated during fast commit replay
2 parents 18118a4 + f340b3d commit d8ad2ce

File tree

19 files changed

+196
-160
lines changed

19 files changed

+196
-160
lines changed

fs/ext4/acl.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ ext4_acl_to_disk(const struct posix_acl *acl, size_t *size)
139139
/*
140140
* Inode operation get_posix_acl().
141141
*
142-
* inode->i_mutex: don't care
142+
* inode->i_rwsem: don't care
143143
*/
144144
struct posix_acl *
145145
ext4_get_acl(struct inode *inode, int type, bool rcu)
@@ -183,7 +183,7 @@ ext4_get_acl(struct inode *inode, int type, bool rcu)
183183
/*
184184
* Set the access or default ACL of an inode.
185185
*
186-
* inode->i_mutex: down unless called from ext4_new_inode
186+
* inode->i_rwsem: down unless called from ext4_new_inode
187187
*/
188188
static int
189189
__ext4_set_acl(handle_t *handle, struct inode *inode, int type,
@@ -271,8 +271,8 @@ ext4_set_acl(struct user_namespace *mnt_userns, struct inode *inode,
271271
/*
272272
* Initialize the ACLs of a new inode. Called from ext4_new_inode.
273273
*
274-
* dir->i_mutex: down
275-
* inode->i_mutex: up (access to inode is still exclusive)
274+
* dir->i_rwsem: down
275+
* inode->i_rwsem: up (access to inode is still exclusive)
276276
*/
277277
int
278278
ext4_init_acl(handle_t *handle, struct inode *inode, struct inode *dir)

fs/ext4/ext4.h

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1028,7 +1028,7 @@ struct ext4_inode_info {
10281028

10291029
/*
10301030
* Extended attributes can be read independently of the main file
1031-
* data. Taking i_mutex even when reading would cause contention
1031+
* data. Taking i_rwsem even when reading would cause contention
10321032
* between readers of EAs and writers of regular file data, so
10331033
* instead we synchronize on xattr_sem when reading or changing
10341034
* EAs.
@@ -1750,6 +1750,7 @@ struct ext4_sb_info {
17501750
spinlock_t s_fc_lock;
17511751
struct buffer_head *s_fc_bh;
17521752
struct ext4_fc_stats s_fc_stats;
1753+
tid_t s_fc_ineligible_tid;
17531754
#ifdef CONFIG_EXT4_DEBUG
17541755
int s_fc_debug_max_replay;
17551756
#endif
@@ -1795,10 +1796,7 @@ static inline int ext4_valid_inum(struct super_block *sb, unsigned long ino)
17951796
enum {
17961797
EXT4_MF_MNTDIR_SAMPLED,
17971798
EXT4_MF_FS_ABORTED, /* Fatal error detected */
1798-
EXT4_MF_FC_INELIGIBLE, /* Fast commit ineligible */
1799-
EXT4_MF_FC_COMMITTING /* File system underoing a fast
1800-
* commit.
1801-
*/
1799+
EXT4_MF_FC_INELIGIBLE /* Fast commit ineligible */
18021800
};
18031801

18041802
static inline void ext4_set_mount_flag(struct super_block *sb, int bit)
@@ -2926,7 +2924,7 @@ void __ext4_fc_track_create(handle_t *handle, struct inode *inode,
29262924
struct dentry *dentry);
29272925
void ext4_fc_track_create(handle_t *handle, struct dentry *dentry);
29282926
void ext4_fc_track_inode(handle_t *handle, struct inode *inode);
2929-
void ext4_fc_mark_ineligible(struct super_block *sb, int reason);
2927+
void ext4_fc_mark_ineligible(struct super_block *sb, int reason, handle_t *handle);
29302928
void ext4_fc_start_update(struct inode *inode);
29312929
void ext4_fc_stop_update(struct inode *inode);
29322930
void ext4_fc_del(struct inode *inode);
@@ -2935,6 +2933,9 @@ void ext4_fc_replay_cleanup(struct super_block *sb);
29352933
int ext4_fc_commit(journal_t *journal, tid_t commit_tid);
29362934
int __init ext4_fc_init_dentry_cache(void);
29372935
void ext4_fc_destroy_dentry_cache(void);
2936+
int ext4_fc_record_regions(struct super_block *sb, int ino,
2937+
ext4_lblk_t lblk, ext4_fsblk_t pblk,
2938+
int len, int replay);
29382939

29392940
/* mballoc.c */
29402941
extern const struct seq_operations ext4_mb_seq_groups_ops;
@@ -3407,7 +3408,7 @@ do { \
34073408
#define EXT4_FREECLUSTERS_WATERMARK 0
34083409
#endif
34093410

3410-
/* Update i_disksize. Requires i_mutex to avoid races with truncate */
3411+
/* Update i_disksize. Requires i_rwsem to avoid races with truncate */
34113412
static inline void ext4_update_i_disksize(struct inode *inode, loff_t newsize)
34123413
{
34133414
WARN_ON_ONCE(S_ISREG(inode->i_mode) &&
@@ -3418,7 +3419,7 @@ static inline void ext4_update_i_disksize(struct inode *inode, loff_t newsize)
34183419
up_write(&EXT4_I(inode)->i_data_sem);
34193420
}
34203421

3421-
/* Update i_size, i_disksize. Requires i_mutex to avoid races with truncate */
3422+
/* Update i_size, i_disksize. Requires i_rwsem to avoid races with truncate */
34223423
static inline int ext4_update_inode_size(struct inode *inode, loff_t newsize)
34233424
{
34243425
int changed = 0;

fs/ext4/ext4_jbd2.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -491,7 +491,7 @@ static inline int ext4_free_data_revoke_credits(struct inode *inode, int blocks)
491491
/*
492492
* This function controls whether or not we should try to go down the
493493
* dioread_nolock code paths, which makes it safe to avoid taking
494-
* i_mutex for direct I/O reads. This only works for extent-based
494+
* i_rwsem for direct I/O reads. This only works for extent-based
495495
* files, and it doesn't work if data journaling is enabled, since the
496496
* dioread_nolock code uses b_private to pass information back to the
497497
* I/O completion handler, and this conflicts with the jbd's use of

fs/ext4/extents.c

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ static int ext4_ext_trunc_restart_fn(struct inode *inode, int *dropped)
9797
* Drop i_data_sem to avoid deadlock with ext4_map_blocks. At this
9898
* moment, get_block can be called only for blocks inside i_size since
9999
* page cache has been already dropped and writes are blocked by
100-
* i_mutex. So we can safely drop the i_data_sem here.
100+
* i_rwsem. So we can safely drop the i_data_sem here.
101101
*/
102102
BUG_ON(EXT4_JOURNAL(inode) == NULL);
103103
ext4_discard_preallocations(inode, 0);
@@ -4572,7 +4572,7 @@ static long ext4_zero_range(struct file *file, loff_t offset,
45724572

45734573
flags = EXT4_GET_BLOCKS_CREATE_UNWRIT_EXT;
45744574

4575-
/* Wait all existing dio workers, newcomers will block on i_mutex */
4575+
/* Wait all existing dio workers, newcomers will block on i_rwsem */
45764576
inode_dio_wait(inode);
45774577

45784578
/* Preallocate the range including the unaligned edges */
@@ -4738,7 +4738,7 @@ long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
47384738
goto out;
47394739
}
47404740

4741-
/* Wait all existing dio workers, newcomers will block on i_mutex */
4741+
/* Wait all existing dio workers, newcomers will block on i_rwsem */
47424742
inode_dio_wait(inode);
47434743

47444744
ret = ext4_alloc_file_blocks(file, lblk, max_blocks, new_size, flags);
@@ -5334,7 +5334,7 @@ static int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len)
53345334
ret = PTR_ERR(handle);
53355335
goto out_mmap;
53365336
}
5337-
ext4_fc_mark_ineligible(sb, EXT4_FC_REASON_FALLOC_RANGE);
5337+
ext4_fc_mark_ineligible(sb, EXT4_FC_REASON_FALLOC_RANGE, handle);
53385338

53395339
down_write(&EXT4_I(inode)->i_data_sem);
53405340
ext4_discard_preallocations(inode, 0);
@@ -5474,7 +5474,7 @@ static int ext4_insert_range(struct inode *inode, loff_t offset, loff_t len)
54745474
ret = PTR_ERR(handle);
54755475
goto out_mmap;
54765476
}
5477-
ext4_fc_mark_ineligible(sb, EXT4_FC_REASON_FALLOC_RANGE);
5477+
ext4_fc_mark_ineligible(sb, EXT4_FC_REASON_FALLOC_RANGE, handle);
54785478

54795479
/* Expand file to avoid data loss if there is error while shifting */
54805480
inode->i_size += len;
@@ -5571,7 +5571,7 @@ static int ext4_insert_range(struct inode *inode, loff_t offset, loff_t len)
55715571
* stuff such as page-cache locking consistency, bh mapping consistency or
55725572
* extent's data copying must be performed by caller.
55735573
* Locking:
5574-
* i_mutex is held for both inodes
5574+
* i_rwsem is held for both inodes
55755575
* i_data_sem is locked for write for both inodes
55765576
* Assumptions:
55775577
* All pages from requested range are locked for both inodes
@@ -6091,11 +6091,15 @@ int ext4_ext_clear_bb(struct inode *inode)
60916091

60926092
ext4_mb_mark_bb(inode->i_sb,
60936093
path[j].p_block, 1, 0);
6094+
ext4_fc_record_regions(inode->i_sb, inode->i_ino,
6095+
0, path[j].p_block, 1, 1);
60946096
}
60956097
ext4_ext_drop_refs(path);
60966098
kfree(path);
60976099
}
60986100
ext4_mb_mark_bb(inode->i_sb, map.m_pblk, map.m_len, 0);
6101+
ext4_fc_record_regions(inode->i_sb, inode->i_ino,
6102+
map.m_lblk, map.m_pblk, map.m_len, 1);
60996103
}
61006104
cur = cur + map.m_len;
61016105
}

0 commit comments

Comments
 (0)