Actual implementation: 194 195 /* ja...@bpgc.com: Solaris has a nasty indicator: 0x82 which also 196 indicates linux swap. Be careful before believing this is Solaris. */ 197 198 static void 199 parse_solaris_x86(struct parsed_partitions *state, struct block_device *bdev, 200 u32 offset, u32 size, int origin) 201 { 202 #ifdef CONFIG_SOLARIS_X86_PARTITION 203 Sector sect; 204 struct solaris_x86_vtoc *v; 205 int i; 206 short max_nparts; 207 208 v = (struct solaris_x86_vtoc *)read_dev_sector(bdev, offset+1, §); 209 if (!v) 210 return; 211 if (le32_to_cpu(v->v_sanity) != SOLARIS_X86_VTOC_SANE) { 212 put_dev_sector(sect); 213 return; 214 } 215 printk(" %s%d: <solaris:", state->name, origin); 216 if (le32_to_cpu(v->v_version) != 1) { 217 printk(" cannot handle version %d vtoc>\n", 218 le32_to_cpu(v->v_version)); 219 put_dev_sector(sect); 220 return; 221 } 222 /* Ensure we can handle previous case of VTOC with 8 entries gracefully */ 223 max_nparts = le16_to_cpu (v->v_nparts) > 8 ? SOLARIS_X86_NUMSLICE : 8; 224 for (i=0; i<max_nparts && state->next<state->limit; i++) { 225 struct solaris_x86_slice *s = &v->v_slice[i]; 226 if (s->s_size == 0) 227 continue; 228 printk(" [s%d]", i); And according to: 405 } subtypes[] = { 406 {FREEBSD_PARTITION, parse_freebsd}, 407 {NETBSD_PARTITION, parse_netbsd}, 408 {OPENBSD_PARTITION, parse_openbsd}, 409 {MINIX_PARTITION, parse_minix}, 410 {UNIXWARE_PARTITION, parse_unixware}, 411 {SOLARIS_X86_PARTITION, parse_solaris_x86}, 412 {NEW_SOLARIS_X86_PARTITION, parse_solaris_x86}, 413 {0, NULL}, 414 }; 415 caller is: 416 int msdos_partition(struct parsed_partitions *state, struct block_device *bdev) 417 { 418 int sector_size = bdev_logical_block_size(bdev) / 512; 419 Sector sect; 420 unsigned char *data; 421 struct partition *p; 422 struct fat_boot_sector *fb; 473 } 474 } 475 #endif 476 p = (struct partition *) (data + 0x1be); 477 478 /* 479 * Look for partitions in two passes: 480 * First find the primary and DOS-type extended partitions. 481 * On the second pass look inside *BSD, Unixware and Solaris partitions. 482 */ 483 484 state->next = 5; 485 for (slot = 1 ; slot <= 4 ; slot++, p++) { 486 u32 start = START_SECT(p)*sector_size; 487 u32 size = NR_SECTS(p)*sector_size; 488 if (!size) 489 continue; 490 if (is_extended_partition(p)) { 491 /* prevent someone doing mkfs or mkswap on an 492 extended partition, but leave room for LILO */ 493 put_partition(state, slot, start, size == 1 ? 1 : 2); 494 printk(" <"); 495 parse_extended(state, bdev, start, size); 496 printk(" >"); 497 continue; 498 } 499 put_partition(state, slot, start, size); 500 if (SYS_IND(p) == LINUX_RAID_PARTITION) 501 state->parts[slot].flags = 1; 502 if (SYS_IND(p) == DM6_PARTITION) 503 printk("[DM]"); 504 if (SYS_IND(p) == EZD_PARTITION) 505 printk("[EZD]"); 506 } 507 508 printk("\n"); 509 510 /* second pass - output for each on a separate line */ 511 p = (struct partition *) (0x1be + data); 512 for (slot = 1 ; slot <= 4 ; slot++, p++) { 513 unsigned char id = SYS_IND(p); 514 int n; 515 516 if (!NR_SECTS(p)) 517 continue; 518 519 for (n = 0; subtypes[n].parse && id != subtypes[n].id; n++) 520 ; 521 522 if (!subtypes[n].parse) 523 continue; 524 subtypes[n].parse(state, bdev, START_SECT(p)*sector_size, 525 NR_SECTS(p)*sector_size, slot); 526 } 527 put_dev_sector(sect); 528 return 1; 529 } 157 static struct parsed_partitions * 158 check_partition(struct gendisk *hd, struct block_device *bdev) 159 { 160 struct parsed_partitions *state; 161 int i, res, err; 162 163 state = kmalloc(sizeof(struct parsed_partitions), GFP_KERNEL); 164 if (!state) 165 return NULL; 166 167 disk_name(hd, 0, state->name); 168 printk(KERN_INFO " %s:", state->name); 169 if (isdigit(state->name[strlen(state->name)-1])) 170 sprintf(state->name, "p"); 171 172 state->limit = disk_max_parts(hd); 173 i = res = err = 0; 174 while (!res && check_part[i]) { 175 memset(&state->parts, 0, sizeof(state->parts)); 176 res = check_part[i++](state, bdev); 177 if (res < 0) { 178 /* We have hit an I/O error which we don't report now. 179 * But record it, and let the others do their job. 180 */ 181 err = res; 182 res = 0; 183 } Called by: 1147 static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part) 1148 { 1149 struct gendisk *disk; 1150 int ret; 1151 int partno; 1152 int perm = 0; 1153 1154 if (mode & FMODE_READ) 1155 perm |= MAY_READ; 1156 if (mode & FMODE_WRITE) 1157 perm |= MAY_WRITE; 1158 /* 1159 * hooks: /n/, see "layering violations". 1160 */ 1161 ret = devcgroup_inode_permission(bdev->bd_inode, perm); 1162 if (ret != 0) { 1163 bdput(bdev); 1164 return ret; 1165 } 1166 1167 lock_kernel(); 1168 restart: 1169 1170 ret = -ENXIO; 1205 if (!bdev->bd_openers) { 1206 bd_set_size(bdev,(loff_t)get_capacity(disk)<<9); 1207 bdi = blk_get_backing_dev_info(bdev); 1208 if (bdi == NULL) 1209 bdi = &default_backing_dev_info; 1210 bdev->bd_inode->i_data.backing_dev_info = bdi; 1211 } 1212 if (bdev->bd_invalidated) 1213 rescan_partitions(disk, bdev); 1214 } else { 1215 struct block_device *whole; 1216 whole = bdget_disk(disk, 0); 1217 ret = -ENOMEM; 1218 if (!whole) 1219 goto out_clear; 1220 BUG_ON(for_part); 1221 ret = __blkdev_get(whole, mode, 1); 1222 if (ret) 1223 goto out_clear; 1224 bdev->bd_contains = whole; 1225 bdev->bd_inode->i_data.backing_dev_info = 1226 whole->bd_inode->i_data.backing_dev_info; 1227 bdev->bd_part = disk_get_part(disk, partno); 1228 if (!(disk->flags & GENHD_FL_UP) || 1229 !bdev->bd_part || !bdev->bd_part->nr_sects) { 1230 ret = -ENXIO; 1231 goto out_clear; 1232 } 1233 bd_set_size(bdev, (loff_t)bdev->bd_part->nr_sects << 9); 1234 } 1235 } else { 1236 put_disk(disk); 1237 module_put(disk->fops->owner); 1238 disk = NULL; 1239 if (bdev->bd_contains == bdev) { 1240 if (bdev->bd_disk->fops->open) { 1241 ret = bdev->bd_disk->fops->open(bdev, mode); 1242 if (ret) 1243 goto out_unlock_bdev; 1244 } 1245 if (bdev->bd_invalidated) 1246 rescan_partitions(bdev->bd_disk, bdev); /rescan_parti called by: 458 /* Not exported, helper to add_disk(). */ 459 void register_disk(struct gendisk *disk) 460 { 461 struct device *ddev = disk_to_dev(disk); 462 struct block_device *bdev; 463 struct disk_part_iter piter; 464 struct hd_struct *part; 465 int err; 466 487 /* No minors to use for partitions */ 488 if (!disk_partitionable(disk)) 489 goto exit; 490 491 /* No such device (e.g., media were just removed) */ 492 if (!get_capacity(disk)) 493 goto exit; 494 495 bdev = bdget_disk(disk, 0); 496 if (!bdev) 497 goto exit; 498 499 bdev->bd_invalidated = 1; 500 err = blkdev_get(bdev, FMODE_READ); 501 if (err < 0) 502 goto exit; 503 blkdev_put(bdev, FMODE_READ); 504 505 exit: 506 /* announce disk after possible partitions are created */ 507 dev_set_uevent_suppress(ddev, 0); 508 kobject_uevent(&ddev->kobj, KOBJ_ADD); 509 510 /* announce possible partitions */ 511 disk_part_iter_init(&piter, disk, 0); 512 while ((part = disk_part_iter_next(&piter))) 513 kobject_uevent(&part_to_dev(part)->kobj, KOBJ_ADD); 514 disk_part_iter_exit(&piter); 515 } 516 |