aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2020-03-28 16:51:52 -0400
committerTheodore Ts'o <tytso@mit.edu>2020-04-10 00:10:47 -0400
commita4ce6ecc4979faccd6cec1ba7e7b391d3b097244 (patch)
tree8f38f8fea91b43e28092754f580044d41bcea1b6
parent8fd92e9af006da392d667775b8bbe0db9e8639d2 (diff)
downloade2fsprogs-a4ce6ecc4979faccd6cec1ba7e7b391d3b097244.tar.gz
ext4: add support for printing the error code associated with an error
The error code allows the kernel to bucket the possible cause of an ext4 corruption by Unix errno codes (e.g., EIO, EFSBADCRC, ESHUTDOWN, etc.) Signed-off-by: Theodore Ts'o <tytso@mit.edu>
-rw-r--r--lib/e2p/Makefile.in15
-rw-r--r--lib/e2p/e2p.h2
-rw-r--r--lib/e2p/errcode.c47
-rw-r--r--lib/e2p/ls.c26
-rw-r--r--lib/ext2fs/ext2_fs.h3
-rw-r--r--lib/ext2fs/tst_super_size.c3
6 files changed, 80 insertions, 16 deletions
diff --git a/lib/e2p/Makefile.in b/lib/e2p/Makefile.in
index 9e96884a0..3e4395ec8 100644
--- a/lib/e2p/Makefile.in
+++ b/lib/e2p/Makefile.in
@@ -20,17 +20,20 @@ OBJS= feature.o fgetflags.o fsetflags.o fgetversion.o fsetversion.o \
getflags.o getversion.o hashstr.o iod.o ls.o ljs.o mntopts.o \
parse_num.o pe.o pf.o ps.o setflags.o setversion.o uuid.o \
ostype.o percent.o crypto_mode.o fgetproject.o fsetproject.o \
- encoding.o
+ encoding.o errcode.o
SRCS= $(srcdir)/feature.c $(srcdir)/fgetflags.c \
$(srcdir)/fsetflags.c $(srcdir)/fgetversion.c \
$(srcdir)/fsetversion.c $(srcdir)/getflags.c \
$(srcdir)/getversion.c $(srcdir)/hashstr.c $(srcdir)/iod.c \
- $(srcdir)/ls.c $(srcdir)/ljs.c $(srcdir)/mntopts.c $(srcdir)/parse_num.c \
- $(srcdir)/pe.c $(srcdir)/pf.c $(srcdir)/ps.c \
- $(srcdir)/setflags.c $(srcdir)/setversion.c $(srcdir)/uuid.c \
- $(srcdir)/ostype.c $(srcdir)/percent.c $(srcdir)/crypto_mode.c \
- $(srcdir)/fgetproject.c $(srcdir)/fsetproject.c $(srcdir)/encoding.c
+ $(srcdir)/ls.c $(srcdir)/ljs.c $(srcdir)/mntopts.c \
+ $(srcdir)/parse_num.c $(srcdir)/pe.c $(srcdir)/pf.c \
+ $(srcdir)/ps.c $(srcdir)/setflags.c $(srcdir)/setversion.c \
+ $(srcdir)/uuid.c $(srcdir)/ostype.c $(srcdir)/percent.c \
+ $(srcdir)/crypto_mode.c $(srcdir)/fgetproject.c \
+ $(srcdir)/fsetproject.c $(srcdir)/encoding.c \
+ $(srcdir)/errcode.c
+
HFILES= e2p.h
LIBRARY= libe2p
diff --git a/lib/e2p/e2p.h b/lib/e2p/e2p.h
index ae7dd74dd..90efb6249 100644
--- a/lib/e2p/e2p.h
+++ b/lib/e2p/e2p.h
@@ -87,3 +87,5 @@ int e2p_str2encoding(const char *string);
const char *e2p_encoding2str(int encoding);
int e2p_get_encoding_flags(int encoding);
int e2p_str2encoding_flags(int encoding, char *param, __u16 *flags);
+
+const char *e2p_errcode2str(int err);
diff --git a/lib/e2p/errcode.c b/lib/e2p/errcode.c
new file mode 100644
index 000000000..27d4b15f8
--- /dev/null
+++ b/lib/e2p/errcode.c
@@ -0,0 +1,47 @@
+/*
+ * errcode.c - convert an error code to a string
+ */
+
+#include "config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+static const char *err_string[] = {
+ "",
+ "UNKNOWN", /* 1 */
+ "EIO", /* 2 */
+ "ENOMEM", /* 3 */
+ "EFSBADCRC", /* 4 */
+ "EFSCORRUPTED", /* 5 */
+ "ENOSPC", /* 6 */
+ "ENOKEY", /* 7 */
+ "EROFS", /* 8 */
+ "EFBIG", /* 9 */
+ "EEXIST", /* 10 */
+ "ERANGE", /* 11 */
+ "EOVERFLOW", /* 12 */
+ "EBUSY", /* 13 */
+ "ENOTDIR", /* 14 */
+ "ENOTEMPTY", /* 15 */
+ "ESHUTDOWN", /* 16 */
+ "EFAULT", /* 17 */
+};
+
+#define ARRAY_SIZE(array) \
+ (sizeof(array) / sizeof(array[0]))
+
+/* Return the name of an encoding or NULL */
+const char *e2p_errcode2str(int err)
+{
+ unsigned int i;
+ static char buf[32];
+
+ if (err < ARRAY_SIZE(err_string))
+ return err_string[err];
+
+ sprintf(buf, "UNKNOWN_ERRCODE_%d", err);
+ return buf;
+}
+
+
diff --git a/lib/e2p/ls.c b/lib/e2p/ls.c
index 740bc8de1..5aad15d76 100644
--- a/lib/e2p/ls.c
+++ b/lib/e2p/ls.c
@@ -422,10 +422,15 @@ void list_super2(struct ext2_super_block * sb, FILE *f)
EXT2_LEN_STR(sb->s_first_error_func));
fprintf(f, "First error line #: %u\n",
sb->s_first_error_line);
- fprintf(f, "First error inode #: %u\n",
- sb->s_first_error_ino);
- fprintf(f, "First error block #: %llu\n",
- sb->s_first_error_block);
+ if (sb->s_first_error_ino)
+ fprintf(f, "First error inode #: %u\n",
+ sb->s_first_error_ino);
+ if (sb->s_first_error_block)
+ fprintf(f, "First error block #: %llu\n",
+ sb->s_first_error_block);
+ if (sb->s_first_error_errcode)
+ fprintf(f, "First error err: %s\n",
+ e2p_errcode2str(sb->s_first_error_errcode));
}
if (sb->s_last_error_time) {
tm = sb->s_last_error_time;
@@ -434,10 +439,15 @@ void list_super2(struct ext2_super_block * sb, FILE *f)
EXT2_LEN_STR(sb->s_last_error_func));
fprintf(f, "Last error line #: %u\n",
sb->s_last_error_line);
- fprintf(f, "Last error inode #: %u\n",
- sb->s_last_error_ino);
- fprintf(f, "Last error block #: %llu\n",
- sb->s_last_error_block);
+ if (sb->s_last_error_ino)
+ fprintf(f, "Last error inode #: %u\n",
+ sb->s_last_error_ino);
+ if (sb->s_last_error_block)
+ fprintf(f, "Last error block #: %llu\n",
+ sb->s_last_error_block);
+ if (sb->s_last_error_errcode)
+ fprintf(f, "Last error err: %s\n",
+ e2p_errcode2str(sb->s_last_error_errcode));
}
if (ext2fs_has_feature_mmp(sb)) {
fprintf(f, "MMP block number: %llu\n",
diff --git a/lib/ext2fs/ext2_fs.h b/lib/ext2fs/ext2_fs.h
index 6c20ea778..0376674c4 100644
--- a/lib/ext2fs/ext2_fs.h
+++ b/lib/ext2fs/ext2_fs.h
@@ -755,7 +755,8 @@ struct ext2_super_block {
__u8 s_lastcheck_hi;
__u8 s_first_error_time_hi;
__u8 s_last_error_time_hi;
- __u8 s_pad[2];
+ __u8 s_first_error_errcode;
+ __u8 s_last_error_errcode;
/*27c*/ __le16 s_encoding; /* Filename charset encoding */
__le16 s_encoding_flags; /* Filename charset encoding flags */
__le32 s_reserved[95]; /* Padding to the end of the block */
diff --git a/lib/ext2fs/tst_super_size.c b/lib/ext2fs/tst_super_size.c
index ab38dd59d..80a5269bc 100644
--- a/lib/ext2fs/tst_super_size.c
+++ b/lib/ext2fs/tst_super_size.c
@@ -148,7 +148,8 @@ int main(int argc, char **argv)
check_field(s_lastcheck_hi, 1);
check_field(s_first_error_time_hi, 1);
check_field(s_last_error_time_hi, 1);
- check_field(s_pad, 2);
+ check_field(s_first_error_errcode, 1);
+ check_field(s_last_error_errcode, 1);
check_field(s_encoding, 2);
check_field(s_encoding_flags, 2);
check_field(s_reserved, 95 * 4);