static int sun_create_disklabel(struct fdisk_context *cxt) { unsigned int ndiv; struct fdisk_sun_label *sun; /* libfdisk sun handler */ struct sun_disklabel *sunlabel; /* on disk data */ int rc = 0; assert(cxt); assert(cxt->label); assert(fdisk_is_label(cxt, SUN)); /* map first sector to header */ rc = fdisk_init_firstsector_buffer(cxt, 0, 0); if (rc) return rc; sun = (struct fdisk_sun_label *) cxt->label; sun->header = (struct sun_disklabel *) cxt->firstsector; sunlabel = sun->header; cxt->label->nparts_max = SUN_MAXPARTITIONS; sunlabel->magic = cpu_to_be16(SUN_LABEL_MAGIC); sunlabel->vtoc.version = cpu_to_be32(SUN_VTOC_VERSION); sunlabel->vtoc.sanity = cpu_to_be32(SUN_VTOC_SANITY); sunlabel->vtoc.nparts = cpu_to_be16(SUN_MAXPARTITIONS); #ifdef HDIO_GETGEO if (cxt->geom.heads && cxt->geom.sectors) { fdisk_sector_t llsectors; if (blkdev_get_sectors(cxt->dev_fd, (unsigned long long *) &llsectors) == 0) { int sec_fac = cxt->sector_size / 512; fdisk_sector_t llcyls; llcyls = llsectors / (cxt->geom.heads * cxt->geom.sectors * sec_fac); cxt->geom.cylinders = llcyls; if (cxt->geom.cylinders != llcyls) cxt->geom.cylinders = ~0; } else { fdisk_warnx(cxt, _("BLKGETSIZE ioctl failed on %s. " "Using geometry cylinder value of %llu. " "This value may be truncated for devices " "> 33.8 GB."), cxt->dev_path, cxt->geom.cylinders); } } else #endif ask_geom(cxt); sunlabel->acyl = cpu_to_be16(0); sunlabel->pcyl = cpu_to_be16(cxt->geom.cylinders); sunlabel->rpm = cpu_to_be16(5400); sunlabel->intrlv = cpu_to_be16(1); sunlabel->apc = cpu_to_be16(0); sunlabel->nhead = cpu_to_be16(cxt->geom.heads); sunlabel->nsect = cpu_to_be16(cxt->geom.sectors); sunlabel->ncyl = cpu_to_be16(cxt->geom.cylinders); snprintf((char *) sunlabel->label_id, sizeof(sunlabel->label_id), "Linux cyl %ju alt %u hd %u sec %ju", (uintmax_t) cxt->geom.cylinders, be16_to_cpu(sunlabel->acyl), cxt->geom.heads, (uintmax_t) cxt->geom.sectors); if (cxt->geom.cylinders * cxt->geom.heads * cxt->geom.sectors >= 150 * 2048) { ndiv = cxt->geom.cylinders - (50 * 2048 / (cxt->geom.heads * cxt->geom.sectors)); /* 50M swap */ } else ndiv = cxt->geom.cylinders * 2 / 3; /* create the default layout only if no-script defined */ if (!cxt->script) { set_partition(cxt, 0, 0, ndiv * cxt->geom.heads * cxt->geom.sectors, SUN_TAG_LINUX_NATIVE); set_partition(cxt, 1, ndiv * cxt->geom.heads * cxt->geom.sectors, cxt->geom.cylinders * cxt->geom.heads * cxt->geom.sectors, SUN_TAG_LINUX_SWAP); sunlabel->vtoc.infos[1].flags |= cpu_to_be16(SUN_FLAG_UNMNT); set_partition(cxt, 2, 0, cxt->geom.cylinders * cxt->geom.heads * cxt->geom.sectors, SUN_TAG_WHOLEDISK); } { unsigned short *ush = (unsigned short *)sunlabel; unsigned short csum = 0; while(ush < (unsigned short *)(&sunlabel->csum)) csum ^= *ush++; sunlabel->csum = csum; } fdisk_label_set_changed(cxt->label, 1); cxt->label->nparts_cur = count_used_partitions(cxt); fdisk_info(cxt, _("Created a new Sun disklabel.")); return 0; }
static int sun_create_disklabel(struct fdisk_context *cxt) { struct hd_geometry geometry; sector_t llsectors, llcyls; unsigned int ndiv, sec_fac; int res; struct fdisk_sun_label *sun; /* libfdisk sun handler */ struct sun_disklabel *sunlabel; /* on disk data */ assert(cxt); assert(cxt->label); assert(fdisk_is_disklabel(cxt, SUN)); /* map first sector to header */ fdisk_zeroize_firstsector(cxt); sun = (struct fdisk_sun_label *) cxt->label; sun->header = (struct sun_disklabel *) cxt->firstsector; sunlabel = sun->header; cxt->label->nparts_max = SUN_MAXPARTITIONS; sunlabel->magic = cpu_to_be16(SUN_LABEL_MAGIC); sunlabel->vtoc.version = cpu_to_be32(SUN_VTOC_VERSION); sunlabel->vtoc.sanity = cpu_to_be32(SUN_VTOC_SANITY); sunlabel->vtoc.nparts = cpu_to_be16(SUN_MAXPARTITIONS); res = blkdev_get_sectors(cxt->dev_fd, &llsectors); sec_fac = cxt->sector_size / 512; #ifdef HDIO_GETGEO if (!ioctl(cxt->dev_fd, HDIO_GETGEO, &geometry)) { cxt->geom.heads = geometry.heads; cxt->geom.sectors = geometry.sectors; if (res == 0) { llcyls = llsectors / (cxt->geom.heads * cxt->geom.sectors * sec_fac); cxt->geom.cylinders = llcyls; if (cxt->geom.cylinders != llcyls) cxt->geom.cylinders = ~0; } else { cxt->geom.cylinders = geometry.cylinders; fdisk_warnx(cxt, _("BLKGETSIZE ioctl failed on %s. " "Using geometry cylinder value of %llu. " "This value may be truncated for devices " "> 33.8 GB."), cxt->dev_path, cxt->geom.cylinders); } } else #endif ask_geom(cxt); sunlabel->acyl = cpu_to_be16(0); sunlabel->pcyl = cpu_to_be16(cxt->geom.cylinders); sunlabel->rpm = cpu_to_be16(5400); sunlabel->intrlv = cpu_to_be16(1); sunlabel->apc = cpu_to_be16(0); sunlabel->nhead = cpu_to_be16(cxt->geom.heads); sunlabel->nsect = cpu_to_be16(cxt->geom.sectors); sunlabel->ncyl = cpu_to_be16(cxt->geom.cylinders); snprintf((char *) sunlabel->label_id, sizeof(sunlabel->label_id), "Linux cyl %llu alt %u hd %u sec %llu", cxt->geom.cylinders, be16_to_cpu(sunlabel->acyl), cxt->geom.heads, cxt->geom.sectors); if (cxt->geom.cylinders * cxt->geom.heads * cxt->geom.sectors >= 150 * 2048) { ndiv = cxt->geom.cylinders - (50 * 2048 / (cxt->geom.heads * cxt->geom.sectors)); /* 50M swap */ } else ndiv = cxt->geom.cylinders * 2 / 3; set_sun_partition(cxt, 0, 0, ndiv * cxt->geom.heads * cxt->geom.sectors, SUN_TAG_LINUX_NATIVE); set_sun_partition(cxt, 1, ndiv * cxt->geom.heads * cxt->geom.sectors, cxt->geom.cylinders * cxt->geom.heads * cxt->geom.sectors, SUN_TAG_LINUX_SWAP); sunlabel->vtoc.infos[1].flags |= cpu_to_be16(SUN_FLAG_UNMNT); set_sun_partition(cxt, 2, 0, cxt->geom.cylinders * cxt->geom.heads * cxt->geom.sectors, SUN_TAG_WHOLEDISK); { unsigned short *ush = (unsigned short *)sunlabel; unsigned short csum = 0; while(ush < (unsigned short *)(&sunlabel->csum)) csum ^= *ush++; sunlabel->csum = csum; } fdisk_label_set_changed(cxt->label, 1); cxt->label->nparts_cur = count_used_partitions(cxt); fdisk_sinfo(cxt, FDISK_INFO_SUCCESS, _("Created a new Sun disklabel.")); return 0; }