static sector_t get_dev_blocks(char *dev) { int fd; sector_t size; if ((fd = open(dev, O_RDONLY)) < 0) err(EXIT_FAILURE, _("cannot open %s"), dev); if (blkdev_get_sectors(fd, &size) == -1) { close(fd); err(EXIT_FAILURE, _("BLKGETSIZE ioctl failed on %s"), dev); } close(fd); return size/2; }
static int get_size(const char *dev, int silent, uintmax_t *sz) { int fd, rc = 0; fd = open(dev, O_RDONLY); if (fd < 0) { if (!silent) warn(_("cannot open %s"), dev); return -errno; } if (blkdev_get_sectors(fd, (unsigned long long *) sz) == -1) { if (!silent) warn(_("Cannot get size of %s"), dev); rc = -errno; } close(fd); return rc; }
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; struct hd_geometry geometry; sector_t llsectors; int res; /* the result from the ioctl */ int sec_fac; /* the sector factor */ assert(cxt); assert(cxt->label); assert(fdisk_is_disklabel(cxt, SGI)); sec_fac = cxt->sector_size / 512; /* determine the sector factor */ res = blkdev_get_sectors(cxt->dev_fd, &llsectors); #ifdef HDIO_GETGEO /* TODO: it seems unnecessary, geometry is already set in the context */ if (ioctl(cxt->dev_fd, HDIO_GETGEO, &geometry) < 0) { fdisk_warn(cxt, _("HDIO_GETGEO ioctl failed on %s"), cxt->dev_path); return -1; } cxt->geom.heads = geometry.heads; cxt->geom.sectors = geometry.sectors; if (res == 0) { /* the get device size ioctl was successful */ sector_t llcyls; 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 */ cxt->geom.cylinders = geometry.cylinders; fdisk_warnx(cxt, _("Warning: 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 fdisk_zeroize_firstsector(cxt); 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(geometry.cylinders); sgilabel->devparam.head_vol0 = cpu_to_be16(0); sgilabel->devparam.ntrks = cpu_to_be16(geometry.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(geometry.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; }
int main(int argc, char **argv) { int fd, fd2, c, i, j, k, n; unsigned long long size; struct hd_geometry g; struct slice all; struct blkpg_ioctl_arg a; struct blkpg_partition pt; struct pt *ptp; enum action what = LIST; char *p, *type, *diskdevice, *device; int lower, upper; int verbose = 0; int ret = 0; initpts(); init_crc32(); lower = upper = 0; type = device = diskdevice = NULL; while ((c = getopt_long (argc, argv, short_opts, long_opts, NULL)) != -1) switch(c) { case 'l': what = LIST; break; case 'a': what = ADD; break; case 'd': what = DELETE; break; case 'g': force_gpt = 1; break; case 'n': p = optarg; lower = atoi(p); p = strchr(p, '-'); if (p) upper = atoi(p+1); else upper = lower; break; case 't': type = optarg; break; case 'v': verbose = 1; break; case '?': default: fprintf(stderr, "unknown option\n"); exit(1); } if (optind == argc-2) { device = argv[optind]; diskdevice = argv[optind+1]; } else if (optind == argc-1) { diskdevice = device = argv[optind]; } else { fprintf(stderr, "call: partx -opts [device] wholedisk\n"); exit(1); } fd = open(diskdevice, O_RDONLY); if (fd == -1) { perror(diskdevice); exit(1); } /* remove the indicated partitions from the kernel partition tables */ if (what == DELETE) { if (device != diskdevice) { fprintf(stderr, "call: partx -d [--nr M-N] wholedisk\n"); exit(1); } if (!lower) lower = 1; while (upper == 0 || lower <= upper) { int err; if (lower > MAXSLICES) break; pt.pno = lower; pt.start = 0; pt.length = 0; pt.devname[0] = 0; pt.volname[0] = 0; a.op = BLKPG_DEL_PARTITION; a.flags = 0; a.datalen = sizeof(pt); a.data = &pt; if (ioctl(fd, BLKPG, &a) == -1) err = errno; else err = 0; errmerge(err, lower, "error deleting partition %d: ", "error deleting partitions %d-%d: "); /* expected errors: EBUSY: mounted or in use as swap ENXIO: no such nonempty partition EINVAL: not wholedisk, or bad pno EACCES/EPERM: permission denied */ if (err && err != EBUSY && err != ENXIO) { ret = 1; break; } if (err == 0 && verbose) printf("deleted partition %d\n", lower); lower++; } errmerge(0, 0, "error deleting partition %d: ", "error deleting partitions %d-%d: "); return ret; } if (device != diskdevice) { fd2 = open(device, O_RDONLY); if (fd2 == -1) { perror(device); exit(1); } } else { fd2 = fd; } if (ioctl(fd, HDIO_GETGEO, &g)) { perror("HDIO_GETGEO"); exit(1); } if (g.start != 0) { fprintf(stderr, "last arg is not the whole disk\n"); fprintf(stderr, "call: partx -opts device wholedisk\n"); exit(1); } if (ioctl(fd2, HDIO_GETGEO, &g)) { perror("HDIO_GETGEO"); exit(1); } all.start = g.start; if (blkdev_get_sectors(fd2, &size) != 0) { perror("partx"); exit(1); } all.size = (unsigned int) size; if (verbose) printf("device %s: start %d size %d\n", device, all.start, all.size); if (all.size == 0) { fprintf(stderr, "That disk slice has size 0\n"); exit(0); } if (all.size == 2) all.size = 0; /* probably extended partition */ /* add the indicated partitions to the kernel partition tables */ if (!lower) lower = 1; for (i = 0; i < ptct; i++) { ptp = &pts[i]; if (!type || !strcmp(type, ptp->type)) { n = ptp->fn(fd, all, slices, ARRAY_SIZE(slices)); if (n >= 0 && verbose) printf("%s: %d slices\n", ptp->type, n); if (n > 0 && (verbose || what == LIST)) { for (j=0; j<n; j++) printf("#%2d: %9d-%9d (%9d sectors, %6d MB)\n", lower+j, slices[j].start, slices[j].start+slices[j].size-1, slices[j].size, (int)((512 * (long long) slices[j].size) / 1000000)); } if (n > 0 && what == ADD) { /* test for overlap, as in the case of an extended partition, and reduce size */ for (j=0; j<n; j++) { for (k=j+1; k<n; k++) { if (slices[k].start > slices[j].start && slices[k].start < slices[j].start + slices[j].size) { slices[j].size = slices[k].start - slices[j].start; if (verbose) printf("reduced size of " "partition #%d to %d\n", lower+j, slices[j].size); } } } for (j=0; j<n; j++) { /* skip unused/empty partitions */ if (slices[j].size == 0) continue; pt.pno = lower+j; pt.start = 512 * (long long) slices[j].start; pt.length = 512 * (long long) slices[j].size; pt.devname[0] = 0; pt.volname[0] = 0; a.op = BLKPG_ADD_PARTITION; a.flags = 0; a.datalen = sizeof(pt); a.data = &pt; if (ioctl(fd, BLKPG, &a) == -1) { perror("BLKPG"); fprintf(stderr, "error adding partition %d\n", lower+j); } else if (verbose) printf("added partition %d\n", lower+j); } } } } return 0; }
static int sgi_create_disklabel(struct fdisk_context *cxt) { struct hd_geometry geometry; struct { unsigned int start; unsigned int nsect; int sysid; } old[4]; int i=0; sector_t llsectors; int res; /* the result from the ioctl */ int sec_fac; /* the sector factor */ sec_fac = cxt->sector_size / 512; /* determine the sector factor */ fprintf(stderr, _("Building a new SGI disklabel.\n")); other_endian = (BYTE_ORDER == LITTLE_ENDIAN); res = blkdev_get_sectors(cxt->dev_fd, &llsectors); #ifdef HDIO_GETGEO if (ioctl(cxt->dev_fd, HDIO_GETGEO, &geometry) < 0) err(EXIT_FAILURE, _("HDIO_GETGEO ioctl failed on %s"), cxt->dev_path); cxt->geom.heads = geometry.heads; cxt->geom.sectors = geometry.sectors; if (res == 0) { /* the get device size ioctl was successful */ sector_t llcyls; 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 */ cxt->geom.cylinders = geometry.cylinders; fprintf(stderr, _("Warning: BLKGETSIZE ioctl failed on %s. " "Using geometry cylinder value of %llu.\n" "This value may be truncated for devices" " > 33.8 GB.\n"), cxt->dev_path, cxt->geom.cylinders); } #endif /* * Convert old MBR to SGI label, make it DEPRECATED, this feature * has to be handled in by any top-level fdisk command. */ for (i = 0; i < 4; i++) { old[i].sysid = 0; if (mbr_is_valid_magic(cxt->firstsector)) { if (get_part_table(i)->sys_ind) { old[i].sysid = get_part_table(i)->sys_ind; old[i].start = get_start_sect(get_part_table(i)); old[i].nsect = get_nr_sects(get_part_table(i)); if (debug) printf(_("ID=%02x\tSTART=%d\tLENGTH=%d\n"), old[i].sysid, old[i].start, old[i].nsect); } } } for (i = 0; i < 4; i++) if (old[i].sysid) { printf(_("Trying to keep parameters of partitions already set.\n")); break; } fdisk_zeroize_firstsector(cxt); sgilabel->magic = SSWAP32(SGI_LABEL_MAGIC); sgilabel->boot_part = SSWAP16(0); sgilabel->swap_part = SSWAP16(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 = SSWAP16(geometry.cylinders); sgilabel->devparam.head_vol0 = SSWAP16(0); sgilabel->devparam.ntrks = SSWAP16(geometry.heads); /* tracks/cylinder (heads) */ sgilabel->devparam.cmd_tag_queue_depth = (0); sgilabel->devparam.unused0 = (0); sgilabel->devparam.unused1 = SSWAP16(0); sgilabel->devparam.nsect = SSWAP16(geometry.sectors); /* sectors/track */ sgilabel->devparam.bytes = SSWAP16(cxt->sector_size); sgilabel->devparam.ilfact = SSWAP16(1); sgilabel->devparam.flags = SSWAP32(TRACK_FWD|\ IGNORE_ERRORS|RESEEK); sgilabel->devparam.datarate = SSWAP32(0); sgilabel->devparam.retries_on_error = SSWAP32(1); sgilabel->devparam.ms_per_word = SSWAP32(0); sgilabel->devparam.xylogics_gap1 = SSWAP16(0); sgilabel->devparam.xylogics_syncdelay = SSWAP16(0); sgilabel->devparam.xylogics_readdelay = SSWAP16(0); sgilabel->devparam.xylogics_gap2 = SSWAP16(0); sgilabel->devparam.xylogics_readgate = SSWAP16(0); sgilabel->devparam.xylogics_writecont = SSWAP16(0); memset(&(sgilabel->directory), 0, sizeof(struct volume_directory)*15); memset(&(sgilabel->partitions), 0, sizeof(struct sgi_partition)*16); cxt->disklabel = FDISK_DISKLABEL_SGI; partitions = 16; volumes = 15; sgi_set_entire(cxt); sgi_set_volhdr(cxt); for (i = 0; i < 4; i++) { if (old[i].sysid) { sgi_set_partition(cxt, i, old[i].start, old[i].nsect, old[i].sysid); } } return 0; }
void create_sgilabel(void) { struct hd_geometry geometry; struct { unsigned int start; unsigned int nsect; int sysid; } old[4]; int i=0; unsigned long long llsectors; int res; /* the result from the ioctl */ int sec_fac; /* the sector factor */ sec_fac = sector_size / 512; /* determine the sector factor */ fprintf(stderr, _("Building a new SGI disklabel.\n")); other_endian = (BYTE_ORDER == LITTLE_ENDIAN); res = blkdev_get_sectors(fd, &llsectors); #ifdef HDIO_GETGEO if (!ioctl(fd, HDIO_GETGEO, &geometry)) { heads = geometry.heads; sectors = geometry.sectors; if (res == 0) { /* the get device size ioctl was successful */ unsigned long long llcyls; llcyls = llsectors / (heads * sectors * sec_fac); cylinders = llcyls; if (cylinders != llcyls) /* truncated? */ cylinders = ~0; } else { /* otherwise print error and use truncated version */ cylinders = geometry.cylinders; fprintf(stderr, _("Warning: BLKGETSIZE ioctl failed on %s. " "Using geometry cylinder value of %d.\n" "This value may be truncated for devices" " > 33.8 GB.\n"), disk_device, cylinders); } } #endif for (i = 0; i < 4; i++) { old[i].sysid = 0; if (valid_part_table_flag(MBRbuffer)) { if (get_part_table(i)->sys_ind) { old[i].sysid = get_part_table(i)->sys_ind; old[i].start = get_start_sect(get_part_table(i)); old[i].nsect = get_nr_sects(get_part_table(i)); if (debug) printf(_("ID=%02x\tSTART=%d\tLENGTH=%d\n"), old[i].sysid, old[i].start, old[i].nsect); } } } for (i = 0; i < 4; i++) if (old[i].sysid) { printf(_("Trying to keep parameters of partitions already set.\n")); break; } zeroize_mbr_buffer(); sgilabel->magic = SSWAP32(SGI_LABEL_MAGIC); sgilabel->boot_part = SSWAP16(0); sgilabel->swap_part = SSWAP16(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 = SSWAP16(geometry.cylinders); sgilabel->devparam.head_vol0 = SSWAP16(0); sgilabel->devparam.ntrks = SSWAP16(geometry.heads); /* tracks/cylinder (heads) */ sgilabel->devparam.cmd_tag_queue_depth = (0); sgilabel->devparam.unused0 = (0); sgilabel->devparam.unused1 = SSWAP16(0); sgilabel->devparam.nsect = SSWAP16(geometry.sectors); /* sectors/track */ sgilabel->devparam.bytes = SSWAP16(sector_size); sgilabel->devparam.ilfact = SSWAP16(1); sgilabel->devparam.flags = SSWAP32(TRACK_FWD|\ IGNORE_ERRORS|RESEEK); sgilabel->devparam.datarate = SSWAP32(0); sgilabel->devparam.retries_on_error = SSWAP32(1); sgilabel->devparam.ms_per_word = SSWAP32(0); sgilabel->devparam.xylogics_gap1 = SSWAP16(0); sgilabel->devparam.xylogics_syncdelay = SSWAP16(0); sgilabel->devparam.xylogics_readdelay = SSWAP16(0); sgilabel->devparam.xylogics_gap2 = SSWAP16(0); sgilabel->devparam.xylogics_readgate = SSWAP16(0); sgilabel->devparam.xylogics_writecont = SSWAP16(0); memset(&(sgilabel->directory), 0, sizeof(struct volume_directory)*15); memset(&(sgilabel->partitions), 0, sizeof(struct sgi_partition)*16); disklabel = SGI_LABEL; partitions = 16; volumes = 15; sgi_set_entire(); sgi_set_volhdr(); for (i = 0; i < 4; i++) { if (old[i].sysid) { sgi_set_partition(i, old[i].start, old[i].nsect, old[i].sysid); } } }
int main(int argc, char *argv[]) { char *device, *volume, *fsname; int inodes; unsigned long long total_blocks, ino_bytes, ino_blocks, data_blocks; unsigned long long user_specified_total_blocks = 0; int verbose = 0; int fd; struct bfssb sb; struct bfsi ri; struct bfsde de; struct stat statbuf; time_t now; int c, i, len; char *p; progname = argv[0]; if ((p = strrchr(progname, '/')) != NULL) progname = p+1; if (argc < 2) usage(); if (argc == 2 && (!strcmp(argv[1], "-V") || !strcmp(argv[1], "--version"))) { printf(_("%s (%s)\n"), progname, PACKAGE_STRING); exit(0); } volume = fsname = " "; /* is there a default? */ inodes = 0; while ((c = getopt(argc, argv, "vF:N:V:cl:")) != -1) { switch (c) { case 'N': inodes = atol(optarg); break; case 'V': len = strlen(optarg); if (len <= 0 || len > 6) fatal(_("volume name too long")); volume = strdup(optarg); break; case 'F': len = strlen(optarg); if (len <= 0 || len > 6) fatal(_("fsname name too long")); fsname = strdup(optarg); break; case 'v': verbose = 1; break; /* when called via mkfs we may get options c,l,v */ case 'c': case 'l': break; default: usage(); } } if (optind == argc) usage(); device = argv[optind++]; if (stat(device, &statbuf) == -1) { perror(device); fatal(_("cannot stat device %s"), device); } if (!S_ISBLK(statbuf.st_mode)) fatal(_("%s is not a block special device"), device); fd = open(device, O_RDWR | O_EXCL); if (fd == -1) { perror(device); fatal(_("cannot open %s"), device); } if (optind == argc-1) user_specified_total_blocks = atoll(argv[optind]); else if (optind != argc) usage(); if (blkdev_get_sectors(fd, &total_blocks) == -1) { if (!user_specified_total_blocks) { perror("blkdev_get_sectors"); fatal(_("cannot get size of %s"), device); } total_blocks = user_specified_total_blocks; } else if (user_specified_total_blocks) { if (user_specified_total_blocks > total_blocks) fatal(_("blocks argument too large, max is %llu"), total_blocks); total_blocks = user_specified_total_blocks; } if (!inodes) { /* pick some reasonable default */ inodes = 8*(total_blocks/800); if (inodes < 48) inodes = 48; if (inodes > 512) inodes = 512; } else { /* believe the user */ if (inodes > 512) fatal(_("too many inodes - max is 512")); } ino_bytes = inodes * sizeof(struct bfsi); ino_blocks = (ino_bytes + BFS_BLOCKSIZE - 1) / BFS_BLOCKSIZE; data_blocks = total_blocks - ino_blocks - 1; /* mimic the behaviour of SCO's mkfs - maybe this limit is needed */ if (data_blocks < 32) fatal(_("not enough space, need at least %llu blocks"), ino_blocks + 33); memset(&sb, 0, sizeof(sb)); sb.s_magic = BFS_SUPER_MAGIC; sb.s_start = ino_bytes + sizeof(struct bfssb); sb.s_end = total_blocks * BFS_BLOCKSIZE - 1; sb.s_from = sb.s_to = sb.s_backup_from = sb.s_backup_to = -1; memcpy(sb.s_fsname, fsname, 6); memcpy(sb.s_volume, volume, 6); if (verbose) { fprintf(stderr, _("Device: %s\n"), device); fprintf(stderr, _("Volume: <%-6s>\n"), volume); fprintf(stderr, _("FSname: <%-6s>\n"), fsname); fprintf(stderr, _("BlockSize: %d\n"), BFS_BLOCKSIZE); if (ino_blocks==1) fprintf(stderr, _("Inodes: %d (in 1 block)\n"), inodes); else fprintf(stderr, _("Inodes: %d (in %lld blocks)\n"), inodes, ino_blocks); fprintf(stderr, _("Blocks: %lld\n"), total_blocks); fprintf(stderr, _("Inode end: %d, Data end: %d\n"), sb.s_start-1, sb.s_end); } if (write(fd, &sb, sizeof(sb)) != sizeof(sb)) fatal(_("error writing superblock")); memset(&ri, 0, sizeof(ri)); ri.i_ino = BFS_ROOT_INO; ri.i_first_block = 1 + ino_blocks; ri.i_last_block = ri.i_first_block + (inodes * sizeof(de) - 1) / BFS_BLOCKSIZE; ri.i_bytes_to_end = ri.i_first_block * BFS_BLOCKSIZE + 2 * sizeof(struct bfsde) - 1; ri.i_type = BFS_DIR_TYPE; ri.i_mode = S_IFDIR | 0755; /* or just 0755 */ ri.i_uid = 0; ri.i_gid = 1; /* random */ ri.i_nlinks = 2; time(&now); ri.i_atime = now; ri.i_mtime = now; ri.i_ctime = now; if (write(fd, &ri, sizeof(ri)) != sizeof(ri)) fatal(_("error writing root inode")); memset(&ri, 0, sizeof(ri)); for (i=1; i<inodes; i++) if (write(fd, &ri, sizeof(ri)) != sizeof(ri)) fatal(_("error writing inode")); if (lseek(fd, (1 + ino_blocks)*BFS_BLOCKSIZE, SEEK_SET) == -1) fatal(_("seek error")); memset(&de, 0, sizeof(de)); de.d_ino = BFS_ROOT_INO; memcpy(de.d_name, ".", 1); if (write(fd, &de, sizeof(de)) != sizeof(de)) fatal(_("error writing . entry")); memcpy(de.d_name, "..", 2); if (write(fd, &de, sizeof(de)) != sizeof(de)) fatal(_("error writing .. entry")); if (close(fd) == -1) { perror(device); fatal(_("error closing %s"), device); } 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; }
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_label(cxt, SGI)); #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) { /* the get device size ioctl was successful */ fdisk_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, 0, 0); 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; /* don't create default layout when a script defined */ if (!cxt->script) { sgi_set_entire(cxt); sgi_set_volhdr(cxt); } cxt->label->nparts_cur = count_used_partitions(cxt); fdisk_info(cxt, _("Created a new SGI disklabel.")); return 0; }