Re: [PATCH 02/14] fs/buffer: add some new buffer read helpers
flat view
From: Zhang Yi <yi.zhang@huawei.com>
Date: 2022-08-31 13:11:48
Also in:
linux-fsdevel, lkml, ntfs3
Thanks for the review and suggestions. On 2022/8/31 19:30, Jan Kara wrote:
On Wed 31-08-22 15:20:59, Zhang Yi wrote:quoted
Current ll_rw_block() helper is fragile because it assumes that locked buffer means it's under IO which is submitted by some other who hold the lock, it skip buffer if it failed to get the lock, so it's only safe on the readahead path. Unfortunately, now that most filesystems still use this helper mistakenly on the sync metadata read path. There is no guarantee that the one who hold the buffer lock always submit IO (e.g. buffer_migrate_folio_norefs() after commit 88dbcbb3a484 ("blkdev: avoid migration stalls for blkdev pages"), it could lead to false positive -EIO when submitting reading IO. This patch add some friendly buffer read helpers to prepare replace ll_rw_block() and similar calls. We can only call bh_readahead_[] helpers for the readahead paths. Signed-off-by: Zhang Yi <yi.zhang@huawei.com>This looks mostly good. Just a few small nits below.
[..]
quoted
diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h index c3863c417b00..8a01c07c0418 100644 --- a/include/linux/buffer_head.h +++ b/include/linux/buffer_head.h
[..]
quoted
+static inline void bh_read_nowait(struct buffer_head *bh, blk_opf_t op_flags) +{ + lock_buffer(bh); + __bh_read(bh, op_flags, false); +} + +static inline int bh_read(struct buffer_head *bh, blk_opf_t op_flags) +{ + lock_buffer(bh); + return __bh_read(bh, op_flags, true); +}I would use bh_uptodate_or_lock() helper in the above two functions to avoid locking the buffer in case it is already uptodate.
Yes, it's a good point, it seems we could also remove "if (!buffer_uptodate(bh))" before above two helpers in the latter patches, like in fs/jbd2/journal.c.
@@ -1893,15 +1893,14 @@ static int journal_get_superblock(journal_t *journal) { struct buffer_head *bh; journal_superblock_t *sb; - int err = -EIO; + int err; bh = journal->j_sb_buffer; J_ASSERT(bh != NULL); - if (!buffer_uptodate(bh)) { - ll_rw_block(REQ_OP_READ, 1, &bh); - wait_on_buffer(bh); - if (!buffer_uptodate(bh)) { + err = bh_read(bh, 0); + if (err) { - printk(KERN_ERR - "JBD2: IO error reading journal superblock\n"); - goto out; + printk(KERN_ERR + "JBD2: IO error reading journal superblock\n"); + goto out;
... Thanks, Yi.