From patchwork Wed May 9 07:48:23 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 10388491 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id D2D98602C2 for ; Wed, 9 May 2018 07:50:29 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C1E9028E68 for ; Wed, 9 May 2018 07:50:29 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B59BC28E73; Wed, 9 May 2018 07:50:29 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI, T_DKIM_INVALID autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 47DF228E05 for ; Wed, 9 May 2018 07:50:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933908AbeEIHuX (ORCPT ); Wed, 9 May 2018 03:50:23 -0400 Received: from bombadil.infradead.org ([198.137.202.133]:53448 "EHLO bombadil.infradead.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933383AbeEIHuW (ORCPT ); Wed, 9 May 2018 03:50:22 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20170209; h=References:In-Reply-To:Message-Id: Date:Subject:Cc:To:From:Sender:Reply-To:MIME-Version:Content-Type: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id: List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=XQFecbGfWJn42kds14m3l+TmQWegQHWexXUSZ/G9v74=; b=Hn9ESU26uFtMe/R2Zv1hQUadL 8mr2Q50JrvOlRK7FMhfaCpzM2QcOL17oEYkpDXHQvTi6PZkctdJIT6dRA6SN0vRlH1axc9QHnsZ7q APbeY5JPFxf28K37+oWXceHW/rV6r2k1i319oSjAaXK+m9eFzcN0YE91pIpWzb7OtGxUmzMNa/KxP bveGCXho7adJmlUIlWhVBxvhkBFeJDg3vYunGkZuSQImSXn1TW2rkOHbw1Vm0Y1QMNR6E0n5nvhCl G+meFVKdK07hnG7zeF9wKPlRBDdzC2igaixs5pZZdcj58ZMuXYywWYsSl9UevF65RknO7qWJgtI88 7AKP2geBA==; Received: from 213-225-15-246.nat.highway.a1.net ([213.225.15.246] helo=localhost) by bombadil.infradead.org with esmtpsa (Exim 4.90_1 #2 (Red Hat Linux)) id 1fGJrZ-0002A3-9h; Wed, 09 May 2018 07:50:13 +0000 From: Christoph Hellwig To: linux-xfs@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org, linux-block@vger.kernel.org, linux-mm@kvack.org Subject: [PATCH 26/33] xfs: allow writeback on pages without buffer heads Date: Wed, 9 May 2018 09:48:23 +0200 Message-Id: <20180509074830.16196-27-hch@lst.de> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180509074830.16196-1-hch@lst.de> References: <20180509074830.16196-1-hch@lst.de> X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org. See http://www.infradead.org/rpr.html Sender: linux-xfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP We'll soon allow these through changes in the iomap write_begin and page_mkwrite implementations, so get ready for them. After the previous refactoring this is as simple as not maintaining the bh variable if the page doesn' thave private data, and skipping the non-uptodate buffer check in this case for the writepage path, and adding a new per-page I/O completion handler that skips all buffer head manipulation. Signed-off-by: Christoph Hellwig --- fs/xfs/xfs_aops.c | 47 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 34 insertions(+), 13 deletions(-) diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index c76c943473be..879599f723b6 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -91,6 +91,19 @@ xfs_find_daxdev_for_inode( return mp->m_ddev_targp->bt_daxdev; } +static void +xfs_finish_page_writeback( + struct inode *inode, + struct bio_vec *bvec, + int error) +{ + if (error) { + SetPageError(bvec->bv_page); + mapping_set_error(inode->i_mapping, -EIO); + } + end_page_writeback(bvec->bv_page); +} + /* * We're now finished for good with this page. Update the page state via the * associated buffer_heads, paying attention to the start and end offsets that @@ -103,7 +116,7 @@ xfs_find_daxdev_for_inode( * and buffers potentially freed after every call to end_buffer_async_write. */ static void -xfs_finish_page_writeback( +xfs_finish_buffer_writeback( struct inode *inode, struct bio_vec *bvec, int error) @@ -178,9 +191,12 @@ xfs_destroy_ioend( next = bio->bi_private; /* walk each page on bio, ending page IO on them */ - bio_for_each_segment_all(bvec, bio, i) - xfs_finish_page_writeback(inode, bvec, error); - + bio_for_each_segment_all(bvec, bio, i) { + if (page_has_buffers(bvec->bv_page)) + xfs_finish_buffer_writeback(inode, bvec, error); + else + xfs_finish_page_writeback(inode, bvec, error); + } bio_put(bio); } @@ -816,7 +832,7 @@ xfs_writepage_map( { LIST_HEAD(submit_list); struct xfs_ioend *ioend, *next; - struct buffer_head *bh; + struct buffer_head *bh = NULL; ssize_t len = i_blocksize(inode); int error = 0; int count = 0; @@ -824,6 +840,9 @@ xfs_writepage_map( loff_t file_offset; /* file offset of page */ unsigned poffset; /* offset into page */ + if (page_has_buffers(page)) + bh = page_buffers(page); + /* * Walk the blocks on the page, and we we run off then end of the * current map or find the current map invalid, grab a new one. @@ -832,11 +851,9 @@ xfs_writepage_map( * replace the bufferhead with some other state tracking mechanism in * future. */ - file_offset = page_offset(page); - bh = page_buffers(page); - for (poffset = 0; + for (poffset = 0, file_offset = page_offset(page); poffset < PAGE_SIZE; - poffset += len, file_offset += len, bh = bh->b_this_page) { + poffset += len, file_offset += len) { /* past the range we are writing, so nothing more to write. */ if (file_offset >= end_offset) break; @@ -844,10 +861,11 @@ xfs_writepage_map( /* * Block does not contain valid data, skip it. */ - if (!buffer_uptodate(bh)) { + if (bh && !buffer_uptodate(bh)) { if (PageUptodate(page)) ASSERT(buffer_mapped(bh)); uptodate = false; + bh = bh->b_this_page; continue; } @@ -872,10 +890,15 @@ xfs_writepage_map( * meaningless for holes (!mapped && uptodate), so check we did * have a buffer covering a hole here and continue. */ + if (bh) + bh = bh->b_this_page; continue; } - xfs_map_at_offset(inode, bh, &wpc->imap, file_offset); + if (bh) { + xfs_map_at_offset(inode, bh, &wpc->imap, file_offset); + bh = bh->b_this_page; + } xfs_add_to_ioend(inode, file_offset, page, wpc, wbc, &submit_list); count++; @@ -960,8 +983,6 @@ xfs_do_writepage( trace_xfs_writepage(inode, page, 0, 0); - ASSERT(page_has_buffers(page)); - /* * Refuse to write the page out if we are called from reclaim context. *