Skip to content

Commit cf52eed

Browse files
committed
Merge tag 'ext4_for_linus-6.7-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4
Pull ext4 fixes from Ted Ts'o: "Fix various bugs / regressions for ext4, including a soft lockup, a WARN_ON, and a BUG" * tag 'ext4_for_linus-6.7-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4: jbd2: fix soft lockup in journal_finish_inode_data_buffers() ext4: fix warning in ext4_dio_write_end_io() jbd2: increase the journal IO's priority jbd2: correct the printing of write_flags in jbd2_write_superblock() ext4: prevent the normalized size from exceeding EXT_MAX_BLOCKS
2 parents eaadbba + 6c02757 commit cf52eed

5 files changed

Lines changed: 35 additions & 20 deletions

File tree

fs/ext4/file.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -349,9 +349,10 @@ static void ext4_inode_extension_cleanup(struct inode *inode, ssize_t count)
349349
return;
350350
}
351351
/*
352-
* If i_disksize got extended due to writeback of delalloc blocks while
353-
* the DIO was running we could fail to cleanup the orphan list in
354-
* ext4_handle_inode_extension(). Do it now.
352+
* If i_disksize got extended either due to writeback of delalloc
353+
* blocks or extending truncate while the DIO was running we could fail
354+
* to cleanup the orphan list in ext4_handle_inode_extension(). Do it
355+
* now.
355356
*/
356357
if (!list_empty(&EXT4_I(inode)->i_orphan) && inode->i_nlink) {
357358
handle_t *handle = ext4_journal_start(inode, EXT4_HT_INODE, 2);
@@ -386,10 +387,11 @@ static int ext4_dio_write_end_io(struct kiocb *iocb, ssize_t size,
386387
* blocks. But the code in ext4_iomap_alloc() is careful to use
387388
* zeroed/unwritten extents if this is possible; thus we won't leave
388389
* uninitialized blocks in a file even if we didn't succeed in writing
389-
* as much as we intended.
390+
* as much as we intended. Also we can race with truncate or write
391+
* expanding the file so we have to be a bit careful here.
390392
*/
391-
WARN_ON_ONCE(i_size_read(inode) < READ_ONCE(EXT4_I(inode)->i_disksize));
392-
if (pos + size <= READ_ONCE(EXT4_I(inode)->i_disksize))
393+
if (pos + size <= READ_ONCE(EXT4_I(inode)->i_disksize) &&
394+
pos + size <= i_size_read(inode))
393395
return size;
394396
return ext4_handle_inode_extension(inode, pos, size);
395397
}

fs/ext4/mballoc.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4478,6 +4478,10 @@ ext4_mb_normalize_request(struct ext4_allocation_context *ac,
44784478
start = max(start, rounddown(ac->ac_o_ex.fe_logical,
44794479
(ext4_lblk_t)EXT4_BLOCKS_PER_GROUP(ac->ac_sb)));
44804480

4481+
/* avoid unnecessary preallocation that may trigger assertions */
4482+
if (start + size > EXT_MAX_BLOCKS)
4483+
size = EXT_MAX_BLOCKS - start;
4484+
44814485
/* don't cover already allocated blocks in selected range */
44824486
if (ar->pleft && start <= ar->lleft) {
44834487
size -= ar->lleft + 1 - start;

fs/jbd2/commit.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ static int journal_submit_commit_record(journal_t *journal,
119119
struct commit_header *tmp;
120120
struct buffer_head *bh;
121121
struct timespec64 now;
122-
blk_opf_t write_flags = REQ_OP_WRITE | REQ_SYNC;
122+
blk_opf_t write_flags = REQ_OP_WRITE | JBD2_JOURNAL_REQ_FLAGS;
123123

124124
*cbh = NULL;
125125

@@ -270,6 +270,7 @@ static int journal_finish_inode_data_buffers(journal_t *journal,
270270
if (!ret)
271271
ret = err;
272272
}
273+
cond_resched();
273274
spin_lock(&journal->j_list_lock);
274275
jinode->i_flags &= ~JI_COMMIT_RUNNING;
275276
smp_mb();
@@ -395,8 +396,7 @@ void jbd2_journal_commit_transaction(journal_t *journal)
395396
*/
396397
jbd2_journal_update_sb_log_tail(journal,
397398
journal->j_tail_sequence,
398-
journal->j_tail,
399-
REQ_SYNC);
399+
journal->j_tail, 0);
400400
mutex_unlock(&journal->j_checkpoint_mutex);
401401
} else {
402402
jbd2_debug(3, "superblock not updated\n");
@@ -715,6 +715,7 @@ void jbd2_journal_commit_transaction(journal_t *journal)
715715

716716
for (i = 0; i < bufs; i++) {
717717
struct buffer_head *bh = wbuf[i];
718+
718719
/*
719720
* Compute checksum.
720721
*/
@@ -727,7 +728,8 @@ void jbd2_journal_commit_transaction(journal_t *journal)
727728
clear_buffer_dirty(bh);
728729
set_buffer_uptodate(bh);
729730
bh->b_end_io = journal_end_buffer_io_sync;
730-
submit_bh(REQ_OP_WRITE | REQ_SYNC, bh);
731+
submit_bh(REQ_OP_WRITE | JBD2_JOURNAL_REQ_FLAGS,
732+
bh);
731733
}
732734
cond_resched();
733735

fs/jbd2/journal.c

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1100,8 +1100,7 @@ int __jbd2_update_log_tail(journal_t *journal, tid_t tid, unsigned long block)
11001100
* space and if we lose sb update during power failure we'd replay
11011101
* old transaction with possibly newly overwritten data.
11021102
*/
1103-
ret = jbd2_journal_update_sb_log_tail(journal, tid, block,
1104-
REQ_SYNC | REQ_FUA);
1103+
ret = jbd2_journal_update_sb_log_tail(journal, tid, block, REQ_FUA);
11051104
if (ret)
11061105
goto out;
11071106

@@ -1775,8 +1774,7 @@ static int journal_reset(journal_t *journal)
17751774
*/
17761775
jbd2_journal_update_sb_log_tail(journal,
17771776
journal->j_tail_sequence,
1778-
journal->j_tail,
1779-
REQ_SYNC | REQ_FUA);
1777+
journal->j_tail, REQ_FUA);
17801778
mutex_unlock(&journal->j_checkpoint_mutex);
17811779
}
17821780
return jbd2_journal_start_thread(journal);
@@ -1798,9 +1796,16 @@ static int jbd2_write_superblock(journal_t *journal, blk_opf_t write_flags)
17981796
return -EIO;
17991797
}
18001798

