diff options
Diffstat (limited to 'fs/partitions')
-rw-r--r-- | fs/partitions/check.c | 10 | ||||
-rw-r--r-- | fs/partitions/ibm.c | 101 |
2 files changed, 76 insertions, 35 deletions
diff --git a/fs/partitions/check.c b/fs/partitions/check.c index 8a17f7edcc74..99e33ef40be4 100644 --- a/fs/partitions/check.c +++ b/fs/partitions/check.c | |||
@@ -404,7 +404,7 @@ struct hd_struct *add_partition(struct gendisk *disk, int partno, | |||
404 | pdev->devt = devt; | 404 | pdev->devt = devt; |
405 | 405 | ||
406 | /* delay uevent until 'holders' subdir is created */ | 406 | /* delay uevent until 'holders' subdir is created */ |
407 | pdev->uevent_suppress = 1; | 407 | dev_set_uevent_suppress(pdev, 1); |
408 | err = device_add(pdev); | 408 | err = device_add(pdev); |
409 | if (err) | 409 | if (err) |
410 | goto out_put; | 410 | goto out_put; |
@@ -414,7 +414,7 @@ struct hd_struct *add_partition(struct gendisk *disk, int partno, | |||
414 | if (!p->holder_dir) | 414 | if (!p->holder_dir) |
415 | goto out_del; | 415 | goto out_del; |
416 | 416 | ||
417 | pdev->uevent_suppress = 0; | 417 | dev_set_uevent_suppress(pdev, 0); |
418 | if (flags & ADDPART_FLAG_WHOLEDISK) { | 418 | if (flags & ADDPART_FLAG_WHOLEDISK) { |
419 | err = device_create_file(pdev, &dev_attr_whole_disk); | 419 | err = device_create_file(pdev, &dev_attr_whole_disk); |
420 | if (err) | 420 | if (err) |
@@ -426,7 +426,7 @@ struct hd_struct *add_partition(struct gendisk *disk, int partno, | |||
426 | rcu_assign_pointer(ptbl->part[partno], p); | 426 | rcu_assign_pointer(ptbl->part[partno], p); |
427 | 427 | ||
428 | /* suppress uevent if the disk supresses it */ | 428 | /* suppress uevent if the disk supresses it */ |
429 | if (!ddev->uevent_suppress) | 429 | if (!dev_get_uevent_suppress(pdev)) |
430 | kobject_uevent(&pdev->kobj, KOBJ_ADD); | 430 | kobject_uevent(&pdev->kobj, KOBJ_ADD); |
431 | 431 | ||
432 | return p; | 432 | return p; |
@@ -459,7 +459,7 @@ void register_disk(struct gendisk *disk) | |||
459 | dev_set_name(ddev, disk->disk_name); | 459 | dev_set_name(ddev, disk->disk_name); |
460 | 460 | ||
461 | /* delay uevents, until we scanned partition table */ | 461 | /* delay uevents, until we scanned partition table */ |
462 | ddev->uevent_suppress = 1; | 462 | dev_set_uevent_suppress(ddev, 1); |
463 | 463 | ||
464 | if (device_add(ddev)) | 464 | if (device_add(ddev)) |
465 | return; | 465 | return; |
@@ -494,7 +494,7 @@ void register_disk(struct gendisk *disk) | |||
494 | 494 | ||
495 | exit: | 495 | exit: |
496 | /* announce disk after possible partitions are created */ | 496 | /* announce disk after possible partitions are created */ |
497 | ddev->uevent_suppress = 0; | 497 | dev_set_uevent_suppress(ddev, 0); |
498 | kobject_uevent(&ddev->kobj, KOBJ_ADD); | 498 | kobject_uevent(&ddev->kobj, KOBJ_ADD); |
499 | 499 | ||
500 | /* announce possible partitions */ | 500 | /* announce possible partitions */ |
diff --git a/fs/partitions/ibm.c b/fs/partitions/ibm.c index 1e064c4a4f86..46297683cd34 100644 --- a/fs/partitions/ibm.c +++ b/fs/partitions/ibm.c | |||
@@ -21,20 +21,38 @@ | |||
21 | * compute the block number from a | 21 | * compute the block number from a |
22 | * cyl-cyl-head-head structure | 22 | * cyl-cyl-head-head structure |
23 | */ | 23 | */ |
24 | static inline int | 24 | static sector_t |
25 | cchh2blk (struct vtoc_cchh *ptr, struct hd_geometry *geo) { | 25 | cchh2blk (struct vtoc_cchh *ptr, struct hd_geometry *geo) { |
26 | return ptr->cc * geo->heads * geo->sectors + | 26 | |
27 | ptr->hh * geo->sectors; | 27 | sector_t cyl; |
28 | __u16 head; | ||
29 | |||
30 | /*decode cylinder and heads for large volumes */ | ||
31 | cyl = ptr->hh & 0xFFF0; | ||
32 | cyl <<= 12; | ||
33 | cyl |= ptr->cc; | ||
34 | head = ptr->hh & 0x000F; | ||
35 | return cyl * geo->heads * geo->sectors + | ||
36 | head * geo->sectors; | ||
28 | } | 37 | } |
29 | 38 | ||
30 | /* | 39 | /* |
31 | * compute the block number from a | 40 | * compute the block number from a |
32 | * cyl-cyl-head-head-block structure | 41 | * cyl-cyl-head-head-block structure |
33 | */ | 42 | */ |
34 | static inline int | 43 | static sector_t |
35 | cchhb2blk (struct vtoc_cchhb *ptr, struct hd_geometry *geo) { | 44 | cchhb2blk (struct vtoc_cchhb *ptr, struct hd_geometry *geo) { |
36 | return ptr->cc * geo->heads * geo->sectors + | 45 | |
37 | ptr->hh * geo->sectors + | 46 | sector_t cyl; |
47 | __u16 head; | ||
48 | |||
49 | /*decode cylinder and heads for large volumes */ | ||
50 | cyl = ptr->hh & 0xFFF0; | ||
51 | cyl <<= 12; | ||
52 | cyl |= ptr->cc; | ||
53 | head = ptr->hh & 0x000F; | ||
54 | return cyl * geo->heads * geo->sectors + | ||
55 | head * geo->sectors + | ||
38 | ptr->b; | 56 | ptr->b; |
39 | } | 57 | } |
40 | 58 | ||
@@ -43,14 +61,15 @@ cchhb2blk (struct vtoc_cchhb *ptr, struct hd_geometry *geo) { | |||
43 | int | 61 | int |
44 | ibm_partition(struct parsed_partitions *state, struct block_device *bdev) | 62 | ibm_partition(struct parsed_partitions *state, struct block_device *bdev) |
45 | { | 63 | { |
46 | int blocksize, offset, size,res; | 64 | int blocksize, res; |
47 | loff_t i_size; | 65 | loff_t i_size, offset, size, fmt_size; |
48 | dasd_information2_t *info; | 66 | dasd_information2_t *info; |
49 | struct hd_geometry *geo; | 67 | struct hd_geometry *geo; |
50 | char type[5] = {0,}; | 68 | char type[5] = {0,}; |
51 | char name[7] = {0,}; | 69 | char name[7] = {0,}; |
52 | union label_t { | 70 | union label_t { |
53 | struct vtoc_volume_label vol; | 71 | struct vtoc_volume_label_cdl vol; |
72 | struct vtoc_volume_label_ldl lnx; | ||
54 | struct vtoc_cms_label cms; | 73 | struct vtoc_cms_label cms; |
55 | } *label; | 74 | } *label; |
56 | unsigned char *data; | 75 | unsigned char *data; |
@@ -85,14 +104,16 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev) | |||
85 | if (data == NULL) | 104 | if (data == NULL) |
86 | goto out_readerr; | 105 | goto out_readerr; |
87 | 106 | ||
88 | strncpy (type, data, 4); | ||
89 | if ((!info->FBA_layout) && (!strcmp(info->type, "ECKD"))) | ||
90 | strncpy(name, data + 8, 6); | ||
91 | else | ||
92 | strncpy(name, data + 4, 6); | ||
93 | memcpy(label, data, sizeof(union label_t)); | 107 | memcpy(label, data, sizeof(union label_t)); |
94 | put_dev_sector(sect); | 108 | put_dev_sector(sect); |
95 | 109 | ||
110 | if ((!info->FBA_layout) && (!strcmp(info->type, "ECKD"))) { | ||
111 | strncpy(type, label->vol.vollbl, 4); | ||
112 | strncpy(name, label->vol.volid, 6); | ||
113 | } else { | ||
114 | strncpy(type, label->lnx.vollbl, 4); | ||
115 | strncpy(name, label->lnx.volid, 6); | ||
116 | } | ||
96 | EBCASC(type, 4); | 117 | EBCASC(type, 4); |
97 | EBCASC(name, 6); | 118 | EBCASC(name, 6); |
98 | 119 | ||
@@ -110,36 +131,54 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev) | |||
110 | /* | 131 | /* |
111 | * VM style CMS1 labeled disk | 132 | * VM style CMS1 labeled disk |
112 | */ | 133 | */ |
134 | blocksize = label->cms.block_size; | ||
113 | if (label->cms.disk_offset != 0) { | 135 | if (label->cms.disk_offset != 0) { |
114 | printk("CMS1/%8s(MDSK):", name); | 136 | printk("CMS1/%8s(MDSK):", name); |
115 | /* disk is reserved minidisk */ | 137 | /* disk is reserved minidisk */ |
116 | blocksize = label->cms.block_size; | ||
117 | offset = label->cms.disk_offset; | 138 | offset = label->cms.disk_offset; |
118 | size = (label->cms.block_count - 1) | 139 | size = (label->cms.block_count - 1) |
119 | * (blocksize >> 9); | 140 | * (blocksize >> 9); |
120 | } else { | 141 | } else { |
121 | printk("CMS1/%8s:", name); | 142 | printk("CMS1/%8s:", name); |
122 | offset = (info->label_block + 1); | 143 | offset = (info->label_block + 1); |
123 | size = i_size >> 9; | 144 | size = label->cms.block_count |
145 | * (blocksize >> 9); | ||
124 | } | 146 | } |
147 | put_partition(state, 1, offset*(blocksize >> 9), | ||
148 | size-offset*(blocksize >> 9)); | ||
125 | } else { | 149 | } else { |
126 | /* | 150 | if (strncmp(type, "LNX1", 4) == 0) { |
127 | * Old style LNX1 or unlabeled disk | 151 | printk("LNX1/%8s:", name); |
128 | */ | 152 | if (label->lnx.ldl_version == 0xf2) { |
129 | if (strncmp(type, "LNX1", 4) == 0) | 153 | fmt_size = label->lnx.formatted_blocks |
130 | printk ("LNX1/%8s:", name); | 154 | * (blocksize >> 9); |
131 | else | 155 | } else if (!strcmp(info->type, "ECKD")) { |
156 | /* formated w/o large volume support */ | ||
157 | fmt_size = geo->cylinders * geo->heads | ||
158 | * geo->sectors * (blocksize >> 9); | ||
159 | } else { | ||
160 | /* old label and no usable disk geometry | ||
161 | * (e.g. DIAG) */ | ||
162 | fmt_size = i_size >> 9; | ||
163 | } | ||
164 | size = i_size >> 9; | ||
165 | if (fmt_size < size) | ||
166 | size = fmt_size; | ||
167 | offset = (info->label_block + 1); | ||
168 | } else { | ||
169 | /* unlabeled disk */ | ||
132 | printk("(nonl)"); | 170 | printk("(nonl)"); |
133 | offset = (info->label_block + 1); | 171 | size = i_size >> 9; |
134 | size = i_size >> 9; | 172 | offset = (info->label_block + 1); |
135 | } | 173 | } |
136 | put_partition(state, 1, offset*(blocksize >> 9), | 174 | put_partition(state, 1, offset*(blocksize >> 9), |
137 | size-offset*(blocksize >> 9)); | 175 | size-offset*(blocksize >> 9)); |
176 | } | ||
138 | } else if (info->format == DASD_FORMAT_CDL) { | 177 | } else if (info->format == DASD_FORMAT_CDL) { |
139 | /* | 178 | /* |
140 | * New style CDL formatted disk | 179 | * New style CDL formatted disk |
141 | */ | 180 | */ |
142 | unsigned int blk; | 181 | sector_t blk; |
143 | int counter; | 182 | int counter; |
144 | 183 | ||
145 | /* | 184 | /* |
@@ -166,7 +205,8 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev) | |||
166 | /* skip FMT4 / FMT5 / FMT7 labels */ | 205 | /* skip FMT4 / FMT5 / FMT7 labels */ |
167 | if (f1.DS1FMTID == _ascebc['4'] | 206 | if (f1.DS1FMTID == _ascebc['4'] |
168 | || f1.DS1FMTID == _ascebc['5'] | 207 | || f1.DS1FMTID == _ascebc['5'] |
169 | || f1.DS1FMTID == _ascebc['7']) { | 208 | || f1.DS1FMTID == _ascebc['7'] |
209 | || f1.DS1FMTID == _ascebc['9']) { | ||
170 | blk++; | 210 | blk++; |
171 | data = read_dev_sector(bdev, blk * | 211 | data = read_dev_sector(bdev, blk * |
172 | (blocksize/512), | 212 | (blocksize/512), |
@@ -174,8 +214,9 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev) | |||
174 | continue; | 214 | continue; |
175 | } | 215 | } |
176 | 216 | ||
177 | /* only FMT1 valid at this point */ | 217 | /* only FMT1 and 8 labels valid at this point */ |
178 | if (f1.DS1FMTID != _ascebc['1']) | 218 | if (f1.DS1FMTID != _ascebc['1'] && |
219 | f1.DS1FMTID != _ascebc['8']) | ||
179 | break; | 220 | break; |
180 | 221 | ||
181 | /* OK, we got valid partition data */ | 222 | /* OK, we got valid partition data */ |