From mboxrd@z Thu Jan 1 00:00:00 1970 From: Bob Peterson Date: Fri, 24 Jul 2020 13:32:54 -0500 Subject: [Cluster-devel] [GFS2 PATCH 01/11] gfs2: inline gfs2_write_jdata_pagevec into gfs2_write_cache_jdata In-Reply-To: <20200724183304.366913-1-rpeterso@redhat.com> References: <20200724183304.366913-1-rpeterso@redhat.com> Message-ID: <20200724183304.366913-2-rpeterso@redhat.com> List-Id: To: cluster-devel.redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit This patch inlines function gfs2_write_jdata_pagevec() into function gfs2_write_cache_jdata(). Since gfs2_write_cache_jdata() is a gfs2-specific copy of write_cache_pages(), we should preserve the structure and logic of write_cache_pages() so upstream changes can be more easily ported without all the hokey "ret = 1...if (ret > 0) ret = 0" kludge and obfuscated logic. Signed-off-by: Bob Peterson --- fs/gfs2/aops.c | 185 ++++++++++++++++++++++--------------------------- 1 file changed, 84 insertions(+), 101 deletions(-) diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c index 68cd700a2719..d6f471cbd62b 100644 --- a/fs/gfs2/aops.c +++ b/fs/gfs2/aops.c @@ -222,102 +222,6 @@ static int gfs2_writepages(struct address_space *mapping, return ret; } -/** - * gfs2_write_jdata_pagevec - Write back a pagevec's worth of pages - * @mapping: The mapping - * @wbc: The writeback control - * @pvec: The vector of pages - * @nr_pages: The number of pages to write - * @done_index: Page index - * - * Returns: non-zero if loop should terminate, zero otherwise - */ - -static int gfs2_write_jdata_pagevec(struct address_space *mapping, - struct writeback_control *wbc, - struct pagevec *pvec, - int nr_pages, - pgoff_t *done_index) -{ - struct inode *inode = mapping->host; - struct gfs2_sbd *sdp = GFS2_SB(inode); - unsigned nrblocks = nr_pages * (PAGE_SIZE >> inode->i_blkbits); - int i; - int ret; - - ret = gfs2_trans_begin(sdp, nrblocks, nrblocks); - if (ret < 0) - return ret; - - for(i = 0; i < nr_pages; i++) { - struct page *page = pvec->pages[i]; - - *done_index = page->index; - - lock_page(page); - - if (unlikely(page->mapping != mapping)) { -continue_unlock: - unlock_page(page); - continue; - } - - if (!PageDirty(page)) { - /* someone wrote it for us */ - goto continue_unlock; - } - - if (PageWriteback(page)) { - if (wbc->sync_mode != WB_SYNC_NONE) - wait_on_page_writeback(page); - else - goto continue_unlock; - } - - BUG_ON(PageWriteback(page)); - if (!clear_page_dirty_for_io(page)) - goto continue_unlock; - - trace_wbc_writepage(wbc, inode_to_bdi(inode)); - - ret = __gfs2_jdata_writepage(page, wbc); - if (unlikely(ret)) { - if (ret == AOP_WRITEPAGE_ACTIVATE) { - unlock_page(page); - ret = 0; - } else { - - /* - * done_index is set past this page, - * so media errors will not choke - * background writeout for the entire - * file. This has consequences for - * range_cyclic semantics (ie. it may - * not be suitable for data integrity - * writeout). - */ - *done_index = page->index + 1; - ret = 1; - break; - } - } - - /* - * We stop writing back only if we are not doing - * integrity sync. In case of integrity sync we have to - * keep going until we have written all the pages - * we tagged for writeback prior to entering this loop. - */ - if (--wbc->nr_to_write <= 0 && wbc->sync_mode == WB_SYNC_NONE) { - ret = 1; - break; - } - - } - gfs2_trans_end(sdp); - return ret; -} - /** * gfs2_write_cache_jdata - Like write_cache_pages but different * @mapping: The mapping to write @@ -331,6 +235,8 @@ static int gfs2_write_jdata_pagevec(struct address_space *mapping, static int gfs2_write_cache_jdata(struct address_space *mapping, struct writeback_control *wbc) { + struct inode *inode = mapping->host; + struct gfs2_sbd *sdp = GFS2_SB(inode); int ret = 0; int done = 0; struct pagevec pvec; @@ -369,16 +275,93 @@ static int gfs2_write_cache_jdata(struct address_space *mapping, tag_pages_for_writeback(mapping, index, end); done_index = index; while (!done && (index <= end)) { + int i; + unsigned nrblocks; + nr_pages = pagevec_lookup_range_tag(&pvec, mapping, &index, end, tag); if (nr_pages == 0) break; - ret = gfs2_write_jdata_pagevec(mapping, wbc, &pvec, nr_pages, &done_index); - if (ret) - done = 1; - if (ret > 0) - ret = 0; + nrblocks = nr_pages * (PAGE_SIZE >> inode->i_blkbits); + ret = gfs2_trans_begin(sdp, nrblocks, nrblocks); + if (ret < 0) + break; + + for (i = 0; i < nr_pages; i++) { + struct page *page = pvec.pages[i]; + + done_index = page->index; + + lock_page(page); + + /* + * Page truncated or invalidated. We can freely skip it + * then, even for data integrity operations: the page + * has disappeared concurrently, so there could be no + * real expectation of this data interity operation + * even if there is now a new, dirty page at the same + * pagecache address. + */ + if (unlikely(page->mapping != mapping)) { +continue_unlock: + unlock_page(page); + continue; + } + + if (!PageDirty(page)) { + /* someone wrote it for us */ + goto continue_unlock; + } + + if (PageWriteback(page)) { + if (wbc->sync_mode != WB_SYNC_NONE) + wait_on_page_writeback(page); + else + goto continue_unlock; + } + + BUG_ON(PageWriteback(page)); + if (!clear_page_dirty_for_io(page)) + goto continue_unlock; + + trace_wbc_writepage(wbc, inode_to_bdi(inode)); + ret = __gfs2_jdata_writepage(page, wbc); + if (unlikely(ret)) { + if (ret == AOP_WRITEPAGE_ACTIVATE) { + unlock_page(page); + ret = 0; + } else { + /* + * done_index is set past this page, + * so media errors will not choke + * background writeout for the entire + * file. This has consequences for + * range_cyclic semantics (ie. it may + * not be suitable for data integrity + * writeout). + */ + done_index = page->index + 1; + done = 1; + break; + } + } + + /* + * We stop writing back only if we are not doing + * integrity sync. In case of integrity sync we have to + * keep going until we have written all the pages + * we tagged for writeback prior to entering this loop. + */ + if (--wbc->nr_to_write <= 0 && + wbc->sync_mode == WB_SYNC_NONE) { + done = 1; + break; + } + + } + gfs2_trans_end(sdp); + pagevec_release(&pvec); cond_resched(); } -- 2.26.2