From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.2 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,NICE_REPLY_A,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_SANE_1 autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B2A7CC433EF for ; Wed, 15 Sep 2021 01:28:18 +0000 (UTC) Received: from lists.ozlabs.org (lists.ozlabs.org [112.213.38.117]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id BA71861244 for ; Wed, 15 Sep 2021 01:28:17 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org BA71861244 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=huawei.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=lists.ozlabs.org Received: from boromir.ozlabs.org (localhost [IPv6:::1]) by lists.ozlabs.org (Postfix) with ESMTP id 4H8Mzh1Gf8z2xvG for ; Wed, 15 Sep 2021 11:28:16 +1000 (AEST) Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=huawei.com (client-ip=45.249.212.188; helo=szxga02-in.huawei.com; envelope-from=guoxuenan@huawei.com; receiver=) Received: from szxga02-in.huawei.com (szxga02-in.huawei.com [45.249.212.188]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 4H8MzY1tSkz2xqy for ; Wed, 15 Sep 2021 11:28:05 +1000 (AEST) Received: from dggemv711-chm.china.huawei.com (unknown [172.30.72.55]) by szxga02-in.huawei.com (SkyGuard) with ESMTP id 4H8MtB2zgmz4wff; Wed, 15 Sep 2021 09:23:30 +0800 (CST) Received: from kwepemm600004.china.huawei.com (7.193.23.242) by dggemv711-chm.china.huawei.com (10.1.198.66) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2308.8; Wed, 15 Sep 2021 09:27:56 +0800 Received: from [10.174.177.238] (10.174.177.238) by kwepemm600004.china.huawei.com (7.193.23.242) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2308.8; Wed, 15 Sep 2021 09:27:55 +0800 Message-ID: <1f835b93-4739-01ee-823e-cc7c6c1dabf2@huawei.com> Date: Wed, 15 Sep 2021 09:27:55 +0800 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Thunderbird/91.0.2 Subject: Re: [PATCH v2 4/5] dump.erofs: add -i options to dump file information of specific inode number To: Gao Xiang References: <20210914074424.1875409-1-guoxuenan@huawei.com> <20210914074424.1875409-4-guoxuenan@huawei.com> From: Guo Xuenan In-Reply-To: Content-Type: text/plain; charset="UTF-8"; format=flowed Content-Transfer-Encoding: 8bit X-Originating-IP: [10.174.177.238] X-ClientProxiedBy: dggems705-chm.china.huawei.com (10.3.19.182) To kwepemm600004.china.huawei.com (7.193.23.242) X-CFilter-Loop: Reflected X-BeenThere: linux-erofs@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Development of Linux EROFS file system List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-erofs@lists.ozlabs.org, mpiglet@outlook.com Errors-To: linux-erofs-bounces+linux-erofs=archiver.kernel.org@lists.ozlabs.org Sender: "Linux-erofs" Hi Xiang: Thanks for your detailed and thoughtful reply, we will modify it according to your suggestions. As you said, we are also considering  handle hard-link issue in the follow-up work. The filemap supporting will be added in patch v3. Previously, we only adapted the interface modified by Jianan, without realizing relevant functions, we'll study on it. 在 2021/9/14 21:20, Gao Xiang 写道: > On Tue, Sep 14, 2021 at 03:44:23PM +0800, Guo Xuenan wrote: >> From: Wang Qi >> >> Signed-off-by: Guo Xuenan >> Signed-off-by: Wang Qi > Just a rough check, it still doesn't handle hardlink, but that is fine > anyway. > > I think if the first patches get into shape, we could merge them in > advance. > > Also, I'd like to add a feature to get the independent file > distribution in the fiemap-likewise form, which is useful to debug some > specific compressed files (by using the patch Jianan backported before.) > > > Thanks, > Gao Xiang > >> --- >> dump/main.c | 161 +++++++++++++++++++++++++++++++++++++++++++++++++++- >> 1 file changed, 159 insertions(+), 2 deletions(-) >> >> diff --git a/dump/main.c b/dump/main.c >> index 0778354..233de50 100644 >> --- a/dump/main.c >> +++ b/dump/main.c >> @@ -21,8 +21,10 @@ >> >> struct dumpcfg { >> bool print_superblock; >> + bool print_inode; >> bool print_statistic; >> bool print_version; >> + u64 ino; >> }; >> static struct dumpcfg dumpcfg; >> >> @@ -109,8 +111,9 @@ static void usage(void) >> fputs("usage: [options] erofs-image\n\n" >> "Dump erofs layout from erofs-image, and [options] are:\n" >> "--help display this help and exit.\n" >> - "-s print information about superblock\n" >> + "-s print information about superblock\n" >> "-S print statistic information of the erofs-image\n" >> + "-i # print target # inode info\n" >> "-V print the version number of dump.erofs and exit.\n", >> stdout); >> } >> @@ -123,10 +126,16 @@ static void dumpfs_print_version(void) >> static int dumpfs_parse_options_cfg(int argc, char **argv) >> { >> int opt; >> + u64 i; >> >> - while ((opt = getopt_long(argc, argv, "sSV", >> + while ((opt = getopt_long(argc, argv, "i:sSV", >> long_options, NULL)) != -1) { >> switch (opt) { >> + case 'i': >> + i = atoll(optarg); >> + dumpcfg.print_inode = true; >> + dumpcfg.ino = i; >> + break; >> case 's': >> dumpcfg.print_superblock = true; >> break; >> @@ -179,6 +188,151 @@ static int get_file_compressed_size(struct erofs_inode *inode, >> } >> return 0; >> } >> +static int get_path_by_nid(erofs_nid_t nid, erofs_nid_t parent_nid, >> + erofs_nid_t target, char *path, unsigned int pos) >> +{ >> + int err; >> + struct erofs_inode inode = {.nid = nid}; >> + erofs_off_t offset; >> + char buf[EROFS_BLKSIZ]; >> + >> + path[pos++] = '/'; >> + if (target == sbi.root_nid) >> + return 0; >> + >> + err = erofs_read_inode_from_disk(&inode); >> + if (err) { >> + erofs_err("read inode %lu failed", nid); >> + return err; >> + } >> + >> + offset = 0; >> + while (offset < inode.i_size) { >> + erofs_off_t maxsize = min_t(erofs_off_t, >> + inode.i_size - offset, EROFS_BLKSIZ); >> + struct erofs_dirent *de = (void *)buf; >> + struct erofs_dirent *end; >> + unsigned int nameoff; >> + >> + err = erofs_pread(&inode, buf, maxsize, offset); >> + if (err) >> + return err; >> + >> + nameoff = le16_to_cpu(de->nameoff); >> + if (nameoff < sizeof(struct erofs_dirent) || >> + nameoff >= PAGE_SIZE) { >> + erofs_err("invalid de[0].nameoff %u @ nid %llu", >> + nameoff, nid | 0ULL); >> + return -EFSCORRUPTED; >> + } >> + >> + end = (void *)buf + nameoff; >> + while (de < end) { >> + const char *dname; >> + unsigned int dname_len; >> + >> + nameoff = le16_to_cpu(de->nameoff); >> + dname = (char *)buf + nameoff; >> + if (de + 1 >= end) >> + dname_len = strnlen(dname, maxsize - nameoff); >> + else >> + dname_len = le16_to_cpu(de[1].nameoff) >> + - nameoff; >> + >> + /* a corrupted entry is found */ >> + if (nameoff + dname_len > maxsize || >> + dname_len > EROFS_NAME_LEN) { >> + erofs_err("bogus dirent @ nid %llu", >> + le64_to_cpu(de->nid) | 0ULL); >> + DBG_BUGON(1); >> + return -EFSCORRUPTED; >> + } >> + >> + if (de->nid == target) { >> + memcpy(path + pos, dname, dname_len); >> + return 0; >> + } >> + >> + if (de->file_type == EROFS_FT_DIR && >> + de->nid != parent_nid && >> + de->nid != nid) { >> + memcpy(path + pos, dname, dname_len); >> + err = get_path_by_nid(de->nid, nid, >> + target, path, pos + dname_len); >> + if (!err) >> + return 0; >> + memset(path + pos, 0, dname_len); >> + } >> + ++de; >> + } >> + offset += maxsize; >> + } >> + return -1; >> +} >> + >> +static void dumpfs_print_inode(void) >> +{ >> + int err; >> + erofs_off_t size; >> + u16 access_mode; >> + time_t t; >> + erofs_nid_t nid = dumpcfg.ino; >> + struct erofs_inode inode = {.nid = nid}; >> + char path[PATH_MAX + 1] = {0}; >> + char access_mode_str[] = "rwxrwxrwx"; >> + >> + err = erofs_read_inode_from_disk(&inode); >> + if (err) { >> + erofs_err("read inode %lu from disk failed", nid); >> + return; >> + } >> + >> + err = get_file_compressed_size(&inode, &size); >> + if (err) { >> + erofs_err("get file size failed\n"); >> + return; >> + } >> + >> + fprintf(stdout, "Inode %lu info:\n", dumpcfg.ino); >> + err = get_path_by_nid(sbi.root_nid, sbi.root_nid, nid, path, 0); >> + >> + fprintf(stdout, "File path: %s\n", >> + !err ? path : "path not found"); >> + fprintf(stdout, "File nid: %lu\n", inode.nid); >> + fprintf(stdout, "File inode core size: %d\n", inode.inode_isize); >> + fprintf(stdout, "File original size: %lu\n", inode.i_size); >> + fprintf(stdout, "File on-disk size: %lu\n", size); >> + fprintf(stdout, "File compress rate: %.2f%%\n", >> + (double)(100 * size) / (double)(inode.i_size)); >> + fprintf(stdout, "File extent size: %u\n", inode.extent_isize); >> + fprintf(stdout, "File xattr size: %u\n", inode.xattr_isize); >> + fprintf(stdout, "File type: "); >> + switch (inode.i_mode & S_IFMT) { >> + case S_IFBLK: fprintf(stdout, "block device\n"); break; >> + case S_IFCHR: fprintf(stdout, "character device\n"); break; >> + case S_IFDIR: fprintf(stdout, "directory\n"); break; >> + case S_IFIFO: fprintf(stdout, "FIFO/pipe\n"); break; >> + case S_IFLNK: fprintf(stdout, "symlink\n"); break; >> + case S_IFREG: fprintf(stdout, "regular file\n"); break; >> + case S_IFSOCK: fprintf(stdout, "socket\n"); break; >> + default: fprintf(stdout, "unknown?\n"); break; >> + } >> + >> + access_mode = inode.i_mode & 0777; >> + t = inode.i_ctime; >> + for (int i = 8; i >= 0; i--) >> + if (((access_mode >> i) & 1) == 0) >> + access_mode_str[8 - i] = '-'; >> + fprintf(stdout, "File access: %04o/%s\n", >> + access_mode, access_mode_str); >> + fprintf(stdout, "File uid: %u\n", inode.i_uid); >> + fprintf(stdout, "File gid: %u\n", inode.i_gid); >> + fprintf(stdout, "File datalayout: %d\n", inode.datalayout); >> + fprintf(stdout, "File nlink: %u\n", inode.i_nlink); >> + fprintf(stdout, "File create time: %s", ctime(&t)); >> + fprintf(stdout, "File access time: %s", ctime(&t)); >> + fprintf(stdout, "File modify time: %s", ctime(&t)); >> +} >> >> static int get_file_type(const char *filename) >> { >> @@ -514,6 +668,9 @@ int main(int argc, char **argv) >> >> if (dumpcfg.print_statistic) >> dumpfs_print_statistic(); >> + >> + if (dumpcfg.print_inode) >> + dumpfs_print_inode(); >> out: >> if (cfg.c_img_path) >> free(cfg.c_img_path); >> -- >> 2.25.4 > .