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
17641764 * WB_SYNC_ALL, the writes are posted using REQ_SYNC; this
17651765 * causes the writes to be flagged as synchronous writes.
17661766 */
1767−int __block_write_full_page(struct inode *inode, struct page *page,
1767+int __block_write_full_folio(struct inode *inode, struct folio *folio,
17681768 get_block_t *get_block, struct writeback_control *wbc,
17691769 bh_end_io_t *handler)
17701770 {
@@ -1776,14 +1776,14 @@ int __block_write_full_page(struct inode *inode, struct page *page, · 5 unmodified lines
17761776 int nr_underway = 0;
17771777 blk_opf_t write_flags = wbc_to_write_flags(wbc);
17781778
1779− head = folio_create_buffers(page_folio(page), inode,
1779+ head = folio_create_buffers(folio, inode,
17801780 (1 << BH_Dirty) | (1 << BH_Uptodate));
17811781
17821782 /*
17831783 * Be very careful. We have no exclusion from block_dirty_folio
17841784 * here, and the (potentially unmapped) buffers may become dirty at
17851785 * 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.
17871787 *
17881788 * Buffers outside i_size may be dirtied by block_dirty_folio;
17891789 * 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
17931793 blocksize = bh->b_size;
17941794 bbits = block_size_bits(blocksize);
17951795
1796− block = (sector_t)page->index << (PAGE_SHIFT - bbits);
1796+ block = (sector_t)folio->index << (PAGE_SHIFT - bbits);
17971797 last_block = (i_size_read(inode) - 1) >> bbits;
17981798
17991799 /*
@@ -1804,7 +1804,7 @@ int __block_write_full_page(struct inode *inode, struct page *page, · 4 unmodified lines
18041804 if (block > last_block) {
18051805 /*
18061806 * mapped buffers outside i_size will occur, because
1807− * this page can be outside i_size when there is a
1807+ * this folio can be outside i_size when there is a
18081808 * truncate in progress.
18091809 */
18101810 /*
@@ -1834,7 +1834,7 @@ int __block_write_full_page(struct inode *inode, struct page *page, · 23 unmodified lines
18341834 continue;
18351835 /*
18361836 * If it's a fully non-blocking write attempt and we cannot
1837− * lock the buffer then redirty the page. Note that this can
1837+ * lock the buffer then redirty the folio. Note that this can
18381838 * potentially cause a busy-wait loop from writeback threads
18391839 * and kswapd activity, but those code paths have their own
18401840 * higher-level throttling.
@@ -1842,7 +1842,7 @@ int __block_write_full_page(struct inode *inode, struct page *page, · 1 unmodified line
18421842 if (wbc->sync_mode != WB_SYNC_NONE) {
18431843 lock_buffer(bh);
18441844 } else if (!trylock_buffer(bh)) {
1845− redirty_page_for_writepage(wbc, page);
1845+ folio_redirty_for_writepage(wbc, folio);
18461846 continue;
18471847 }
18481848 if (test_clear_buffer_dirty(bh)) {
@@ -1853,11 +1853,11 @@ int __block_write_full_page(struct inode *inode, struct page *page, · 4 unmodified lines
18531853 } while ((bh = bh->b_this_page) != head);
18541854
18551855 /*
1856− * The page and its buffers are protected by PageWriteback(), so we can
1857− * drop the bh refcounts early.
1856+ * The folio and its buffers are protected by the writeback flag,
1857+ * so we can drop the bh refcounts early.
18581858 */
1859− BUG_ON(PageWriteback(page));
1860− set_page_writeback(page);
1859+ BUG_ON(folio_test_writeback(folio));
1860+ folio_start_writeback(folio);
18611861
18621862 do {
18631863 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
18671867 }
18681868 bh = next;
18691869 } while (bh != head);
1870− unlock_page(page);
1870+ folio_unlock(folio);
18711871
18721872 err = 0;
18731873 done:
18741874 if (nr_underway == 0) {
18751875 /*
1876− * The page was marked dirty, but the buffers were
1876+ * The folio was marked dirty, but the buffers were
18771877 * clean. Someone wrote them back by hand with
18781878 * write_dirty_buffer/submit_bh. A rare case.
18791879 */
1880− end_page_writeback(page);
1880+ folio_end_writeback(folio);
18811881
18821882 /*
1883− * The page and buffer_heads can be released at any time from
1883+ * The folio and buffer_heads can be released at any time from
18841884 * here on.
18851885 */
18861886 }
@@ -1891,7 +1891,7 @@ recover: · 4 unmodified lines
18911891 * ENOSPC, or some other error. We may already have added some
18921892 * blocks to the file, so we need to write these out to avoid
18931893 * exposing stale data.
1894− * The page is currently locked and not marked for writeback
1894+ * The folio is currently locked and not marked for writeback
18951895 */
18961896 bh = head;
18971897 /* Recovery: lock and submit the mapped buffers */
@@ -1903,15 +1903,15 @@ recover: · 5 unmodified lines
19031903 } else {
19041904 /*
19051905 * The buffer may have been set dirty during
1906− * attachment to a dirty page.
1906+ * attachment to a dirty folio.
19071907 */
19081908 clear_buffer_dirty(bh);
19091909 }
19101910 } while ((bh = bh->b_this_page) != head);
1911− SetPageError(page);
1912− BUG_ON(PageWriteback(page));
1913− mapping_set_error(page->mapping, err);
1914− set_page_writeback(page);
1911+ folio_set_error(folio);
1912+ BUG_ON(folio_test_writeback(folio));
1913+ mapping_set_error(folio->mapping, err);
1914+ folio_start_writeback(folio);
19151915 do {
19161916 struct buffer_head *next = bh->b_this_page;
19171917 if (buffer_async_write(bh)) {
@@ -1921,10 +1921,10 @@ recover: · 3 unmodified lines
19211921 }
19221922 bh = next;
19231923 } while (bh != head);
1924− unlock_page(page);
1924+ folio_unlock(folio);
19251925 goto done;
19261926 }
1927−EXPORT_SYMBOL(__block_write_full_page);
1927+EXPORT_SYMBOL(__block_write_full_folio);
19281928
19291929 /*
19301930 * 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
26772677 int block_write_full_page(struct page *page, get_block_t *get_block,
26782678 struct writeback_control *wbc)
26792679 {
2680+ struct folio *folio = page_folio(page);
26802681 struct inode * const inode = page->mapping->host;
26812682 loff_t i_size = i_size_read(inode);
26822683 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
26842685
26852686 /* Is the page fully inside i_size? */
26862687 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,
26882689 end_buffer_async_write);
26892690
26902691 /* Is the page fully outside i_size? (truncate in progress) */
26912692 offset = i_size & (PAGE_SIZE-1);
26922693 if (page->index >= end_index+1 || !offset) {
2693− unlock_page(page);
2694+ folio_unlock(folio);
26942695 return 0; /* don't care */
26952696 }
26962697
@@ -2702,7 +2703,7 @@ int block_write_full_page(struct page *page, get_block_t *get_block, · 5 unmodified lines
27022703 * writes to that region are not written out to the file."
27032704 */
27042705 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,
27062707 end_buffer_async_write);
27072708 }
27082709 EXPORT_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
107107 folio_zero_segment(folio, offset_in_folio(folio, i_size),
108108 folio_size(folio));
109109
110− return __block_write_full_page(inode, &folio->page,
111− gfs2_get_block_noalloc, wbc,
112− end_buffer_async_write);
110+ return __block_write_full_folio(inode, folio, gfs2_get_block_noalloc,
111+ wbc, end_buffer_async_write);
113112 }
114113
115114 /**
fs/ntfs/aops.c+1−1
@@ -526,7 +526,7 @@ err_out: · 525 unmodified lines
526526 *
527527 * Return 0 on success and -errno on error.
528528 *
529− * Based on ntfs_read_block() and __block_write_full_page().
529+ * Based on ntfs_read_block() and __block_write_full_folio().
530530 */
531531 static int ntfs_write_block(struct page *page, struct writeback_control *wbc)
532532 {
fs/reiserfs/inode.c+1−1
@@ -2506,7 +2506,7 @@ out: · 2505 unmodified lines
25062506
25072507 /*
25082508 * 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 special
2509+ * start/recovery path as __block_write_full_folio, along with special
25102510 * code to handle reiserfs tails.
25112511 */
25122512 static 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
263263 void block_invalidate_folio(struct folio *folio, size_t offset, size_t length);
264264 int block_write_full_page(struct page *page, get_block_t *get_block,
265265 struct writeback_control *wbc);
266−int __block_write_full_page(struct inode *inode, struct page *page,
266+int __block_write_full_folio(struct inode *inode, struct folio *folio,
267267 get_block_t *get_block, struct writeback_control *wbc,
268268 bh_end_io_t *handler);
269269 int 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