Skip to content

Commit 6f9972b

Browse files
committed
Merge tag 'ext4_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4
Pull ext4 updates from Ted Ts'o: "Miscellaneous ext4 cleanups and bug fixes. Pretty boring this cycle..." * tag 'ext4_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4: ext4: add .kunitconfig fragment to enable ext4-specific tests ext: EXT4_KUNIT_TESTS should depend on EXT4_FS instead of selecting it ext4: reset retry counter when ext4_alloc_file_blocks() makes progress ext4: fix potential htree index checksum corruption ext4: factor out htree rep invariant check ext4: Change list_for_each* to list_for_each_entry* ext4: don't try to processed freed blocks until mballoc is initialized ext4: use DEFINE_MUTEX() for mutex lock
2 parents 5b47b10 + 0a76945 commit 6f9972b

File tree

6 files changed

+59
-49
lines changed

6 files changed

+59
-49
lines changed

fs/ext4/.kunitconfig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
CONFIG_KUNIT=y
2+
CONFIG_EXT4_FS=y
3+
CONFIG_EXT4_KUNIT_TESTS=y

fs/ext4/Kconfig

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,7 @@ config EXT4_DEBUG
103103

104104
config EXT4_KUNIT_TESTS
105105
tristate "KUnit tests for ext4" if !KUNIT_ALL_TESTS
106-
select EXT4_FS
107-
depends on KUNIT
106+
depends on EXT4_FS && KUNIT
108107
default KUNIT_ALL_TESTS
109108
help
110109
This builds the ext4 KUnit tests.

