Received: by 2002:a6b:500f:0:0:0:0:0 with SMTP id e15csp855176iob; Thu, 12 May 2022 06:11:18 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyYjXoIX0CjPWaXHIlODbqQNTlDsMQSYtfOXic0lpmblmErmSI/bLFtRA2lOvfK4sueH78Q X-Received: by 2002:a05:6602:27cc:b0:5f0:876e:126b with SMTP id l12-20020a05660227cc00b005f0876e126bmr13688316ios.129.1652361077964; Thu, 12 May 2022 06:11:17 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1652361077; cv=none; d=google.com; s=arc-20160816; b=uTdHCFRrN3JSpfa3YktIuLIDOQBLD+UEmJZ0In0sMlbxXo8E8AnCw5VyjV1FmcFbgn LcTErF5m7iR0/Jk3TzIWvZAiQOyPJOqHZEc5XULqOHwT/6LfSodOep/1mNWwDwiVZDK3 SSwN49Of55xtmw0c5opayPUwnuaB8ojWJCsFnBDYcQG6969gzXWmsY6YAz+b8k3sC0en BaF+pdqnm1Coe0p0fKdncXPZfEWQ3ZcZ9Eba3uSn69pK1F5SC9g3pNnTrAbYZyBQoG6K 8FgyA4Fnb6NGwA1Nrb8uVReSELZ/QRiApGOGyhmgTwB+mDsNkvO5pxqZ50LS8lUlfKz1 yaTg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from; bh=fldUsR3hxk7VZnP7cdl4ixbTDzPRhUFkslPzWxbyoyI=; b=OF1csYfMWr+5NR8OIhckC8lofPRXbj73PegOgVLM5Ml5mXIFIltiQ0RkOP+IieWCUb M0w6uezfmJHLlGyb5h3ol2BywkzIPW9NKJxjns4f4DAsbZU6YIKWEDTkmdYxE1LTiOEi qyuETngTdE4EmJKkwhNyPgMsRwALm/aDuvtsQF56VYl8Dl5VZb6z6HEB6taRk10DQF4C Vzch/86qWUV0pImkzxmAsmuC9AW9J1Zu+bK0X/kYC2hSlexfI5zY/Jc9Z12AQHL2+A/F fS9/5GNcupGXiwWpAA/qp7j6b3O8I/z/vd4wuR/RSfZrRhlpXB3jyqYzGLvTEKxGWWP7 N3eA== 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=alibaba.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id e11-20020a92d74b000000b002cd9182384asi4839939ilq.91.2022.05.12.06.11.04; Thu, 12 May 2022 06:11:17 -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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=alibaba.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1350023AbiELF4H (ORCPT + 99 others); Thu, 12 May 2022 01:56:07 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40624 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237798AbiELF4G (ORCPT ); Thu, 12 May 2022 01:56:06 -0400 Received: from out30-44.freemail.mail.aliyun.com (out30-44.freemail.mail.aliyun.com [115.124.30.44]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3B17A20F4C for ; Wed, 11 May 2022 22:56:04 -0700 (PDT) X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R391e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=e01e04426;MF=jefflexu@linux.alibaba.com;NM=1;PH=DS;RN=4;SR=0;TI=SMTPD_---0VCzTOIt_1652334961; Received: from localhost(mailfrom:jefflexu@linux.alibaba.com fp:SMTPD_---0VCzTOIt_1652334961) by smtp.aliyun-inc.com(127.0.0.1); Thu, 12 May 2022 13:56:01 +0800 From: Jeffle Xu To: xiang@kernel.org, chao@kernel.org, linux-erofs@lists.ozlabs.org Cc: linux-kernel@vger.kernel.org Subject: [PATCH v2] erofs: scan devices from device table Date: Thu, 12 May 2022 13:56:01 +0800 Message-Id: <20220512055601.106109-1-jefflexu@linux.alibaba.com> X-Mailer: git-send-email 2.27.0 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-9.9 required=5.0 tests=BAYES_00, ENV_AND_HDR_SPF_MATCH,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE,UNPARSEABLE_RELAY,USER_IN_DEF_SPF_WL 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 When "-o device" mount option is not specified, scan the device table and instantiate the devices if there's any in the device table. In this case, the tag field of each device slot uniquely specifies a device. Signed-off-by: Jeffle Xu Reviewed-by: Gao Xiang --- changes since v1: tweak the error warning when device tag is empty --- fs/erofs/erofs_fs.h | 9 ++-- fs/erofs/super.c | 102 ++++++++++++++++++++++++++++++-------------- 2 files changed, 72 insertions(+), 39 deletions(-) diff --git a/fs/erofs/erofs_fs.h b/fs/erofs/erofs_fs.h index 1238ca104f09..1adde3a813b4 100644 --- a/fs/erofs/erofs_fs.h +++ b/fs/erofs/erofs_fs.h @@ -37,12 +37,9 @@ #define EROFS_SB_EXTSLOT_SIZE 16 struct erofs_deviceslot { - union { - u8 uuid[16]; /* used for device manager later */ - u8 userdata[64]; /* digest(sha256), etc. */ - } u; - __le32 blocks; /* total fs blocks of this device */ - __le32 mapped_blkaddr; /* map starting at mapped_blkaddr */ + u8 tag[64]; /* digest(sha256), etc. */ + __le32 blocks; /* total fs blocks of this device */ + __le32 mapped_blkaddr; /* map starting at mapped_blkaddr */ u8 reserved[56]; }; #define EROFS_DEVT_SLOT_SIZE sizeof(struct erofs_deviceslot) diff --git a/fs/erofs/super.c b/fs/erofs/super.c index 4a623630e1c4..7f0082cb4361 100644 --- a/fs/erofs/super.c +++ b/fs/erofs/super.c @@ -219,7 +219,52 @@ static int erofs_load_compr_cfgs(struct super_block *sb, } #endif -static int erofs_init_devices(struct super_block *sb, +static int erofs_init_device(struct erofs_buf *buf, struct super_block *sb, + struct erofs_device_info *dif, erofs_off_t *pos) +{ + struct erofs_sb_info *sbi = EROFS_SB(sb); + struct erofs_deviceslot *dis; + struct block_device *bdev; + void *ptr; + int ret; + + ptr = erofs_read_metabuf(buf, sb, erofs_blknr(*pos), EROFS_KMAP); + if (IS_ERR(ptr)) + return PTR_ERR(ptr); + dis = ptr + erofs_blkoff(*pos); + + if (!dif->path) { + if (!dis->tag[0]) { + erofs_err(sb, "empty device tag @ pos %llu", *pos); + return -EINVAL; + } + dif->path = kmemdup_nul(dis->tag, sizeof(dis->tag), GFP_KERNEL); + if (!dif->path) + return -ENOMEM; + } + + if (erofs_is_fscache_mode(sb)) { + ret = erofs_fscache_register_cookie(sb, &dif->fscache, + dif->path, false); + if (ret) + return ret; + } else { + bdev = blkdev_get_by_path(dif->path, FMODE_READ | FMODE_EXCL, + sb->s_type); + if (IS_ERR(bdev)) + return PTR_ERR(bdev); + dif->bdev = bdev; + dif->dax_dev = fs_dax_get_by_bdev(bdev, &dif->dax_part_off); + } + + dif->blocks = le32_to_cpu(dis->blocks); + dif->mapped_blkaddr = le32_to_cpu(dis->mapped_blkaddr); + sbi->total_blocks += dif->blocks; + *pos += EROFS_DEVT_SLOT_SIZE; + return 0; +} + +static int erofs_scan_devices(struct super_block *sb, struct erofs_super_block *dsb) { struct erofs_sb_info *sbi = EROFS_SB(sb); @@ -227,8 +272,6 @@ static int erofs_init_devices(struct super_block *sb, erofs_off_t pos; struct erofs_buf buf = __EROFS_BUF_INITIALIZER; struct erofs_device_info *dif; - struct erofs_deviceslot *dis; - void *ptr; int id, err = 0; sbi->total_blocks = sbi->primarydevice_blocks; @@ -237,7 +280,8 @@ static int erofs_init_devices(struct super_block *sb, else ondisk_extradevs = le16_to_cpu(dsb->extra_devices); - if (ondisk_extradevs != sbi->devs->extra_devices) { + if (sbi->devs->extra_devices && + ondisk_extradevs != sbi->devs->extra_devices) { erofs_err(sb, "extra devices don't match (ondisk %u, given %u)", ondisk_extradevs, sbi->devs->extra_devices); return -EINVAL; @@ -248,39 +292,31 @@ static int erofs_init_devices(struct super_block *sb, sbi->device_id_mask = roundup_pow_of_two(ondisk_extradevs + 1) - 1; pos = le16_to_cpu(dsb->devt_slotoff) * EROFS_DEVT_SLOT_SIZE; down_read(&sbi->devs->rwsem); - idr_for_each_entry(&sbi->devs->tree, dif, id) { - struct block_device *bdev; - - ptr = erofs_read_metabuf(&buf, sb, erofs_blknr(pos), - EROFS_KMAP); - if (IS_ERR(ptr)) { - err = PTR_ERR(ptr); - break; - } - dis = ptr + erofs_blkoff(pos); - - if (erofs_is_fscache_mode(sb)) { - err = erofs_fscache_register_cookie(sb, &dif->fscache, - dif->path, false); + if (sbi->devs->extra_devices) { + idr_for_each_entry(&sbi->devs->tree, dif, id) { + err = erofs_init_device(&buf, sb, dif, &pos); if (err) break; - } else { - bdev = blkdev_get_by_path(dif->path, - FMODE_READ | FMODE_EXCL, - sb->s_type); - if (IS_ERR(bdev)) { - err = PTR_ERR(bdev); + } + } else { + for (id = 0; id < ondisk_extradevs; id++) { + dif = kzalloc(sizeof(*dif), GFP_KERNEL); + if (!dif) { + err = -ENOMEM; break; } - dif->bdev = bdev; - dif->dax_dev = fs_dax_get_by_bdev(bdev, - &dif->dax_part_off); - } - dif->blocks = le32_to_cpu(dis->blocks); - dif->mapped_blkaddr = le32_to_cpu(dis->mapped_blkaddr); - sbi->total_blocks += dif->blocks; - pos += EROFS_DEVT_SLOT_SIZE; + err = idr_alloc(&sbi->devs->tree, dif, 0, 0, GFP_KERNEL); + if (err < 0) { + kfree(dif); + break; + } + ++sbi->devs->extra_devices; + + err = erofs_init_device(&buf, sb, dif, &pos); + if (err) + break; + } } up_read(&sbi->devs->rwsem); erofs_put_metabuf(&buf); @@ -367,7 +403,7 @@ static int erofs_read_superblock(struct super_block *sb) goto out; /* handle multiple devices */ - ret = erofs_init_devices(sb, dsb); + ret = erofs_scan_devices(sb, dsb); if (erofs_sb_has_ztailpacking(sbi)) erofs_info(sb, "EXPERIMENTAL compressed inline data feature in use. Use at your own risk!"); -- 2.27.0