Received: by 2002:ac0:a5a7:0:0:0:0:0 with SMTP id m36-v6csp2032193imm; Tue, 10 Jul 2018 11:59:01 -0700 (PDT) X-Google-Smtp-Source: AAOMgpcS1kdNpzjMJYND13aiiQ9ieS/WV+csv7HwkHn/U9d3LCziStO0tm7UfnglSgycJ742CZim X-Received: by 2002:a65:48cd:: with SMTP id o13-v6mr22949621pgs.99.1531249141849; Tue, 10 Jul 2018 11:59:01 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1531249141; cv=none; d=google.com; s=arc-20160816; b=Yt1osG9Lin5u6w4F4TxDr0938GzPZRhjiZtduLRr4HSi+b4K+u04A1KAkF52gnpWt9 ZDbMP2D+9f20i54mMua138sEMuAhocDmWx7nOisjRxkNZmWlixS60KtpSWHAynnzlf6/ yM8jeWJB2yEZFEAIpWQ8OboXhdUtxAxZ45ezFS6UrwMcFkFXa3r7IPA3VOOL1ORNa5+H IMt7GJt6XsqlmgpIMs/CRjvLR3dlqo+RD3wJ3bYUQpWHB1kC7csDWMloI+qAZ6gyPNXh hRAAaeenaTyBXwsF+Ai+5W5aUq7QxcftI7DEG8B2A/dLDnAV3pnbXQO99At07PK8cNHh SYOg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:user-agent:references :in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=JTrOzZlLpnl7j31BEOIFrNvBwTghc5B3YddiBm3VGfA=; b=aIp3OyPzJW0PikCjNOAmRkE1mGMyV7PBCJ0LC5GO2PiM+1MIKRhZRXWmy2FSPtVgrV FNbOJgco+QTV4upTTXb2AaEd2qjMGTKAHzxy0T3UMxCpkSJkf54LrAQkj/KYf0xYjC8Y lbK8HOMsA5GtNNTNfh6UAxoqBWWMVUdmUxx3ln/XZqVU9bK1aWQKOR6CJX0jhkTaOg/h ErT1eBv+lSXRVQp2mzvGwne5qcP4phApwEjnI6KSfGVbmbs3arH5um4EajyJnOxXJhJB lqf1Zf44K4UZMsz6jH69/RNOEdVY8mZL8xGGK+t1bqQzt4NsqdLHWQ6J0jQYIGAr0t6a RJfQ== ARC-Authentication-Results: i=1; mx.google.com; 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 Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id x3-v6si4140352pgg.347.2018.07.10.11.58.46; Tue, 10 Jul 2018 11:59:01 -0700 (PDT) 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; 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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732662AbeGJS0G (ORCPT + 99 others); Tue, 10 Jul 2018 14:26:06 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:43616 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1732630AbeGJS0F (ORCPT ); Tue, 10 Jul 2018 14:26:05 -0400 Received: from localhost (LFbn-1-12247-202.w90-92.abo.wanadoo.fr [90.92.61.202]) by mail.linuxfoundation.org (Postfix) with ESMTPSA id 71F13E74; Tue, 10 Jul 2018 18:25:54 +0000 (UTC) From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, martin bayern , Richard Weinberger Subject: [PATCH 3.18 04/23] ubi: fastmap: Correctly handle interrupted erasures in EBA Date: Tue, 10 Jul 2018 20:24:37 +0200 Message-Id: <20180710182309.068147079@linuxfoundation.org> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180710182308.877332304@linuxfoundation.org> References: <20180710182308.877332304@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 3.18-stable review patch. If anyone has any objections, please let me know. ------------------ From: Richard Weinberger commit 781932375ffc6411713ee0926ccae8596ed0261c upstream. Fastmap cannot track the LEB unmap operation, therefore it can happen that after an interrupted erasure the mapping still looks good from Fastmap's point of view, while reading from the PEB will cause an ECC error and confuses the upper layer. Instead of teaching users of UBI how to deal with that, we read back the VID header and check for errors. If the PEB is empty or shows ECC errors we fixup the mapping and schedule the PEB for erasure. Fixes: dbb7d2a88d2a ("UBI: Add fastmap core") Cc: Reported-by: martin bayern Signed-off-by: Richard Weinberger Signed-off-by: Greg Kroah-Hartman --- drivers/mtd/ubi/eba.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 91 insertions(+), 1 deletion(-) --- a/drivers/mtd/ubi/eba.c +++ b/drivers/mtd/ubi/eba.c @@ -350,6 +350,82 @@ out_unlock: return err; } +#ifdef CONFIG_MTD_UBI_FASTMAP +/** + * check_mapping - check and fixup a mapping + * @ubi: UBI device description object + * @vol: volume description object + * @lnum: logical eraseblock number + * @pnum: physical eraseblock number + * + * Checks whether a given mapping is valid. Fastmap cannot track LEB unmap + * operations, if such an operation is interrupted the mapping still looks + * good, but upon first read an ECC is reported to the upper layer. + * Normaly during the full-scan at attach time this is fixed, for Fastmap + * we have to deal with it while reading. + * If the PEB behind a LEB shows this symthom we change the mapping to + * %UBI_LEB_UNMAPPED and schedule the PEB for erasure. + * + * Returns 0 on success, negative error code in case of failure. + */ +static int check_mapping(struct ubi_device *ubi, struct ubi_volume *vol, int lnum, + int *pnum) +{ + int err; + struct ubi_vid_hdr *vid_hdr; + + if (!ubi->fast_attach) + return 0; + + vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); + if (!vid_hdr) + return -ENOMEM; + + err = ubi_io_read_vid_hdr(ubi, *pnum, vid_hdr, 0); + if (err > 0 && err != UBI_IO_BITFLIPS) { + int torture = 0; + + switch (err) { + case UBI_IO_FF: + case UBI_IO_FF_BITFLIPS: + case UBI_IO_BAD_HDR: + case UBI_IO_BAD_HDR_EBADMSG: + break; + default: + ubi_assert(0); + } + + if (err == UBI_IO_BAD_HDR_EBADMSG || err == UBI_IO_FF_BITFLIPS) + torture = 1; + + down_read(&ubi->fm_sem); + vol->eba_tbl[lnum] = UBI_LEB_UNMAPPED; + up_read(&ubi->fm_sem); + ubi_wl_put_peb(ubi, vol->vol_id, lnum, *pnum, torture); + + *pnum = UBI_LEB_UNMAPPED; + } else if (err < 0) { + ubi_err("unable to read VID header back from PEB %i: %i", + *pnum, err); + + goto out_free; + } + + err = 0; + +out_free: + ubi_free_vid_hdr(ubi, vid_hdr); + + return err; +} +#else +static int check_mapping(struct ubi_device *ubi, struct ubi_volume *vol, int lnum, + int *pnum) +{ + return 0; +} +#endif + /** * ubi_eba_read_leb - read data. * @ubi: UBI device description object @@ -381,7 +457,13 @@ int ubi_eba_read_leb(struct ubi_device * return err; pnum = vol->eba_tbl[lnum]; - if (pnum < 0) { + if (pnum >= 0) { + err = check_mapping(ubi, vol, lnum, &pnum); + if (err < 0) + goto out_unlock; + } + + if (pnum == UBI_LEB_UNMAPPED) { /* * The logical eraseblock is not mapped, fill the whole buffer * with 0xFF bytes. The exception is static volumes for which @@ -627,6 +709,14 @@ int ubi_eba_write_leb(struct ubi_device pnum = vol->eba_tbl[lnum]; if (pnum >= 0) { + err = check_mapping(ubi, vol, lnum, &pnum); + if (err < 0) { + leb_write_unlock(ubi, vol_id, lnum); + return err; + } + } + + if (pnum >= 0) { dbg_eba("write %d bytes at offset %d of LEB %d:%d, PEB %d", len, offset, vol_id, lnum, pnum);