Пример #1
0
static void progress_init(struct progress_struct *progress,
			  const char *label,__u32 max)
{
	int	i;

	memset(progress, 0, sizeof(struct progress_struct));
	if (quiet)
		return;

	/*
	 * Figure out how many digits we need
	 */
	i = int_log10(max);
	sprintf(progress->format, "%%%dd/%%%dld", i, i);
	memset(progress->backup, '\b', sizeof(progress->backup)-1);
	progress->backup[sizeof(progress->backup)-1] = 0;
	if ((2*i)+1 < (int) sizeof(progress->backup))
		progress->backup[(2*i)+1] = 0;
	progress->max = max;

	progress->skip_progress = 0;
	if (getenv("MKE2FS_SKIP_PROGRESS"))
		progress->skip_progress++;

	fputs(label, stdout);
	fflush(stdout);
}
Пример #2
0
void ext2fs_numeric_progress_init(ext2_filsys fs,
				  struct ext2fs_numeric_progress_struct * progress,
				  const char *label, __u64 max)
{
	/*
	 * The PRINT_PROGRESS flag turns on or off ALL
	 * progress-related messages, whereas the SKIP_PROGRESS
	 * environment variable prints the start and end messages but
	 * not the numeric countdown in the middle.
	 */
	if (!(fs->flags & EXT2_FLAG_PRINT_PROGRESS))
		return;

	memset(spaces, ' ', sizeof(spaces)-1);
	spaces[sizeof(spaces)-1] = 0;
	memset(backspaces, '\b', sizeof(backspaces)-1);
	backspaces[sizeof(backspaces)-1] = 0;
	progress->skip_progress = 0;
	if (getenv("E2FSPROGS_SKIP_PROGRESS"))
		progress->skip_progress++;

	memset(progress, 0, sizeof(*progress));

	/*
	 * Figure out how many digits we need
	 */
	progress->max = max;
	progress->log_max = int_log10(max);

	if (label) {
		fputs(label, stdout);
		fflush(stdout);
	}
}
Пример #3
0
static void show_stats(ext2_filsys fs)
{
	struct ext2_super_block *s = fs->super;
	char 			buf[80];
        char                    *os;
	blk_t			group_block;
	dgrp_t			i;
	int			need, col_left;
	
	if (fs_param.s_blocks_count != s->s_blocks_count)
		fprintf(stderr, _("warning: %u blocks unused.\n\n"),
		       fs_param.s_blocks_count - s->s_blocks_count);

	memset(buf, 0, sizeof(buf));
	strncpy(buf, s->s_volume_name, sizeof(s->s_volume_name));
	printf(_("Filesystem label=%s\n"), buf);
	fputs(_("OS type: "), stdout);
        os = e2p_os2string(fs->super->s_creator_os);
	fputs(os, stdout);
	free(os);
	printf("\n");
	printf(_("Block size=%u (log=%u)\n"), fs->blocksize,
		s->s_log_block_size);
	printf(_("Fragment size=%u (log=%u)\n"), fs->fragsize,
		s->s_log_frag_size);
	printf(_("%u inodes, %u blocks\n"), s->s_inodes_count,
	       s->s_blocks_count);
#ifdef EMBED
	printf(_("%u blocks (%d%%) reserved for the super user\n"),
		s->s_r_blocks_count,
	       100 * s->s_r_blocks_count / s->s_blocks_count);
#else
	printf(_("%u blocks (%2.2f%%) reserved for the super user\n"),
		s->s_r_blocks_count,
	       100.0 * s->s_r_blocks_count / s->s_blocks_count);
#endif
	printf(_("First data block=%u\n"), s->s_first_data_block);
	if (s->s_reserved_gdt_blocks)
		printf(_("Maximum filesystem blocks=%lu\n"),
		       (s->s_reserved_gdt_blocks + fs->desc_blocks) *
		       (fs->blocksize / sizeof(struct ext2_group_desc)) *
		       s->s_blocks_per_group);
	if (fs->group_desc_count > 1)
		printf(_("%u block groups\n"), fs->group_desc_count);
	else
		printf(_("%u block group\n"), fs->group_desc_count);
	printf(_("%u blocks per group, %u fragments per group\n"),
	       s->s_blocks_per_group, s->s_frags_per_group);
	printf(_("%u inodes per group\n"), s->s_inodes_per_group);

	if (fs->group_desc_count == 1) {
		printf("\n");
		return;
	}

	printf(_("Superblock backups stored on blocks: "));
	group_block = s->s_first_data_block;
	col_left = 0;
	for (i = 1; i < fs->group_desc_count; i++) {
		group_block += s->s_blocks_per_group;
		if (!ext2fs_bg_has_super(fs, i))
			continue;
		if (i != 1)
			printf(", ");
		need = int_log10(group_block) + 2;
		if (need > col_left) {
			printf("\n\t");
			col_left = 72;
		}
		col_left -= need;
		printf("%u", group_block);
	}
	printf("\n\n");
}
Пример #4
0
static void frag_report(const char *filename)
{
	struct statfs	fsinfo;
#ifdef HAVE_FSTAT64
	struct stat64	fileinfo;
#else
	struct stat	fileinfo;
#endif
	int		bs;
	long		fd;
	unsigned long	block, last_block = 0, numblocks, i, count;
	long		bpib;	/* Blocks per indirect block */
	long		cylgroups;
	int		num_extents = 0, expected;
	int		is_ext2 = 0;
	static int	once = 1;
	unsigned int	flags;
	int rc;

#ifdef HAVE_OPEN64
	fd = open64(filename, O_RDONLY);
#else
	fd = open(filename, O_RDONLY);
#endif
	if (fd < 0) {
		perror("open");
		return;
	}

	if (statfs(filename, &fsinfo) < 0) {
		perror("statfs");
		return;
	}
#ifdef HAVE_FSTAT64
	if (stat64(filename, &fileinfo) < 0) {
#else
	if (stat(filename, &fileinfo) < 0) {
#endif
		perror("stat");
		return;
	}
	if (ioctl(fd, EXT3_IOC_GETFLAGS, &flags) < 0)
		flags = 0;
	if (!(flags & EXT4_EXTENTS_FL) &&
	    ((fsinfo.f_type == 0xef51) || (fsinfo.f_type == 0xef52) ||
	     (fsinfo.f_type == 0xef53)))
		is_ext2++;
	if (verbose && once)
		printf("Filesystem type is: %lx\n",
		       (unsigned long) fsinfo.f_type);

	cylgroups = div_ceil(fsinfo.f_blocks, fsinfo.f_bsize*8);
	if (verbose && is_ext2 && once)
		printf("Filesystem cylinder groups is approximately %ld\n",
		       cylgroups);

	physical_width = int_log10(fsinfo.f_blocks);
	if (physical_width < 8)
		physical_width = 8;

	if (ioctl(fd, FIGETBSZ, &bs) < 0) { /* FIGETBSZ takes an int */
		perror("FIGETBSZ");
		close(fd);
		return;
	}

	if (no_bs)
		bs = 1024;

	bpib = bs / 4;
	numblocks = (fileinfo.st_size + (bs-1)) / bs;
	logical_width = int_log10(numblocks);
	if (logical_width < 7)
		logical_width = 7;
	filesize = (long long)fileinfo.st_size;
	if (verbose)
		printf("File size of %s is %lld (%ld block%s, blocksize %d)\n",
		       filename, (long long) fileinfo.st_size, numblocks,
		       numblocks == 1 ? "" : "s", bs);
	if (force_bmap ||
	    filefrag_fiemap(fd, int_log2(bs), &num_extents) != 0) {
		for (i = 0, count = 0; i < numblocks; i++) {
			if (is_ext2 && last_block) {
				if (((i-EXT2_DIRECT) % bpib) == 0)
					last_block++;
				if (((i-EXT2_DIRECT-bpib) % (bpib*bpib)) == 0)
					last_block++;
				if (((i-EXT2_DIRECT-bpib-bpib*bpib) %
							(bpib*bpib*bpib)) == 0)
					last_block++;
			}
			rc = get_bmap(fd, i, &block);
			if (block == 0)
				continue;
			if (!num_extents)
				num_extents++;
			count++;
			if (last_block && (block != last_block+1) ) {
				if (verbose)
					printf("Discontinuity: Block %ld is at "
					       "%lu (was %lu)\n",
					       i, block, last_block+1);
				num_extents++;
			}
			last_block = block;
		}
	}
	if (num_extents == 1)
		printf("%s: 1 extent found", filename);
	else
		printf("%s: %d extents found", filename, num_extents);
	expected = (count/((bs*8)-(fsinfo.f_files/8/cylgroups)-3))+1;
	if (is_ext2 && expected < num_extents)
		printf(", perfection would be %d extent%s\n", expected,
			(expected>1) ? "s" : "");
	else
		fputc('\n', stdout);
	close(fd);
	once = 0;
}

static void usage(const char *progname)
{
	fprintf(stderr, "Usage: %s [-Bbvsx] file ...\n", progname);
	exit(1);
}
Пример #5
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;
}