From patchwork Tue May 2 16:48:23 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Golle X-Patchwork-Id: 89431 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp777950vqo; Tue, 2 May 2023 10:21:47 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ67JDQnI8aV5WUpEmSt9CBoVlYD+kwdBBZVOidnkrMmoZTsNeGq3Pobh2o/jRsERUyOQ3Yc X-Received: by 2002:a05:6a00:14d1:b0:63b:8df5:f8d with SMTP id w17-20020a056a0014d100b0063b8df50f8dmr29639624pfu.3.1683048106755; Tue, 02 May 2023 10:21:46 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1683048106; cv=none; d=google.com; s=arc-20160816; b=znfIIMoXv9Ew55eFgs2CA51Z4On+nMewJhrq5n/yW4eteBM9LdGVBacSKUs/NYOVdl QRbUU1XF7DbX0votYfgDG+mlLuty9exQFJofiO17pc0+YFxnmjh4IQK2Rj/ssbUz2qMu ySVHPU/SPjE43aLnYa7TfPpX10cLrjRuwsOhYE2btENO8lVlfAQnxELaW6pOlqwCfk/8 TQiELgSugUpjrKM8Z2IbTSgR3C8LwcdxnySrvDmg64qfn1wv7AWY+anYUXwzWMqN1/2j kHCdbF7JIQgZMW/T+pl01A/eqNQnyRzq6JsAQ5S2U839szqRNZh179ujkvfBGd/NI9wF YrYw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:in-reply-to:content-disposition:mime-version :references:message-id:subject:to:from:date; bh=/i0rZ0ExOGMbyFWeG3s/rRav7Gohip265Q7lUb0gKck=; b=Mv8fqp869BoYpGbFYN4c6QS5pX9koV2k7Hs0eE9n0FFG3vpwjkXQ2q5VPU1EgViuSP Lgft2LxGBVEys63imdyj6q5TsAJFz8HyNn/jBu+IOmgFGiOkpNMKt/yLid1lsmwGPfUK hSU2899LFJt8dQIGcfCIasznN95fnGVJCOAPjiHoucOcrKu9UWRKcSWkm458j91EuD5a B6eE1calebnh9LoiJGskB5KUUpAK5OscdOqHVU3E5xqdVbEhKei/et3O4gJKHkcSu05V ON4OwxuQqDM7PNq9pc+2DGWZODwDQbi5jGd26+xscPOF2RM0V9wG92pfweNJ/1/3AiOT ajVw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id k4-20020aa79984000000b0063b8982c669si30534580pfh.317.2023.05.02.10.21.34; Tue, 02 May 2023 10:21:46 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233730AbjEBQsf (ORCPT + 99 others); Tue, 2 May 2023 12:48:35 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36876 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233608AbjEBQse (ORCPT ); Tue, 2 May 2023 12:48:34 -0400 Received: from fudo.makrotopia.org (fudo.makrotopia.org [IPv6:2a07:2ec0:3002::71]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 76597212E for ; Tue, 2 May 2023 09:48:30 -0700 (PDT) Received: from local by fudo.makrotopia.org with esmtpsa (TLS1.3:TLS_AES_256_GCM_SHA384:256) (Exim 4.96) (envelope-from ) id 1pttAy-0000Us-1h; Tue, 02 May 2023 18:48:28 +0200 Date: Tue, 2 May 2023 17:48:23 +0100 From: Daniel Golle To: linux-mtd@lists.infradead.org, linux-kernel@vger.kernel.org, Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Zhihao Cheng Subject: [PATCH 2/4] mtd: ubi: block: use notifier to create ubiblock from parameter Message-ID: <726b7629d0819092edeb193f3bfc13c99bd13339.1683043928.git.daniel@makrotopia.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,SPF_HELO_NONE, SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1764803851411068034?= X-GMAIL-MSGID: =?utf-8?q?1764803851411068034?= Use UBI_VOLUME_ADDED notification to create ubiblock device specified on kernel cmdline or module parameter. This makes things more simple and has the advantage that ubiblock devices on volumes which are not present at the time the ubi module is probed will still be created. Suggested-by: Zhihao Cheng Signed-off-by: Daniel Golle --- drivers/mtd/ubi/block.c | 150 ++++++++++++++++++++++------------------ 1 file changed, 82 insertions(+), 68 deletions(-) diff --git a/drivers/mtd/ubi/block.c b/drivers/mtd/ubi/block.c index 6f5804f4b8f55..7f3024bddf306 100644 --- a/drivers/mtd/ubi/block.c +++ b/drivers/mtd/ubi/block.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -65,10 +66,10 @@ struct ubiblock_pdu { }; /* Numbers of elements set in the @ubiblock_param array */ -static int ubiblock_devs __initdata; +static int ubiblock_devs; /* MTD devices specification parameters */ -static struct ubiblock_param ubiblock_param[UBIBLOCK_MAX_DEVICES] __initdata; +static struct ubiblock_param ubiblock_param[UBIBLOCK_MAX_DEVICES]; struct ubiblock { struct ubi_volume_desc *desc; @@ -533,6 +534,83 @@ static int ubiblock_resize(struct ubi_volume_info *vi) return 0; } +static bool +match_volume_desc(struct ubi_volume_info *vi, const char *name, int ubi_num, int vol_id) +{ + int err, len; + struct path path; + struct kstat stat; + + if (ubi_num == -1) { + /* No ubi num, name must be a vol device path */ + err = kern_path(name, LOOKUP_FOLLOW, &path); + if (err) + return false; + + err = vfs_getattr(&path, &stat, STATX_TYPE, AT_STATX_SYNC_AS_STAT); + path_put(&path); + if (err) + return false; + + if (!S_ISCHR(stat.mode)) + return false; + + if (vi->ubi_num != ubi_major2num(MAJOR(stat.rdev))) + return false; + + if (vi->vol_id != MINOR(stat.rdev) - 1) + return false; + + return true; + } else if (vol_id == -1) { + if (vi->ubi_num != ubi_num) + return false; + + len = strnlen(name, UBI_VOL_NAME_MAX + 1); + if (len < 1 || vi->name_len != len) + return false; + + if (strcmp(name, vi->name)) + return false; + + return true; + } else { + if (vi->ubi_num != ubi_num) + return false; + + if (vi->vol_id != vol_id) + return false; + + return true; + } +} + +static void +ubiblock_create_from_param(struct ubi_volume_info *vi) +{ + int i, ret = 0; + struct ubiblock_param *p; + + /* + * Iterate over ubiblock cmdline parameters. If a parameter matches the + * newly added volume create the ubiblock device for it. + */ + for (i = 0; i < ubiblock_devs; i++) { + p = &ubiblock_param[i]; + + if (!match_volume_desc(vi, p->name, p->ubi_num, p->vol_id)) + continue; + + ret = ubiblock_create(vi); + if (ret) { + pr_err( + "UBI: block: can't add '%s' volume on ubi%d_%d, err=%d\n", + vi->name, p->ubi_num, p->vol_id, ret); + } + break; + } +} + static int ubiblock_notify(struct notifier_block *nb, unsigned long notification_type, void *ns_ptr) { @@ -540,10 +618,7 @@ static int ubiblock_notify(struct notifier_block *nb, switch (notification_type) { case UBI_VOLUME_ADDED: - /* - * We want to enforce explicit block device creation for - * volumes, so when a volume is added we do nothing. - */ + ubiblock_create_from_param(&nt->vi); break; case UBI_VOLUME_REMOVED: ubiblock_remove(&nt->vi, true); @@ -569,56 +644,6 @@ static struct notifier_block ubiblock_notifier = { .notifier_call = ubiblock_notify, }; -static struct ubi_volume_desc * __init -open_volume_desc(const char *name, int ubi_num, int vol_id) -{ - if (ubi_num == -1) - /* No ubi num, name must be a vol device path */ - return ubi_open_volume_path(name, UBI_READONLY); - else if (vol_id == -1) - /* No vol_id, must be vol_name */ - return ubi_open_volume_nm(ubi_num, name, UBI_READONLY); - else - return ubi_open_volume(ubi_num, vol_id, UBI_READONLY); -} - -static void __init ubiblock_create_from_param(void) -{ - int i, ret = 0; - struct ubiblock_param *p; - struct ubi_volume_desc *desc; - struct ubi_volume_info vi; - - /* - * If there is an error creating one of the ubiblocks, continue on to - * create the following ubiblocks. This helps in a circumstance where - * the kernel command-line specifies multiple block devices and some - * may be broken, but we still want the working ones to come up. - */ - for (i = 0; i < ubiblock_devs; i++) { - p = &ubiblock_param[i]; - - desc = open_volume_desc(p->name, p->ubi_num, p->vol_id); - if (IS_ERR(desc)) { - pr_err( - "UBI: block: can't open volume on ubi%d_%d, err=%ld\n", - p->ubi_num, p->vol_id, PTR_ERR(desc)); - continue; - } - - ubi_get_volume_info(desc, &vi); - ubi_close_volume(desc); - - ret = ubiblock_create(&vi); - if (ret) { - pr_err( - "UBI: block: can't add '%s' volume on ubi%d_%d, err=%d\n", - vi.name, p->ubi_num, p->vol_id, ret); - continue; - } - } -} - static void ubiblock_remove_all(void) { struct ubiblock *next; @@ -644,18 +669,7 @@ int __init ubiblock_init(void) if (ubiblock_major < 0) return ubiblock_major; - /* - * Attach block devices from 'block=' module param. - * Even if one block device in the param list fails to come up, - * still allow the module to load and leave any others up. - */ - ubiblock_create_from_param(); - - /* - * Block devices are only created upon user requests, so we ignore - * existing volumes. - */ - ret = ubi_register_volume_notifier(&ubiblock_notifier, 1); + ret = ubi_register_volume_notifier(&ubiblock_notifier, 0); if (ret) goto err_unreg; return 0;