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

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
...@@ -46,7 +46,7 @@ iomap_page_create(struct inode *inode, struct page *page) ...@@ -46,7 +46,7 @@ iomap_page_create(struct inode *inode, struct page *page)
{ {
struct iomap_page *iop = to_iomap_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; return iop;
iop = kmalloc(sizeof(*iop), GFP_NOFS | __GFP_NOFAIL); iop = kmalloc(sizeof(*iop), GFP_NOFS | __GFP_NOFAIL);
...@@ -147,7 +147,7 @@ iomap_iop_set_range_uptodate(struct page *page, unsigned off, unsigned len) ...@@ -147,7 +147,7 @@ iomap_iop_set_range_uptodate(struct page *page, unsigned off, unsigned len)
unsigned int i; unsigned int i;
spin_lock_irqsave(&iop->uptodate_lock, flags); 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) if (i >= first && i <= last)
set_bit(i, iop->uptodate); set_bit(i, iop->uptodate);
else if (!test_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, ...@@ -1077,7 +1077,7 @@ iomap_finish_page_writeback(struct inode *inode, struct page *page,
mapping_set_error(inode->i_mapping, -EIO); 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); WARN_ON_ONCE(iop && atomic_read(&iop->write_count) <= 0);
if (!iop || atomic_dec_and_test(&iop->write_count)) if (!iop || atomic_dec_and_test(&iop->write_count))
...@@ -1373,7 +1373,7 @@ iomap_writepage_map(struct iomap_writepage_ctx *wpc, ...@@ -1373,7 +1373,7 @@ iomap_writepage_map(struct iomap_writepage_ctx *wpc,
int error = 0, count = 0, i; int error = 0, count = 0, i;
LIST_HEAD(submit_list); 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); WARN_ON_ONCE(iop && atomic_read(&iop->write_count) != 0);
/* /*
......
...@@ -473,7 +473,7 @@ static int metapage_readpage(struct file *fp, struct page *page) ...@@ -473,7 +473,7 @@ static int metapage_readpage(struct file *fp, struct page *page)
struct inode *inode = page->mapping->host; struct inode *inode = page->mapping->host;
struct bio *bio = NULL; struct bio *bio = NULL;
int block_offset; 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 page_start; /* address of page in fs blocks */
sector_t pblock; sector_t pblock;
int xlen; int xlen;
......
...@@ -544,7 +544,7 @@ xfs_discard_page( ...@@ -544,7 +544,7 @@ xfs_discard_page(
page, ip->i_ino, offset); page, ip->i_ino, offset);
error = xfs_bmap_punch_delalloc_range(ip, start_fsb, 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)) if (error && !XFS_FORCED_SHUTDOWN(mp))
xfs_alert(mp, "page discard unable to remove delalloc mapping."); xfs_alert(mp, "page discard unable to remove delalloc mapping.");
out_invalidate: out_invalidate:
......
...@@ -899,4 +899,20 @@ static inline int page_mkwrite_check_truncate(struct page *page, ...@@ -899,4 +899,20 @@ static inline int page_mkwrite_check_truncate(struct page *page,
return offset; 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 */ #endif /* _LINUX_PAGEMAP_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment