History

buffer: convert __block_write_full_page() to __block_write_full_folio()

Remove nine hidden calls to compound_head() by using a folio instead of a page.

Matthew Wilcox (Oracle) committed 3 years ago

Commit 53418a11 parent c1401fd5 files · +32 −32Browse files

Unified · Split

5 files
  1. fs/buffer.c +27 −26
  2. fs/gfs2/aops.c +2 −3
  3. fs/ntfs/aops.c +1 −1
  4. fs/reiserfs/inode.c +1 −1
  5. include/linux/buffer_head.h +1 −1
fs/buffer.c+27−26
@@ -1764,7 +1764,7 @@ static struct buffer_head *folio_create_buffers(struct folio *folio, · 1763 unmodified lines
1764 * WB_SYNC_ALL, the writes are posted using REQ_SYNC; this1764 * WB_SYNC_ALL, the writes are posted using REQ_SYNC; this
1765 * causes the writes to be flagged as synchronous writes.1765 * causes the writes to be flagged as synchronous writes.
1766 */1766 */
1767int __block_write_full_page(struct inode *inode, struct page *page,1767int __block_write_full_folio(struct inode *inode, struct folio *folio,
1768 get_block_t *get_block, struct writeback_control *wbc,1768 get_block_t *get_block, struct writeback_control *wbc,
1769 bh_end_io_t *handler)1769 bh_end_io_t *handler)
1770{1770{
@@ -1776,14 +1776,14 @@ int __block_write_full_page(struct inode *inode, struct page *page, · 5 unmodified lines
1776 int nr_underway = 0;1776 int nr_underway = 0;
1777 blk_opf_t write_flags = wbc_to_write_flags(wbc);1777 blk_opf_t write_flags = wbc_to_write_flags(wbc);
1778 1778
1779 head = folio_create_buffers(page_folio(page), inode,1779 head = folio_create_buffers(folio, inode,
1780 (1 << BH_Dirty) | (1 << BH_Uptodate));1780 (1 << BH_Dirty) | (1 << BH_Uptodate));
1781 1781
1782 /*1782 /*
1783 * Be very careful. We have no exclusion from block_dirty_folio1783 * Be very careful. We have no exclusion from block_dirty_folio
1784 * here, and the (potentially unmapped) buffers may become dirty at1784 * here, and the (potentially unmapped) buffers may become dirty at
1785 * any time. If a buffer becomes dirty here after we've inspected it1785 * any time. If a buffer becomes dirty here after we've inspected it
1786 * then we just miss that fact, and the page stays dirty.1786 * then we just miss that fact, and the folio stays dirty.
1787 *1787 *
1788 * Buffers outside i_size may be dirtied by block_dirty_folio;1788 * Buffers outside i_size may be dirtied by block_dirty_folio;
1789 * handle that here by just cleaning them.1789 * handle that here by just cleaning them.
@@ -1793,7 +1793,7 @@ int __block_write_full_page(struct inode *inode, struct page *page, · 3 unmodified lines
1793 blocksize = bh->b_size;1793 blocksize = bh->b_size;
1794 bbits = block_size_bits(blocksize);1794 bbits = block_size_bits(blocksize);
1795 1795
1796 block = (sector_t)page->index << (PAGE_SHIFT - bbits);1796 block = (sector_t)folio->index << (PAGE_SHIFT - bbits);
1797 last_block = (i_size_read(inode) - 1) >> bbits;1797 last_block = (i_size_read(inode) - 1) >> bbits;
1798 1798
1799 /*1799 /*
@@ -1804,7 +1804,7 @@ int __block_write_full_page(struct inode *inode, struct page *page, · 4 unmodified lines
1804 if (block > last_block) {1804 if (block > last_block) {
1805 /*1805 /*
1806 * mapped buffers outside i_size will occur, because1806 * mapped buffers outside i_size will occur, because
1807 * this page can be outside i_size when there is a1807 * this folio can be outside i_size when there is a
1808 * truncate in progress.1808 * truncate in progress.
1809 */1809 */
1810 /*1810 /*
@@ -1834,7 +1834,7 @@ int __block_write_full_page(struct inode *inode, struct page *page, · 23 unmodified lines
1834 continue;1834 continue;
1835 /*1835 /*
1836 * If it's a fully non-blocking write attempt and we cannot1836 * If it's a fully non-blocking write attempt and we cannot
1837 * lock the buffer then redirty the page. Note that this can1837 * lock the buffer then redirty the folio. Note that this can
1838 * potentially cause a busy-wait loop from writeback threads1838 * potentially cause a busy-wait loop from writeback threads
1839 * and kswapd activity, but those code paths have their own1839 * and kswapd activity, but those code paths have their own
1840 * higher-level throttling.1840 * higher-level throttling.
@@ -1842,7 +1842,7 @@ int __block_write_full_page(struct inode *inode, struct page *page, · 1 unmodified line
1842 if (wbc->sync_mode != WB_SYNC_NONE) {1842 if (wbc->sync_mode != WB_SYNC_NONE) {
1843 lock_buffer(bh);1843 lock_buffer(bh);
1844 } else if (!trylock_buffer(bh)) {1844 } else if (!trylock_buffer(bh)) {
1845 redirty_page_for_writepage(wbc, page);1845 folio_redirty_for_writepage(wbc, folio);
1846 continue;1846 continue;
1847 }1847 }
1848 if (test_clear_buffer_dirty(bh)) {1848 if (test_clear_buffer_dirty(bh)) {
@@ -1853,11 +1853,11 @@ int __block_write_full_page(struct inode *inode, struct page *page, · 4 unmodified lines
1853 } while ((bh = bh->b_this_page) != head);1853 } while ((bh = bh->b_this_page) != head);
1854 1854
1855 /*1855 /*
1856 * The page and its buffers are protected by PageWriteback(), so we can1856 * The folio and its buffers are protected by the writeback flag,
1857 * drop the bh refcounts early.1857 * so we can drop the bh refcounts early.
1858 */1858 */
1859 BUG_ON(PageWriteback(page));1859 BUG_ON(folio_test_writeback(folio));
1860 set_page_writeback(page);1860 folio_start_writeback(folio);
1861 1861
1862 do {1862 do {
1863 struct buffer_head *next = bh->b_this_page;1863 struct buffer_head *next = bh->b_this_page;
@@ -1867,20 +1867,20 @@ int __block_write_full_page(struct inode *inode, struct page *page, · 3 unmodified lines
1867 }1867 }
1868 bh = next;1868 bh = next;
1869 } while (bh != head);1869 } while (bh != head);
1870 unlock_page(page);1870 folio_unlock(folio);
1871 1871
1872 err = 0;1872 err = 0;
1873done:1873done:
1874 if (nr_underway == 0) {1874 if (nr_underway == 0) {
1875 /*1875 /*
1876 * The page was marked dirty, but the buffers were1876 * The folio was marked dirty, but the buffers were
1877 * clean. Someone wrote them back by hand with1877 * clean. Someone wrote them back by hand with
1878 * write_dirty_buffer/submit_bh. A rare case.1878 * write_dirty_buffer/submit_bh. A rare case.
1879 */1879 */
1880 end_page_writeback(page);1880 folio_end_writeback(folio);
1881 1881
1882 /*1882 /*
1883 * The page and buffer_heads can be released at any time from1883 * The folio and buffer_heads can be released at any time from
1884 * here on.1884 * here on.
1885 */1885 */
1886 }1886 }
@@ -1891,7 +1891,7 @@ recover: · 4 unmodified lines
1891 * ENOSPC, or some other error. We may already have added some1891 * ENOSPC, or some other error. We may already have added some
1892 * blocks to the file, so we need to write these out to avoid1892 * blocks to the file, so we need to write these out to avoid
1893 * exposing stale data.1893 * exposing stale data.
1894 * The page is currently locked and not marked for writeback1894 * The folio is currently locked and not marked for writeback
1895 */1895 */
1896 bh = head;1896 bh = head;
1897 /* Recovery: lock and submit the mapped buffers */1897 /* Recovery: lock and submit the mapped buffers */
@@ -1903,15 +1903,15 @@ recover: · 5 unmodified lines
1903 } else {1903 } else {
1904 /*1904 /*
1905 * The buffer may have been set dirty during1905 * The buffer may have been set dirty during
1906 * attachment to a dirty page.1906 * attachment to a dirty folio.
1907 */1907 */
1908 clear_buffer_dirty(bh);1908 clear_buffer_dirty(bh);
1909 }1909 }
1910 } while ((bh = bh->b_this_page) != head);1910 } while ((bh = bh->b_this_page) != head);
1911 SetPageError(page);1911 folio_set_error(folio);
1912 BUG_ON(PageWriteback(page));1912 BUG_ON(folio_test_writeback(folio));
1913 mapping_set_error(page->mapping, err);1913 mapping_set_error(folio->mapping, err);
1914 set_page_writeback(page);1914 folio_start_writeback(folio);
1915 do {1915 do {
1916 struct buffer_head *next = bh->b_this_page;1916 struct buffer_head *next = bh->b_this_page;
1917 if (buffer_async_write(bh)) {1917 if (buffer_async_write(bh)) {
@@ -1921,10 +1921,10 @@ recover: · 3 unmodified lines
1921 }1921 }
1922 bh = next;1922 bh = next;
1923 } while (bh != head);1923 } while (bh != head);
1924 unlock_page(page);1924 folio_unlock(folio);
1925 goto done;1925 goto done;
1926}1926}
1927EXPORT_SYMBOL(__block_write_full_page);1927EXPORT_SYMBOL(__block_write_full_folio);
1928 1928
1929/*1929/*
1930 * If a page has any new buffers, zero them out here, and mark them uptodate1930 * If a page has any new buffers, zero them out here, and mark them uptodate
@@ -2677,6 +2677,7 @@ EXPORT_SYMBOL(block_truncate_page); · 746 unmodified lines
2677int block_write_full_page(struct page *page, get_block_t *get_block,2677int block_write_full_page(struct page *page, get_block_t *get_block,
2678 struct writeback_control *wbc)2678 struct writeback_control *wbc)
2679{2679{
2680 struct folio *folio = page_folio(page);
2680 struct inode * const inode = page->mapping->host;2681 struct inode * const inode = page->mapping->host;
2681 loff_t i_size = i_size_read(inode);2682 loff_t i_size = i_size_read(inode);
2682 const pgoff_t end_index = i_size >> PAGE_SHIFT;2683 const pgoff_t end_index = i_size >> PAGE_SHIFT;
@@ -2684,13 +2685,13 @@ int block_write_full_page(struct page *page, get_block_t *get_block, · 1 unmodified line
2684 2685
2685 /* Is the page fully inside i_size? */2686 /* Is the page fully inside i_size? */
2686 if (page->index < end_index)2687 if (page->index < end_index)
2687 return __block_write_full_page(inode, page, get_block, wbc,2688 return __block_write_full_folio(inode, folio, get_block, wbc,
2688 end_buffer_async_write);2689 end_buffer_async_write);
2689 2690
2690 /* Is the page fully outside i_size? (truncate in progress) */2691 /* Is the page fully outside i_size? (truncate in progress) */
2691 offset = i_size & (PAGE_SIZE-1);2692 offset = i_size & (PAGE_SIZE-1);
2692 if (page->index >= end_index+1 || !offset) {2693 if (page->index >= end_index+1 || !offset) {
2693 unlock_page(page);2694 folio_unlock(folio);
2694 return 0; /* don't care */2695 return 0; /* don't care */
2695 }2696 }
2696 2697
@@ -2702,7 +2703,7 @@ int block_write_full_page(struct page *page, get_block_t *get_block, · 5 unmodified lines
2702 * writes to that region are not written out to the file."2703 * writes to that region are not written out to the file."
2703 */2704 */
2704 zero_user_segment(page, offset, PAGE_SIZE);2705 zero_user_segment(page, offset, PAGE_SIZE);
2705 return __block_write_full_page(inode, page, get_block, wbc,2706 return __block_write_full_folio(inode, folio, get_block, wbc,
2706 end_buffer_async_write);2707 end_buffer_async_write);
2707}2708}
2708EXPORT_SYMBOL(block_write_full_page);2709EXPORT_SYMBOL(block_write_full_page);
fs/gfs2/aops.c+2−3
@@ -107,9 +107,8 @@ static int gfs2_write_jdata_folio(struct folio *folio, · 106 unmodified lines
107 folio_zero_segment(folio, offset_in_folio(folio, i_size),107 folio_zero_segment(folio, offset_in_folio(folio, i_size),
108 folio_size(folio));108 folio_size(folio));
109 109
110 return __block_write_full_page(inode, &folio->page,110 return __block_write_full_folio(inode, folio, gfs2_get_block_noalloc,
111 gfs2_get_block_noalloc, wbc,111 wbc, end_buffer_async_write);
112 end_buffer_async_write);
113}112}
114 113
115/**114/**
fs/ntfs/aops.c+1−1
@@ -526,7 +526,7 @@ err_out: · 525 unmodified lines
526 *526 *
527 * Return 0 on success and -errno on error.527 * Return 0 on success and -errno on error.
528 *528 *
529 * Based on ntfs_read_block() and __block_write_full_page().529 * Based on ntfs_read_block() and __block_write_full_folio().
530 */530 */
531static int ntfs_write_block(struct page *page, struct writeback_control *wbc)531static int ntfs_write_block(struct page *page, struct writeback_control *wbc)
532{532{
fs/reiserfs/inode.c+1−1
@@ -2506,7 +2506,7 @@ out: · 2505 unmodified lines
2506 2506
2507/*2507/*
2508 * mason@suse.com: updated in 2.5.54 to follow the same general io2508 * mason@suse.com: updated in 2.5.54 to follow the same general io
2509 * start/recovery path as __block_write_full_page, along with special2509 * start/recovery path as __block_write_full_folio, along with special
2510 * code to handle reiserfs tails.2510 * code to handle reiserfs tails.
2511 */2511 */
2512static int reiserfs_write_full_page(struct page *page,2512static int reiserfs_write_full_page(struct page *page,
include/linux/buffer_head.h+1−1
@@ -263,7 +263,7 @@ extern int buffer_heads_over_limit; · 262 unmodified lines
263void block_invalidate_folio(struct folio *folio, size_t offset, size_t length);263void block_invalidate_folio(struct folio *folio, size_t offset, size_t length);
264int block_write_full_page(struct page *page, get_block_t *get_block,264int block_write_full_page(struct page *page, get_block_t *get_block,
265 struct writeback_control *wbc);265 struct writeback_control *wbc);
266int __block_write_full_page(struct inode *inode, struct page *page,266int __block_write_full_folio(struct inode *inode, struct folio *folio,
267 get_block_t *get_block, struct writeback_control *wbc,267 get_block_t *get_block, struct writeback_control *wbc,
268 bh_end_io_t *handler);268 bh_end_io_t *handler);
269int block_read_full_folio(struct folio *, get_block_t *);269int block_read_full_folio(struct folio *, get_block_t *);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t