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, &sect);
    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



Reply via email to