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); }
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); } }
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"); }
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); }
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; }