diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-03-26 19:04:22 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-03-26 19:04:22 -0400 |
| commit | 21cdbc1378e8aa96e1ed4a606dce1a8e7daf7fdf (patch) | |
| tree | 55b6c294b912ccdc3eede15960b0ece53a69d902 /fs | |
| parent | 86d9c070175de65890794fa227b68297da6206d8 (diff) | |
| parent | ef3500b2b2955af4fa6b0564b51c0c604e38c571 (diff) | |
Merge branch 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6
* 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6: (81 commits)
[S390] remove duplicated #includes
[S390] cpumask: use mm_cpumask() wrapper
[S390] cpumask: Use accessors code.
[S390] cpumask: prepare for iterators to only go to nr_cpu_ids/nr_cpumask_bits.
[S390] cpumask: remove cpu_coregroup_map
[S390] fix clock comparator save area usage
[S390] Add hwcap flag for the etf3 enhancement facility
[S390] Ensure that ipl panic notifier is called late.
[S390] fix dfp elf hwcap/facility bit detection
[S390] smp: perform initial cpu reset before starting a cpu
[S390] smp: fix memory leak on __cpu_up
[S390] ipl: Improve checking logic and remove switch defaults.
[S390] s390dbf: Remove needless check for NULL pointer.
[S390] s390dbf: Remove redundant initilizations.
[S390] use kzfree()
[S390] BUG to BUG_ON changes
[S390] zfcpdump: Prevent zcore from beeing built as a kernel module.
[S390] Use csum_partial in checksum.h
[S390] cleanup lowcore.h
[S390] eliminate ipl_device from lowcore
...
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/partitions/ibm.c | 101 |
1 files changed, 71 insertions, 30 deletions
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 */ |
