int fdisk_read_firstsector(struct fdisk_context *cxt) { ssize_t r; int rc; assert(cxt); assert(cxt->sector_size); rc = fdisk_init_firstsector_buffer(cxt); if (rc) return rc; assert(cxt->sector_size == cxt->firstsector_bufsz); DBG(CXT, ul_debugobj(cxt, "reading first sector " "buffer [sector_size=%lu]", cxt->sector_size)); r = lseek(cxt->dev_fd, 0, SEEK_SET); if (r == -1) { DBG(CXT, ul_debugobj(cxt, "failed to seek to first sector %m")); return -errno; } r = read(cxt->dev_fd, cxt->firstsector, cxt->sector_size); if (r != cxt->sector_size) { if (!errno) errno = EINVAL; /* probably too small file/device */ DBG(CXT, ul_debugobj(cxt, "failed to read first sector %m")); return -errno; } return 0; }
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 sgi_create_disklabel(struct fdisk_context *cxt) { struct fdisk_sgi_label *sgi; struct sgi_disklabel *sgilabel; int rc; assert(cxt); assert(cxt->label); assert(fdisk_is_disklabel(cxt, SGI)); #ifdef HDIO_GETGEO if (cxt->geom.heads && cxt->geom.sectors) { sector_t llsectors; if (blkdev_get_sectors(cxt->dev_fd, &llsectors) == 0) { /* the get device size ioctl was successful */ sector_t llcyls; int sec_fac = cxt->sector_size / 512; llcyls = llsectors / (cxt->geom.heads * cxt->geom.sectors * sec_fac); cxt->geom.cylinders = llcyls; if (cxt->geom.cylinders != llcyls) /* truncated? */ cxt->geom.cylinders = ~0; } else { /* otherwise print error and use truncated version */ 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); } } #endif rc = fdisk_init_firstsector_buffer(cxt); if (rc) return rc; sgi = (struct fdisk_sgi_label *) cxt->label; sgi->header = (struct sgi_disklabel *) cxt->firstsector; sgilabel = sgi->header; sgilabel->magic = cpu_to_be32(SGI_LABEL_MAGIC); sgilabel->root_part_num = cpu_to_be16(0); sgilabel->swap_part_num = cpu_to_be16(1); /* sizeof(sgilabel->boot_file) = 16 > 6 */ memset(sgilabel->boot_file, 0, 16); strcpy((char *) sgilabel->boot_file, "/unix"); sgilabel->devparam.skew = (0); sgilabel->devparam.gap1 = (0); sgilabel->devparam.gap2 = (0); sgilabel->devparam.sparecyl = (0); sgilabel->devparam.pcylcount = cpu_to_be16(cxt->geom.cylinders); sgilabel->devparam.head_vol0 = cpu_to_be16(0); sgilabel->devparam.ntrks = cpu_to_be16(cxt->geom.heads); /* tracks/cylinder (heads) */ sgilabel->devparam.cmd_tag_queue_depth = (0); sgilabel->devparam.unused0 = (0); sgilabel->devparam.unused1 = cpu_to_be16(0); sgilabel->devparam.nsect = cpu_to_be16(cxt->geom.sectors); /* sectors/track */ sgilabel->devparam.bytes = cpu_to_be16(cxt->sector_size); sgilabel->devparam.ilfact = cpu_to_be16(1); sgilabel->devparam.flags = cpu_to_be32( SGI_DEVPARAM_TRACK_FWD | SGI_DEVPARAM_IGNORE_ERRORS | SGI_DEVPARAM_RESEEK); sgilabel->devparam.datarate = cpu_to_be32(0); sgilabel->devparam.retries_on_error = cpu_to_be32(1); sgilabel->devparam.ms_per_word = cpu_to_be32(0); sgilabel->devparam.xylogics_gap1 = cpu_to_be16(0); sgilabel->devparam.xylogics_syncdelay = cpu_to_be16(0); sgilabel->devparam.xylogics_readdelay = cpu_to_be16(0); sgilabel->devparam.xylogics_gap2 = cpu_to_be16(0); sgilabel->devparam.xylogics_readgate = cpu_to_be16(0); sgilabel->devparam.xylogics_writecont = cpu_to_be16(0); memset(&(sgilabel->volume), 0, sizeof(struct sgi_volume) * SGI_MAXVOLUMES); memset(&(sgilabel->partitions), 0, sizeof(struct sgi_partition) * SGI_MAXPARTITIONS); cxt->label->nparts_max = SGI_MAXPARTITIONS; sgi_set_entire(cxt); sgi_set_volhdr(cxt); cxt->label->nparts_cur = count_used_partitions(cxt); fdisk_sinfo(cxt, FDISK_INFO_SUCCESS, _("Created a new SGI disklabel.")); return 0; }