On Mon 17-02-25 14:59:55, Zhang Yi wrote: > From: Zhang Yi <yi.zhang@xxxxxxxxxx> > > In __jbd2_journal_erase(), the block_stop parameter includes the last > block of a contiguous region; however, the calculation of byte_stop is > incorrect, as it does not account for the bytes in that last block. > Consequently, the page cache is not cleared properly, which occasionally > causes the ext4/050 test to fail. > > Since block_stop operates on inclusion semantics, it involves repeated > increments and decrements by 1, significantly increasing the complexity > of the calculations. Optimize the calculation and fix the incorrect > byte_stop by make both block_stop and byte_stop to use exclusion > semantics. > > This fixes a failure in fstests ext4/050. > > Fixes: 01d5d96542fd ("ext4: add discard/zeroout flags to journal flush") > Signed-off-by: Zhang Yi <yi.zhang@xxxxxxxxxx> Looks good! Feel free to add: Reviewed-by: Jan Kara <jack@xxxxxxx> Honza > --- > fs/jbd2/journal.c | 15 ++++++--------- > 1 file changed, 6 insertions(+), 9 deletions(-) > > diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c > index d8084b31b361..49a9e99cbc03 100644 > --- a/fs/jbd2/journal.c > +++ b/fs/jbd2/journal.c > @@ -1965,17 +1965,15 @@ static int __jbd2_journal_erase(journal_t *journal, unsigned int flags) > return err; > } > > - if (block_start == ~0ULL) { > - block_start = phys_block; > - block_stop = block_start - 1; > - } > + if (block_start == ~0ULL) > + block_stop = block_start = phys_block; > > /* > * last block not contiguous with current block, > * process last contiguous region and return to this block on > * next loop > */ > - if (phys_block != block_stop + 1) { > + if (phys_block != block_stop) { > block--; > } else { > block_stop++; > @@ -1994,11 +1992,10 @@ static int __jbd2_journal_erase(journal_t *journal, unsigned int flags) > */ > byte_start = block_start * journal->j_blocksize; > byte_stop = block_stop * journal->j_blocksize; > - byte_count = (block_stop - block_start + 1) * > - journal->j_blocksize; > + byte_count = (block_stop - block_start) * journal->j_blocksize; > > truncate_inode_pages_range(journal->j_dev->bd_mapping, > - byte_start, byte_stop); > + byte_start, byte_stop - 1); > > if (flags & JBD2_JOURNAL_FLUSH_DISCARD) { > err = blkdev_issue_discard(journal->j_dev, > @@ -2013,7 +2010,7 @@ static int __jbd2_journal_erase(journal_t *journal, unsigned int flags) > } > > if (unlikely(err != 0)) { > - pr_err("JBD2: (error %d) unable to wipe journal at physical blocks %llu - %llu", > + pr_err("JBD2: (error %d) unable to wipe journal at physical blocks [%llu, %llu)", > err, block_start, block_stop); > return err; > } > -- > 2.46.1 > -- Jan Kara <jack@xxxxxxxx> SUSE Labs, CR