From patchwork Sat Aug 5 16:25:39 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Golle X-Patchwork-Id: 131513 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:c44e:0:b0:3f2:4152:657d with SMTP id w14csp567973vqr; Sat, 5 Aug 2023 10:42:51 -0700 (PDT) X-Google-Smtp-Source: AGHT+IGEi06SYaKdYVdZWzgn0avMenq4ntV4tmgZaON7Zk36U/AdimsIB8kH5tTFFWbAq4TXnhq/ X-Received: by 2002:a17:907:7708:b0:982:45ca:ac06 with SMTP id kw8-20020a170907770800b0098245caac06mr4205756ejc.60.1691257371211; Sat, 05 Aug 2023 10:42:51 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1691257371; cv=none; d=google.com; s=arc-20160816; b=njtQpTSPN6hG+6l/S8dQBBPdtJNJUcV1ZE8CmZ7jsDMIfAIZvUI6CO5gdt+XoSb2oW soXEnBidRAPo3TE2ppdxGULJj4v0wRgEhoIB70uZ+h21olDoSEd7EmxHwKp4ZKH3eU7j zMFhpd1a6Xc2rq/bxnoYGY9VGqycRQHMfMGM8wq1cfxQCBtZiOxqEIXZRLpCOxQ0xRXt NkfnTMk2Dmnq5i2Wz251lWzNfLddSQA8cZGVexOesJ8Ii83AEfagGvv1Rc5ay3Axv3sA ZtV0GDJTfJM5n6Yx/0MrdMBK2/HXHs6RlyFHDjar7K1+GSGpk0T8NlOjbrcELnj+xjkG o/WQ== 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=gyt4xAsIrq5txTp5OjpxkNoVi3HwSGUGngOZAnCrLkE=; fh=WrF5P4rt5GKLKZXFPrBfHwP5VFIZG8GPN/h4vsvn4l4=; b=Lk/VbbA56BTS/Kv9LMw+9EHmcFmRtNHbOkTjVRCOP3L/X8pTCV0Y+j5wxjWZnfLooi feHS0hYri4IYstB1tpBBzwbWsMAoUdfm8/EqxbucCoUzBraN/oO3FGhVtkIzABQdjKLW liY5DCeq2ECLD0tB/mk7Go9RLkyJApFbqYhsWUYtBczM4sBSmS9r4Zi1whKLLzCvbdA0 xNSsx/N3FAAzkdoQlOLF2TRwDOUEiGbzcuDoAL/5z7tjevUIzQGTdX41uTUImGOJOCkB 20MaX5VUfTITh//65OxPFXszJPQnHsnhbVifk6AmgJ8V5QelGS7uJmGokXHv/TsFEhgh D7vw== 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 k15-20020a1709065fcf00b0099cb60f1905si1419229ejv.263.2023.08.05.10.42.25; Sat, 05 Aug 2023 10:42:51 -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 S229514AbjHEQZw (ORCPT + 99 others); Sat, 5 Aug 2023 12:25:52 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38932 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229436AbjHEQZv (ORCPT ); Sat, 5 Aug 2023 12:25:51 -0400 Received: from pidgin.makrotopia.org (pidgin.makrotopia.org [185.142.180.65]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 85FCECD for ; Sat, 5 Aug 2023 09:25:50 -0700 (PDT) Received: from local by pidgin.makrotopia.org with esmtpsa (TLS1.3:TLS_AES_256_GCM_SHA384:256) (Exim 4.96) (envelope-from ) id 1qSK66-0000eW-29; Sat, 05 Aug 2023 16:25:46 +0000 Date: Sat, 5 Aug 2023 17:25:39 +0100 From: Daniel Golle To: Randy Dunlap , Richard Weinberger , Miquel Raynal , Vignesh Raghavendra , linux-kernel@vger.kernel.org, linux-mtd@lists.infradead.org Subject: [PATCH v2 3/7] mtd: ubi: block: use notifier to create ubiblock from parameter Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_BLOCKED,SPF_HELO_NONE,SPF_PASS 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: INBOX X-GMAIL-THRID: 1773411889223622537 X-GMAIL-MSGID: 1773411889223622537 Use UBI_VOLUME_ADDED notification to create ubiblock device specified on kernel cmdline or module parameter. This makes thing 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 | 152 ++++++++++++++++++++++------------------ 1 file changed, 84 insertions(+), 68 deletions(-) diff --git a/drivers/mtd/ubi/block.c b/drivers/mtd/ubi/block.c index 69fa6fecb8494..e0618bbde3613 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; @@ -532,6 +533,85 @@ 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; + } + + 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; + } + + 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) { @@ -539,10 +619,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); @@ -568,56 +645,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; @@ -643,18 +670,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;