From patchwork Tue Feb 20 09:59:47 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Prutyanov X-Patchwork-Id: 875455 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-ext4-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=virtuozzo.com header.i=@virtuozzo.com header.b="djLsroo6"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3zlx1v45x2z9s0b for ; Tue, 20 Feb 2018 21:00:19 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751586AbeBTKAR (ORCPT ); Tue, 20 Feb 2018 05:00:17 -0500 Received: from mail-he1eur01on0116.outbound.protection.outlook.com ([104.47.0.116]:10020 "EHLO EUR01-HE1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751510AbeBTKAP (ORCPT ); Tue, 20 Feb 2018 05:00:15 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=virtuozzo.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=LAMFBhFraDzi6oY9/BBLFEWPrfu48VR9E3AH6k8ganU=; b=djLsroo6ZU9O4VPCZlsj38fk72vGwTPo2MKyOmY7Lfqpd8+gVAtrEPFV4buZyWcb0bLApRG482fpOJIkCJfK2TLVFnVTMU2oncyiCn9m1+Z+LWz2QVfl5vc90CY5JwRjgTZEUF/K/ijdZnmTj1wM1XiL0otf6zIkYGpOUh4w5FI= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=viktor.prutyanov@virtuozzo.com; Received: from vprutyanov-pc.sw.ru (195.214.232.6) by AM4PR08MB2849.eurprd08.prod.outlook.com (2603:10a6:205:d::31) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.506.18; Tue, 20 Feb 2018 10:00:08 +0000 From: Viktor Prutyanov To: linux-ext4@vger.kernel.org Cc: Theodore Ts'o , Dmitry Monakhov , Viktor Prutyanov Subject: [PATCH v3 2/5] dumpe2fs: add JSON output of block groups Date: Tue, 20 Feb 2018 12:59:47 +0300 Message-Id: <20180220095950.23462-3-viktor.prutyanov@virtuozzo.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180220095950.23462-1-viktor.prutyanov@virtuozzo.com> References: <20180220095950.23462-1-viktor.prutyanov@virtuozzo.com> MIME-Version: 1.0 X-Originating-IP: [195.214.232.6] X-ClientProxiedBy: HE1PR0902CA0058.eurprd09.prod.outlook.com (2603:10a6:7:15::47) To AM4PR08MB2849.eurprd08.prod.outlook.com (2603:10a6:205:d::31) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 033a38c6-a692-4972-3453-08d57848b9a0 X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(7020095)(4652020)(5600026)(4604075)(4534165)(7168020)(4627221)(201703031133081)(201702281549075)(2017052603307)(7153060)(7193020); SRVR:AM4PR08MB2849; X-Microsoft-Exchange-Diagnostics: 1; AM4PR08MB2849; 3:IB6nhG0WQQEOMaU0MGhmb3vFQyFbekRpu98sGkTOnTskmtS42RdPQj8/ljfPqZZfBAAqrZcpjBIFQoXcJiMMFdrJW1g6b5h8EdawEQ7GE/Uolt8AgYuXyxMYxDz4LjS5l7KWzrp60xNdTtOjCSxZy9UJvIICNubCyBIEaV33UIvUPkCMhUppiur19NozGUNVcR3IirmyzIfdgyiCZm0TKyQDQ2rwG22HAfo5bZQj5W9jgnIKsC1qqXlm5aoI45nF; 25:uOhhsQ+aZqZ897g4aK1V0sK53nazeomWVjoBei4cK/hcr0h01EYapW8bOtyxME9QtmVa2/swURoMt+t7XmO4G5vUsDIfow25qnrEcTFhK3SR7GKueoZUifJjHQsYWjmI7tQd29vXA1w3lmMDAcRMoB1IB5DMpin40LiUu35BJAItfPAd9DyDgdr8R35SUITTFUtL4nyOIDYJ42SPbf/LowZ1xHwPFNhdU09s4VmX6ZnR6qc1Ww1BmKi4XKYDZQglZgDgAnoHqjwZQxWeqIxoBqgyCoEO7SQIkLOharGkFMwFrVkrKGo/bakmkQ4QJy9eJCAD/9gKElV/upDjAF3X+w==; 31:LX6jfXvVy1CCt+oTMka1Of9gGFCOr3hhKlOgL7cmMgMwf45RCvKNoYxBu6quprUpMgIGcOyA8vY/TgCDFVHs8PfB2I9/hkr1/GTvkTP/0nGTJz5UqSsog7lmzTV2V03irwvHGeM0LkarGmxdKmV0mzA2RrRivx9b/JDZxt4UWWc6ZDMMCAZ5G1+V+38KY7RkZgzixKMazjlcbzkdlIeNxuGrWgPp4VRe0g7DnzOglZI= X-MS-TrafficTypeDiagnostic: AM4PR08MB2849: X-Microsoft-Exchange-Diagnostics: 1; AM4PR08MB2849; 20:U/kSQ8GR0zhkKTdkyAWpIOHTpRX7lwIstlCwKLg46K/FP8ttsot4TAGUwQ8WqlnGSGdoGeJxIJ4W/MMNmfLU6airMKZ/s19qRu1JwP6PfEssgJ8tzngi51cwLCFWqc+jdSgfq5IFue89tNxJztEVDKIDY/ZbhRJMW0splWR0CSvorldX9tWdu9PDfcFxtBiDz7Oj6C9dmC7eQvXDSo+53vOBkRjAWJ0NF4mPpYSYNB28bcbNCe5RxCfm3Asg69tSrbZl1f7o18YsY0fKuJm9PZXfW0Vb+8mWhpQcqkl5LStEf4QnrM8GGC6NPTY64o8iP5rk93XjGMF1KwWm7vUchWHoMd5E7DMZ4th71+3uUCSNjPq60y4Aje5ot6WM/HfSCjvbGBtbDosc6kraqoSMqWc5IN9VD0SoGd7y+VJP0eYej7/Hdi3G7AkrJh6tya80HL0L2fuP5YrgSazFWda8z6uNnapPzEcdQMqOYOFs/DhtuKt7iLiOZGXhmicgKqDJ; 4:2kovMzrFb+zG1Ga4OMfXC/Ya0rH7bAi3QxMymUnEyZvy9xkAzPOw5aG6JYRdHbpX461lU6DXuzIbmqQTb3x0cZW4LQc4GrnIwjWUzNqGLHFONbdi2pJ1qv9Dpg/IajU5lpgCQJLohAdMJqbZQ4mgV5cPURDAvk5lXzavzdMeymwqTlVhzJp5fNIOyGIUbfVCpQj+ZbTMCGk+14T+oyfLjN+3/mPh9d2NLcHEJhGg087SaE9wzr0wCRK67mUj3sJYdF0GHD5bwaa6qJgwQGalkA== X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6040501)(2401047)(8121501046)(5005006)(3231101)(944501161)(93006095)(93001095)(10201501046)(3002001)(6041288)(20161123560045)(20161123564045)(20161123558120)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123562045)(6072148)(201708071742011); SRVR:AM4PR08MB2849; BCL:0; PCL:0; RULEID:; SRVR:AM4PR08MB2849; X-Forefront-PRVS: 05891FB07F X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10019020)(39850400004)(366004)(396003)(39380400002)(346002)(376002)(199004)(189003)(52116002)(16586007)(478600001)(54906003)(59450400001)(5660300001)(1076002)(68736007)(6666003)(51416003)(107886003)(69596002)(50466002)(86362001)(48376002)(8676002)(16526019)(186003)(76176011)(6116002)(55236004)(2950100002)(6916009)(26005)(3846002)(316002)(2906002)(386003)(81156014)(6506007)(81166006)(7736002)(97736004)(53416004)(8936002)(6486002)(305945005)(36756003)(50226002)(53936002)(66066001)(6512007)(47776003)(25786009)(2351001)(105586002)(4326008)(106356001)(2361001)(16060500001); DIR:OUT; SFP:1102; SCL:1; SRVR:AM4PR08MB2849; H:vprutyanov-pc.sw.ru; FPR:; SPF:None; PTR:InfoNoRecords; A:1; MX:1; LANG:en; Received-SPF: None (protection.outlook.com: virtuozzo.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: 1; AM4PR08MB2849; 23:gyguzLnCt9f/yJcbt0//xBLgshRHeRYGvpBy7GFa8k6WnqYUS90sV2nDWwyvB9U/yN9Sx0AuGbktEUtfLPbbaMl+mduN2ZzHQ81IF7CYulHbdIBZlcULd2pIUC8MAXYDWT/GyRsxHaUD6o73aCf5eswhQZUfb/dM2NLx7QdsPsGoL88F6IsK8Qr3XsqFVMyb9H4xAspNwO+AuJ+A2q02GUtDBJpkAqy4bG3A9q+aBuT5WSXOP7SU/hsKBxixr1cFNxV0x75yV9tumOpkq3ZffM62I9lGwOVVr5yG2nfJnUSx5bgA0Jo7bgvMs2+4ee++3AxSWuHBqVPokkWXkMuAJubWuAmzOPKjZHxs2vZZMka+MV8Iqsn5r3aGalBWrvEN2TUwi2CrlPATT8D1+UBoJ3FmScjHvLpVmbWEsiWTYNbmGLI63clKXQYuYxsTSVzUxKAZvJgrsp7/5R/wNZQ/wlUn1kv+rIdBjfwSswwj9Vt+cidkSJWFYiX4m27JK7yjxNys5rSmEH8JK/svHEDw48VB0IP5ucFoW6ieBdvqOGfdzSfStJaqG1zfMONVgldlfkPVvCxatw7PGVVGMCFXgqH1i+sf0vjpSGN6fHMyv6lb0TjM9zXCIKJw1nvp6OL66dOyT4lGL1lUbRwItEtmj5Q7leZzQYOODtBQUvBpibZk3VDANr31jkrx/3CDCJsfyTlRE5iKMDa2Kf1LKsKHpaycZDOcvftN9iqS0+mBrbZaAKB4XHHwdZt/aJg8cuRzU581ewaLkE5kXrJZgqY0Lx1TWsqk0PtXNgq9NVodydLeGjJjRvekey2o/RkFBRePm1wQGn8VLc+JQTFpR7PHwURMf2+wCVBjcnp8sjstCMNw4YfTHTQayaNqTxdBEx2d7F4IM6KMRQi/AM51/lMzFMhYf7WV/MHdl5rIdAQdL9f14UKMxLTIVr9GR4hjbH7f5CGj1Mg88JTZVRjgVPmtDZEuyVie5EU9ZXsE/s9hogGIWa0cuveRuHCGieubZ3NTmaFBUS9/TTG99R+d5rnfg4FwALYvs0Up8UMucT0GxaMcufJObAb3/BDWlEGsm3IYkN3tuFlcBuaFcr4Lwu1PfGR8j3JMBvHI/Wol7XF7ckLrpnfpZxQhtKjh7bIG0IY6be6MJw7g3sd1bh86lLqZM9aWS/B5noyf6D6p0hyPAKWzuOgG+W0H9ANywPAqwPq0DS5D9HZbYV4cucSdel7pkXhYWBPnOAXexVzvCemk0mpiPvCGDEeYoWJZEj8qtOB0G8VYd8VhKCzE4IrK9/qmhxQ+/yqWRAiWr5EU+KldZ8c= X-Microsoft-Exchange-Diagnostics: 1; AM4PR08MB2849; 6:ExqMC94gsK+BdeVnnL/OF7oWFt1PCSpKNqcdVWm00baqLU1gSfqv/RyC3SlNyHl24H2Baam3zRDcbaBSy4YBn6qrCXedCPErZa//gUiqul3QOWY08wEI7U8RqBV9BMD2qSvT/SQo5wEDck7sRfqHEMPn7spX/DFB8otsaQ6EbUkYS5sbom29RJrjpxeFwbWC4zlfcl6tcMlvOtReP4CdBvZmD0a/9LYXCsoV3ayW5yDgU/F/8o4O+RdRqNM0BNqZbZDGKPHVBOx0DNtrELAdVDKxPVI6SYq/ayG4hN5XwDl33hQ79gknfXjA4SDNKum6zqG73q9Fr2YTRIVz0xflA+pMwPdctBiJgL3PzAMaf1s=; 5:Ql4ORJRmsfxBvWywlIjpb9pUwBQgYuhiVjpS06F99B+ZSFl6yN/BSSPlZKNjO5PBbU7UZuolz2FAb+LBCEjfvo/FD06yXhVSskL6k4Bx9Y5IekvC0nKI5YREFRU4rLuFQUm/fRyo0amY5e22EtnNXdQOmKC2qzpZSH6CzZQKJm0=; 24:nIS60P5kgwp9PvEMys/DFrmDWqYlF5Sdn5CFISAo1RgkB7yakA3FXSB1DcviAuht5iChodFjqhmZySLvpicGEhQuGagRpCLM81wcXDtcvl0=; 7:lnfB9eM7rLA3hWYl6cpeRe4iw3BPzwknpju8eY1XNq2QJ7Oe1hVOqsgUzH3nDPmON1EY5HfdJua2SCC+SPJc67+UZUt1OeN8FWxoJXntCvQSAcn5KtenbI6gA9m4izXP5b7LnnbuU9lMdSTTwH+hroM7Jn2lwwwcPRvlEe47uI6ce/RH+sEQ5HUqjSx0Ev4FhDRuDiR8wkPMx0HPes+JcjnFsuLSG1YOETatfpobv7Hjia77HGbZMytE2h0KXISi SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; AM4PR08MB2849; 20:u8Tvn8+HplEM1YBt/ChO0TTCF8wgdXLmUU4O+hSlfMeRww4chRVSPYRmKpdEiRinJnOWSy/Zz6wHV0x/XAMDSa29lODnI+AsPQYKcHSYB1NqTBXYT8mli0cFXabyy61pgXdUjziQd59abm615mgAhj+ztWrPAlDHGKuMJaCpJ8c= X-OriginatorOrg: virtuozzo.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 20 Feb 2018 10:00:08.6461 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 033a38c6-a692-4972-3453-08d57848b9a0 X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 0bc7f26d-0264-416e-a6fc-8352af79c58f X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM4PR08MB2849 Sender: linux-ext4-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org This patch adds '-j' option for JSON output of block groups information Signed-off-by: Viktor Prutyanov --- misc/dumpe2fs.8.in | 3 + misc/dumpe2fs.c | 272 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 270 insertions(+), 5 deletions(-) diff --git a/misc/dumpe2fs.8.in b/misc/dumpe2fs.8.in index da78d4fc..d03ee8be 100644 --- a/misc/dumpe2fs.8.in +++ b/misc/dumpe2fs.8.in @@ -72,6 +72,9 @@ as the pathname to the image file. .B \-x print the detailed group information block numbers in hexadecimal format .TP +.B \-j +use JSON ouput format +.TP .B \-V print the version number of .B dumpe2fs diff --git a/misc/dumpe2fs.c b/misc/dumpe2fs.c index ca9953a1..319c296b 100644 --- a/misc/dumpe2fs.c +++ b/misc/dumpe2fs.c @@ -42,6 +42,7 @@ extern int optind; #include "support/nls-enable.h" #include "support/plausible.h" +#include "support/json-out.h" #include "../version.h" #define in_use(m, x) (ext2fs_test_bit ((x), (m))) @@ -53,7 +54,7 @@ static int blocks64 = 0; static void usage(void) { - fprintf(stderr, _("Usage: %s [-bfghixV] [-o superblock=] " + fprintf(stderr, _("Usage: %s [-bfghixjV] [-o superblock=] " "[-o blocksize=] device\n"), program_name); exit(1); } @@ -69,6 +70,17 @@ static void print_number(unsigned long long num) printf("%llu", num); } +static void snprint_number(char *str, size_t size, unsigned long long num) +{ + if (hex_format) { + if (blocks64) + snprintf(str, size, "0x%08llx", num); + else + snprintf(str, size, "0x%04llx", num); + } else + snprintf(str, size, "%llu", num); +} + static void print_range(unsigned long long a, unsigned long long b) { if (hex_format) { @@ -80,6 +92,19 @@ static void print_range(unsigned long long a, unsigned long long b) printf("%llu-%llu", a, b); } +static struct json_obj *json_create_range_obj(unsigned long long a, + unsigned long long b) +{ + struct json_obj *obj = json_obj_create(); + char buf[32]; + const char *fmt = hex_format ? (blocks64 ? "0x%08llx" : "0x%04llx") : "%llu"; + + json_obj_add_fmt_buf_str(obj, "start", buf, sizeof(buf), fmt, a); + json_obj_add_fmt_buf_str(obj, "len", buf, sizeof(buf), fmt, b - a + 1); + + return obj; +} + static void print_free(unsigned long group, char * bitmap, unsigned long num, unsigned long offset, int ratio) { @@ -106,6 +131,31 @@ static void print_free(unsigned long group, char * bitmap, } } +static void fill_json_free(struct json_list *list, unsigned long group, + char *bitmap, unsigned long num, unsigned long offset, int ratio) +{ + unsigned long i; + unsigned long j; + unsigned long long a, b; + + offset /= ratio; + offset += group * num; + for (i = 0; i < num; i++) + if (!in_use (bitmap, i)) + { + for (j = i; j < num && !in_use (bitmap, j); j++) + ; + if (--j == i) + a = b = (i + offset) * ratio; + else { + a = (i + offset) * ratio; + b = (j + offset) * ratio; + i = j; + } + json_list_add_obj(list, json_create_range_obj(a, b)); + } +} + static void print_bg_opt(int bg_flags, int mask, const char *str, int *first) { @@ -136,6 +186,25 @@ static void print_bg_opts(ext2_filsys fs, dgrp_t i) fputc('\n', stdout); } +static void fill_json_bg_opts(struct json_obj *obj, ext2_filsys fs, dgrp_t i) +{ + int bg_flags = 0; + struct json_list *bg_opts_list = json_list_create_in_obj(obj, "bg-opts", + JSON_VAL_STRING); + + if (ext2fs_has_group_desc_csum(fs)) + bg_flags = ext2fs_bg_flags(fs, i); + else + return; + + if (bg_flags & EXT2_BG_INODE_UNINIT) + json_list_add_str(bg_opts_list, "INODE_UNINIT"); + if (bg_flags & EXT2_BG_BLOCK_UNINIT) + json_list_add_str(bg_opts_list, "BLOCK_UNINIT"); + if (bg_flags & EXT2_BG_INODE_ZEROED) + json_list_add_str(bg_opts_list, "ITABLE_ZEROED"); +} + static void print_bg_rel_offset(ext2_filsys fs, blk64_t block, int itable, blk64_t first_block, blk64_t last_block) { @@ -150,6 +219,29 @@ static void print_bg_rel_offset(ext2_filsys fs, blk64_t block, int itable, } } +static struct json_obj* json_create_bg_rel_offset_obj(ext2_filsys fs, + blk64_t block, int itable, blk64_t first_block, blk64_t last_block) +{ + struct json_obj *obj = json_obj_create(); + char buf[32]; + + if ((block >= first_block) && (block <= last_block)) { + if (itable && block == first_block) + return obj; + snprintf(buf, sizeof(buf), "%u", (unsigned)(block - first_block)); + json_obj_add_str(obj, "offset", buf); + } else if (ext2fs_has_feature_flex_bg(fs->super)) { + dgrp_t flex_grp = ext2fs_group_of_blk2(fs, block); + snprintf(buf, sizeof(buf), "%u", flex_grp); + json_obj_add_str(obj, "bg", buf); + snprintf(buf, sizeof(buf), "%u", + (unsigned)(block-ext2fs_group_first_block2(fs,flex_grp))); + json_obj_add_str(obj, "offset", buf); + } + + return obj; +} + static void list_desc(ext2_filsys fs, int grp_only) { unsigned long i; @@ -321,6 +413,165 @@ static void list_desc(ext2_filsys fs, int grp_only) free(inode_bitmap); } +static void fill_json_desc(struct json_obj *obj, ext2_filsys fs) +{ + unsigned long i; + blk64_t first_block, last_block; + blk64_t super_blk, old_desc_blk, new_desc_blk; + char *block_bitmap=NULL, *inode_bitmap=NULL; + const char *units = "blocks"; + int inode_blocks_per_group, old_desc_blocks, reserved_gdt; + int block_nbytes, inode_nbytes; + int has_super; + blk64_t blk_itr = EXT2FS_B2C(fs, fs->super->s_first_data_block); + ext2_ino_t ino_itr = 1; + errcode_t retval; + struct json_list *desc_list = json_list_create_in_obj(obj, "desc", JSON_VAL_OBJECT); + char buf[64]; + + if (ext2fs_has_feature_bigalloc(fs->super)) + units = "clusters"; + + block_nbytes = EXT2_CLUSTERS_PER_GROUP(fs->super) / 8; + inode_nbytes = EXT2_INODES_PER_GROUP(fs->super) / 8; + + if (fs->block_map) + block_bitmap = malloc(block_nbytes); + if (fs->inode_map) + inode_bitmap = malloc(inode_nbytes); + inode_blocks_per_group = ((fs->super->s_inodes_per_group * + EXT2_INODE_SIZE(fs->super)) + + EXT2_BLOCK_SIZE(fs->super) - 1) / + EXT2_BLOCK_SIZE(fs->super); + reserved_gdt = fs->super->s_reserved_gdt_blocks; + first_block = fs->super->s_first_data_block; + if (ext2fs_has_feature_meta_bg(fs->super)) + old_desc_blocks = fs->super->s_first_meta_bg; + else + old_desc_blocks = fs->desc_blocks; + + for (i = 0; i < fs->group_desc_count; i++) { + struct json_obj *group_obj = json_obj_create(); + + json_list_add_obj(desc_list, group_obj); + + first_block = ext2fs_group_first_block2(fs, i); + last_block = ext2fs_group_last_block2(fs, i); + + ext2fs_super_and_bgd_loc2(fs, i, &super_blk, + &old_desc_blk, &new_desc_blk, 0); + + json_obj_add_fmt_buf_str(group_obj, "num", buf, sizeof(buf), "%lu", i); + json_obj_add_obj(group_obj, "blocks", + json_create_range_obj(first_block, last_block)); + if (ext2fs_has_group_desc_csum(fs)) { + unsigned csum = ext2fs_bg_checksum(fs, i); + unsigned exp_csum = ext2fs_group_desc_csum(fs, i); + + json_obj_add_fmt_buf_str(group_obj, "group-desc-csum", + buf, sizeof(buf), "0x%04x", csum); + if (csum != exp_csum) + json_obj_add_fmt_buf_str(group_obj, "group-desc-csum-exp", + buf, sizeof(buf), "0x%04x", exp_csum); + } + + fill_json_bg_opts(group_obj, fs, i); + has_super = ((i==0) || super_blk); + if (has_super) { + json_obj_add_str(group_obj, "superblock-type", + i == 0 ? "Primary" : "Backup"); + snprint_number(buf, sizeof(buf), super_blk); + json_obj_add_str(group_obj, "superblock-at", buf); + } + if (old_desc_blk) { + json_obj_add_obj(group_obj, "group-descriptors-at", + json_create_range_obj(old_desc_blk, + old_desc_blk + old_desc_blocks - 1)); + if (reserved_gdt) { + json_obj_add_obj(group_obj, "reserved-gdt-blocks-at", + json_create_range_obj(old_desc_blk + old_desc_blocks, + old_desc_blk + old_desc_blocks + reserved_gdt - 1)); + } + } else if (new_desc_blk) { + snprint_number(buf, sizeof(buf), new_desc_blk); + json_obj_add_str(group_obj, "group-desc-at", buf); + has_super++; + } + + snprint_number(buf, sizeof(buf), ext2fs_block_bitmap_loc(fs, i)); + json_obj_add_str(group_obj, "block-bitmap-at", buf); + json_obj_add_obj(group_obj, "block-bitmap-rel-offset", + json_create_bg_rel_offset_obj(fs, + ext2fs_block_bitmap_loc(fs, i), 0, + first_block, last_block)); + if (ext2fs_has_feature_metadata_csum(fs->super)) + json_obj_add_fmt_buf_str(group_obj, "block-bitmap-csum", buf, + sizeof(buf), "0x%08x", ext2fs_block_bitmap_checksum(fs, i)); + + snprint_number(buf, sizeof(buf), ext2fs_inode_bitmap_loc(fs, i)); + json_obj_add_str(group_obj, "inode-bitmap-at", buf); + json_obj_add_obj(group_obj, "inode-bitmap-rel-offset", + json_create_bg_rel_offset_obj(fs, + ext2fs_inode_bitmap_loc(fs, i), 0, + first_block, last_block)); + if (ext2fs_has_feature_metadata_csum(fs->super)) + json_obj_add_fmt_buf_str(group_obj, "inode-bitmap-csum", buf, + sizeof(buf), "0x%08x", ext2fs_inode_bitmap_checksum(fs, i)); + + json_obj_add_obj(group_obj, "inode-table-at", + json_create_range_obj(ext2fs_inode_table_loc(fs, i), + ext2fs_inode_table_loc(fs, i) + + inode_blocks_per_group - 1)); + + json_obj_add_obj(group_obj, "inode-table-rel-offset", + json_create_bg_rel_offset_obj(fs, + ext2fs_inode_table_loc(fs, i), 1, + first_block, last_block)); + + json_obj_add_fmt_buf_str(group_obj, "free-blocks-count", buf, + sizeof(buf), "%u %s", ext2fs_bg_free_blocks_count(fs, i), units); + json_obj_add_fmt_buf_str(group_obj, "free-inodes-count", buf, + sizeof(buf), "%u", ext2fs_bg_free_inodes_count(fs, i)); + json_obj_add_fmt_buf_str(group_obj, "used-dirs-count", buf, + sizeof(buf), "%u", ext2fs_bg_used_dirs_count(fs, i)); + json_obj_add_fmt_buf_str(group_obj, "unused-inodes", buf, + sizeof(buf), "%u", ext2fs_bg_itable_unused(fs, i)); + if (block_bitmap) { + struct json_list *free_blocks_list; + + free_blocks_list = json_list_create_in_obj(group_obj, + "free-blocks", JSON_VAL_OBJECT); + retval = ext2fs_get_block_bitmap_range2(fs->block_map, + blk_itr, block_nbytes << 3, block_bitmap); + if (!retval) + fill_json_free(free_blocks_list, i, + block_bitmap, + fs->super->s_clusters_per_group, + fs->super->s_first_data_block, + EXT2FS_CLUSTER_RATIO(fs)); + blk_itr += fs->super->s_clusters_per_group; + } + if (inode_bitmap) { + struct json_list *free_inodes_list; + + free_inodes_list = json_list_create_in_obj(group_obj, + "free-inodes", JSON_VAL_OBJECT); + retval = ext2fs_get_inode_bitmap_range2(fs->inode_map, + ino_itr, inode_nbytes << 3, inode_bitmap); + if (!retval) + fill_json_free(free_inodes_list, i, + inode_bitmap, + fs->super->s_inodes_per_group, + 1, 1); + ino_itr += fs->super->s_inodes_per_group; + } + } + if (block_bitmap) + free(block_bitmap); + if (inode_bitmap) + free(inode_bitmap); +} + static void list_bad_blocks(ext2_filsys fs, int dump) { badblocks_list bb_list = 0; @@ -510,6 +761,8 @@ int main (int argc, char ** argv) int header_only = 0; int c; int grp_only = 0; + int json = 0; + struct json_obj *dump_obj; #ifdef ENABLE_NLS setlocale(LC_MESSAGES, ""); @@ -524,7 +777,7 @@ int main (int argc, char ** argv) if (argc && *argv) program_name = *argv; - while ((c = getopt(argc, argv, "bfghixVo:")) != EOF) { + while ((c = getopt(argc, argv, "bfghixjVo:")) != EOF) { switch (c) { case 'b': print_badblocks++; @@ -553,6 +806,9 @@ int main (int argc, char ** argv) case 'x': hex_format++; break; + case 'j': + json++; + break; default: usage(); } @@ -597,6 +853,8 @@ try_open_again: check_plausibility(device_name, CHECK_FS_EXIST, NULL); exit (1); } + if (json) + dump_obj = json_obj_create(); fs->default_bitmap_type = EXT2FS_BMAP64_RBTREE; if (ext2fs_has_feature_64bit(fs->super)) blocks64 = 1; @@ -616,10 +874,11 @@ try_open_again: ext2fs_close_free(&fs); exit(0); } - if (ext2fs_has_feature_journal(fs->super) && + if (!json && ext2fs_has_feature_journal(fs->super) && (fs->super->s_journal_inum != 0)) print_inline_journal_information(fs); - list_bad_blocks(fs, 0); + if (!json) + list_bad_blocks(fs, 0); if (header_only) { if (json) { json_obj_print_json(dump_obj, 0); @@ -639,7 +898,10 @@ try_bitmaps_again: if (!retval && (fs->flags & EXT2_FLAG_IGNORE_CSUM_ERRORS)) printf("%s", _("\n*** Checksum errors detected in bitmaps! Run e2fsck now!\n\n")); just_descriptors: - list_desc(fs, grp_only); + if (json) + fill_json_desc(dump_obj, fs); + else + list_desc(fs, grp_only); if (retval) { printf(_("\n%s: %s: error reading bitmaps: %s\n"), program_name, device_name,