void dos_delete_partition(int i) { struct pte *pe = &ptes[i]; struct partition *p = pe->part_table; struct partition *q = pe->ext_pointer; /* Note that for the fifth partition (i == 4) we don't actually decrement partitions. */ if (i < 4) { if (IS_EXTENDED (p->sys_ind) && i == ext_index) { partitions = 4; ptes[ext_index].ext_pointer = NULL; extended_offset = 0; } clear_partition(p); } else if (!q->sys_ind && i > 4) { /* the last one in the chain - just delete */ --partitions; --i; clear_partition(ptes[i].ext_pointer); ptes[i].changed = 1; } else { /* not the last one - further ones will be moved down */ if (i > 4) { /* delete this link in the chain */ p = ptes[i-1].ext_pointer; *p = *q; set_start_sect(p, get_start_sect(q)); set_nr_sects(p, get_nr_sects(q)); ptes[i-1].changed = 1; } else if (partitions > 5) { /* 5 will be moved to 4 */ /* the first logical in a longer chain */ struct pte *pe = &ptes[5]; if (pe->part_table) /* prevent SEGFAULT */ set_start_sect(pe->part_table, get_partition_start(pe) - extended_offset); pe->offset = extended_offset; pe->changed = 1; } if (partitions > 5) { partitions--; while (i < partitions) { ptes[i] = ptes[i+1]; i++; } } else /* the only logical: clear only */ clear_partition(ptes[i].part_table); } }
int main(int argc, char **argv) { int c, fd, partno; const char *wholedisk; uint64_t start; static const struct option longopts[] = { {"help", no_argument, 0, 'h'}, {"version", no_argument, 0, 'V'}, {NULL, no_argument, 0, '0'}, }; setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); atexit(close_stdout); while ((c = getopt_long(argc, argv, "Vh", longopts, NULL)) != -1) switch (c) { case 'V': printf(UTIL_LINUX_VERSION); return EXIT_SUCCESS; case 'h': usage(stdout); default: errtryhelp(EXIT_FAILURE); } if (argc != 4) usage(stderr); wholedisk = argv[1]; partno = strtou32_or_err(argv[2], _("invalid partition number argument")); if ((fd = open(wholedisk, O_RDONLY)) < 0) err(EXIT_FAILURE, _("cannot open %s"), wholedisk); if (get_partition_start(fd, partno, &start)) err(EXIT_FAILURE, _("%s: failed to get start of the partition number %s"), wholedisk, argv[2]); if (partx_resize_partition(fd, partno, start, strtou64_or_err(argv[3], _("invalid length argument")))) err(EXIT_FAILURE, _("failed to resize partition")); if (close_fd(fd) != 0) err(EXIT_FAILURE, _("write failed")); return 0; }
errcode_t mk_hugefiles(ext2_filsys fs, const char *device_name) { unsigned long i; ext2_ino_t dir; errcode_t retval; blk64_t fs_blocks, part_offset = 0; unsigned long align; int d, dsize; char *t; if (!get_bool_from_profile(fs_types, "make_hugefiles", 0)) return 0; if (!EXT2_HAS_INCOMPAT_FEATURE(fs->super, EXT3_FEATURE_INCOMPAT_EXTENTS)) return EXT2_ET_EXTENT_NOT_SUPPORTED; uid = get_int_from_profile(fs_types, "hugefiles_uid", 0); gid = get_int_from_profile(fs_types, "hugefiles_gid", 0); fs->umask = get_int_from_profile(fs_types, "hugefiles_umask", 077); num_files = get_int_from_profile(fs_types, "num_hugefiles", 0); t = get_string_from_profile(fs_types, "hugefiles_slack", "1M"); num_slack = parse_num_blocks2(t, fs->super->s_log_block_size); free(t); t = get_string_from_profile(fs_types, "hugefiles_size", "0"); num_blocks = parse_num_blocks2(t, fs->super->s_log_block_size); free(t); t = get_string_from_profile(fs_types, "hugefiles_align", "0"); align = parse_num_blocks2(t, fs->super->s_log_block_size); free(t); if (get_bool_from_profile(fs_types, "hugefiles_align_disk", 0)) { part_offset = get_partition_start(device_name) / (fs->blocksize / 512); if (part_offset % EXT2FS_CLUSTER_RATIO(fs)) { fprintf(stderr, _("Partition offset of %llu (%uk) blocks " "not compatible with cluster size %u.\n"), part_offset, fs->blocksize, EXT2_CLUSTER_SIZE(fs->super)); exit(1); } } num_blocks = round_up_align(num_blocks, align, 0); zero_hugefile = get_bool_from_profile(fs_types, "zero_hugefiles", zero_hugefile); t = get_string_from_profile(fs_types, "hugefiles_dir", "/"); retval = create_directory(fs, t, &dir); free(t); if (retval) return retval; fn_prefix = get_string_from_profile(fs_types, "hugefiles_name", "hugefile"); idx_digits = get_int_from_profile(fs_types, "hugefiles_digits", 5); d = int_log10(num_files) + 1; if (idx_digits > d) d = idx_digits; dsize = strlen(fn_prefix) + d + 16; fn_buf = malloc(dsize); if (!fn_buf) { free(fn_prefix); return ENOMEM; } strcpy(fn_buf, fn_prefix); fn_numbuf = fn_buf + strlen(fn_prefix); free(fn_prefix); fs_blocks = ext2fs_free_blocks_count(fs->super); if (fs_blocks < num_slack + align) return ENOSPC; fs_blocks -= num_slack + align; if (num_blocks && num_blocks > fs_blocks) return ENOSPC; if (num_blocks == 0 && num_files == 0) num_files = 1; if (num_files == 0 && num_blocks) { num_files = fs_blocks / num_blocks; fs_blocks -= (num_files / 16) + 1; fs_blocks -= calc_overhead(fs, num_blocks) * num_files; num_files = fs_blocks / num_blocks; } if (num_blocks == 0 && num_files > 1) { num_blocks = fs_blocks / num_files; fs_blocks -= (num_files / 16) + 1; fs_blocks -= calc_overhead(fs, num_blocks) * num_files; num_blocks = fs_blocks / num_files; } num_slack += calc_overhead(fs, num_blocks) * num_files; num_slack += (num_files / 16) + 1; /* space for dir entries */ goal = get_start_block(fs, num_slack); goal = round_up_align(goal, align, part_offset); if ((num_blocks ? num_blocks : fs_blocks) > (0x80000000UL / fs->blocksize)) fs->super->s_feature_ro_compat |= EXT2_FEATURE_RO_COMPAT_LARGE_FILE; if (!quiet) { if (zero_hugefile && verbose) printf("%s", _("Huge files will be zero'ed\n")); printf(_("Creating %lu huge file(s) "), num_files); if (num_blocks) printf(_("with %llu blocks each"), num_blocks); fputs(": ", stdout); } if (num_blocks == 0) num_blocks = ext2fs_blocks_count(fs->super) - goal; for (i=0; i < num_files; i++) { ext2_ino_t ino; retval = mk_hugefile(fs, num_blocks, dir, i, &ino); if (retval) { com_err(program_name, retval, _("while creating huge file %lu"), i); goto errout; } } if (!quiet) fputs(_("done\n"), stdout); errout: free(fn_buf); return retval; }