Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp5125560imu; Tue, 8 Jan 2019 12:00:39 -0800 (PST) X-Google-Smtp-Source: ALg8bN5JQ4AjO1E+/q9AOee6YHL0D0mMg4qbMtH7PjkhvUF91uVV4Zh/z21PrOAP7jaDMOChvgbq X-Received: by 2002:a17:902:47aa:: with SMTP id r39mr3075104pld.219.1546977639730; Tue, 08 Jan 2019 12:00:39 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1546977639; cv=none; d=google.com; s=arc-20160816; b=0PukRbF2KOcCyXqdlZ4h+J8oHymHc2hrO9SH0IMjK1WqyntWOplm5OBjsH2ouVPUQh ixKEICja8r/qOgpqLR0mB9gRHBjIlL+kVcfEDaWHRy4o8NAd+j4wBV6EaWaXudmAqh/J osi9hKDfuNGs7em6sbhNngBQcvfHB8haP86HnoLrE4FGgr5ssOH8x/I/x9IlctPhCzqH seRCz+Z1/IxlbsibYFePhHyUqVb7ZtjjSYMhguUNJGaOQqBz4OEHxBLjW8z5I76VCbl4 ivUZ391VsTpJCzmMmz3/dvRY7Gr4IzSh+k9pqafsg6Rh/5XPSin35mz7EWPzVffUvxku izrA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=WETC0hGp79aQ+l97joKok7f2RKsfFKgKNMeMnGBR/uM=; b=W9shKqL5KfSdukgoZBLk5h2AsKr7oFzo9zwEGuumpMRCOgTBGXEN0hDWSTTsYLHXI7 4GFDftgSSBuSci7CvQTqB/8wCHMmxoHbcMfxZJnUIXlY/6IiFb+lI7Z4bLxJrnbMrsmr HTOHCvDUlKKUZle0wdG0UYZq/LACHcj4NmH7vKUBFoODRFJQtJJHtUD0UaMrsCxTZGca i0ngbO3BwlKBdnVbpNlfZktZbEXLxHLdDcy70gvThqqRMwXqAAF66CF9Q2TOxVr6AQvh 9bgaXIqfLCd6kHee3biuOpeFswpZrZpTOOcOFu5PRoyoWHG1L/4Ql0FB3SgI+BeVOGuW 5vrA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=u1rH9mBz; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 82si27834416pfa.115.2019.01.08.12.00.22; Tue, 08 Jan 2019 12:00:39 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=u1rH9mBz; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731105AbfAHT6b (ORCPT + 99 others); Tue, 8 Jan 2019 14:58:31 -0500 Received: from mail.kernel.org ([198.145.29.99]:37012 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730431AbfAHT3e (ORCPT ); Tue, 8 Jan 2019 14:29:34 -0500 Received: from sasha-vm.mshome.net (c-73-47-72-35.hsd1.nh.comcast.net [73.47.72.35]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id D698620827; Tue, 8 Jan 2019 19:29:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1546975773; bh=KKE87vKhUUlTRn2Ex7cq6LzrtuakMaOHZ96sDL95GGU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=u1rH9mBzomm7a4jJI72KjfFjHE7Zj8E4EsDrDIQTwpFUfHQVWzOU5/ZehrB4I+K9j GErmxZgU2ZK3tsrFVW5QETyb6/nVus9j5lZluQwWORtXD/XyCa9BaKKuuQOsP+LaBF 6dN4mhCjAm5XTqhDHh9NoBVS/MPoipJ2C9/Lm8uk= From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Brian Foster , Andrew Morton , Linus Torvalds , Sasha Levin , linux-mm@kvack.org Subject: [PATCH AUTOSEL 4.20 113/117] mm/page-writeback.c: don't break integrity writeback on ->writepage() error Date: Tue, 8 Jan 2019 14:26:21 -0500 Message-Id: <20190108192628.121270-113-sashal@kernel.org> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20190108192628.121270-1-sashal@kernel.org> References: <20190108192628.121270-1-sashal@kernel.org> MIME-Version: 1.0 X-Patchwork-Hint: Ignore Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Brian Foster [ Upstream commit 3fa750dcf29e8606e3969d13d8e188cc1c0f511d ] write_cache_pages() 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. [akpm@linux-foundation.org: fix typo in comment] Link: http://lkml.kernel.org/r/20181116134304.32440-1-bfoster@redhat.com Signed-off-by: Brian Foster Reviewed-by: Jan Kara Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Sasha Levin --- 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..7d1010453fb9 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 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; } /* -- 2.19.1