Andreas Gruenbacher <agruenba@xxxxxxxxxx> writes: > On Mon, Jun 5, 2023 at 12:55 PM Ritesh Harjani (IBM) > <ritesh.list@xxxxxxxxx> wrote: >> We would eventually use iomap_iop_** function naming by the rest of the >> buffered-io iomap code. This patch update function arguments and naming >> from iomap_set_range_uptodate() -> iomap_iop_set_range_uptodate(). >> iop_set_range_uptodate() then becomes an accessor function used by >> iomap_iop_** functions. >> >> Signed-off-by: Ritesh Harjani (IBM) <ritesh.list@xxxxxxxxx> >> --- >> fs/iomap/buffered-io.c | 111 +++++++++++++++++++++++------------------ >> 1 file changed, 63 insertions(+), 48 deletions(-) >> >> diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c >> index 6fffda355c45..136f57ccd0be 100644 >> --- a/fs/iomap/buffered-io.c >> +++ b/fs/iomap/buffered-io.c >> @@ -24,14 +24,14 @@ >> #define IOEND_BATCH_SIZE 4096 >> >> /* >> - * Structure allocated for each folio when block size < folio size >> - * to track sub-folio uptodate status and I/O completions. >> + * Structure allocated for each folio to track per-block uptodate state >> + * and I/O completions. >> */ >> struct iomap_page { >> atomic_t read_bytes_pending; >> atomic_t write_bytes_pending; >> - spinlock_t uptodate_lock; >> - unsigned long uptodate[]; >> + spinlock_t state_lock; >> + unsigned long state[]; >> }; >> >> static inline struct iomap_page *to_iomap_page(struct folio *folio) >> @@ -43,6 +43,48 @@ static inline struct iomap_page *to_iomap_page(struct folio *folio) >> >> static struct bio_set iomap_ioend_bioset; >> >> +static bool iop_test_full_uptodate(struct folio *folio) >> +{ >> + struct iomap_page *iop = to_iomap_page(folio); >> + struct inode *inode = folio->mapping->host; >> + >> + return bitmap_full(iop->state, i_blocks_per_folio(inode, folio)); >> +} > > Can this be called iop_test_fully_uptodate(), please? > IMHO, iop_test_full_uptodate() looks fine. It goes similar to bitmap_full() function. >> + >> +static bool iop_test_block_uptodate(struct folio *folio, unsigned int block) >> +{ >> + struct iomap_page *iop = to_iomap_page(folio); >> + >> + return test_bit(block, iop->state); >> +} >> + >> +static void iop_set_range_uptodate(struct inode *inode, struct folio *folio, >> + size_t off, size_t len) >> +{ >> + struct iomap_page *iop = to_iomap_page(folio); > > Note that to_iomap_page() does folio_test_private() followed by > folio_get_private(), which doesn't really make sense in places where > we know that iop is defined. Maybe we want to split that up. > I think in mm we have PG_Private flag which gets set as a pageflag. So folio_test_private() actually checks whether we have PG_Private flag set or not ( I guess it could be to overload folio->private use). For file folio, maybe can we directly return folio_get_private(folio) from to_iomap_page(folio) ? >> + unsigned int first_blk = off >> inode->i_blkbits; >> + unsigned int last_blk = (off + len - 1) >> inode->i_blkbits; >> + unsigned int nr_blks = last_blk - first_blk + 1; >> + unsigned long flags; >> + >> + spin_lock_irqsave(&iop->state_lock, flags); >> + bitmap_set(iop->state, first_blk, nr_blks); >> + if (iop_test_full_uptodate(folio)) >> + folio_mark_uptodate(folio); >> + spin_unlock_irqrestore(&iop->state_lock, flags); >> +} >> + >> +static void iomap_iop_set_range_uptodate(struct inode *inode, >> + struct folio *folio, size_t off, size_t len) >> +{ >> + struct iomap_page *iop = to_iomap_page(folio); >> + >> + if (iop) >> + iop_set_range_uptodate(inode, folio, off, len); >> + else >> + folio_mark_uptodate(folio); >> +} > > This patch passes the inode into iomap_iop_set_range_uptodate() and > removes the iop argument. Can this be done in a separate patch, > please? > > We have a few places like the above, where we look up the iop without > using it. Would a function like folio_has_iop() make more sense? > Just realized that we should also rename to_iomap_page(folio) -> iomap_get_iop(folio). For your comment, we can use that as - +static void iomap_iop_set_range_uptodate(struct inode *inode, + struct folio *folio, size_t off, size_t len) +{ + if (iomap_get_iop(folio)) + iop_set_range_uptodate(inode, folio, off, len); + else + folio_mark_uptodate(folio); +} Does this looks ok? -ritesh