From d55818a797bf66cc9fc3c02eb0b4d39689b9d030 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20H=C3=B6ppner?= Date: Wed, 24 May 2023 19:40:21 +0200 Subject: [PATCH] dasdfmt: Fall back to full format if space release fails MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In certain storage setups the Release Allocated Space (RAS) command to free up space on the storage server previously allocated for an ESE DASD might not work. At the moment dasdfmt will error out if RAS is failing. This however is not ideal for the default case when a user is expecting dasdfmt to simply format the disk. One workaround would be to specify --no-discard to disable RAS completely. However, a sane default handling that tries to work every time is more reasonable. Change the default handling as follows: If an ESE is detected default to QUICK mode and try RAS. If RAS fails, fall back to the FULL format mode and display a warning accordingly. If -M (--mode) QUICK is specified explicitly dasdfmt will still error out on a failing RAS. A combination with --no-discard will still allow for a QUICK format on an ESE DASD in that case, if desired. Reviewed-by: Stefan Haberland Signed-off-by: Jan Höppner Signed-off-by: Steffen Eiden --- dasdfmt/dasdfmt.8 | 11 ++++++++--- dasdfmt/dasdfmt.c | 23 ++++++++++++++++++----- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/dasdfmt/dasdfmt.8 b/dasdfmt/dasdfmt.8 index c3e98faa..bef5c097 100644 --- a/dasdfmt/dasdfmt.8 +++ b/dasdfmt/dasdfmt.8 @@ -118,12 +118,17 @@ Specify the \fImode\fR to be used to format the device. Valid modes are: .IP full Format the entire disk with the specified blocksize. (default) .IP quick -Format the first two tracks and write label and partition information. Only use -this option if you are sure that the target DASD already contains a regular +Format the first two tracks and write label and partition information. Use this +option only if you are sure that the target DASD already contains a regular format with the specified blocksize. A blocksize can optionally be specified using \fB-b\fR (\fB--blocksize\fR). .br -For thin-provisioned DASD ESE volumes this is the default mode. +For thin-provisioned DASD ESE volumes, quick is the default mode. A full space +release then precedes the formatting step. If this space release fails, dasdfmt +falls back to a full-format mode. Formatting stops if the space release fails +and quick mode was specified explicitly using \fB-M\fR. Specify the +\fB--no-discard\fR option to omit the space release. + .IP expand Format all unformatted tracks at the end of the target DASD. This mode assumes that tracks at the beginning of the DASD volume have already been correctly diff --git a/dasdfmt/dasdfmt.c b/dasdfmt/dasdfmt.c index fa25c03e..2065e12e 100644 --- a/dasdfmt/dasdfmt.c +++ b/dasdfmt/dasdfmt.c @@ -1230,7 +1230,7 @@ static void dasdfmt_find_start(unsigned int cylinders, unsigned int heads, format_params->start_unit = first; } -static void dasdfmt_release_space(void) +static int dasdfmt_release_space(void) { format_data_t r = { .start_unit = 0, @@ -1240,12 +1240,21 @@ static void dasdfmt_release_space(void) int err = 0; if (!g.ese || g.no_discard) - return; + return 0; printf("Releasing space for the entire device...\n"); err = dasd_release_space(g.dev_node, &r); - if (err) + /* + * Warn or Error on failing RAS depending on QUICK mode set explicitly or automatically + */ + if (err && !g.mode_specified) { + warnx("Could not release space. Falling back to full format."); + return 1; + } else if (err && g.mode_specified) { error("Could not release space: %s", strerror(err)); + } + + return 0; } static void dasdfmt_prepare_and_format(unsigned int cylinders, unsigned int heads, @@ -1445,8 +1454,12 @@ static void do_format_dasd(volume_label_t *vlabel, format_data_t *p, dasdfmt_prepare_and_format(cylinders, heads, p); break; case QUICK: - dasdfmt_release_space(); - dasdfmt_quick_format(cylinders, heads, p); + if (dasdfmt_release_space()) { + p->stop_unit = (cylinders * heads) - 1; + dasdfmt_prepare_and_format(cylinders, heads, p); + } else { + dasdfmt_quick_format(cylinders, heads, p); + } break; case EXPAND: dasdfmt_expand_format(cylinders, heads, p);