mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
dasdfmt: Add support for thin-provisioned volumes
Make dasdfmt aware of thinly provisioned (Extent Space Efficient (ESE)) DASD volumes. If an ESE volume is recognised a QUICK format is performed, formatting only the first two tracks. The mode can always be overwritten by --mode. Previously allocated space is always released before formatting, if not specified otherwise. The option --no-discard (-D) is provided to omit the space release. Reviewed-by: Stefan Haberland <sth@linux.ibm.com> Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
This commit is contained in:
@@ -122,6 +122,8 @@ 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 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.
|
||||
.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
|
||||
@@ -136,6 +138,10 @@ using \fB-b\fR (\fB--blocksize\fR).
|
||||
Perform a complete format check on a DASD volume. A blocksize can be specified
|
||||
with \fB-b\fR (\fB--blocksize\fR).
|
||||
|
||||
.TP
|
||||
\fB--no-discard\fR
|
||||
Omit a full space release when formatting a thin-provisioned DASD ESE volume.
|
||||
|
||||
.TP
|
||||
\fB-r\fR \fIcylindercount\fR or \fB--requestsize\fR=\fIcylindercount\fR
|
||||
Number of cylinders to be processed in one formatting step.
|
||||
|
||||
@@ -53,6 +53,7 @@ static const struct util_prg prg = {
|
||||
/* Defines for options with no short command */
|
||||
#define OPT_CHECK 128
|
||||
#define OPT_NOZERO 129
|
||||
#define OPT_NODISCARD 130
|
||||
|
||||
static struct util_opt opt_vec[] = {
|
||||
UTIL_OPT_SECTION("FORMAT ACTIONS"),
|
||||
@@ -105,6 +106,11 @@ static struct util_opt opt_vec[] = {
|
||||
.desc = "Prevent storage server from modifying record 0",
|
||||
.flags = UTIL_OPT_FLAG_NOSHORT,
|
||||
},
|
||||
{
|
||||
.option = { "no-discard", no_argument, NULL, OPT_NODISCARD },
|
||||
.desc = "Do not discard space before formatting",
|
||||
.flags = UTIL_OPT_FLAG_NOSHORT,
|
||||
},
|
||||
{
|
||||
.option = { NULL, no_argument, NULL, 'y' },
|
||||
.desc = "Start formatting without further user-confirmation",
|
||||
@@ -921,6 +927,8 @@ static void dasdfmt_print_info(dasdfmt_info_t *info, char *devname,
|
||||
printf("Drive Geometry: %d Cylinders * %d Heads = %d Tracks\n",
|
||||
cylinders, heads, (cylinders * heads));
|
||||
|
||||
printf("Device Type: %s Provisioned\n",
|
||||
info->ese ? "Thinly" : "Fully");
|
||||
printf("\nI am going to format the device ");
|
||||
printf("%s in the following way:\n", devname);
|
||||
printf(" Device number of device : 0x%x\n", info->dasd_info.devno);
|
||||
@@ -939,7 +947,10 @@ static void dasdfmt_print_info(dasdfmt_info_t *info, char *devname,
|
||||
(p->intensity & DASD_FMT_INT_COMPAT) ? "yes" : "no");
|
||||
printf(" Blocksize : %d\n", p->blksize);
|
||||
printf(" Mode : %s\n", mode_str[mode]);
|
||||
|
||||
if (info->ese) {
|
||||
printf(" Full Space Release : %s\n",
|
||||
(info->no_discard || mode == FULL) ? "no" : "yes");
|
||||
}
|
||||
if (info->testmode)
|
||||
printf("Test mode active, omitting ioctl.\n");
|
||||
}
|
||||
@@ -1234,6 +1245,26 @@ static void dasdfmt_format(dasdfmt_info_t *info, unsigned int cylinders,
|
||||
process_tracks(info, cylinders, heads, format_params);
|
||||
}
|
||||
|
||||
static void dasdfmt_release_space(dasdfmt_info_t *info)
|
||||
{
|
||||
format_data_t r = {
|
||||
.start_unit = 0,
|
||||
.stop_unit = 0,
|
||||
.intensity = DASD_FMT_INT_ESE_FULL,
|
||||
};
|
||||
int err = 0;
|
||||
|
||||
if (!info->ese || info->no_discard)
|
||||
return;
|
||||
|
||||
printf("Releasing space for the entire device...\n");
|
||||
err = dasd_release_space(dev_filename, &r);
|
||||
if (err) {
|
||||
ERRMSG_EXIT(EXIT_FAILURE, "%s: Could not release space (%s)\n",
|
||||
prog_name, strerror(err));
|
||||
}
|
||||
}
|
||||
|
||||
static void dasdfmt_prepare_and_format(dasdfmt_info_t *info,
|
||||
unsigned int cylinders,
|
||||
unsigned int heads, format_data_t *p)
|
||||
@@ -1329,6 +1360,8 @@ static void dasdfmt_quick_format(dasdfmt_info_t *info, unsigned int cylinders,
|
||||
|
||||
if (info->force) {
|
||||
printf("Skipping format check due to --force.\n");
|
||||
} else if (info->ese) {
|
||||
printf("Skipping format check due to thin-provisioned device.\n");
|
||||
} else {
|
||||
check_blocksize(info, p->blksize);
|
||||
|
||||
@@ -1438,6 +1471,7 @@ static void do_format_dasd(dasdfmt_info_t *info, char *devname,
|
||||
dasdfmt_prepare_and_format(info, cylinders, heads, p);
|
||||
break;
|
||||
case QUICK:
|
||||
dasdfmt_release_space(info);
|
||||
dasdfmt_quick_format(info, cylinders, heads, p);
|
||||
break;
|
||||
case EXPAND:
|
||||
@@ -1461,6 +1495,19 @@ static void do_format_dasd(dasdfmt_info_t *info, char *devname,
|
||||
}
|
||||
}
|
||||
|
||||
static void eval_format_mode(dasdfmt_info_t *info)
|
||||
{
|
||||
if (!info->force && info->mode_specified && info->ese && mode == EXPAND) {
|
||||
ERRMSG_EXIT(EXIT_FAILURE,
|
||||
"WARNING: The specified device is thin-provisioned\n"
|
||||
"Format mode 'expand' is not feasible.\n"
|
||||
"Use --mode=full or --mode=quick to perform a clean format\n");
|
||||
}
|
||||
|
||||
if (!info->mode_specified)
|
||||
mode = info->ese ? QUICK : FULL;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
dasdfmt_info_t info = {
|
||||
@@ -1496,8 +1543,6 @@ int main(int argc, char *argv[])
|
||||
format_params.blksize = DEFAULT_BLOCKSIZE;
|
||||
format_params.intensity = DASD_FMT_INT_COMPAT;
|
||||
|
||||
mode = FULL;
|
||||
|
||||
/*************** parse parameters **********************/
|
||||
|
||||
while (1) {
|
||||
@@ -1601,6 +1646,10 @@ int main(int argc, char *argv[])
|
||||
"invalid. Consult the man page for "
|
||||
"more information.\n",
|
||||
prog_name, optarg);
|
||||
info.mode_specified = 1;
|
||||
break;
|
||||
case OPT_NODISCARD:
|
||||
info.no_discard = 1;
|
||||
break;
|
||||
case OPT_CHECK:
|
||||
info.check = 1;
|
||||
@@ -1645,6 +1694,9 @@ int main(int argc, char *argv[])
|
||||
"device information failed (%s).\n",
|
||||
prog_name, strerror(rc));
|
||||
|
||||
info.ese = dasd_sys_ese(dev_filename);
|
||||
eval_format_mode(&info);
|
||||
|
||||
/* Either let the user specify the blksize or get it from the kernel */
|
||||
if (!info.blksize_specified) {
|
||||
if (!(mode == FULL ||
|
||||
|
||||
@@ -92,6 +92,9 @@ typedef struct dasdfmt_info {
|
||||
int force_host;
|
||||
int layout_specified;
|
||||
int check;
|
||||
int mode_specified;
|
||||
int ese;
|
||||
int no_discard;
|
||||
} dasdfmt_info_t;
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user