[Cluster-devel] [PATCH v2 06/14] buffer: Make block_write_full_page() handle large folios correctly

Andreas Grünbacher andreas.gruenbacher at gmail.com
Tue Jun 6 23:15:34 UTC 2023


Am Mi., 7. Juni 2023 um 00:41 Uhr schrieb Matthew Wilcox (Oracle)
<willy at infradead.org>:
> Keep the interface as struct page, but work entirely on the folio
> internally.  Removes several PAGE_SIZE assumptions and removes
> some references to page->index and page->mapping.
>
> Signed-off-by: Matthew Wilcox (Oracle) <willy at infradead.org>
> Tested-by: Bob Peterson <rpeterso at redhat.com>
> Reviewed-by: Bob Peterson <rpeterso at redhat.com>
> ---
>  fs/buffer.c | 22 ++++++++++------------
>  1 file changed, 10 insertions(+), 12 deletions(-)
>
> diff --git a/fs/buffer.c b/fs/buffer.c
> index 4d518df50fab..d8c2c000676b 100644
> --- a/fs/buffer.c
> +++ b/fs/buffer.c
> @@ -2678,33 +2678,31 @@ int block_write_full_page(struct page *page, get_block_t *get_block,
>                         struct writeback_control *wbc)
>  {
>         struct folio *folio = page_folio(page);
> -       struct inode * const inode = page->mapping->host;
> +       struct inode * const inode = folio->mapping->host;
>         loff_t i_size = i_size_read(inode);
> -       const pgoff_t end_index = i_size >> PAGE_SHIFT;
> -       unsigned offset;
>
> -       /* Is the page fully inside i_size? */
> -       if (page->index < end_index)
> +       /* Is the folio fully inside i_size? */
> +       if (folio_pos(folio) + folio_size(folio) <= i_size)
>                 return __block_write_full_folio(inode, folio, get_block, wbc,
>                                                end_buffer_async_write);
>
> -       /* Is the page fully outside i_size? (truncate in progress) */
> -       offset = i_size & (PAGE_SIZE-1);
> -       if (page->index >= end_index+1 || !offset) {
> +       /* Is the folio fully outside i_size? (truncate in progress) */
> +       if (folio_pos(folio) > i_size) {

The folio is also fully outside i_size if folio_pos(folio) == i_size.

>                 folio_unlock(folio);
>                 return 0; /* don't care */
>         }
>
>         /*
> -        * The page straddles i_size.  It must be zeroed out on each and every
> +        * The folio straddles i_size.  It must be zeroed out on each and every
>          * writepage invocation because it may be mmapped.  "A file is mapped
>          * in multiples of the page size.  For a file that is not a multiple of
> -        * the  page size, the remaining memory is zeroed when mapped, and
> +        * the page size, the remaining memory is zeroed when mapped, and
>          * writes to that region are not written out to the file."
>          */
> -       zero_user_segment(page, offset, PAGE_SIZE);
> +       folio_zero_segment(folio, offset_in_folio(folio, i_size),
> +                       folio_size(folio));
>         return __block_write_full_folio(inode, folio, get_block, wbc,
> -                                                       end_buffer_async_write);
> +                       end_buffer_async_write);
>  }
>  EXPORT_SYMBOL(block_write_full_page);
>
> --
> 2.39.2
>

Thanks,
Andreas



More information about the Cluster-devel mailing list