mirror of
https://github.com/torvalds/linux
synced 2024-11-05 18:23:50 +00:00
s390/dasd: check count address during online setting
A common way to prepare a z/VM mini disk is to format the real device with a z/VM tool like CPFMTXA and then define a mini disk that excludes the first cylinder, i.e. the cylinder 0 of the virtual disk is located at cylinder 1 of the real device. The DASD device driver will recognize such a mini disk as formatted, as the uniform record layout on the disk matches that of an LDL formatted device. However, the cylinder value in the 'count' field of the ECKD records matches the geometry of the real device, and not that of the mini disk, so I/O requests will fail with 'record not found' errors. To make the mini disk usable, it needs to be formatted with a tool like dasdfmt. To enable tools like distribution installation tools to recognize this situation, the DASD device driver should report such a mini disk as 'not formatted'. To this end we need to extend the device recognition code to check not just for proper record sizes, but also for proper cylinder/head/record values. Signed-off-by: Stefan Haberland <stefan.haberland@de.ibm.com> Reviewed-by: Stefan Weinhuber <wein@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
parent
72abaadf25
commit
3bc9fef9cc
1 changed files with 12 additions and 2 deletions
|
@ -139,6 +139,10 @@ dasd_eckd_set_online(struct ccw_device *cdev)
|
|||
static const int sizes_trk0[] = { 28, 148, 84 };
|
||||
#define LABEL_SIZE 140
|
||||
|
||||
/* head and record addresses of count_area read in analysis ccw */
|
||||
static const int count_area_head[] = { 0, 0, 0, 0, 2 };
|
||||
static const int count_area_rec[] = { 1, 2, 3, 4, 1 };
|
||||
|
||||
static inline unsigned int
|
||||
round_up_multiple(unsigned int no, unsigned int mult)
|
||||
{
|
||||
|
@ -1939,7 +1943,10 @@ static int dasd_eckd_end_analysis(struct dasd_block *block)
|
|||
count_area = NULL;
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (private->count_area[i].kl != 4 ||
|
||||
private->count_area[i].dl != dasd_eckd_cdl_reclen(i) - 4) {
|
||||
private->count_area[i].dl != dasd_eckd_cdl_reclen(i) - 4 ||
|
||||
private->count_area[i].cyl != 0 ||
|
||||
private->count_area[i].head != count_area_head[i] ||
|
||||
private->count_area[i].record != count_area_rec[i]) {
|
||||
private->uses_cdl = 0;
|
||||
break;
|
||||
}
|
||||
|
@ -1951,7 +1958,10 @@ static int dasd_eckd_end_analysis(struct dasd_block *block)
|
|||
for (i = 0; i < 5; i++) {
|
||||
if ((private->count_area[i].kl != 0) ||
|
||||
(private->count_area[i].dl !=
|
||||
private->count_area[0].dl))
|
||||
private->count_area[0].dl) ||
|
||||
private->count_area[i].cyl != 0 ||
|
||||
private->count_area[i].head != count_area_head[i] ||
|
||||
private->count_area[i].record != count_area_rec[i])
|
||||
break;
|
||||
}
|
||||
if (i == 5)
|
||||
|
|
Loading…
Reference in a new issue