[Ocfs2-devel] [patch 04/28] ocfs2: add errors=continue
Mark Fasheh
mfasheh at suse.de
Fri Aug 28 16:45:44 PDT 2015
On Wed, Aug 26, 2015 at 03:11:29PM -0700, Andrew Morton wrote:
> From: Goldwyn Rodrigues <rgoldwyn at suse.de>
> Subject: ocfs2: add errors=continue
>
> OCFS2 is often used in high-availaibility systems. However, ocfs2
> converts the filesystem to read-only at the drop of the hat. This may not
> be necessary, since turning the filesystem read-only would affect other
> running processes as well, decreasing availability.
>
> This attempt is to add errors=continue, which would return the EIO to the
> calling process and terminate furhter processing so that the filesystem is
> not corrupted further. However, the filesystem is not converted to
> read-only.
>
> As a future plan, I intend to create a small utility or extend fsck.ocfs2
> to fix small errors such as in the inode. The input to the utility such
> as the inode can come from the kernel logs so we don't have to schedule a
> downtime for fixing small-enough errors.
>
> The patch changes the ocfs2_error to return an error. The error returned
> depends on the mount option set. If none is set, the default is to turn
> the filesystem read-only.
>
> Perhaps errors=continue is not the best option name. Historically it is
> used for making an attempt to progress in the current process itself.
> Should we call it errors=eio? or errors=killproc? Suggestions/Comments
> welcome.
errors=continue seems fine to me, thanks for this Goldwyn.
>
> Sources are available at:
> https://github.com/goldwynr/linux/tree/error-cont
>
> Signed-off-by: Goldwyn Rodrigues <rgoldwyn at suse.com>
> Cc: Mark Fasheh <mfasheh at suse.com>
> Cc: Joel Becker <jlbec at evilplan.org>
> Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
Reviewed-by: Mark Fasheh <mfasheh at suse.de>
> ---
>
> fs/ocfs2/ocfs2.h | 2 +
> fs/ocfs2/super.c | 59 ++++++++++++++++++++++++++++++++-------------
> fs/ocfs2/super.h | 2 -
> 3 files changed, 45 insertions(+), 18 deletions(-)
>
> diff -puN fs/ocfs2/ocfs2.h~add-errors=continue fs/ocfs2/ocfs2.h
> --- a/fs/ocfs2/ocfs2.h~add-errors=continue
> +++ a/fs/ocfs2/ocfs2.h
> @@ -286,6 +286,8 @@ enum ocfs2_mount_options
> OCFS2_MOUNT_HB_GLOBAL = 1 << 14, /* Global heartbeat */
>
> OCFS2_MOUNT_JOURNAL_ASYNC_COMMIT = 1 << 15, /* Journal Async Commit */
> + OCFS2_MOUNT_ERRORS_CONT = 1 << 16, /* Return EIO to the calling process on error */
> + OCFS2_MOUNT_ERRORS_ROFS = 1 << 17, /* Change filesystem to read-only on error */
> };
>
> #define OCFS2_OSB_SOFT_RO 0x0001
> diff -puN fs/ocfs2/super.c~add-errors=continue fs/ocfs2/super.c
> --- a/fs/ocfs2/super.c~add-errors=continue
> +++ a/fs/ocfs2/super.c
> @@ -192,6 +192,7 @@ enum {
> Opt_resv_level,
> Opt_dir_resv_level,
> Opt_journal_async_commit,
> + Opt_err_cont,
> Opt_err,
> };
>
> @@ -224,6 +225,7 @@ static const match_table_t tokens = {
> {Opt_resv_level, "resv_level=%u"},
> {Opt_dir_resv_level, "dir_resv_level=%u"},
> {Opt_journal_async_commit, "journal_async_commit"},
> + {Opt_err_cont, "errors=continue"},
> {Opt_err, NULL}
> };
>
> @@ -1330,10 +1332,19 @@ static int ocfs2_parse_options(struct su
> mopt->mount_opt |= OCFS2_MOUNT_NOINTR;
> break;
> case Opt_err_panic:
> + mopt->mount_opt &= ~OCFS2_MOUNT_ERRORS_CONT;
> + mopt->mount_opt &= ~OCFS2_MOUNT_ERRORS_ROFS;
> mopt->mount_opt |= OCFS2_MOUNT_ERRORS_PANIC;
> break;
> case Opt_err_ro:
> + mopt->mount_opt &= ~OCFS2_MOUNT_ERRORS_CONT;
> mopt->mount_opt &= ~OCFS2_MOUNT_ERRORS_PANIC;
> + mopt->mount_opt |= OCFS2_MOUNT_ERRORS_ROFS;
> + break;
> + case Opt_err_cont:
> + mopt->mount_opt &= ~OCFS2_MOUNT_ERRORS_ROFS;
> + mopt->mount_opt &= ~OCFS2_MOUNT_ERRORS_PANIC;
> + mopt->mount_opt |= OCFS2_MOUNT_ERRORS_CONT;
> break;
> case Opt_data_ordered:
> mopt->mount_opt &= ~OCFS2_MOUNT_DATA_WRITEBACK;
> @@ -1530,6 +1541,8 @@ static int ocfs2_show_options(struct seq
>
> if (opts & OCFS2_MOUNT_ERRORS_PANIC)
> seq_printf(s, ",errors=panic");
> + else if (opts & OCFS2_MOUNT_ERRORS_CONT)
> + seq_printf(s, ",errors=continue");
> else
> seq_printf(s, ",errors=remount-ro");
>
> @@ -2539,31 +2552,43 @@ static void ocfs2_delete_osb(struct ocfs
> memset(osb, 0, sizeof(struct ocfs2_super));
> }
>
> -/* Put OCFS2 into a readonly state, or (if the user specifies it),
> - * panic(). We do not support continue-on-error operation. */
> -static void ocfs2_handle_error(struct super_block *sb)
> +/* Depending on the mount option passed, perform one of the following:
> + * Put OCFS2 into a readonly state (default)
> + * Return EIO so that only the process errs
> + * Fix the error as if fsck.ocfs2 -y
> + * panic
> + */
> +static int ocfs2_handle_error(struct super_block *sb)
> {
> struct ocfs2_super *osb = OCFS2_SB(sb);
> + int rv = 0;
> +
> + ocfs2_set_osb_flag(osb, OCFS2_OSB_ERROR_FS);
> + pr_crit("On-disk corruption discovered. "
> + "Please run fsck.ocfs2 once the filesystem is unmounted.\n");
>
> - if (osb->s_mount_opt & OCFS2_MOUNT_ERRORS_PANIC)
> + if (osb->s_mount_opt & OCFS2_MOUNT_ERRORS_PANIC) {
> panic("OCFS2: (device %s): panic forced after error\n",
> sb->s_id);
> + } else if (osb->s_mount_opt & OCFS2_MOUNT_ERRORS_CONT) {
> + pr_crit("OCFS2: Returning error to the calling process.\n");
> + rv = -EIO;
> + } else { /* default option */
> + rv = -EROFS;
> + if (sb->s_flags & MS_RDONLY &&
> + (ocfs2_is_soft_readonly(osb) ||
> + ocfs2_is_hard_readonly(osb)))
> + return rv;
>
> - ocfs2_set_osb_flag(osb, OCFS2_OSB_ERROR_FS);
> -
> - if (sb->s_flags & MS_RDONLY &&
> - (ocfs2_is_soft_readonly(osb) ||
> - ocfs2_is_hard_readonly(osb)))
> - return;
> + pr_crit("OCFS2: File system is now read-only.\n");
> + sb->s_flags |= MS_RDONLY;
> + ocfs2_set_ro_flag(osb, 0);
> + }
>
> - printk(KERN_CRIT "File system is now read-only due to the potential "
> - "of on-disk corruption. Please run fsck.ocfs2 once the file "
> - "system is unmounted.\n");
> - sb->s_flags |= MS_RDONLY;
> - ocfs2_set_ro_flag(osb, 0);
> + return rv;
> }
>
> -void __ocfs2_error(struct super_block *sb, const char *function,
> +int __ocfs2_error(struct super_block *sb, const char *function,
> const char *fmt, ...)
> {
> struct va_format vaf;
> @@ -2580,7 +2605,7 @@ void __ocfs2_error(struct super_block *s
>
> va_end(args);
>
> - ocfs2_handle_error(sb);
> + return ocfs2_handle_error(sb);
> }
>
> /* Handle critical errors. This is intentionally more drastic than
> diff -puN fs/ocfs2/super.h~add-errors=continue fs/ocfs2/super.h
> --- a/fs/ocfs2/super.h~add-errors=continue
> +++ a/fs/ocfs2/super.h
> @@ -32,7 +32,7 @@ int ocfs2_publish_get_mount_state(struct
> int node_num);
>
> __printf(3, 4)
> -void __ocfs2_error(struct super_block *sb, const char *function,
> +int __ocfs2_error(struct super_block *sb, const char *function,
> const char *fmt, ...);
>
> #define ocfs2_error(sb, fmt, args...) __ocfs2_error(sb, __PRETTY_FUNCTION__, fmt, ##args)
> _
--
Mark Fasheh
More information about the Ocfs2-devel
mailing list