fs/ext4/extents.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4382,8 +4382,7 @@ static int ext4_alloc_file_blocks(struct file *file, ext4_lblk_t offset,
43824382
{
43834383
struct inode *inode = file_inode(file);
43844384
handle_t *handle;
4385-
int ret = 0;
4386-
int ret2 = 0, ret3 = 0;
4385+
int ret, ret2 = 0, ret3 = 0;
43874386
int retries = 0;
43884387
int depth = 0;
43894388
struct ext4_map_blocks map;
@@ -4408,7 +4407,7 @@ static int ext4_alloc_file_blocks(struct file *file, ext4_lblk_t offset,
44084407
depth = ext_depth(inode);
44094408

44104409
retry:
4411-
while (ret >= 0 && len) {
4410+
while (len) {
44124411
/*
44134412
* Recalculate credits when extent tree depth changes.
44144413
*/
@@ -4430,9 +4429,13 @@ static int ext4_alloc_file_blocks(struct file *file, ext4_lblk_t offset,
44304429
inode->i_ino, map.m_lblk,
44314430
map.m_len, ret);
44324431
ext4_mark_inode_dirty(handle, inode);
4433-
ret2 = ext4_journal_stop(handle);
4432+
ext4_journal_stop(handle);
44344433
break;
44354434
}
4435+
/*
4436+
* allow a full retry cycle for any remaining allocations
4437+
*/
4438+
retries = 0;
44364439
map.m_lblk += ret;
44374440
map.m_len = len = len - ret;
44384441
epos = (loff_t)map.m_lblk << inode->i_blkbits;
@@ -4450,11 +4453,8 @@ static int ext4_alloc_file_blocks(struct file *file, ext4_lblk_t offset,
44504453
if (unlikely(ret2))
44514454
break;
44524455
}
4453-
if (ret == -ENOSPC &&
4454-
ext4_should_retry_alloc(inode->i_sb, &retries)) {
4455-
ret = 0;
4456+
if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries))
44564457
goto retry;
4457-
}
44584458

44594459
return ret > 0 ? ret2 : ret;
44604460
}

fs/ext4/fast_commit.c

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -915,13 +915,11 @@ static int ext4_fc_submit_inode_data_all(journal_t *journal)
915915
struct super_block *sb = (struct super_block *)(journal->j_private);
916916
struct ext4_sb_info *sbi = EXT4_SB(sb);
917917
struct ext4_inode_info *ei;
918-
struct list_head *pos;
919918
int ret = 0;
920919

921920
spin_lock(&sbi->s_fc_lock);
922921
ext4_set_mount_flag(sb, EXT4_MF_FC_COMMITTING);
923-
list_for_each(pos, &sbi->s_fc_q[FC_Q_MAIN]) {
924-
ei = list_entry(pos, struct ext4_inode_info, i_fc_list);
922+
list_for_each_entry(ei, &sbi->s_fc_q[FC_Q_MAIN], i_fc_list) {
925923
ext4_set_inode_state(&ei->vfs_inode, EXT4_STATE_FC_COMMITTING);
926924
while (atomic_read(&ei->i_fc_updates)) {
927925
DEFINE_WAIT(wait);
@@ -978,17 +976,15 @@ __releases(&sbi->s_fc_lock)
978976
{
979977
struct super_block *sb = (struct super_block *)(journal->j_private);
980978
struct ext4_sb_info *sbi = EXT4_SB(sb);
981-
struct ext4_fc_dentry_update *fc_dentry;
979+
struct ext4_fc_dentry_update *fc_dentry, *fc_dentry_n;
982980
struct inode *inode;
983-
struct list_head *pos, *n, *fcd_pos, *fcd_n;
984-
struct ext4_inode_info *ei;
981+
struct ext4_inode_info *ei, *ei_n;
985982
int ret;
986983

987984
if (list_empty(&sbi->s_fc_dentry_q[FC_Q_MAIN]))
988985
return 0;
989-
list_for_each_safe(fcd_pos, fcd_n, &sbi->s_fc_dentry_q[FC_Q_MAIN]) {
990-
fc_dentry = list_entry(fcd_pos, struct ext4_fc_dentry_update,
991-
fcd_list);
986+
list_for_each_entry_safe(fc_dentry, fc_dentry_n,
987+
&sbi->s_fc_dentry_q[FC_Q_MAIN], fcd_list) {
992988
if (fc_dentry->fcd_op != EXT4_FC_TAG_CREAT) {
993989
spin_unlock(&sbi->s_fc_lock);
994990
if (!ext4_fc_add_dentry_tlv(
@@ -1004,8 +1000,8 @@ __releases(&sbi->s_fc_lock)
10041000
}
10051001

10061002
inode = NULL;
1007-
list_for_each_safe(pos, n, &sbi->s_fc_q[FC_Q_MAIN]) {
1008-
ei = list_entry(pos, struct ext4_inode_info, i_fc_list);
1003+
list_for_each_entry_safe(ei, ei_n, &sbi->s_fc_q[FC_Q_MAIN],
1004+
i_fc_list) {
10091005
if (ei->vfs_inode.i_ino == fc_dentry->fcd_ino) {
10101006
inode = &ei->vfs_inode;
10111007
break;
@@ -1057,7 +1053,6 @@ static int ext4_fc_perform_commit(journal_t *journal)
10571053
struct ext4_sb_info *sbi = EXT4_SB(sb);
10581054
struct ext4_inode_info *iter;
10591055
struct ext4_fc_head head;
1060-
struct list_head *pos;
10611056
struct inode *inode;
10621057
struct blk_plug plug;
10631058
int ret = 0;
@@ -1099,8 +1094,7 @@ static int ext4_fc_perform_commit(journal_t *journal)
10991094
goto out;
11001095
}
11011096

1102-
list_for_each(pos, &sbi->s_fc_q[FC_Q_MAIN]) {
1103-
iter = list_entry(pos, struct ext4_inode_info, i_fc_list);
1097+
list_for_each_entry(iter, &sbi->s_fc_q[FC_Q_MAIN], i_fc_list) {
11041098
inode = &iter->vfs_inode;
11051099
if (!ext4_test_inode_state(inode, EXT4_STATE_FC_COMMITTING))
11061100
continue;
@@ -1226,18 +1220,17 @@ static void ext4_fc_cleanup(journal_t *journal, int full)
12261220
{
12271221
struct super_block *sb = journal->j_private;
12281222
struct ext4_sb_info *sbi = EXT4_SB(sb);
1229-
struct ext4_inode_info *iter;
1223+
struct ext4_inode_info *iter, *iter_n;
12301224
struct ext4_fc_dentry_update *fc_dentry;
1231-
struct list_head *pos, *n;
12321225

12331226
if (full && sbi->s_fc_bh)
12341227
sbi->s_fc_bh = NULL;
12351228

12361229
jbd2_fc_release_bufs(journal);
12371230

12381231
spin_lock(&sbi->s_fc_lock);
1239-
list_for_each_safe(pos, n, &sbi->s_fc_q[FC_Q_MAIN]) {
1240-
iter = list_entry(pos, struct ext4_inode_info, i_fc_list);
1232+
list_for_each_entry_safe(iter, iter_n, &sbi->s_fc_q[FC_Q_MAIN],
1233+
i_fc_list) {
12411234
list_del_init(&iter->i_fc_list);
12421235
ext4_clear_inode_state(&iter->vfs_inode,
12431236
EXT4_STATE_FC_COMMITTING);

fs/ext4/namei.c

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -731,6 +731,29 @@ struct stats dx_show_entries(struct dx_hash_info *hinfo, struct inode *dir,
731731
(space/bcount)*100/blocksize);
732732
return (struct stats) { names, space, bcount};
733733
}
734+
735+
/*
736+
* Linear search cross check
737+
*/
738+
static inline void htree_rep_invariant_check(struct dx_entry *at,
739+
struct dx_entry *target,
740+
u32 hash, unsigned int n)
741+
{
742+
while (n--) {
743+
dxtrace(printk(KERN_CONT ","));
744+
if (dx_get_hash(++at) > hash) {
745+
at--;
746+
break;
747+
}
748+
}
749+
ASSERT(at == target - 1);
750+
}
751+
#else /* DX_DEBUG */
752+
static inline void htree_rep_invariant_check(struct dx_entry *at,
753+
struct dx_entry *target,
754+
u32 hash, unsigned int n)
755+
{
756+
}
734757
#endif /* DX_DEBUG */
735758

736759
/*
@@ -827,20 +850,7 @@ dx_probe(struct ext4_filename *fname, struct inode *dir,
827850
p = m + 1;
828851
}
829852

830-
if (0) { // linear search cross check
831-
unsigned n = count - 1;
832-
at = entries;
833-
while (n--)
834-
{
835-
dxtrace(printk(KERN_CONT ","));
836-
if (dx_get_hash(++at) > hash)
837-
{
838-
at--;
839-
break;
840-
}
841-
}
842-
ASSERT(at == p - 1);
843-
}
853+
htree_rep_invariant_check(entries, p, hash, count - 1);
844854

845855
at = p - 1;
846856
dxtrace(printk(KERN_CONT " %x->%u\n",
@@ -2401,11 +2411,10 @@ static int ext4_dx_add_entry(handle_t *handle, struct ext4_filename *fname,
24012411
(frame - 1)->bh);
24022412
if (err)
24032413
goto journal_error;
2404-
if (restart) {
2405-
err = ext4_handle_dirty_dx_node(handle, dir,
2406-
frame->bh);
2414+
err = ext4_handle_dirty_dx_node(handle, dir,
2415+
frame->bh);
2416+
if (err)
24072417
goto journal_error;
2408-
}
24092418
} else {
24102419
struct dx_root *dxroot;
24112420
memcpy((char *) entries2, (char *) entries,

fs/ext4/super.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@
5959
#include <trace/events/ext4.h>
6060

6161
static struct ext4_lazy_init *ext4_li_info;
62-
static struct mutex ext4_li_mtx;
62+
static DEFINE_MUTEX(ext4_li_mtx);
6363
static struct ratelimit_state ext4_mount_msg_ratelimit;
6464

6565
static int ext4_load_journal(struct super_block *, struct ext4_super_block *,
@@ -4875,7 +4875,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
48754875

48764876
set_task_ioprio(sbi->s_journal->j_task, journal_ioprio);
48774877

4878-
sbi->s_journal->j_commit_callback = ext4_journal_commit_callback;
48794878
sbi->s_journal->j_submit_inode_data_buffers =
48804879
ext4_journal_submit_inode_data_buffers;
48814880
sbi->s_journal->j_finish_inode_data_buffers =
@@ -4987,6 +4986,14 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
49874986
goto failed_mount5;
49884987
}
49894988

4989+
/*
4990+
* We can only set up the journal commit callback once
4991+
* mballoc is initialized
4992+
*/
4993+
if (sbi->s_journal)
4994+
sbi->s_journal->j_commit_callback =
4995+
ext4_journal_commit_callback;
4996+
49904997
block = ext4_count_free_clusters(sb);
49914998
ext4_free_blocks_count_set(sbi->s_es,
49924999
EXT4_C2B(sbi, block));
@@ -6667,7 +6674,6 @@ static int __init ext4_init_fs(void)
66676674

66686675
ratelimit_state_init(&ext4_mount_msg_ratelimit, 30 * HZ, 64);
66696676
ext4_li_info = NULL;
6670-
mutex_init(&ext4_li_mtx);
66716677

66726678
/* Build-time check for flags consistency */
66736679
ext4_check_flag_values();

0 commit comments

Comments
 (0)