From patchwork Mon Jul 31 19:11:53 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Golle X-Patchwork-Id: 128857 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:918b:0:b0:3e4:2afc:c1 with SMTP id s11csp2241893vqg; Mon, 31 Jul 2023 13:12:02 -0700 (PDT) X-Google-Smtp-Source: APBJJlG7RDRxF//kNr0iMGqY27Vyc7tXIt1bFvjmtWVCrCQkgrMxW87ezipAD1+/CqOw5aEnOZJ0 X-Received: by 2002:a17:902:c412:b0:1b6:8a99:4979 with SMTP id k18-20020a170902c41200b001b68a994979mr13169009plk.22.1690834321902; Mon, 31 Jul 2023 13:12:01 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1690834321; cv=none; d=google.com; s=arc-20160816; b=inRLf6SzgN2qb1xJJzqGSaKeJG+mphydHNzdMk4Ymi/QeyYvdkH25rcjy1EM4vet/q 1gLqKyQ7H3a+6RYpDy7nMMEKNsqnrH1kh1kguWEs5cpCVB7uG+ORzxQl8X2aumX9e10T Ji6KyUSTObpp0QbkYBG+1bqt6fTvbNR3bKqYQl3EAGm26vyV6pAGqfCwMKL5Pxoo0HZJ ywTiPuxvRTO55TbEwXRjOmntWOFyTCynQ00f6sbu+U9Lw174Vo4/gcklGWFzSwsdr1gG 36fUklEdDMwGVfZFNSjDxujdtTectAAiMOCTwGFSBAyb7uovm70ubOOqdWYpp2ORc78n oqpw== 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=kFGsI/e2yvLWxse1j39HJ6gb+i8cDJSBRhHonL9x+u0=; b=M8196Gid2goTWpxJmHdtPyJiaLt+wiEZviSWZf53aa5Io5KFg0yvMDPEoVfeA97KM3 k9LjAfluMHyTIz1Y+Qp6gw25Sb/g94Erzh8ALcx5QY6M+O6IqUPwDIyvEN8TELVui4Gh x3nRDw15xrtQi5Jb8JYXhMhQPkpL5o8l1gyYyiq9l3rq5J7dkQ8tEFpmf91uRswJoF4R TGPo8HmuXB29KhWPLgEiOadLzSZ/sOqMwfObgZy+Lsj0HngIkyDwsgs0PwhaBsAPNXu5 1TJBsJoUw8sAW0PgSSu/gAMFzrC3coeAR8Mss8UmH+h6Bz+RLmb72CPid2wf4jUlAzb9 xLAg== 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 j1-20020a17090a840100b002612b8cd1dcsi4271890pjn.162.2023.07.31.13.11.48; Mon, 31 Jul 2023 13:12:01 -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 S229915AbjGaTMR (ORCPT + 99 others); Mon, 31 Jul 2023 15:12:17 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48284 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230118AbjGaTMN (ORCPT ); Mon, 31 Jul 2023 15:12:13 -0400 Received: from pidgin.makrotopia.org (pidgin.makrotopia.org [185.142.180.65]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8A1671710 for ; Mon, 31 Jul 2023 12:12:10 -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 1qQYJI-0001hK-2C; Mon, 31 Jul 2023 19:12:06 +0000 Date: Mon, 31 Jul 2023 20:11:53 +0100 From: Daniel Golle To: Richard Weinberger , Miquel Raynal , Vignesh Raghavendra , linux-kernel@vger.kernel.org, linux-mtd@lists.infradead.org Subject: [PATCH 2/6] 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,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: INBOX X-GMAIL-THRID: 1772968289745229844 X-GMAIL-MSGID: 1772968289745229844 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;