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);