From patchwork Fri Nov 16 13:43:04 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Brian Foster X-Patchwork-Id: 10686385 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B3C26109C for ; Fri, 16 Nov 2018 13:43:09 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A450F2BF3B for ; Fri, 16 Nov 2018 13:43:09 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9813F2CF78; Fri, 16 Nov 2018 13:43:09 +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=-2.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_NONE autolearn=unavailable version=3.3.1 Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2FA212BF3B for ; Fri, 16 Nov 2018 13:43:09 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 21FBF6B09C3; Fri, 16 Nov 2018 08:43:08 -0500 (EST) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id 1CED46B09C4; Fri, 16 Nov 2018 08:43:08 -0500 (EST) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 0BDB06B09C5; Fri, 16 Nov 2018 08:43:08 -0500 (EST) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from mail-qk1-f199.google.com (mail-qk1-f199.google.com [209.85.222.199]) by kanga.kvack.org (Postfix) with ESMTP id D45456B09C3 for ; Fri, 16 Nov 2018 08:43:07 -0500 (EST) Received: by mail-qk1-f199.google.com with SMTP id w185so51914850qka.9 for ; Fri, 16 Nov 2018 05:43:07 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-original-authentication-results:x-gm-message-state:from:to :subject:date:message-id; bh=or9H+KPHxX3hdEjA1p0eHFdiEwbFaCuDAVuA2PCHHqE=; b=a+0dGVgt5ei8Tm0M0IbYFQnSltabjpxNQLsRW6GCfhyYtW0+fn5GuPd1TValsNlEXG BUrkpSvLZry9SFjHLEc/dZCCWZgtfippBfnfzEFpy7RCKyIF8//VSvrGuHNkuiKukScV nxCnRi1VMiZaEu++e/5XQ6IP64et5DKyXvG32H9JmZ0nrR7tE+hJdZYQdBdqHRATJ8EV wIR0fPwZB7yvyYR08rZZpiO5xtnPI/jv0X3O1phk/IwzQwZbb6VOHDryRQ43DJWuzLuW 7HDLQvHqcmbnE+G0dezPAK9esulJCfr+wZN7MOHMP45khMxOSL6eNDI8jMeFQYPJFERQ frtA== X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of bfoster@redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=bfoster@redhat.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com X-Gm-Message-State: AGRZ1gKBXowIG5QD5nHt95sJXRRcA7sr31FtG0CxcSjQ9YS3glCzuce6 meTrX/qlOTqx1M+MyRnhAqulbhxctqcCCDQJwl5Wn87+qTz+7T4gOisJ8mrfAttKGZmccPz8WKC R6FwLw+LVY12F7+qfjSf4qv0nH2d+3UgK4hS8bxgNBqmpVI6JSCtld8///TKUEaL5qg== X-Received: by 2002:a37:4e58:: with SMTP id c85mr1815384qkb.27.1542375787542; Fri, 16 Nov 2018 05:43:07 -0800 (PST) X-Google-Smtp-Source: AFSGD/UKAGmNXSxVwrKEETylHs4Wix+Hnm7rviCrf1pl5MDc+Rw4+1pf+CgT5Yc6A0ajXtgq5tmv X-Received: by 2002:a37:4e58:: with SMTP id c85mr1815332qkb.27.1542375786641; Fri, 16 Nov 2018 05:43:06 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1542375786; cv=none; d=google.com; s=arc-20160816; b=Dg0ICk9g5oWIB6oc17L/g1s8lLJY91UXzs9U1CTPPZFwM9xXHcGWQ1lEpqlEUGIXB3 GKCErE10ApoQJgHTlVjmm6R0+gTCOoSLbwQXjb+OYbh+U4dLemVcTnd2ZDARlye9PJJ1 3ygBs/TumR5VHsDzX/H5cComgtYtmamwi7/20oiEhmQt1yd9IWIs9tcZd+oIPh652SZ0 DVPNe+QmUifrGcSTxgi9zyaY/kGj79WbD6TOkxlvJmzRX55cPEEAQzhAMCLRB2OZWVKC dO1eHfjjCeBc0cLLoz2trK1f/kSELbbMZdZTpJdHtexAV8xriYc3RQiLs0+DmfNOknFh tDUw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=message-id:date:subject:to:from; bh=or9H+KPHxX3hdEjA1p0eHFdiEwbFaCuDAVuA2PCHHqE=; b=vMAujVET0x/QntGkPBoOy+VdVwUYsI4JnDlXXTwQYkFKsfuR/xdMimttqY+S91Vyj2 OCidzpdETtfbqszQlc/R9mYzFOCKlG7utcCeXYkVGTH+bcUtYvbFCYIul/DjzVvfLtXB ZxJwVf36qQCJO/IhbYZuCu5kjkAcHU5ZYNZgUZa4WU2WUDNX06y8o51pcfpMpd2K+MFY l/ccqsAc3d6aVdhTS6UkXYyPARbZ9a6XqB47sFNqg5UFvA+GD7Mw8I8Psa6UFeKJvm5k 9VDnRPfBCGToUnXPl64wOn19yJc5tAk0g8J2QxvvOpJKMni6xfEhftXYbFZ7XKg+UAXj R7sA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of bfoster@redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=bfoster@redhat.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: from mx1.redhat.com (mx1.redhat.com. [209.132.183.28]) by mx.google.com with ESMTPS id w2si15075050qta.292.2018.11.16.05.43.06 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 16 Nov 2018 05:43:06 -0800 (PST) Received-SPF: pass (google.com: domain of bfoster@redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; Authentication-Results: mx.google.com; spf=pass (google.com: domain of bfoster@redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=bfoster@redhat.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id A6AF2394D4D; Fri, 16 Nov 2018 13:43:05 +0000 (UTC) Received: from bfoster.bos.redhat.com (dhcp-41-2.bos.redhat.com [10.18.41.2]) by smtp.corp.redhat.com (Postfix) with ESMTP id 192BB600C8; Fri, 16 Nov 2018 13:43:05 +0000 (UTC) From: Brian Foster To: linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-xfs@vger.kernel.org, linux-ext4@vger.kernel.org Subject: [PATCH v2] mm: don't break integrity writeback on ->writepage() error Date: Fri, 16 Nov 2018 08:43:04 -0500 Message-Id: <20181116134304.32440-1-bfoster@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Fri, 16 Nov 2018 13:43:05 +0000 (UTC) X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: X-Virus-Scanned: ClamAV using ClamSMTP The write_cache_pages() function is used in both background and integrity writeback scenarios by various filesystems. Background writeback is mostly concerned with cleaning a certain number of dirty pages based on various mm heuristics. It may not write the full set of dirty pages or wait for I/O to complete. Integrity writeback is responsible for persisting a set of dirty pages before the writeback job completes. For example, an fsync() call must perform integrity writeback to ensure data is on disk before the call returns. write_cache_pages() unconditionally breaks out of its processing loop in the event of a ->writepage() error. This is fine for background writeback, which had no strict requirements and will eventually come around again. This can cause problems for integrity writeback on filesystems that might need to clean up state associated with failed page writeouts. For example, XFS performs internal delayed allocation accounting before returning a ->writepage() error, where applicable. If the current writeback happens to be associated with an unmount and write_cache_pages() completes the writeback prematurely due to error, the filesystem is unmounted in an inconsistent state if dirty+delalloc pages still exist. To handle this problem, update write_cache_pages() to always process the full set of pages for integrity writeback regardless of ->writepage() errors. Save the first encountered error and return it to the caller once complete. This facilitates XFS (or any other fs that expects integrity writeback to process the entire set of dirty pages) to clean up its internal state completely in the event of persistent mapping errors. Background writeback continues to exit on the first error encountered. Signed-off-by: Brian Foster Reviewed-by: Jan Kara --- Here's a v2 with minor enhancenents based on Andrew Morton's feedback. I combined the additional comments with the existing one to avoid having too many multi-indent/multi-line comments in this area. Brian v2: - Dropped unnecessary ->for_sync check. - Added comment and updated commit log description. v1: https://marc.info/?l=linux-fsdevel&m=154143578027082&w=2 mm/page-writeback.c | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/mm/page-writeback.c b/mm/page-writeback.c index 3f690bae6b78..59b4b56d3762 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c @@ -2154,6 +2154,7 @@ int write_cache_pages(struct address_space *mapping, { int ret = 0; int done = 0; + int error; struct pagevec pvec; int nr_pages; pgoff_t uninitialized_var(writeback_index); @@ -2227,25 +2228,31 @@ int write_cache_pages(struct address_space *mapping, goto continue_unlock; trace_wbc_writepage(wbc, inode_to_bdi(mapping->host)); - ret = (*writepage)(page, wbc, data); - if (unlikely(ret)) { - if (ret == AOP_WRITEPAGE_ACTIVATE) { + error = (*writepage)(page, wbc, data); + if (unlikely(error)) { + /* + * Handle errors according to the type of + * writeback. There's no need to continue to for + * background writeback. Just push done_index + * past this page so media errors won't choke + * writeout for the entire file. For integrity + * writeback, we must process the entire dirty + * set regardless of errors because the fs may + * still have state to clear for each page. In + * that case we continue processing and return + * the first error. + */ + if (error == 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). - */ + error = 0; + } else if (wbc->sync_mode != WB_SYNC_ALL) { + ret = error; done_index = page->index + 1; done = 1; break; } + if (!ret) + ret = error; } /*