Theodore Ts'o | 0b2681f | 2009-07-22 03:40:58 -0400 | [diff] [blame] | 1 | /* |
| 2 | * e2freefrag - report filesystem free-space fragmentation |
| 3 | * |
| 4 | * Copyright (C) 2009 Sun Microsystems, Inc. |
| 5 | * |
| 6 | * Author: Rupesh Thakare <rupesh@sun.com> |
| 7 | * Andreas Dilger <adilger@sun.com> |
| 8 | * |
| 9 | * %Begin-Header% |
| 10 | * This file may be redistributed under the terms of the GNU Public |
| 11 | * License version 2. |
| 12 | * %End-Header% |
| 13 | */ |
| 14 | #include <stdio.h> |
| 15 | #ifdef HAVE_UNISTD_H |
| 16 | #include <unistd.h> |
| 17 | #endif |
| 18 | #ifdef HAVE_STDLIB_H |
| 19 | #include <stdlib.h> |
| 20 | #endif |
| 21 | #ifdef HAVE_GETOPT_H |
| 22 | #include <getopt.h> |
| 23 | #else |
| 24 | extern char *optarg; |
| 25 | extern int optind; |
| 26 | #endif |
| 27 | |
| 28 | #include "ext2fs/ext2_fs.h" |
| 29 | #include "ext2fs/ext2fs.h" |
| 30 | #include "e2freefrag.h" |
| 31 | |
JP Abgrall | e0ed740 | 2014-03-19 19:08:39 -0700 | [diff] [blame] | 32 | static void usage(const char *prog) |
Theodore Ts'o | 0b2681f | 2009-07-22 03:40:58 -0400 | [diff] [blame] | 33 | { |
| 34 | fprintf(stderr, "usage: %s [-c chunksize in kb] [-h] " |
| 35 | "device_name\n", prog); |
JP Abgrall | e0ed740 | 2014-03-19 19:08:39 -0700 | [diff] [blame] | 36 | #ifndef DEBUGFS |
Theodore Ts'o | 0b2681f | 2009-07-22 03:40:58 -0400 | [diff] [blame] | 37 | exit(1); |
JP Abgrall | e0ed740 | 2014-03-19 19:08:39 -0700 | [diff] [blame] | 38 | #endif |
Theodore Ts'o | 0b2681f | 2009-07-22 03:40:58 -0400 | [diff] [blame] | 39 | } |
| 40 | |
| 41 | static int ul_log2(unsigned long arg) |
| 42 | { |
| 43 | int l = 0; |
| 44 | |
| 45 | arg >>= 1; |
| 46 | while (arg) { |
| 47 | l++; |
| 48 | arg >>= 1; |
| 49 | } |
| 50 | return l; |
| 51 | } |
| 52 | |
JP Abgrall | e0ed740 | 2014-03-19 19:08:39 -0700 | [diff] [blame] | 53 | static void init_chunk_info(ext2_filsys fs, struct chunk_info *info) |
Theodore Ts'o | 0b2681f | 2009-07-22 03:40:58 -0400 | [diff] [blame] | 54 | { |
| 55 | int i; |
| 56 | |
Theodore Ts'o | 0b2681f | 2009-07-22 03:40:58 -0400 | [diff] [blame] | 57 | info->blocksize_bits = ul_log2((unsigned long)fs->blocksize); |
Theodore Ts'o | cba91c4 | 2009-08-09 19:40:14 -0400 | [diff] [blame] | 58 | if (info->chunkbytes) { |
| 59 | info->chunkbits = ul_log2(info->chunkbytes); |
| 60 | info->blks_in_chunk = info->chunkbytes >> info->blocksize_bits; |
| 61 | } else { |
| 62 | info->chunkbits = ul_log2(DEFAULT_CHUNKSIZE); |
| 63 | info->blks_in_chunk = DEFAULT_CHUNKSIZE >> info->blocksize_bits; |
| 64 | } |
Theodore Ts'o | 0b2681f | 2009-07-22 03:40:58 -0400 | [diff] [blame] | 65 | |
| 66 | info->min = ~0UL; |
| 67 | info->max = info->avg = 0; |
| 68 | info->real_free_chunks = 0; |
| 69 | |
Andreas Dilger | ad751f1 | 2009-07-24 18:32:25 -0400 | [diff] [blame] | 70 | for (i = 0; i < MAX_HIST; i++) { |
| 71 | info->histogram.fc_chunks[i] = 0; |
| 72 | info->histogram.fc_blocks[i] = 0; |
| 73 | } |
Theodore Ts'o | 0b2681f | 2009-07-22 03:40:58 -0400 | [diff] [blame] | 74 | } |
| 75 | |
JP Abgrall | e0ed740 | 2014-03-19 19:08:39 -0700 | [diff] [blame] | 76 | static void update_chunk_stats(struct chunk_info *info, |
| 77 | unsigned long chunk_size) |
Theodore Ts'o | 1e48a45 | 2009-08-09 20:15:46 -0400 | [diff] [blame] | 78 | { |
JP Abgrall | e0ed740 | 2014-03-19 19:08:39 -0700 | [diff] [blame] | 79 | unsigned long idx; |
Theodore Ts'o | 1e48a45 | 2009-08-09 20:15:46 -0400 | [diff] [blame] | 80 | |
JP Abgrall | e0ed740 | 2014-03-19 19:08:39 -0700 | [diff] [blame] | 81 | idx = ul_log2(chunk_size) + 1; |
| 82 | if (idx >= MAX_HIST) |
| 83 | idx = MAX_HIST-1; |
| 84 | info->histogram.fc_chunks[idx]++; |
| 85 | info->histogram.fc_blocks[idx] += chunk_size; |
Theodore Ts'o | 1e48a45 | 2009-08-09 20:15:46 -0400 | [diff] [blame] | 86 | |
| 87 | if (chunk_size > info->max) |
| 88 | info->max = chunk_size; |
| 89 | if (chunk_size < info->min) |
| 90 | info->min = chunk_size; |
| 91 | info->avg += chunk_size; |
| 92 | info->real_free_chunks++; |
| 93 | } |
| 94 | |
JP Abgrall | e0ed740 | 2014-03-19 19:08:39 -0700 | [diff] [blame] | 95 | static void scan_block_bitmap(ext2_filsys fs, struct chunk_info *info) |
Theodore Ts'o | 0b2681f | 2009-07-22 03:40:58 -0400 | [diff] [blame] | 96 | { |
JP Abgrall | e0ed740 | 2014-03-19 19:08:39 -0700 | [diff] [blame] | 97 | unsigned long long blocks_count = ext2fs_blocks_count(fs->super); |
Theodore Ts'o | 0b2681f | 2009-07-22 03:40:58 -0400 | [diff] [blame] | 98 | unsigned long long chunks = (blocks_count + info->blks_in_chunk) >> |
| 99 | (info->chunkbits - info->blocksize_bits); |
| 100 | unsigned long long chunk_num; |
| 101 | unsigned long last_chunk_size = 0; |
| 102 | unsigned long long chunk_start_blk = 0; |
Theodore Ts'o | 3e343b8 | 2009-08-09 20:09:10 -0400 | [diff] [blame] | 103 | int used; |
Theodore Ts'o | 0b2681f | 2009-07-22 03:40:58 -0400 | [diff] [blame] | 104 | |
| 105 | for (chunk_num = 0; chunk_num < chunks; chunk_num++) { |
| 106 | unsigned long long blk, num_blks; |
| 107 | int chunk_free; |
| 108 | |
| 109 | /* Last chunk may be smaller */ |
| 110 | if (chunk_start_blk + info->blks_in_chunk > blocks_count) |
| 111 | num_blks = blocks_count - chunk_start_blk; |
| 112 | else |
| 113 | num_blks = info->blks_in_chunk; |
| 114 | |
| 115 | chunk_free = 0; |
| 116 | |
| 117 | /* Initialize starting block for first chunk correctly else |
| 118 | * there is a segfault when blocksize = 1024 in which case |
| 119 | * block_map->start = 1 */ |
Theodore Ts'o | 3e343b8 | 2009-08-09 20:09:10 -0400 | [diff] [blame] | 120 | for (blk = 0; blk < num_blks; blk++, chunk_start_blk++) { |
| 121 | if (chunk_num == 0 && blk == 0) { |
| 122 | blk = fs->super->s_first_data_block; |
| 123 | chunk_start_blk = blk; |
| 124 | } |
JP Abgrall | e0ed740 | 2014-03-19 19:08:39 -0700 | [diff] [blame] | 125 | used = ext2fs_fast_test_block_bitmap2(fs->block_map, |
| 126 | chunk_start_blk >> fs->cluster_ratio_bits); |
Theodore Ts'o | 0b2681f | 2009-07-22 03:40:58 -0400 | [diff] [blame] | 127 | if (!used) { |
| 128 | last_chunk_size++; |
| 129 | chunk_free++; |
| 130 | } |
| 131 | |
| 132 | if (used && last_chunk_size != 0) { |
Theodore Ts'o | 1e48a45 | 2009-08-09 20:15:46 -0400 | [diff] [blame] | 133 | update_chunk_stats(info, last_chunk_size); |
Theodore Ts'o | 0b2681f | 2009-07-22 03:40:58 -0400 | [diff] [blame] | 134 | last_chunk_size = 0; |
| 135 | } |
| 136 | } |
| 137 | |
| 138 | if (chunk_free == info->blks_in_chunk) |
| 139 | info->free_chunks++; |
| 140 | } |
Theodore Ts'o | 1e48a45 | 2009-08-09 20:15:46 -0400 | [diff] [blame] | 141 | if (last_chunk_size != 0) |
| 142 | update_chunk_stats(info, last_chunk_size); |
Theodore Ts'o | 0b2681f | 2009-07-22 03:40:58 -0400 | [diff] [blame] | 143 | } |
| 144 | |
JP Abgrall | e0ed740 | 2014-03-19 19:08:39 -0700 | [diff] [blame] | 145 | static errcode_t get_chunk_info(ext2_filsys fs, struct chunk_info *info, |
| 146 | FILE *f) |
Theodore Ts'o | 0b2681f | 2009-07-22 03:40:58 -0400 | [diff] [blame] | 147 | { |
| 148 | unsigned long total_chunks; |
JP Abgrall | e0ed740 | 2014-03-19 19:08:39 -0700 | [diff] [blame] | 149 | const char *unitp = "KMGTPEZY"; |
Theodore Ts'o | 0b2681f | 2009-07-22 03:40:58 -0400 | [diff] [blame] | 150 | int units = 10; |
JP Abgrall | e0ed740 | 2014-03-19 19:08:39 -0700 | [diff] [blame] | 151 | unsigned long start = 0, end; |
Theodore Ts'o | 0b2681f | 2009-07-22 03:40:58 -0400 | [diff] [blame] | 152 | int i, retval = 0; |
| 153 | |
| 154 | scan_block_bitmap(fs, info); |
| 155 | |
JP Abgrall | e0ed740 | 2014-03-19 19:08:39 -0700 | [diff] [blame] | 156 | fprintf(f, "Total blocks: %llu\nFree blocks: %u (%0.1f%%)\n", |
| 157 | ext2fs_blocks_count(fs->super), fs->super->s_free_blocks_count, |
| 158 | (double)fs->super->s_free_blocks_count * 100 / |
| 159 | ext2fs_blocks_count(fs->super)); |
Theodore Ts'o | 0b2681f | 2009-07-22 03:40:58 -0400 | [diff] [blame] | 160 | |
Theodore Ts'o | cba91c4 | 2009-08-09 19:40:14 -0400 | [diff] [blame] | 161 | if (info->chunkbytes) { |
JP Abgrall | e0ed740 | 2014-03-19 19:08:39 -0700 | [diff] [blame] | 162 | fprintf(f, "\nChunksize: %lu bytes (%u blocks)\n", |
| 163 | info->chunkbytes, info->blks_in_chunk); |
| 164 | total_chunks = (ext2fs_blocks_count(fs->super) + |
Theodore Ts'o | cba91c4 | 2009-08-09 19:40:14 -0400 | [diff] [blame] | 165 | info->blks_in_chunk) >> |
| 166 | (info->chunkbits - info->blocksize_bits); |
JP Abgrall | e0ed740 | 2014-03-19 19:08:39 -0700 | [diff] [blame] | 167 | fprintf(f, "Total chunks: %lu\nFree chunks: %lu (%0.1f%%)\n", |
| 168 | total_chunks, info->free_chunks, |
| 169 | (double)info->free_chunks * 100 / total_chunks); |
Theodore Ts'o | cba91c4 | 2009-08-09 19:40:14 -0400 | [diff] [blame] | 170 | } |
Theodore Ts'o | 0b2681f | 2009-07-22 03:40:58 -0400 | [diff] [blame] | 171 | |
| 172 | /* Display chunk information in KB */ |
| 173 | if (info->real_free_chunks) { |
JP Abgrall | e0ed740 | 2014-03-19 19:08:39 -0700 | [diff] [blame] | 174 | unsigned int scale = fs->blocksize >> 10; |
| 175 | info->min = info->min * scale; |
| 176 | info->max = info->max * scale; |
| 177 | info->avg = info->avg / info->real_free_chunks * scale; |
Theodore Ts'o | 0b2681f | 2009-07-22 03:40:58 -0400 | [diff] [blame] | 178 | } else { |
| 179 | info->min = 0; |
| 180 | } |
| 181 | |
JP Abgrall | e0ed740 | 2014-03-19 19:08:39 -0700 | [diff] [blame] | 182 | fprintf(f, "\nMin. free extent: %lu KB \nMax. free extent: %lu KB\n" |
| 183 | "Avg. free extent: %lu KB\n", info->min, info->max, info->avg); |
| 184 | fprintf(f, "Num. free extent: %lu\n", info->real_free_chunks); |
Theodore Ts'o | 0b2681f | 2009-07-22 03:40:58 -0400 | [diff] [blame] | 185 | |
JP Abgrall | e0ed740 | 2014-03-19 19:08:39 -0700 | [diff] [blame] | 186 | fprintf(f, "\nHISTOGRAM OF FREE EXTENT SIZES:\n"); |
| 187 | fprintf(f, "%s : %12s %12s %7s\n", "Extent Size Range", |
| 188 | "Free extents", "Free Blocks", "Percent"); |
Theodore Ts'o | 0b2681f | 2009-07-22 03:40:58 -0400 | [diff] [blame] | 189 | for (i = 0; i < MAX_HIST; i++) { |
| 190 | end = 1 << (i + info->blocksize_bits - units); |
Theodore Ts'o | 1e48a45 | 2009-08-09 20:15:46 -0400 | [diff] [blame] | 191 | if (info->histogram.fc_chunks[i] != 0) { |
| 192 | char end_str[32]; |
| 193 | |
| 194 | sprintf(end_str, "%5lu%c-", end, *unitp); |
| 195 | if (i == MAX_HIST-1) |
| 196 | strcpy(end_str, "max "); |
JP Abgrall | e0ed740 | 2014-03-19 19:08:39 -0700 | [diff] [blame] | 197 | fprintf(f, "%5lu%c...%7s : %12lu %12lu %6.2f%%\n", |
| 198 | start, *unitp, end_str, |
| 199 | info->histogram.fc_chunks[i], |
| 200 | info->histogram.fc_blocks[i], |
| 201 | (double)info->histogram.fc_blocks[i] * 100 / |
| 202 | fs->super->s_free_blocks_count); |
Theodore Ts'o | 1e48a45 | 2009-08-09 20:15:46 -0400 | [diff] [blame] | 203 | } |
Theodore Ts'o | 0b2681f | 2009-07-22 03:40:58 -0400 | [diff] [blame] | 204 | start = end; |
| 205 | if (start == 1<<10) { |
| 206 | start = 1; |
| 207 | units += 10; |
| 208 | unitp++; |
| 209 | } |
| 210 | } |
| 211 | |
| 212 | return retval; |
| 213 | } |
| 214 | |
JP Abgrall | e0ed740 | 2014-03-19 19:08:39 -0700 | [diff] [blame] | 215 | static void close_device(char *device_name, ext2_filsys fs) |
Theodore Ts'o | 0b2681f | 2009-07-22 03:40:58 -0400 | [diff] [blame] | 216 | { |
| 217 | int retval = ext2fs_close(fs); |
| 218 | |
| 219 | if (retval) |
| 220 | com_err(device_name, retval, "while closing the filesystem.\n"); |
| 221 | } |
| 222 | |
JP Abgrall | e0ed740 | 2014-03-19 19:08:39 -0700 | [diff] [blame] | 223 | static void collect_info(ext2_filsys fs, struct chunk_info *chunk_info, FILE *f) |
Theodore Ts'o | 0b2681f | 2009-07-22 03:40:58 -0400 | [diff] [blame] | 224 | { |
JP Abgrall | e0ed740 | 2014-03-19 19:08:39 -0700 | [diff] [blame] | 225 | unsigned int retval = 0; |
Theodore Ts'o | 0b2681f | 2009-07-22 03:40:58 -0400 | [diff] [blame] | 226 | |
JP Abgrall | e0ed740 | 2014-03-19 19:08:39 -0700 | [diff] [blame] | 227 | fprintf(f, "Device: %s\n", fs->device_name); |
| 228 | fprintf(f, "Blocksize: %u bytes\n", fs->blocksize); |
Theodore Ts'o | 0b2681f | 2009-07-22 03:40:58 -0400 | [diff] [blame] | 229 | |
| 230 | retval = ext2fs_read_block_bitmap(fs); |
| 231 | if (retval) { |
| 232 | com_err(fs->device_name, retval, "while reading block bitmap"); |
| 233 | close_device(fs->device_name, fs); |
| 234 | exit(1); |
| 235 | } |
| 236 | |
| 237 | init_chunk_info(fs, chunk_info); |
| 238 | |
JP Abgrall | e0ed740 | 2014-03-19 19:08:39 -0700 | [diff] [blame] | 239 | retval = get_chunk_info(fs, chunk_info, f); |
Theodore Ts'o | 0b2681f | 2009-07-22 03:40:58 -0400 | [diff] [blame] | 240 | if (retval) { |
| 241 | com_err(fs->device_name, retval, "while collecting chunk info"); |
| 242 | close_device(fs->device_name, fs); |
| 243 | exit(1); |
| 244 | } |
| 245 | } |
| 246 | |
JP Abgrall | e0ed740 | 2014-03-19 19:08:39 -0700 | [diff] [blame] | 247 | #ifndef DEBUGFS |
| 248 | static void open_device(char *device_name, ext2_filsys *fs) |
Theodore Ts'o | 0b2681f | 2009-07-22 03:40:58 -0400 | [diff] [blame] | 249 | { |
| 250 | int retval; |
JP Abgrall | e0ed740 | 2014-03-19 19:08:39 -0700 | [diff] [blame] | 251 | int flag = EXT2_FLAG_FORCE | EXT2_FLAG_64BITS; |
Theodore Ts'o | 0b2681f | 2009-07-22 03:40:58 -0400 | [diff] [blame] | 252 | |
| 253 | retval = ext2fs_open(device_name, flag, 0, 0, unix_io_manager, fs); |
| 254 | if (retval) { |
| 255 | com_err(device_name, retval, "while opening filesystem"); |
| 256 | exit(1); |
| 257 | } |
JP Abgrall | e0ed740 | 2014-03-19 19:08:39 -0700 | [diff] [blame] | 258 | (*fs)->default_bitmap_type = EXT2FS_BMAP64_RBTREE; |
Theodore Ts'o | 0b2681f | 2009-07-22 03:40:58 -0400 | [diff] [blame] | 259 | } |
JP Abgrall | e0ed740 | 2014-03-19 19:08:39 -0700 | [diff] [blame] | 260 | #endif |
Theodore Ts'o | 0b2681f | 2009-07-22 03:40:58 -0400 | [diff] [blame] | 261 | |
JP Abgrall | e0ed740 | 2014-03-19 19:08:39 -0700 | [diff] [blame] | 262 | #ifdef DEBUGFS |
| 263 | #include "debugfs.h" |
| 264 | |
| 265 | void do_freefrag(int argc, char **argv) |
| 266 | #else |
Theodore Ts'o | 0b2681f | 2009-07-22 03:40:58 -0400 | [diff] [blame] | 267 | int main(int argc, char *argv[]) |
JP Abgrall | e0ed740 | 2014-03-19 19:08:39 -0700 | [diff] [blame] | 268 | #endif |
Theodore Ts'o | 0b2681f | 2009-07-22 03:40:58 -0400 | [diff] [blame] | 269 | { |
JP Abgrall | e0ed740 | 2014-03-19 19:08:39 -0700 | [diff] [blame] | 270 | struct chunk_info chunk_info; |
Theodore Ts'o | 0b2681f | 2009-07-22 03:40:58 -0400 | [diff] [blame] | 271 | ext2_filsys fs = NULL; |
Theodore Ts'o | 0b2681f | 2009-07-22 03:40:58 -0400 | [diff] [blame] | 272 | char *progname; |
Mike Frysinger | b887f08 | 2010-01-04 23:15:32 -0500 | [diff] [blame] | 273 | char *end; |
| 274 | int c; |
Theodore Ts'o | 0b2681f | 2009-07-22 03:40:58 -0400 | [diff] [blame] | 275 | |
JP Abgrall | e0ed740 | 2014-03-19 19:08:39 -0700 | [diff] [blame] | 276 | #ifdef DEBUGFS |
| 277 | if (check_fs_open(argv[0])) |
| 278 | return; |
| 279 | #else |
| 280 | char *device_name; |
| 281 | |
Theodore Ts'o | 137a7dc | 2009-08-09 19:15:45 -0400 | [diff] [blame] | 282 | add_error_table(&et_ext2_error_table); |
JP Abgrall | e0ed740 | 2014-03-19 19:08:39 -0700 | [diff] [blame] | 283 | #endif |
Theodore Ts'o | 0b2681f | 2009-07-22 03:40:58 -0400 | [diff] [blame] | 284 | progname = argv[0]; |
JP Abgrall | e0ed740 | 2014-03-19 19:08:39 -0700 | [diff] [blame] | 285 | memset(&chunk_info, 0, sizeof(chunk_info)); |
Theodore Ts'o | 0b2681f | 2009-07-22 03:40:58 -0400 | [diff] [blame] | 286 | |
| 287 | while ((c = getopt(argc, argv, "c:h")) != EOF) { |
| 288 | switch (c) { |
| 289 | case 'c': |
| 290 | chunk_info.chunkbytes = strtoull(optarg, &end, 0); |
| 291 | if (*end != '\0') { |
| 292 | fprintf(stderr, "%s: bad chunk size '%s'\n", |
| 293 | progname, optarg); |
| 294 | usage(progname); |
| 295 | } |
| 296 | if (chunk_info.chunkbytes & |
| 297 | (chunk_info.chunkbytes - 1)) { |
| 298 | fprintf(stderr, "%s: chunk size must be a " |
Theodore Ts'o | aff2cf8 | 2009-08-09 19:29:30 -0400 | [diff] [blame] | 299 | "power of 2.\n", argv[0]); |
Theodore Ts'o | 0b2681f | 2009-07-22 03:40:58 -0400 | [diff] [blame] | 300 | usage(progname); |
| 301 | } |
| 302 | chunk_info.chunkbytes *= 1024; |
| 303 | break; |
JP Abgrall | 65f0aab | 2014-03-06 13:50:20 -0800 | [diff] [blame] | 304 | case 'h': |
JP Abgrall | e0ed740 | 2014-03-19 19:08:39 -0700 | [diff] [blame] | 305 | default: |
Theodore Ts'o | 0b2681f | 2009-07-22 03:40:58 -0400 | [diff] [blame] | 306 | usage(progname); |
| 307 | break; |
| 308 | } |
| 309 | } |
| 310 | |
JP Abgrall | e0ed740 | 2014-03-19 19:08:39 -0700 | [diff] [blame] | 311 | #ifndef DEBUGFS |
Theodore Ts'o | 0b2681f | 2009-07-22 03:40:58 -0400 | [diff] [blame] | 312 | if (optind == argc) { |
| 313 | fprintf(stderr, "%s: missing device name.\n", progname); |
| 314 | usage(progname); |
| 315 | } |
| 316 | |
| 317 | device_name = argv[optind]; |
| 318 | |
| 319 | open_device(device_name, &fs); |
JP Abgrall | e0ed740 | 2014-03-19 19:08:39 -0700 | [diff] [blame] | 320 | #else |
| 321 | fs = current_fs; |
| 322 | #endif |
Theodore Ts'o | 0b2681f | 2009-07-22 03:40:58 -0400 | [diff] [blame] | 323 | |
Theodore Ts'o | cba91c4 | 2009-08-09 19:40:14 -0400 | [diff] [blame] | 324 | if (chunk_info.chunkbytes && (chunk_info.chunkbytes < fs->blocksize)) { |
Theodore Ts'o | 0b2681f | 2009-07-22 03:40:58 -0400 | [diff] [blame] | 325 | fprintf(stderr, "%s: chunksize must be greater than or equal " |
| 326 | "to filesystem blocksize.\n", progname); |
| 327 | exit(1); |
| 328 | } |
JP Abgrall | e0ed740 | 2014-03-19 19:08:39 -0700 | [diff] [blame] | 329 | collect_info(fs, &chunk_info, stdout); |
| 330 | #ifndef DEBUGFS |
Theodore Ts'o | 0b2681f | 2009-07-22 03:40:58 -0400 | [diff] [blame] | 331 | close_device(device_name, fs); |
| 332 | |
JP Abgrall | e0ed740 | 2014-03-19 19:08:39 -0700 | [diff] [blame] | 333 | return 0; |
| 334 | #endif |
Theodore Ts'o | 0b2681f | 2009-07-22 03:40:58 -0400 | [diff] [blame] | 335 | } |