Пример #1
0
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);
	}
}
Пример #2
0
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;
}
Пример #3
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;
}