diff mbox series

[v4,09/25] mm: Add folio_index, folio_page and folio_contains

Message ID 20210305041901.2396498-10-willy@infradead.org (mailing list archive)
State New, archived
Headers show
Series Page folios | expand

Commit Message

Matthew Wilcox (Oracle) March 5, 2021, 4:18 a.m. UTC
folio_index() is the equivalent of page_index() for folios.  folio_page()
finds the page in a folio for a page cache index.  folio_contains()
tells you whether a folio contains a particular page cache index.

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

Comments

Andrew Morton March 13, 2021, 8:37 p.m. UTC | #1
On Fri,  5 Mar 2021 04:18:45 +0000 "Matthew Wilcox (Oracle)" <willy@infradead.org> wrote:

> folio_index() is the equivalent of page_index() for folios.  folio_page()
> finds the page in a folio for a page cache index.  folio_contains()
> tells you whether a folio contains a particular page cache index.
> 

copy-paste changelog into each function's covering comment?

> ---
>  include/linux/pagemap.h | 23 +++++++++++++++++++++++
>  1 file changed, 23 insertions(+)
> 
> diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
> index f07c03da83f6..5094b50f7680 100644
> --- a/include/linux/pagemap.h
> +++ b/include/linux/pagemap.h
> @@ -447,6 +447,29 @@ static inline bool thp_contains(struct page *head, pgoff_t index)
>  	return page_index(head) == (index & ~(thp_nr_pages(head) - 1UL));
>  }
>  
> +static inline pgoff_t folio_index(struct folio *folio)
> +{
> +        if (unlikely(FolioSwapCache(folio)))
> +                return __page_file_index(&folio->page);
> +        return folio->page.index;
> +}
> +
> +static inline struct page *folio_page(struct folio *folio, pgoff_t index)
> +{
> +	index -= folio_index(folio);
> +	VM_BUG_ON_FOLIO(index >= folio_nr_pages(folio), folio);
> +	return &folio->page + index;
> +}

One would expect folio_page() to be the reverse of page_folio(), only
it isn't anything like that.

> +/* Does this folio contain this index? */
> +static inline bool folio_contains(struct folio *folio, pgoff_t index)
> +{
> +	/* HugeTLBfs indexes the page cache in units of hpage_size */
> +	if (PageHuge(&folio->page))
> +		return folio->page.index == index;
> +	return index - folio_index(folio) < folio_nr_pages(folio);
> +}
> +
>  /*
>   * Given the page we found in the page cache, return the page corresponding
>   * to this index in the file
Matthew Wilcox (Oracle) March 14, 2021, 3:45 a.m. UTC | #2
On Sat, Mar 13, 2021 at 12:37:16PM -0800, Andrew Morton wrote:
> On Fri,  5 Mar 2021 04:18:45 +0000 "Matthew Wilcox (Oracle)" <willy@infradead.org> wrote:
> > folio_index() is the equivalent of page_index() for folios.  folio_page()
> > finds the page in a folio for a page cache index.  folio_contains()
> > tells you whether a folio contains a particular page cache index.
> > 
> 
> copy-paste changelog into each function's covering comment?

Certainly.

> > +static inline struct page *folio_page(struct folio *folio, pgoff_t index)
> > +{
> > +	index -= folio_index(folio);
> > +	VM_BUG_ON_FOLIO(index >= folio_nr_pages(folio), folio);
> > +	return &folio->page + index;
> > +}
> 
> One would expect folio_page() to be the reverse of page_folio(), only
> it isn't anything like that.

It is ... but only for files.  So maybe folio_file_page()?
Christoph Hellwig March 17, 2021, 5:22 p.m. UTC | #3
On Sat, Mar 13, 2021 at 12:37:16PM -0800, Andrew Morton wrote:
> On Fri,  5 Mar 2021 04:18:45 +0000 "Matthew Wilcox (Oracle)" <willy@infradead.org> wrote:
> 
> > folio_index() is the equivalent of page_index() for folios.  folio_page()
> > finds the page in a folio for a page cache index.  folio_contains()
> > tells you whether a folio contains a particular page cache index.
> > 
> 
> copy-paste changelog into each function's covering comment?

Yes, I think documenting all these helpers would be very useful.  The
lack of good commens on some of the page related existing helpers has
driven me insane sometimes.
diff mbox series

Patch

diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
index f07c03da83f6..5094b50f7680 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -447,6 +447,29 @@  static inline bool thp_contains(struct page *head, pgoff_t index)
 	return page_index(head) == (index & ~(thp_nr_pages(head) - 1UL));
 }
 
+static inline pgoff_t folio_index(struct folio *folio)
+{
+        if (unlikely(FolioSwapCache(folio)))
+                return __page_file_index(&folio->page);
+        return folio->page.index;
+}
+
+static inline struct page *folio_page(struct folio *folio, pgoff_t index)
+{
+	index -= folio_index(folio);
+	VM_BUG_ON_FOLIO(index >= folio_nr_pages(folio), folio);
+	return &folio->page + index;
+}
+
+/* Does this folio contain this index? */
+static inline bool folio_contains(struct folio *folio, pgoff_t index)
+{
+	/* HugeTLBfs indexes the page cache in units of hpage_size */
+	if (PageHuge(&folio->page))
+		return folio->page.index == index;
+	return index - folio_index(folio) < folio_nr_pages(folio);
+}
+
 /*
  * Given the page we found in the page cache, return the page corresponding
  * to this index in the file