gfs2: Convert gfs2_end_log_write_bh() to work on a folio

gfs2_end_log_write() has to handle bios which consist of both pages
which belong to folios and pages which were allocated from a mempool and
do not belong to a folio.  It would be cleaner to have separate endio
handlers which handle each type, but it's not clear to me whether that's
even possible.

This patch is slightly forward-looking in that page_folio() cannot
currently return NULL, but it will return NULL in the future for pages
which do not belong to a folio.

This was the last user of page_has_buffers(), so remove it.

Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
This commit is contained in:
Matthew Wilcox (Oracle) 2025-02-10 13:34:45 +00:00 committed by Andreas Gruenbacher
parent 4082976009
commit 536da2a440
2 changed files with 14 additions and 15 deletions

View File

@ -157,7 +157,9 @@ u64 gfs2_log_bmap(struct gfs2_jdesc *jd, unsigned int lblock)
/**
* gfs2_end_log_write_bh - end log write of pagecache data with buffers
* @sdp: The superblock
* @bvec: The bio_vec
* @folio: The folio
* @offset: The first byte within the folio that completed
* @size: The number of bytes that completed
* @error: The i/o status
*
* This finds the relevant buffers and unlocks them and sets the
@ -166,17 +168,13 @@ u64 gfs2_log_bmap(struct gfs2_jdesc *jd, unsigned int lblock)
* that is pinned in the pagecache.
*/
static void gfs2_end_log_write_bh(struct gfs2_sbd *sdp,
struct bio_vec *bvec,
blk_status_t error)
static void gfs2_end_log_write_bh(struct gfs2_sbd *sdp, struct folio *folio,
size_t offset, size_t size, blk_status_t error)
{
struct buffer_head *bh, *next;
struct page *page = bvec->bv_page;
unsigned size;
bh = page_buffers(page);
size = bvec->bv_len;
while (bh_offset(bh) < bvec->bv_offset)
bh = folio_buffers(folio);
while (bh_offset(bh) < offset)
bh = bh->b_this_page;
do {
if (error)
@ -186,7 +184,7 @@ static void gfs2_end_log_write_bh(struct gfs2_sbd *sdp,
size -= bh->b_size;
brelse(bh);
bh = next;
} while(bh && size);
} while (bh && size);
}
/**
@ -203,7 +201,6 @@ static void gfs2_end_log_write(struct bio *bio)
{
struct gfs2_sbd *sdp = bio->bi_private;
struct bio_vec *bvec;
struct page *page;
struct bvec_iter_all iter_all;
if (bio->bi_status) {
@ -217,9 +214,12 @@ static void gfs2_end_log_write(struct bio *bio)
}
bio_for_each_segment_all(bvec, bio, iter_all) {
page = bvec->bv_page;
if (page_has_buffers(page))
gfs2_end_log_write_bh(sdp, bvec, bio->bi_status);
struct page *page = bvec->bv_page;
struct folio *folio = page_folio(page);
if (folio && folio_buffers(folio))
gfs2_end_log_write_bh(sdp, folio, bvec->bv_offset,
bvec->bv_len, bio->bi_status);
else
mempool_free(page, gfs2_page_pool);
}

View File

@ -182,7 +182,6 @@ static inline unsigned long bh_offset(const struct buffer_head *bh)
BUG_ON(!PagePrivate(page)); \
((struct buffer_head *)page_private(page)); \
})
#define page_has_buffers(page) PagePrivate(page)
#define folio_buffers(folio) folio_get_private(folio)
void buffer_check_dirty_writeback(struct folio *folio,