On Nov 27, 2020, at 4:33 AM, Jan Kara wrote: > > We convert errno's to ext4 on-disk format error codes in > save_error_info(). Add a function and a bit of macro magic to make this > simpler. > > Signed-off-by: Jan Kara In hindsight, it would have been better (IMHO) if the EXT4_ERR_* values mapped to the standard x86_64 errors in errno.h, since that is what most admins/users are familiar with (e.g. 5 = EIO, 12 = ENOMEM, 28 = ENOSPC, 30 = EROFS). That would avoid the need to look up the EXT4_ERR_* values, since it doesn't look like dumpe2fs even handles these fields yet. I guess I never noticed the original patch when it was submitted, so water under the bridge, I guess... Reviewed-by: Andreas Dilger > --- > fs/ext4/super.c | 95 ++++++++++++++++++++++++--------------------------------- > 1 file changed, 40 insertions(+), 55 deletions(-) > > diff --git a/fs/ext4/super.c b/fs/ext4/super.c > index 7948c07d0a90..8add06d08495 100644 > --- a/fs/ext4/super.c > +++ b/fs/ext4/super.c > @@ -551,76 +551,61 @@ static bool system_going_down(void) > || system_state == SYSTEM_RESTART; > } > > +struct ext4_err_translation { > + int code; > + int errno; > +}; > + > +#define EXT4_ERR_TRANSLATE(err) { .code = EXT4_ERR_##err, .errno = err } > + > +static struct ext4_err_translation err_translation[] = { > + EXT4_ERR_TRANSLATE(EIO), > + EXT4_ERR_TRANSLATE(ENOMEM), > + EXT4_ERR_TRANSLATE(EFSBADCRC), > + EXT4_ERR_TRANSLATE(EFSCORRUPTED), > + EXT4_ERR_TRANSLATE(ENOSPC), > + EXT4_ERR_TRANSLATE(ENOKEY), > + EXT4_ERR_TRANSLATE(EROFS), > + EXT4_ERR_TRANSLATE(EFBIG), > + EXT4_ERR_TRANSLATE(EEXIST), > + EXT4_ERR_TRANSLATE(ERANGE), > + EXT4_ERR_TRANSLATE(EOVERFLOW), > + EXT4_ERR_TRANSLATE(EBUSY), > + EXT4_ERR_TRANSLATE(ENOTDIR), > + EXT4_ERR_TRANSLATE(ENOTEMPTY), > + EXT4_ERR_TRANSLATE(ESHUTDOWN), > + EXT4_ERR_TRANSLATE(EFAULT), > +}; > + > +static int ext4_errno_to_code(int errno) > +{ > + int i; > + > + for (i = 0; i < ARRAY_SIZE(err_translation); i++) > + if (err_translation[i].errno == errno) > + return err_translation[i].code; > + return EXT4_ERR_UNKNOWN; > +} > + > static void __save_error_info(struct super_block *sb, int error, > __u32 ino, __u64 block, > const char *func, unsigned int line) > { > struct ext4_super_block *es = EXT4_SB(sb)->s_es; > - int err; > > EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS; > if (bdev_read_only(sb->s_bdev)) > return; > + /* We default to EFSCORRUPTED error... */ > + if (error == 0) > + error = EFSCORRUPTED; > es->s_state |= cpu_to_le16(EXT4_ERROR_FS); > ext4_update_tstamp(es, s_last_error_time); > strncpy(es->s_last_error_func, func, sizeof(es->s_last_error_func)); > es->s_last_error_line = cpu_to_le32(line); > es->s_last_error_ino = cpu_to_le32(ino); > es->s_last_error_block = cpu_to_le64(block); > - switch (error) { > - case EIO: > - err = EXT4_ERR_EIO; > - break; > - case ENOMEM: > - err = EXT4_ERR_ENOMEM; > - break; > - case EFSBADCRC: > - err = EXT4_ERR_EFSBADCRC; > - break; > - case 0: > - case EFSCORRUPTED: > - err = EXT4_ERR_EFSCORRUPTED; > - break; > - case ENOSPC: > - err = EXT4_ERR_ENOSPC; > - break; > - case ENOKEY: > - err = EXT4_ERR_ENOKEY; > - break; > - case EROFS: > - err = EXT4_ERR_EROFS; > - break; > - case EFBIG: > - err = EXT4_ERR_EFBIG; > - break; > - case EEXIST: > - err = EXT4_ERR_EEXIST; > - break; > - case ERANGE: > - err = EXT4_ERR_ERANGE; > - break; > - case EOVERFLOW: > - err = EXT4_ERR_EOVERFLOW; > - break; > - case EBUSY: > - err = EXT4_ERR_EBUSY; > - break; > - case ENOTDIR: > - err = EXT4_ERR_ENOTDIR; > - break; > - case ENOTEMPTY: > - err = EXT4_ERR_ENOTEMPTY; > - break; > - case ESHUTDOWN: > - err = EXT4_ERR_ESHUTDOWN; > - break; > - case EFAULT: > - err = EXT4_ERR_EFAULT; > - break; > - default: > - err = EXT4_ERR_UNKNOWN; > - } > - es->s_last_error_errcode = err; > + es->s_last_error_errcode = ext4_errno_to_code(error); > if (!es->s_first_error_time) { > es->s_first_error_time = es->s_last_error_time; > es->s_first_error_time_hi = es->s_last_error_time_hi; > -- > 2.16.4 > Cheers, Andreas