1801-
trace_jbd2_write_superblock(journal, write_flags);
1799+
/*
1800+
* Always set high priority flags to exempt from block layer's
1801+
* QOS policies, e.g. writeback throttle.
1802+
*/
1803+
write_flags |= JBD2_JOURNAL_REQ_FLAGS;
18021804
if (!(journal->j_flags & JBD2_BARRIER))
18031805
write_flags &= ~(REQ_FUA | REQ_PREFLUSH);
1806+
1807+
trace_jbd2_write_superblock(journal, write_flags);
1808+
18041809
if (buffer_write_io_error(bh)) {
18051810
/*
18061811
* Oh, dear. A previous attempt to write the journal
@@ -2050,7 +2055,7 @@ void jbd2_journal_update_sb_errno(journal_t *journal)
20502055
jbd2_debug(1, "JBD2: updating superblock error (errno %d)\n", errcode);
20512056
sb->s_errno = cpu_to_be32(errcode);
20522057

2053-
jbd2_write_superblock(journal, REQ_SYNC | REQ_FUA);
2058+
jbd2_write_superblock(journal, REQ_FUA);
20542059
}
20552060
EXPORT_SYMBOL(jbd2_journal_update_sb_errno);
20562061

@@ -2171,8 +2176,7 @@ int jbd2_journal_destroy(journal_t *journal)
21712176
++journal->j_transaction_sequence;
21722177
write_unlock(&journal->j_state_lock);
21732178

2174-
jbd2_mark_journal_empty(journal,
2175-
REQ_SYNC | REQ_PREFLUSH | REQ_FUA);
2179+
jbd2_mark_journal_empty(journal, REQ_PREFLUSH | REQ_FUA);
21762180
mutex_unlock(&journal->j_checkpoint_mutex);
21772181
} else
21782182
err = -EIO;
@@ -2473,7 +2477,7 @@ int jbd2_journal_flush(journal_t *journal, unsigned int flags)
24732477
* the magic code for a fully-recovered superblock. Any future
24742478
* commits of data to the journal will restore the current
24752479
* s_start value. */
2476-
jbd2_mark_journal_empty(journal, REQ_SYNC | REQ_FUA);
2480+
jbd2_mark_journal_empty(journal, REQ_FUA);
24772481

24782482
if (flags)
24792483
err = __jbd2_journal_erase(journal, flags);
@@ -2519,7 +2523,7 @@ int jbd2_journal_wipe(journal_t *journal, int write)
25192523
if (write) {
25202524
/* Lock to make assertions happy... */
25212525
mutex_lock_io(&journal->j_checkpoint_mutex);
2522-
jbd2_mark_journal_empty(journal, REQ_SYNC | REQ_FUA);
2526+
jbd2_mark_journal_empty(journal, REQ_FUA);
25232527
mutex_unlock(&journal->j_checkpoint_mutex);
25242528
}
25252529

include/linux/jbd2.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1374,6 +1374,9 @@ JBD2_FEATURE_INCOMPAT_FUNCS(csum2, CSUM_V2)
13741374
JBD2_FEATURE_INCOMPAT_FUNCS(csum3, CSUM_V3)
13751375
JBD2_FEATURE_INCOMPAT_FUNCS(fast_commit, FAST_COMMIT)
13761376

1377+
/* Journal high priority write IO operation flags */
1378+
#define JBD2_JOURNAL_REQ_FLAGS (REQ_META | REQ_SYNC | REQ_IDLE)
1379+
13771380
/*
13781381
* Journal flag definitions
13791382
*/

0 commit comments

Comments
 (0)