Viktor Prutyanov <viktor.prutyanov@xxxxxxxxxxxxx> writes: > This patch adds JSON output of superblock information > Looks good. Acked-by: Dmitry Monakhov <dmonakhov@xxxxxxxxxx> > Signed-off-by: Viktor Prutyanov <viktor.prutyanov@xxxxxxxxxxxxx> > --- > debugfs/Makefile.in | 4 +- > lib/e2p/e2p.h | 6 + > lib/e2p/ls.c | 362 ++++++++++++++++++++++++++++++++++++++++++++++++++++ > lib/e2p/pe.c | 18 +++ > lib/e2p/ps.c | 10 ++ > misc/Makefile.in | 8 +- > misc/dumpe2fs.c | 5 +- > 7 files changed, 406 insertions(+), 7 deletions(-) > > diff --git a/debugfs/Makefile.in b/debugfs/Makefile.in > index 57940cde..92a3552a 100644 > --- a/debugfs/Makefile.in > +++ b/debugfs/Makefile.in > @@ -34,9 +34,9 @@ SRCS= debug_cmds.c $(srcdir)/debugfs.c $(srcdir)/util.c $(srcdir)/ls.c \ > $(srcdir)/journal.c $(srcdir)/../e2fsck/revoke.c \ > $(srcdir)/../e2fsck/recovery.c $(srcdir)/do_journal.c > > -LIBS= $(LIBSUPPORT) $(LIBEXT2FS) $(LIBE2P) $(LIBSS) $(LIBCOM_ERR) $(LIBBLKID) \ > +LIBS= $(LIBEXT2FS) $(LIBE2P) $(LIBSUPPORT) $(LIBSS) $(LIBCOM_ERR) $(LIBBLKID) \ > $(LIBUUID) $(LIBMAGIC) $(SYSLIBS) > -DEPLIBS= $(DEPLIBSUPPORT) $(LIBEXT2FS) $(LIBE2P) $(DEPLIBSS) $(DEPLIBCOM_ERR) \ > +DEPLIBS= $(LIBEXT2FS) $(LIBE2P) $(LIBSUPPORT) $(DEPLIBSS) $(DEPLIBCOM_ERR) \ > $(DEPLIBBLKID) $(DEPLIBUUID) > > STATIC_LIBS= $(STATIC_LIBSUPPORT) $(STATIC_LIBEXT2FS) $(STATIC_LIBSS) \ > diff --git a/lib/e2p/e2p.h b/lib/e2p/e2p.h > index e96cdec8..88c08d73 100644 > --- a/lib/e2p/e2p.h > +++ b/lib/e2p/e2p.h > @@ -13,6 +13,8 @@ > > #include <ext2fs/ext2_fs.h> > > +#include "support/json-out.h" > + > #define E2P_FEATURE_COMPAT 0 > #define E2P_FEATURE_INCOMPAT 1 > #define E2P_FEATURE_RO_INCOMPAT 2 > @@ -42,8 +44,10 @@ int iterate_on_dir (const char * dir_name, > void list_super(struct ext2_super_block * s); > void list_super2(struct ext2_super_block * s, FILE *f); > void print_fs_errors (FILE * f, unsigned short errors); > +void snprint_fs_errors (char *str, size_t size, unsigned short errors); > void print_flags (FILE * f, unsigned long flags, unsigned options); > void print_fs_state (FILE * f, unsigned short state); > +void snprint_fs_state (char *str, size_t size, unsigned short state); > int setflags (int fd, unsigned long flags); > int setversion (int fd, unsigned long version); > > @@ -77,3 +81,5 @@ char *e2p_os2string(int os_type); > int e2p_string2os(char *str); > > unsigned int e2p_percent(int percent, unsigned int base); > + > +void fill_json_super(struct json_obj *obj, struct ext2_super_block * s); > diff --git a/lib/e2p/ls.c b/lib/e2p/ls.c > index a7586e09..b690960b 100644 > --- a/lib/e2p/ls.c > +++ b/lib/e2p/ls.c > @@ -37,6 +37,15 @@ static void print_user (unsigned short uid, FILE *f) > fprintf(f, "(user %s)\n", pw->pw_name); > } > > +static void fill_json_user(struct json_obj *obj, unsigned short uid) > +{ > + struct passwd *pw = getpwuid(uid); > + > + json_obj_add_fmt_str(obj, "uid", 32, "%u", uid); > + if (pw) > + json_obj_add_str(obj, "user", pw->pw_name); > +} > + > static void print_group (unsigned short gid, FILE *f) > { > struct group *gr; > @@ -49,6 +58,15 @@ static void print_group (unsigned short gid, FILE *f) > fprintf(f, "(group %s)\n", gr->gr_name); > } > > +static void fill_json_group(struct json_obj *obj, unsigned short gid) > +{ > + struct group *gr = getgrgid(gid); > + > + json_obj_add_fmt_str(obj, "gid", 32, "%u", gid); > + if (gr) > + json_obj_add_str(obj, "group", gr->gr_name); > +} > + > #define MONTH_INT (86400 * 30) > #define WEEK_INT (86400 * 7) > #define DAY_INT (86400) > @@ -117,6 +135,24 @@ static void print_features(struct ext2_super_block * s, FILE *f) > #endif > } > > +static void fill_json_features(struct json_obj *obj, > + struct ext2_super_block *s) > +{ > +#ifdef EXT2_DYNAMIC_REV > + int i, j; > + __u32 *mask = &s->s_feature_compat, m; > + struct json_list *list = json_list_create_in_obj(obj, > + "filesystem-features", JSON_VAL_STRING); > + > + for (i=0; i <3; i++,mask++) { > + for (j=0,m=1; j < 32; j++, m<<=1) { > + if (*mask & m) > + json_list_add_str(list, e2p_feature2string(i, m)); > + } > + } > +#endif > +} > + > static void print_mntopts(struct ext2_super_block * s, FILE *f) > { > #ifdef EXT2_DYNAMIC_REV > @@ -142,6 +178,26 @@ static void print_mntopts(struct ext2_super_block * s, FILE *f) > #endif > } > > +static void fill_json_mntopts(struct json_obj *obj, > + struct ext2_super_block *s) > +{ > +#ifdef EXT2_DYNAMIC_REV > + int i; > + __u32 mask = s->s_default_mount_opts, m; > + struct json_list *list = json_list_create_in_obj(obj, > + "default-mount-options", JSON_VAL_STRING); > + > + if (mask & EXT3_DEFM_JMODE) > + json_list_add_str(list, e2p_mntopt2string(mask & EXT3_DEFM_JMODE)); > + for (i=0,m=1; i < 32; i++, m<<=1) { > + if (m & EXT3_DEFM_JMODE) > + continue; > + if (mask & m) > + json_list_add_str(list, e2p_mntopt2string(m)); > + } > +#endif > +} > + > static void print_super_flags(struct ext2_super_block * s, FILE *f) > { > int flags_found = 0; > @@ -168,6 +224,25 @@ static void print_super_flags(struct ext2_super_block * s, FILE *f) > fputs("(none)\n", f); > } > > +static void fill_json_super_flags(struct json_obj *obj, > + struct ext2_super_block *s) > +{ > + int flags_found = 0; > + struct json_list *list = json_list_create_in_obj(obj, > + "filesystem-flags", JSON_VAL_STRING); > + > + if (s->s_flags == 0) > + return; > + > + if (s->s_flags & EXT2_FLAGS_SIGNED_HASH) > + json_list_add_str(list, "signed_directory_hash"); > + if (s->s_flags & EXT2_FLAGS_UNSIGNED_HASH) > + json_list_add_str(list, "unsigned_directory_hash"); > + if (s->s_flags & EXT2_FLAGS_TEST_FILESYS) > + json_list_add_str(list, "test_filesystem"); > +} > + > + > static __u64 e2p_blocks_count(struct ext2_super_block *super) > { > return super->s_blocks_count | > @@ -213,6 +288,12 @@ static const char *quota_prefix[MAXQUOTAS] = { > [PRJQUOTA] = "Project quota inode:", > }; > > +static const char *json_quota_prefix[MAXQUOTAS] = { > + [USRQUOTA] = "user-quota-inode", > + [GRPQUOTA] = "group-quota-inode", > + [PRJQUOTA] = "project-quota-inode", > +}; > + > /** > * Convert type of quota to written representation > */ > @@ -477,3 +558,284 @@ void list_super (struct ext2_super_block * s) > list_super2(s, stdout); > } > > +static void fill_json_time(struct json_obj *obj, const char *key, char *buf, > + time_t tm) > +{ > + char *str; > + > + if (tm && (ctime_r(&tm, buf))) { > + if (str = strchr(buf, '\n')) > + *str = '\0'; > + json_obj_add_str(obj, key, buf); > + } > +} > + > +void fill_json_super(struct json_obj *obj, struct ext2_super_block * sb) > +{ > + int inode_blocks_per_group; > + char buf[80], *str; > + time_t tm; > + enum quota_type qtype; > + struct json_obj *super_obj = json_obj_create_in_obj(obj, "super"); > + > + inode_blocks_per_group = (((sb->s_inodes_per_group * > + EXT2_INODE_SIZE(sb)) + > + EXT2_BLOCK_SIZE(sb) - 1) / > + EXT2_BLOCK_SIZE(sb)); > + if (sb->s_volume_name[0]) { > + memset(buf, 0, sizeof(buf)); > + strncpy(buf, sb->s_volume_name, sizeof(sb->s_volume_name)); > + } else > + strcpy(buf, "<none>"); > + json_obj_add_str(super_obj, "fs-volume-name", buf); > + if (sb->s_last_mounted[0]) { > + memset(buf, 0, sizeof(buf)); > + strncpy(buf, sb->s_last_mounted, sizeof(sb->s_last_mounted)); > + } else > + strcpy(buf, "<not available>"); > + json_obj_add_str(super_obj, "last-mounted-on", buf); > + json_obj_add_str(super_obj, "fs-uuid", e2p_uuid2str(sb->s_uuid)); > + json_obj_add_fmt_buf_str(super_obj, "fs-magic-number", buf, sizeof(buf), > + "0x%04X", sb->s_magic); > + json_obj_add_fmt_buf_str(super_obj, "fs-revision-level", buf, sizeof(buf), > + "%d", sb->s_rev_level); > + fill_json_features(super_obj, sb); > + fill_json_super_flags(super_obj, sb); > + fill_json_mntopts(super_obj, sb); > + if (sb->s_mount_opts[0]) > + json_obj_add_str(super_obj, "mount-options", sb->s_mount_opts); > + snprint_fs_state(buf, sizeof(buf), sb->s_state); > + json_obj_add_str(super_obj, "fs-state", buf); > + snprint_fs_errors(buf, sizeof(buf), sb->s_errors); > + json_obj_add_str(super_obj, "errors-behaviour", buf); > + str = e2p_os2string(sb->s_creator_os); > + json_obj_add_str(super_obj, "fs-os-type", str); > + free(str); > + json_obj_add_fmt_buf_str(super_obj, "inode-count", buf, sizeof(buf), "%u", > + sb->s_inodes_count); > + json_obj_add_fmt_buf_str(super_obj, "block-count", buf, sizeof(buf), > + "%llu", e2p_blocks_count(sb)); > + json_obj_add_fmt_buf_str(super_obj, "reserved-block-count", buf, > + sizeof(buf), "%llu", e2p_r_blocks_count(sb)); > + if (sb->s_overhead_blocks) > + json_obj_add_fmt_buf_str(super_obj, "overhead-blocks", buf, > + sizeof(buf), "%u", sb->s_overhead_blocks); > + json_obj_add_fmt_buf_str(super_obj, "free-blocks", buf, sizeof(buf), > + "%llu", e2p_free_blocks_count(sb)); > + json_obj_add_fmt_buf_str(super_obj, "free-inodes", buf, sizeof(buf), "%u", > + sb->s_free_inodes_count); > + json_obj_add_fmt_buf_str(super_obj, "first-block", buf, sizeof(buf), "%u", > + sb->s_first_data_block); > + json_obj_add_fmt_buf_str(super_obj, "block-size", buf, sizeof(buf), "%u", > + EXT2_BLOCK_SIZE(sb)); > + if (ext2fs_has_feature_bigalloc(sb)) > + json_obj_add_fmt_buf_str(super_obj, "cluster-size", buf, sizeof(buf), > + "%u", EXT2_CLUSTER_SIZE(sb)); > + else > + json_obj_add_fmt_buf_str(super_obj, "fragment-size", buf, sizeof(buf), > + "%u", EXT2_CLUSTER_SIZE(sb)); > + > + if (ext2fs_has_feature_64bit(sb)) > + json_obj_add_fmt_buf_str(super_obj, "group-descriptor-size", buf, > + sizeof(buf), "%u", sb->s_desc_size); > + if (sb->s_reserved_gdt_blocks) > + json_obj_add_fmt_buf_str(super_obj, "reserved-gdt-blocks", buf, > + sizeof(buf), "%u", sb->s_reserved_gdt_blocks); > + json_obj_add_fmt_buf_str(super_obj, "blocks-per-group", buf, sizeof(buf), > + "%u", sb->s_blocks_per_group); > + if (ext2fs_has_feature_bigalloc(sb)) > + json_obj_add_fmt_buf_str(super_obj, "clusters-per-group", buf, > + sizeof(buf), "%u", sb->s_clusters_per_group); > + else > + json_obj_add_fmt_buf_str(super_obj, "fragments-per-group", buf, > + sizeof(buf), "%u", sb->s_clusters_per_group); > + json_obj_add_fmt_buf_str(super_obj, "inodes-per-group", buf, sizeof(buf), > + "%u", sb->s_inodes_per_group); > + json_obj_add_fmt_buf_str(super_obj, "inode-blocks-per-group", buf, > + sizeof(buf), "%u", inode_blocks_per_group); > + if (sb->s_raid_stride) > + json_obj_add_fmt_buf_str(super_obj, "raid-stride", buf, sizeof(buf), > + "%u", sb->s_raid_stride); > + if (sb->s_raid_stripe_width) > + json_obj_add_fmt_buf_str(super_obj, "raid-stripe-width", buf, > + sizeof(buf), "%u", sb->s_raid_stripe_width); > + if (sb->s_first_meta_bg) > + json_obj_add_fmt_buf_str(super_obj, "first-meta-block-group", buf, > + sizeof(buf), "%u", sb->s_first_meta_bg); > + if (sb->s_log_groups_per_flex) > + json_obj_add_fmt_buf_str(super_obj, "flex-block-group-size", buf, > + sizeof(buf), "%u", 1 << sb->s_log_groups_per_flex); > + > + json_obj_add_fmt_buf_str(super_obj, "inodes-per-group", buf, sizeof(buf), > + "%u", sb->s_inodes_per_group); > + json_obj_add_fmt_buf_str(super_obj, "inode-blocks-per-group", buf, > + sizeof(buf), "%u", inode_blocks_per_group); > + if (sb->s_raid_stride) > + json_obj_add_fmt_buf_str(super_obj, "raid-stride", buf, sizeof(buf), > + "%u", sb->s_raid_stride); > + if (sb->s_raid_stripe_width) > + json_obj_add_fmt_buf_str(super_obj, "raid-stripe-width", buf, > + sizeof(buf), "%u", sb->s_raid_stripe_width); > + if (sb->s_first_meta_bg) > + json_obj_add_fmt_buf_str(super_obj, "first-meta-block-group", buf, > + sizeof(buf), "%u", sb->s_first_meta_bg); > + if (sb->s_log_groups_per_flex) > + json_obj_add_fmt_buf_str(super_obj, "flex-block-group-size", buf, > + sizeof(buf), "%u", 1 << sb->s_log_groups_per_flex); > + fill_json_time(super_obj, "filesystem-created", buf, sb->s_mkfs_time); > + fill_json_time(super_obj, "last-mount-time", buf, sb->s_mtime); > + fill_json_time(super_obj, "last-write-time", buf, sb->s_wtime); > + json_obj_add_fmt_buf_str(super_obj, "mount-count", buf, sizeof(buf), > + "%u", sb->s_mnt_count); > + json_obj_add_fmt_buf_str(super_obj, "maximum-mount-count", buf, > + sizeof(buf), "%d", sb->s_max_mnt_count); > + fill_json_time(super_obj, "last-checked", buf, sb->s_lastcheck); > + json_obj_add_fmt_buf_str(super_obj, "check-interval", buf, sizeof(buf), > + "%u", sb->s_checkinterval); > + json_obj_add_str(super_obj, "check-interval-str", > + interval_string(sb->s_checkinterval)); > + if (sb->s_checkinterval) > + { > + time_t next = sb->s_lastcheck + sb->s_checkinterval; > + > + fill_json_time(super_obj, "next-check-after", buf, > + sb->s_lastcheck + sb->s_checkinterval); > + } > +#define POW2(x) ((__u64) 1 << (x)) > + if (sb->s_kbytes_written) { > + if (sb->s_kbytes_written < POW2(13)) > + json_obj_add_fmt_buf_str(super_obj, "lifetime-writes", buf, > + sizeof(buf), "%llu kB", sb->s_kbytes_written); > + else if (sb->s_kbytes_written < POW2(23)) > + json_obj_add_fmt_buf_str(super_obj, "lifetime-writes", buf, > + sizeof(buf), "%llu MB", > + (sb->s_kbytes_written + POW2(9)) >> 10); > + else if (sb->s_kbytes_written < POW2(33)) > + json_obj_add_fmt_buf_str(super_obj, "lifetime-writes", buf, > + sizeof(buf), "%llu GB", > + (sb->s_kbytes_written + POW2(19)) >> 20); > + else if (sb->s_kbytes_written < POW2(43)) > + json_obj_add_fmt_buf_str(super_obj, "lifetime-writes", buf, > + sizeof(buf), "%llu TB", > + (sb->s_kbytes_written + POW2(29)) >> 30); > + else > + json_obj_add_fmt_buf_str(super_obj, "lifetime-writes", buf, > + sizeof(buf), "%llu PB", > + (sb->s_kbytes_written + POW2(39)) >> 40); > + } > + fill_json_user(super_obj, sb->s_def_resuid); > + fill_json_group(super_obj, sb->s_def_resgid); > + if (sb->s_rev_level >= EXT2_DYNAMIC_REV) { > + json_obj_add_fmt_buf_str(super_obj, "first-inode", buf, sizeof(buf), > + "%d", sb->s_first_ino); > + json_obj_add_fmt_buf_str(super_obj, "inode-size", buf, sizeof(buf), > + "%d", sb->s_inode_size); > + if (sb->s_min_extra_isize) > + json_obj_add_fmt_buf_str(super_obj, "required-extra-isize", buf, > + sizeof(buf), "%d", sb->s_min_extra_isize); > + if (sb->s_want_extra_isize) > + json_obj_add_fmt_buf_str(super_obj, "desired-extra-isize", buf, > + sizeof(buf), "%d", sb->s_want_extra_isize); > + } > + if (!e2p_is_null_uuid(sb->s_journal_uuid)) > + json_obj_add_str(super_obj, "journal-uuid", > + e2p_uuid2str(sb->s_journal_uuid)); > + if (sb->s_journal_inum) > + json_obj_add_fmt_buf_str(super_obj, "journal-inode", buf, > + sizeof(buf), "%u", sb->s_journal_inum); > + if (sb->s_journal_dev) > + json_obj_add_fmt_buf_str(super_obj, "journal-device", buf, > + sizeof(buf), "0x%04x", sb->s_journal_dev); > + if (sb->s_last_orphan) > + json_obj_add_fmt_buf_str(super_obj, "first-orphan-inode", buf, > + sizeof(buf), "%u", sb->s_last_orphan); > + if (ext2fs_has_feature_dir_index(sb) || > + sb->s_def_hash_version) > + json_obj_add_str(super_obj, "default-directory-hash", > + e2p_hash2string(sb->s_def_hash_version)); > + if (!e2p_is_null_uuid(sb->s_hash_seed)) > + json_obj_add_str(super_obj, "directory-hash-seed", > + e2p_uuid2str(sb->s_hash_seed)); > + if (sb->s_jnl_backup_type) { > + switch (sb->s_jnl_backup_type) { > + case 1: > + json_obj_add_str(super_obj, "journal-backup", "inode blocks"); > + break; > + default: > + json_obj_add_fmt_buf_str(super_obj, "journal-backup", buf, > + sizeof(buf), "type %u", sb->s_jnl_backup_type); > + } > + } > + if (sb->s_backup_bgs[0]) > + json_obj_add_fmt_buf_str(super_obj, "backup-block-group-0", buf, > + sizeof(buf), "%u", sb->s_backup_bgs[0]); > + if (sb->s_backup_bgs[1]) > + json_obj_add_fmt_buf_str(super_obj, "backup-block-group-1", buf, > + sizeof(buf), "%u", sb->s_backup_bgs[1]); > + if (sb->s_snapshot_inum) { > + json_obj_add_fmt_buf_str(super_obj, "snapshot-inode", buf, sizeof(buf), > + "%u", sb->s_snapshot_inum); > + json_obj_add_fmt_buf_str(super_obj, "snapshot-id", buf, sizeof(buf), > + "%u", sb->s_snapshot_id); > + json_obj_add_fmt_buf_str(super_obj, "snapshot-reserved-blocks", buf, > + sizeof(buf), "%llu", sb->s_snapshot_r_blocks_count); > + } > + if (sb->s_snapshot_list) > + json_obj_add_fmt_buf_str(super_obj, "snapshot-list-head", buf, > + sizeof(buf), "%u", sb->s_snapshot_list); > + if (sb->s_error_count) > + json_obj_add_fmt_buf_str(super_obj, "fs-error-count", buf, sizeof(buf), > + "%u", sb->s_error_count); > + if (sb->s_first_error_time) { > + fill_json_time(super_obj, "first-error-time", buf, > + sb->s_first_error_time); > + memset(buf, 0, sizeof(buf)); > + strncpy(buf, (char *)sb->s_first_error_func, > + sizeof(sb->s_first_error_func)); > + json_obj_add_str(super_obj, "first-error-function", buf); > + json_obj_add_fmt_buf_str(super_obj, "first-error-line-num", buf, > + sizeof(buf), "%u", sb->s_first_error_line); > + json_obj_add_fmt_buf_str(super_obj, "first-error-inode-num", buf, > + sizeof(buf), "%u", sb->s_first_error_ino); > + json_obj_add_fmt_buf_str(super_obj, "first-error-block-num", buf, > + sizeof(buf), "%llu", sb->s_first_error_block); > + } > + if (sb->s_last_error_time) { > + fill_json_time(super_obj, "last-error-time", buf, > + sb->s_last_error_time); > + memset(buf, 0, sizeof(buf)); > + strncpy(buf, (char *)sb->s_last_error_func, > + sizeof(sb->s_last_error_func)); > + json_obj_add_str(super_obj, "last-error-function", buf); > + json_obj_add_fmt_buf_str(super_obj, "last-error-line-num", buf, > + sizeof(buf), "%u", sb->s_last_error_line); > + json_obj_add_fmt_buf_str(super_obj, "last-error-inode-num", buf, > + sizeof(buf), "%u", sb->s_last_error_ino); > + json_obj_add_fmt_buf_str(super_obj, "last-error-block-num", buf, > + sizeof(buf), "%llu", sb->s_last_error_block); > + } > + if (ext2fs_has_feature_mmp(sb)) { > + json_obj_add_fmt_buf_str(super_obj, "mmp-block-number", buf, > + sizeof(buf), "%llu", (long long)sb->s_mmp_block); > + json_obj_add_fmt_buf_str(super_obj, "mmp-update-interval", buf, > + sizeof(buf), "%u", sb->s_mmp_update_interval); > + } > + for (qtype = 0; qtype < MAXQUOTAS; qtype++) { > + if (*quota_sb_inump(sb, qtype) != 0) > + json_obj_add_fmt_buf_str(super_obj, json_quota_prefix[qtype], buf, > + sizeof(buf), "%u", *quota_sb_inump(sb, qtype)); > + } > + if (ext2fs_has_feature_metadata_csum(sb)) { > + json_obj_add_str(super_obj, "checksum-type", > + checksum_type(sb->s_checksum_type)); > + json_obj_add_fmt_buf_str(super_obj, "checksum", buf, sizeof(buf), > + "0x%08x", sb->s_checksum); > + } > + if (!e2p_is_null_uuid(sb->s_encrypt_pw_salt)) > + json_obj_add_str(super_obj, "encryption-pw-salt", > + e2p_uuid2str(sb->s_encrypt_pw_salt)); > + > + if (ext2fs_has_feature_csum_seed(sb)) > + json_obj_add_fmt_buf_str(super_obj, "checksum-seed", buf, sizeof(buf), > + "0x%08x", sb->s_checksum_seed); > +} > diff --git a/lib/e2p/pe.c b/lib/e2p/pe.c > index 1f24545d..9426e743 100644 > --- a/lib/e2p/pe.c > +++ b/lib/e2p/pe.c > @@ -38,3 +38,21 @@ void print_fs_errors (FILE * f, unsigned short errors) > fprintf (f, "Unknown (continue)"); > } > } > + > +void snprint_fs_errors (char *buf, size_t size, unsigned short errors) > +{ > + switch (errors) > + { > + case EXT2_ERRORS_CONTINUE: > + snprintf (buf, size, "Continue"); > + break; > + case EXT2_ERRORS_RO: > + snprintf (buf, size, "Remount read-only"); > + break; > + case EXT2_ERRORS_PANIC: > + snprintf (buf, size, "Panic"); > + break; > + default: > + snprintf (buf, size, "Unknown"); > + } > +} > diff --git a/lib/e2p/ps.c b/lib/e2p/ps.c > index 757f8a66..19eb6559 100644 > --- a/lib/e2p/ps.c > +++ b/lib/e2p/ps.c > @@ -30,3 +30,13 @@ void print_fs_state (FILE * f, unsigned short state) > if (state & EXT2_ERROR_FS) > fprintf (f, " with errors"); > } > + > +void snprint_fs_state (char *str, size_t size, unsigned short state) > +{ > + if (state & EXT2_VALID_FS) > + snprintf (str, size, "clean"); > + else > + snprintf (str, size, "not clean"); > + if (state & EXT2_ERROR_FS) > + snprintf (str, size, "with errors"); > +} > diff --git a/misc/Makefile.in b/misc/Makefile.in > index 6f631eb1..a863ef62 100644 > --- a/misc/Makefile.in > +++ b/misc/Makefile.in > @@ -170,15 +170,15 @@ e2initrd_helper: e2initrd_helper.o $(DEPLIBS) $(DEPLIBBLKID) $(LIBEXT2FS) > tune2fs: $(TUNE2FS_OBJS) $(DEPLIBS) $(DEPLIBS_E2P) $(DEPLIBBLKID) \ > $(DEPLIBUUID) $(LIBEXT2FS) > $(E) " LD $@" > - $(Q) $(CC) $(ALL_LDFLAGS) -o tune2fs $(TUNE2FS_OBJS) $(LIBS) \ > - $(LIBBLKID) $(LIBUUID) $(LIBEXT2FS) $(LIBS_E2P) \ > + $(Q) $(CC) $(ALL_LDFLAGS) -o tune2fs $(TUNE2FS_OBJS) \ > + $(LIBBLKID) $(LIBUUID) $(LIBEXT2FS) $(LIBS_E2P) $(LIBS) \ > $(LIBINTL) $(SYSLIBS) $(LIBBLKID) $(LIBMAGIC) > > tune2fs.static: $(TUNE2FS_OBJS) $(STATIC_DEPLIBS) $(STATIC_LIBE2P) $(DEPSTATIC_LIBBLKID) > $(E) " LD $@" > $(Q) $(CC) $(LDFLAGS_STATIC) -o tune2fs.static $(TUNE2FS_OBJS) \ > - $(STATIC_LIBS) $(STATIC_LIBBLKID) $(STATIC_LIBUUID) \ > - $(STATIC_LIBE2P) $(LIBINTL) $(SYSLIBS) \ > + $(STATIC_LIBBLKID) $(STATIC_LIBUUID) \ > + $(STATIC_LIBE2P) $(STATIC_LIBS) $(LIBINTL) $(SYSLIBS) \ > $(STATIC_LIBBLKID) $(LIBMAGIC) > > tune2fs.profiled: $(TUNE2FS_OBJS) $(PROFILED_DEPLIBS) \ > diff --git a/misc/dumpe2fs.c b/misc/dumpe2fs.c > index 319c296b..93e4b2ff 100644 > --- a/misc/dumpe2fs.c > +++ b/misc/dumpe2fs.c > @@ -863,7 +863,10 @@ try_open_again: > } else { > if (grp_only) > goto just_descriptors; > - list_super (fs->super); > + if (json) > + fill_json_super(dump_obj, fs->super); > + else > + list_super (fs->super); > if (ext2fs_has_feature_journal_dev(fs->super)) { > print_journal_information(fs, dump_obj); > if (json) { > -- > 2.14.1