From patchwork Fri Mar 27 19:24:15 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dan Ehrenberg X-Patchwork-Id: 455570 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2001:1868:205::9]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id EDF5C1400B6 for ; Sat, 28 Mar 2015 06:26:34 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=fail reason="verification failed; unprotected key" header.d=google.com header.i=@google.com header.b=pg6XVG1i; dkim-adsp=none (unprotected policy); dkim-atps=neutral Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1YbZsM-0000of-HX; Fri, 27 Mar 2015 19:25:02 +0000 Received: from mail-ig0-x22d.google.com ([2607:f8b0:4001:c05::22d]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1YbZsG-0000bQ-Ul for linux-mtd@lists.infradead.org; Fri, 27 Mar 2015 19:24:58 +0000 Received: by igcau2 with SMTP id au2so37313262igc.1 for ; Fri, 27 Mar 2015 12:24:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=ANmZDD/55SDFm5Nthfl/cGCua1+4xqd2MhOTO+7pTr4=; b=pg6XVG1ilcGx+zsv1ol0EZYegS1hCFioTvNl3leFkN0nhNhl6hpMhyn0zbTgpNdJpE zOGg09BroFlf91iaWBQdun7kj4perZbdyYkMs2GosVgArlmPf+vYyaK+YZZVqOFbmibf kO/06QbneGyc4cmf4OjdvcltLazKEVogR/XLF53+8P+f5HHrMPTYmx4vXYtZWL6rNiJS B/VKzRzegxNTS2tQlsdBTzQcll3q6DpcF6jW8KmzsfLBAtcfDxZg74RaARBspg76KZmH DZAVOjkNDkTwza9X5fHYbpeyvf6Iihn81Qd3UZKB1MZ1yghHnx168nRRAHS8WZubPcwm vLkw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=ANmZDD/55SDFm5Nthfl/cGCua1+4xqd2MhOTO+7pTr4=; b=fmyF58RiBoNAK+xA3WPcPhx+woeMvGw45a3pd6q4NTXc+VjzVzMH7ZkGRwzakNOvsM s/Vw/knxOMgx5AnoFluAgmS25MXS4qXWnjYaSoChx31QJZwDz4ktbPLr0kOGyPYnye9h KpFKJeHxqOqqeffHcx56O/HNLxa6oF7X78KPK3+Gerj44pxHlQMFLewDoWckjITqZjTC in/lPBY/MRdeawl+KJTrqicSETfw/a8kO6M5t+bC8fi/fzb5Qah/ZPCU+CnLk4byMHwi qa9Ks4t++ueHMbdg/9gAwBfHoa2Y7Gysrq6Yw1l/dCtfWkrCUwSSUKof7yK5YRyxtxrW xWXA== X-Gm-Message-State: ALoCoQkWIXyTP6zS/oQ7NvJu4d3zupBhk5ysJQIqpMEPSttgLBAUgbgEdOCCBoQR2VVDSdUEwmMK X-Received: by 10.50.119.229 with SMTP id kx5mr610939igb.42.1427484275247; Fri, 27 Mar 2015 12:24:35 -0700 (PDT) Received: from dehrenberg.mtv.corp.google.com ([172.22.65.87]) by mx.google.com with ESMTPSA id qr1sm2229876igb.18.2015.03.27.12.24.33 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 27 Mar 2015 12:24:34 -0700 (PDT) From: Dan Ehrenberg To: computersforpeace@gmail.com, linux-mtd@lists.infradead.org, ezequiel@vanguardiasur.com.ar, Richard Weinberger Subject: [PATCH v3 1/3] mtd: part: Create the master device node when partitioned Date: Fri, 27 Mar 2015 12:24:15 -0700 Message-Id: <1427484257-13708-2-git-send-email-dehrenberg@chromium.org> X-Mailer: git-send-email 2.2.0.rc0.207.ga3a616c In-Reply-To: <1427484257-13708-1-git-send-email-dehrenberg@chromium.org> References: <1427484257-13708-1-git-send-email-dehrenberg@chromium.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20150327_122457_072475_B682BC21 X-CRM114-Status: GOOD ( 23.66 ) X-Spam-Score: -0.7 (/) X-Spam-Report: SpamAssassin version 3.4.0 on bombadil.infradead.org summary: Content analysis details: (-0.7 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low trust [2607:f8b0:4001:c05:0:0:0:22d listed in] [list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record -0.0 T_RP_MATCHES_RCVD Envelope sender domain matches handover relay domain 0.0 HEADER_FROM_DIFFERENT_DOMAINS From and EnvelopeFrom 2nd level mail domains are different 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature Cc: gwendal@chromium.org, Dan Ehrenberg X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org For many use cases, it helps to have a device node for the entire MTD device as well as device nodes for the individual partitions. For example, this allows querying the entire device's properties. A common idiom is to create an additional partition which spans over the whole device. This patch makes a config option, CONFIG_MTD_PARTITIONED_MASTER, which makes the master partition present even when the device is partitioned. This isn't turned on by default since it presents a backwards-incompatible device numbering. The patch also makes the parent of a partition device be the master, if the config flag is set, now that the master is a full device. Signed-off-by: Dan Ehrenberg --- v3: Refactored the mtd_device_parse_register function to make it a bit cleaner drivers/mtd/Kconfig | 13 +++++++++++++ drivers/mtd/mtdcore.c | 52 +++++++++++++++++++++++++++++++++++---------------- drivers/mtd/mtdpart.c | 18 +++++++++++++----- 3 files changed, 62 insertions(+), 21 deletions(-) diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig index 71fea89..a03ad29 100644 --- a/drivers/mtd/Kconfig +++ b/drivers/mtd/Kconfig @@ -309,6 +309,19 @@ config MTD_SWAP The driver provides wear leveling by storing erase counter into the OOB. +config MTD_PARTITIONED_MASTER + bool "Retain master device when partitioned" + default n + depends on MTD + help + For historical reasons, by default, either a master is present or + several partitions are present, but not both. The concern was that + data listed in multiple partitions was dangerous; however, SCSI does + this and it is frequently useful for applications. This config option + leaves the master in even if the device is partitioned. It also makes + the parent of the partition device be the master device, rather than + what lies behind the master. + source "drivers/mtd/chips/Kconfig" source "drivers/mtd/maps/Kconfig" diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index 11883bd..d172195 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -501,6 +502,29 @@ out_error: return ret; } +static int mtd_add_device_partitions(struct mtd_info *mtd, + struct mtd_partition *real_parts, + int nbparts) +{ + int ret; + + if (nbparts == 0 || IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER)) { + ret = add_mtd_device(mtd); + if (ret == 1) + return -ENODEV; + } + + if (nbparts > 0) { + ret = add_mtd_partitions(mtd, real_parts, nbparts); + if (ret && IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER)) + del_mtd_device(mtd); + return ret; + } + + return 0; +} + + /** * mtd_device_parse_register - parse partitions and register an MTD device. * @@ -523,7 +547,8 @@ out_error: * found this functions tries to fallback to information specified in * @parts/@nr_parts. * * If any partitioning info was found, this function registers the found - * partitions. + * partitions. If the MTD_PARTITIONED_MASTER option is set, then the device + * as a whole is registered first. * * If no partitions were found this function just registers the MTD device * @mtd and exits. * @@ -534,27 +559,21 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types, const struct mtd_partition *parts, int nr_parts) { - int err; - struct mtd_partition *real_parts; + int ret; + struct mtd_partition *real_parts = NULL; - err = parse_mtd_partitions(mtd, types, &real_parts, parser_data); - if (err <= 0 && nr_parts && parts) { + ret = parse_mtd_partitions(mtd, types, &real_parts, parser_data); + if (ret <= 0 && nr_parts && parts) { real_parts = kmemdup(parts, sizeof(*parts) * nr_parts, GFP_KERNEL); if (!real_parts) - err = -ENOMEM; + ret = -ENOMEM; else - err = nr_parts; + ret = nr_parts; } - if (err > 0) { - err = add_mtd_partitions(mtd, real_parts, err); - kfree(real_parts); - } else if (err == 0) { - err = add_mtd_device(mtd); - if (err == 1) - err = -ENODEV; - } + if (ret >= 0) + ret = mtd_add_device_partitions(mtd, real_parts, ret); /* * FIXME: some drivers unfortunately call this function more than once. @@ -569,7 +588,8 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types, register_reboot_notifier(&mtd->reboot_notifier); } - return err; + kfree(real_parts); + return ret; } EXPORT_SYMBOL_GPL(mtd_device_parse_register); diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c index e779de3..a19ec5a 100644 --- a/drivers/mtd/mtdpart.c +++ b/drivers/mtd/mtdpart.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "mtdcore.h" @@ -379,10 +380,17 @@ static struct mtd_part *allocate_partition(struct mtd_info *master, slave->mtd.name = name; slave->mtd.owner = master->owner; - /* NOTE: we don't arrange MTDs as a tree; it'd be error-prone - * to have the same data be in two different partitions. + /* NOTE: Historically, we didn't arrange MTDs as a tree out of + * concern for showing the same data in multiple partitions. + * However, it is very useful to have the master node present, + * so the MTD_PARTITIONED_MASTER option allows that. The master + * will have device nodes etc only if this is set, so make the + * parent conditional on that option. Note, this is a way to + * distinguish between the master and the partition in sysfs. */ - slave->mtd.dev.parent = master->dev.parent; + slave->mtd.dev.parent = IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER) ? + &master->dev : + master->dev.parent; slave->mtd._read = part_read; slave->mtd._write = part_write; @@ -631,8 +639,8 @@ EXPORT_SYMBOL_GPL(mtd_del_partition); * and registers slave MTD objects which are bound to the master according to * the partition definitions. * - * We don't register the master, or expect the caller to have done so, - * for reasons of data integrity. + * For historical reasons, this function's caller only registers the master + * if the MTD_PARTITIONED_MASTER config option is set. */ int add_mtd_partitions(struct mtd_info *master,