Commit 24addd84 authored by Matthew Wilcox (Oracle)'s avatar Matthew Wilcox (Oracle) Committed by Darrick J. Wong
Browse files

fs: Introduce i_blocks_per_page



This helper is useful for both THPs and for supporting block size larger
than page size.  Convert all users that I could find (we have a few
different ways of writing this idiom, and I may have missed some).

Signed-off-by: default avatarMatthew Wilcox (Oracle) <willy@infradead.org>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarDave Chinner <dchinner@redhat.com>
Reviewed-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
Acked-by: default avatarDave Kleikamp <dave.kleikamp@oracle.com>
parent 7ed3cd1a
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -46,7 +46,7 @@ iomap_page_create(struct inode *inode, struct page *page)
{
	struct iomap_page *iop = to_iomap_page(page);

	if (iop || i_blocksize(inode) == PAGE_SIZE)
	if (iop || i_blocks_per_page(inode, page) <= 1)
		return iop;

	iop = kmalloc(sizeof(*iop), GFP_NOFS | __GFP_NOFAIL);
@@ -147,7 +147,7 @@ iomap_iop_set_range_uptodate(struct page *page, unsigned off, unsigned len)
	unsigned int i;

	spin_lock_irqsave(&iop->uptodate_lock, flags);
	for (i = 0; i < PAGE_SIZE / i_blocksize(inode); i++) {
	for (i = 0; i < i_blocks_per_page(inode, page); i++) {
		if (i >= first && i <= last)
			set_bit(i, iop->uptodate);
		else if (!test_bit(i, iop->uptodate))
@@ -1077,7 +1077,7 @@ iomap_finish_page_writeback(struct inode *inode, struct page *page,
		mapping_set_error(inode->i_mapping, -EIO);
	}

	WARN_ON_ONCE(i_blocksize(inode) < PAGE_SIZE && !iop);
	WARN_ON_ONCE(i_blocks_per_page(inode, page) > 1 && !iop);
	WARN_ON_ONCE(iop && atomic_read(&iop->write_count) <= 0);

	if (!iop || atomic_dec_and_test(&iop->write_count))
@@ -1373,7 +1373,7 @@ iomap_writepage_map(struct iomap_writepage_ctx *wpc,
	int error = 0, count = 0, i;
	LIST_HEAD(submit_list);

	WARN_ON_ONCE(i_blocksize(inode) < PAGE_SIZE && !iop);
	WARN_ON_ONCE(i_blocks_per_page(inode, page) > 1 && !iop);
	WARN_ON_ONCE(iop && atomic_read(&iop->write_count) != 0);

	/*
+1 −1
Original line number Diff line number Diff line
@@ -473,7 +473,7 @@ static int metapage_readpage(struct file *fp, struct page *page)
	struct inode *inode = page->mapping->host;
	struct bio *bio = NULL;
	int block_offset;
	int blocks_per_page = PAGE_SIZE >> inode->i_blkbits;
	int blocks_per_page = i_blocks_per_page(inode, page);
	sector_t page_start;	/* address of page in fs blocks */
	sector_t pblock;
	int xlen;
+1 −1
Original line number Diff line number Diff line
@@ -544,7 +544,7 @@ xfs_discard_page(
			page, ip->i_ino, offset);

	error = xfs_bmap_punch_delalloc_range(ip, start_fsb,
			PAGE_SIZE / i_blocksize(inode));
			i_blocks_per_page(inode, page));
	if (error && !XFS_FORCED_SHUTDOWN(mp))
		xfs_alert(mp, "page discard unable to remove delalloc mapping.");
out_invalidate:
+16 −0
Original line number Diff line number Diff line
@@ -899,4 +899,20 @@ static inline int page_mkwrite_check_truncate(struct page *page,
	return offset;
}

/**
 * i_blocks_per_page - How many blocks fit in this page.
 * @inode: The inode which contains the blocks.
 * @page: The page (head page if the page is a THP).
 *
 * If the block size is larger than the size of this page, return zero.
 *
 * Context: The caller should hold a refcount on the page to prevent it
 * from being split.
 * Return: The number of filesystem blocks covered by this page.
 */
static inline
unsigned int i_blocks_per_page(struct inode *inode, struct page *page)
{
	return thp_size(page) >> inode->i_blkbits;
}
#endif /* _LINUX_PAGEMAP_H */