diff mbox series

[v4,10/36] fs: Make page_mkwrite_check_truncate thp-aware

Message ID 20200515131656.12890-11-willy@infradead.org (mailing list archive)
State New, archived
Headers show
Series Large pages in the page cache | expand

Commit Message

Matthew Wilcox May 15, 2020, 1:16 p.m. UTC
From: "Matthew Wilcox (Oracle)" <willy@infradead.org>

If the page is compound, check the last index in the page and return
the appropriate size.  Change the return type to ssize_t in case we ever
support pages larger than 2GB.

Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
 include/linux/pagemap.h | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

Comments

Dave Chinner May 21, 2020, 10:01 p.m. UTC | #1
On Fri, May 15, 2020 at 06:16:30AM -0700, Matthew Wilcox wrote:
> From: "Matthew Wilcox (Oracle)" <willy@infradead.org>
> 
> If the page is compound, check the last index in the page and return
> the appropriate size.  Change the return type to ssize_t in case we ever
> support pages larger than 2GB.
> 
> Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
> ---
>  include/linux/pagemap.h | 10 +++++-----
>  1 file changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
> index 1a0bb387948c..c75d7fb7ccbc 100644
> --- a/include/linux/pagemap.h
> +++ b/include/linux/pagemap.h
> @@ -827,22 +827,22 @@ static inline unsigned long dir_pages(struct inode *inode)
>   * @page: the page to check
>   * @inode: the inode to check the page against
>   *
> - * Returns the number of bytes in the page up to EOF,
> + * Return: The number of bytes in the page up to EOF,
>   * or -EFAULT if the page was truncated.
>   */
> -static inline int page_mkwrite_check_truncate(struct page *page,
> +static inline ssize_t page_mkwrite_check_truncate(struct page *page,
>  					      struct inode *inode)
>  {
>  	loff_t size = i_size_read(inode);
>  	pgoff_t index = size >> PAGE_SHIFT;
> -	int offset = offset_in_page(size);
> +	unsigned long offset = offset_in_thp(page, size);
>  
>  	if (page->mapping != inode->i_mapping)
>  		return -EFAULT;
>  
>  	/* page is wholly inside EOF */
> -	if (page->index < index)
> -		return PAGE_SIZE;
> +	if (page->index + hpage_nr_pages(page) - 1 < index)
> +		return thp_size(page);

Can we make these interfaces all use the same namespace prefix?
Here we have a mix of thp and hpage and I have no clue how hpages
are different to thps. If they refer to the same thing (i.e. huge
pages) then can we please make the API consistent before splattering
it all over the filesystem code?

Cheers,

Dave.
Matthew Wilcox May 21, 2020, 11:30 p.m. UTC | #2
On Fri, May 22, 2020 at 08:01:39AM +1000, Dave Chinner wrote:
> On Fri, May 15, 2020 at 06:16:30AM -0700, Matthew Wilcox wrote:
> >  	if (page->mapping != inode->i_mapping)
> >  		return -EFAULT;
> >  
> >  	/* page is wholly inside EOF */
> > -	if (page->index < index)
> > -		return PAGE_SIZE;
> > +	if (page->index + hpage_nr_pages(page) - 1 < index)
> > +		return thp_size(page);
> 
> Can we make these interfaces all use the same namespace prefix?
> Here we have a mix of thp and hpage and I have no clue how hpages
> are different to thps. If they refer to the same thing (i.e. huge
> pages) then can we please make the API consistent before splattering
> it all over the filesystem code?

Yes, they're the same thing.  I'll rename hpage_nr_pages() to thp_count().
diff mbox series

Patch

diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
index 1a0bb387948c..c75d7fb7ccbc 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -827,22 +827,22 @@  static inline unsigned long dir_pages(struct inode *inode)
  * @page: the page to check
  * @inode: the inode to check the page against
  *
- * Returns the number of bytes in the page up to EOF,
+ * Return: The number of bytes in the page up to EOF,
  * or -EFAULT if the page was truncated.
  */
-static inline int page_mkwrite_check_truncate(struct page *page,
+static inline ssize_t page_mkwrite_check_truncate(struct page *page,
 					      struct inode *inode)
 {
 	loff_t size = i_size_read(inode);
 	pgoff_t index = size >> PAGE_SHIFT;
-	int offset = offset_in_page(size);
+	unsigned long offset = offset_in_thp(page, size);
 
 	if (page->mapping != inode->i_mapping)
 		return -EFAULT;
 
 	/* page is wholly inside EOF */
-	if (page->index < index)
-		return PAGE_SIZE;
+	if (page->index + hpage_nr_pages(page) - 1 < index)
+		return thp_size(page);
 	/* page is wholly past EOF */
 	if (page->index > index || !offset)
 		return -EFAULT;