filefrag.c revision 2508eaa71e8bbe93155052ded448e5e78d213715
15faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org/* 25faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org * filefrag.c -- report if a particular file is fragmented 35faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org * 45faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org * Copyright 2003 by Theodore Ts'o. 55faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org * 65faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org * %Begin-Header% 75faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org * This file may be redistributed under the terms of the GNU Public 85faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org * License. 95faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org * %End-Header% 105faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org */ 118b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org 128b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "config.h" 135faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org#ifndef __linux__ 148640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org#include <stdio.h> 155faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org#include <stdlib.h> 163bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org#include <unistd.h> 17d698f77c13d97c61109b861eac4d25b14a5de935bsalomon@google.com 18dbe49f735484f8862e378b63d0a074a301093dd0bsalomon@google.comint main(void) { 192eaaefd7e6a58339b3f93333f1e9cc92252cc303bsalomon@google.com fputs("This program is only supported on Linux!\n", stderr); 2017fc651dbe2e0624f6c85fb6e081d28a87d5a08bbsalomon@google.com exit(EXIT_FAILURE); 2117fc651dbe2e0624f6c85fb6e081d28a87d5a08bbsalomon@google.com} 223bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org#else 233bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org#define _LARGEFILE64_SOURCE 24c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org 25c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org#include <stdio.h> 26c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org#include <stdlib.h> 27c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org#include <unistd.h> 28c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org#include <string.h> 29c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org#include <time.h> 30c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org#include <fcntl.h> 31c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org#include <errno.h> 32c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org#ifdef HAVE_GETOPT_H 33c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org#include <getopt.h> 34c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org#else 35c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.orgextern char *optarg; 367938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.orgextern int optind; 377938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org#endif 387938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org#include <sys/types.h> 397938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org#include <sys/stat.h> 407938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org#include <sys/vfs.h> 41cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org#include <sys/ioctl.h> 427938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org#include <linux/fd.h> 437938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org#include <ext2fs/ext2fs.h> 447938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org#include <ext2fs/ext2_types.h> 457938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org#include <ext2fs/fiemap.h> 467938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org 475faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.orgint verbose = 0; 485faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.orgint blocksize; /* Use specified blocksize (default 1kB) */ 495faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.orgint sync_file = 0; /* fsync file before getting the mapping */ 50cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.orgint xattr_map = 0; /* get xattr mapping */ 518640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.orgint force_bmap; /* force use of FIBMAP instead of FIEMAP */ 528640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.orgint force_extent; /* print output in extent format always */ 535faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.orgint logical_width = 8; 545faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.orgint physical_width = 10; 555faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.orgchar *ext_fmt = "%4d: %*llu..%*llu: %*llu..%*llu: %6llu: %s\n"; 563bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.orgchar *hex_fmt = "%4d: %*llx..%*llx: %*llx..%*llx: %6llx: %s\n"; 57cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org 58cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org#define FILEFRAG_FIEMAP_FLAGS_COMPAT (FIEMAP_FLAG_SYNC | FIEMAP_FLAG_XATTR) 595faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org 605faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org#define FIBMAP _IO(0x00, 1) /* bmap access */ 618b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#define FIGETBSZ _IO(0x00, 2) /* get the block size used for bmap */ 62ce33d60187718e7bb01944ee130c9f5d9fb335eccommit-bot@chromium.org 63025128811219dc45fd99b6c4d1d14f833cf7a26ecommit-bot@chromium.org#define LUSTRE_SUPER_MAGIC 0x0BD00BD0 64025128811219dc45fd99b6c4d1d14f833cf7a26ecommit-bot@chromium.org 65025128811219dc45fd99b6c4d1d14f833cf7a26ecommit-bot@chromium.org#define EXT4_EXTENTS_FL 0x00080000 /* Inode uses extents */ 665faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org#define EXT3_IOC_GETFLAGS _IOR('f', 1, long) 675faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org 68d594dbec0407343b7ac13af9c4580ec5933ab060commit-bot@chromium.orgstatic int int_log2(int arg) 69d594dbec0407343b7ac13af9c4580ec5933ab060commit-bot@chromium.org{ 70d594dbec0407343b7ac13af9c4580ec5933ab060commit-bot@chromium.org int l = 0; 71d594dbec0407343b7ac13af9c4580ec5933ab060commit-bot@chromium.org 72025128811219dc45fd99b6c4d1d14f833cf7a26ecommit-bot@chromium.org arg >>= 1; 73025128811219dc45fd99b6c4d1d14f833cf7a26ecommit-bot@chromium.org while (arg) { 74d594dbec0407343b7ac13af9c4580ec5933ab060commit-bot@chromium.org l++; 75025128811219dc45fd99b6c4d1d14f833cf7a26ecommit-bot@chromium.org arg >>= 1; 76025128811219dc45fd99b6c4d1d14f833cf7a26ecommit-bot@chromium.org } 77d594dbec0407343b7ac13af9c4580ec5933ab060commit-bot@chromium.org return l; 78d594dbec0407343b7ac13af9c4580ec5933ab060commit-bot@chromium.org} 79d594dbec0407343b7ac13af9c4580ec5933ab060commit-bot@chromium.org 805faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.orgstatic int int_log10(unsigned long long arg) 815faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org{ 82cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org int l = 0; 83cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org 845faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org arg = arg / 10; 858640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org while (arg) { 86d594dbec0407343b7ac13af9c4580ec5933ab060commit-bot@chromium.org l++; 87d594dbec0407343b7ac13af9c4580ec5933ab060commit-bot@chromium.org arg = arg / 10; 88c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org } 89c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org return l; 905faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org} 915faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org 928b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgstatic unsigned int div_ceil(unsigned int a, unsigned int b) 935faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org{ 945faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org if (!a) 955faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org return 0; 965faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org return ((a - 1) / b) + 1; 975faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org} 985faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org 99cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.orgstatic int get_bmap(int fd, unsigned long block, unsigned long *phy_blk) 100cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org{ 1015faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org int ret; 1028640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org unsigned int b; 1035faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org 1045faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org b = block; 1055faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org ret = ioctl(fd, FIBMAP, &b); /* FIBMAP takes pointer to integer */ 1065faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org if (ret < 0) { 1075faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org if (errno == EPERM) { 1085faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org fprintf(stderr, "No permission to use FIBMAP ioctl; " 1095faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org "must have root privileges\n"); 1105faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org } 1117938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org } 1125faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org *phy_blk = b; 1135faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org 1145faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org return ret; 1155faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org} 1165faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org 1175faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.orgstatic void print_extent_header(void) 1187938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org{ 1197938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org printf(" ext: %*s %*s length: %*s flags:\n", 1207938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org logical_width * 2 + 3, 1215faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org "logical_offset:", 1225faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org physical_width * 2 + 3, "physical_offset:", 1235faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org physical_width + 1, 1245faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org "expected:"); 1255faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org} 1265faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org 1277938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.orgstatic void print_extent_info(struct fiemap_extent *fm_extent, int cur_ex, 1287938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org unsigned long long expected, int blk_shift, 1297938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org ext2fs_struct_stat *st) 1307938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org{ 1317938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org unsigned long long physical_blk; 1325faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org unsigned long long logical_blk; 1337938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org unsigned long long ext_len; 1347938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org unsigned long long ext_blks; 1355faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org char flags[256] = ""; 1365faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org 1375faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org /* For inline data all offsets should be in bytes, not blocks */ 1385faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org if (fm_extent->fe_flags & FIEMAP_EXTENT_DATA_INLINE) 1395faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org blk_shift = 0; 1405faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org 1415faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org ext_len = fm_extent->fe_length >> blk_shift; 1427938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org ext_blks = (fm_extent->fe_length - 1) >> blk_shift; 1437938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org logical_blk = fm_extent->fe_logical >> blk_shift; 1445faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org physical_blk = fm_extent->fe_physical >> blk_shift; 1455faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org 1465faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org if (expected) 1475faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org sprintf(flags, ext_fmt == hex_fmt ? "%*llx: " : "%*llu: ", 1485faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org physical_width, expected >> blk_shift); 1495faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org else 1505faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org sprintf(flags, "%.*s ", physical_width, " "); 1518640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org 1527938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org if (fm_extent->fe_flags & FIEMAP_EXTENT_UNKNOWN) 1537938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org strcat(flags, "unknown,"); 1547938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org if (fm_extent->fe_flags & FIEMAP_EXTENT_DELALLOC) 155ae761f7545d8ebf181d220169afac2056b057b8ccommit-bot@chromium.org strcat(flags, "delalloc,"); 1565faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org if (fm_extent->fe_flags & FIEMAP_EXTENT_DATA_ENCRYPTED) 1577938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org strcat(flags, "encrypted,"); 1585faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org if (fm_extent->fe_flags & FIEMAP_EXTENT_NOT_ALIGNED) 1595faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org strcat(flags, "not_aligned,"); 1605faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org if (fm_extent->fe_flags & FIEMAP_EXTENT_DATA_INLINE) 1615faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org strcat(flags, "inline,"); 1627938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org if (fm_extent->fe_flags & FIEMAP_EXTENT_DATA_TAIL) 163cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org strcat(flags, "tail_packed,"); 164cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org if (fm_extent->fe_flags & FIEMAP_EXTENT_UNWRITTEN) 1657938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org strcat(flags, "unwritten,"); 1665faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org if (fm_extent->fe_flags & FIEMAP_EXTENT_MERGED) 1678640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org strcat(flags, "merged,"); 1688640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org 1698640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org if (fm_extent->fe_logical + fm_extent->fe_length >= st->st_size) 1705faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org strcat(flags, "eof,"); 1715faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org 1725faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org /* Remove trailing comma, if any */ 1735faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org if (flags[0]) 1745faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org flags[strlen(flags) - 1] = '\0'; 1758640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org 1768640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org printf(ext_fmt, cur_ex, logical_width, logical_blk, 1773bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org logical_width, logical_blk + ext_blks, 178cc9471c36d3967270f7eb26f8b53ce0f17bc9fbbsenorblanco@chromium.org physical_width, physical_blk, 179cc9471c36d3967270f7eb26f8b53ce0f17bc9fbbsenorblanco@chromium.org physical_width, physical_blk + ext_blks, 180cc9471c36d3967270f7eb26f8b53ce0f17bc9fbbsenorblanco@chromium.org ext_len, flags); 1818640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org} 1827938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org 1838640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.orgstatic int filefrag_fiemap(int fd, int blk_shift, int *num_extents, 1848640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org ext2fs_struct_stat *st) 1858640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org{ 1868640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org char buf[16384]; 1875faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org struct fiemap *fiemap = (struct fiemap *)buf; 1885faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org struct fiemap_extent *fm_ext = &fiemap->fm_extents[0]; 1895faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org int count = (sizeof(buf) - sizeof(*fiemap)) / 1905faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org sizeof(struct fiemap_extent); 1918640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org unsigned long long expected = 0; 1927938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org unsigned long flags = 0; 1937938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org unsigned int i; 1947938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org static int fiemap_incompat_printed; 195ae761f7545d8ebf181d220169afac2056b057b8ccommit-bot@chromium.org int fiemap_header_printed = 0; 1968640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org int tot_extents = 0, n = 0; 1977938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org int last = 0; 1988640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org int rc; 1997938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org 2008640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org memset(fiemap, 0, sizeof(struct fiemap)); 2018640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org 2028640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org if (sync_file) 2037938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org flags |= FIEMAP_FLAG_SYNC; 2047938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org 2057938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org if (xattr_map) 206ae761f7545d8ebf181d220169afac2056b057b8ccommit-bot@chromium.org flags |= FIEMAP_FLAG_XATTR; 2077938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org 2085faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org do { 2095faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org fiemap->fm_length = ~0ULL; 2107938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org fiemap->fm_flags = flags; 2117938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org fiemap->fm_extent_count = count; 2127938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org rc = ioctl(fd, FS_IOC_FIEMAP, (unsigned long) fiemap); 213ae761f7545d8ebf181d220169afac2056b057b8ccommit-bot@chromium.org if (rc < 0) { 2145faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org if (errno == EBADR && fiemap_incompat_printed == 0) { 2155faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org printf("FIEMAP failed with unsupported " 2167938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org "flags %x\n", fiemap->fm_flags); 2175faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org fiemap_incompat_printed = 1; 2185faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org } 2197938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org return rc; 2205faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org } 2215faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org 2227938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org /* If 0 extents are returned, then more ioctls are not needed */ 2235faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org if (fiemap->fm_mapped_extents == 0) 2245faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org break; 2255faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org 2265faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org if (verbose && !fiemap_header_printed) { 227377c14a1e648f4427bd11474fad8ac264d98aff2senorblanco@chromium.org print_extent_header(); 2288640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org fiemap_header_printed = 1; 2298640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org } 2308640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org 2318640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org for (i = 0; i < fiemap->fm_mapped_extents; i++) { 2328640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org if (fm_ext[i].fe_logical != 0 && 2338640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org fm_ext[i].fe_physical != expected) { 2348640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org tot_extents++; 2358640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org } else { 2368640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org expected = 0; 2378640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org if (!tot_extents) 2388640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org tot_extents = 1; 2398640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org } 2408640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org if (verbose) 2418640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org print_extent_info(&fm_ext[i], n, expected, 2428640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org blk_shift, st); 2438640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org 2448640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org expected = fm_ext[i].fe_physical + fm_ext[i].fe_length; 2458640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org if (fm_ext[i].fe_flags & FIEMAP_EXTENT_LAST) 2468640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org last = 1; 2478640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org n++; 2488640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org } 2498640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org 2508640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org fiemap->fm_start = (fm_ext[i - 1].fe_logical + 2518640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org fm_ext[i - 1].fe_length); 2525faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org } while (last == 0); 2535faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org 2545faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org *num_extents = tot_extents; 2555faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org 256ae761f7545d8ebf181d220169afac2056b057b8ccommit-bot@chromium.org return 0; 25768400767be5f72e4b9750ccc8bcf0078d42869a7senorblanco@chromium.org} 2586776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org 2596776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org#define EXT2_DIRECT 12 26068400767be5f72e4b9750ccc8bcf0078d42869a7senorblanco@chromium.org 26168400767be5f72e4b9750ccc8bcf0078d42869a7senorblanco@chromium.orgstatic int filefrag_fibmap(int fd, int blk_shift, int *num_extents, 26268400767be5f72e4b9750ccc8bcf0078d42869a7senorblanco@chromium.org ext2fs_struct_stat *st, 263e24ad23ae67ffcb0dc545b7e426cf08d102e0868commit-bot@chromium.org unsigned long numblocks, int is_ext2) 2645faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org{ 2655faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org struct fiemap_extent fm_ext; 2665faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org unsigned long i, last_block; 2677938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org unsigned long long logical; 2687938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org /* Blocks per indirect block */ 2696776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org const long bpib = st->st_blksize / 4; 2707938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org int count; 2717938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org 2727938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org if (force_extent) { 2737938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org memset(&fm_ext, 0, sizeof(fm_ext)); 2748640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org fm_ext.fe_flags = FIEMAP_EXTENT_MERGED; 2758640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org } 2768640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org 2778640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org if (sync_file) 2785faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org fsync(fd); 2795faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org 2805faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org for (i = 0, logical = 0, *num_extents = 0, count = last_block = 0; 2815faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org i < numblocks; 2825faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org i++, logical += st->st_blksize) { 2837938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org unsigned long block = 0; 2845faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org int rc; 285cd3b15ca6364a04b0eeeb4f89c7daa8aefe854c8commit-bot@chromium.org 286cd3b15ca6364a04b0eeeb4f89c7daa8aefe854c8commit-bot@chromium.org if (is_ext2 && last_block) { 287cd3b15ca6364a04b0eeeb4f89c7daa8aefe854c8commit-bot@chromium.org if (((i - EXT2_DIRECT) % bpib) == 0) 2885faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org last_block++; 2896776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org if (((i - EXT2_DIRECT - bpib) % (bpib * bpib)) == 0) 2906776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org last_block++; 2916776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org if (((i - EXT2_DIRECT - bpib - bpib * bpib) % 292cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org (((unsigned long long)bpib) * bpib * bpib)) == 0) 293cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org last_block++; 2947938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org } 2957938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org rc = get_bmap(fd, i, &block); 2967938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org if (rc < 0) 2977938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org return rc; 2987938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org if (block == 0) 2997938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org continue; 3007938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org if (*num_extents == 0) { 3015faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org (*num_extents)++; 3027938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org if (force_extent) { 3037938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org print_extent_header(); 3047938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org fm_ext.fe_physical = block * st->st_blksize; 3057938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org } 3067938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org } 3077938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org count++; 3085faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org if (force_extent && last_block != 0 && 3095faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org (block != last_block + 1 || 3103bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org fm_ext.fe_logical + fm_ext.fe_length != logical)) { 3113bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org print_extent_info(&fm_ext, *num_extents - 1, 3123bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org (last_block + 1) * st->st_blksize, 3133bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org blk_shift, st); 3143bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org fm_ext.fe_logical = logical; 3153bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org fm_ext.fe_physical = block * st->st_blksize; 3163bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org fm_ext.fe_length = 0; 3173bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org (*num_extents)++; 3183bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org } else if (verbose && last_block && (block != last_block + 1)) { 3193bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org printf("Discontinuity: Block %ld is at %lu (was %lu)\n", 3200ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com i, block, last_block + 1); 3217938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org (*num_extents)++; 3220ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com } 3230ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com fm_ext.fe_length += st->st_blksize; 3240ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com last_block = block; 3250ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com } 326cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org 3270ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com if (force_extent) 3280ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com print_extent_info(&fm_ext, *num_extents - 1, 3296340a41108633ac1ce5941e5cd30538630c4c55bbsalomon@google.com last_block * st->st_blksize, blk_shift, st); 3307938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org 3316340a41108633ac1ce5941e5cd30538630c4c55bbsalomon@google.com return count; 3326340a41108633ac1ce5941e5cd30538630c4c55bbsalomon@google.com} 3336340a41108633ac1ce5941e5cd30538630c4c55bbsalomon@google.com 3346340a41108633ac1ce5941e5cd30538630c4c55bbsalomon@google.comstatic void frag_report(const char *filename) 335cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org{ 3366340a41108633ac1ce5941e5cd30538630c4c55bbsalomon@google.com static struct statfs fsinfo; 3376340a41108633ac1ce5941e5cd30538630c4c55bbsalomon@google.com ext2fs_struct_stat st; 338a1ebbe447d5eab098111eb83580e55f2f5f6facabsalomon@google.com int blk_shift; 3390ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com int bs; 3403bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org long fd; 3413bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org unsigned long numblocks; 3420263fcd72ee81ccff012bff85dbee89cd524a930bsalomon@google.com int data_blocks_per_cyl = 1; 3430263fcd72ee81ccff012bff85dbee89cd524a930bsalomon@google.com int num_extents = 1, expected = ~0; 3440263fcd72ee81ccff012bff85dbee89cd524a930bsalomon@google.com int is_ext2 = 0; 3450263fcd72ee81ccff012bff85dbee89cd524a930bsalomon@google.com static dev_t last_device; 3460263fcd72ee81ccff012bff85dbee89cd524a930bsalomon@google.com unsigned int flags; 3470263fcd72ee81ccff012bff85dbee89cd524a930bsalomon@google.com int width; 3483bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org 3497938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org#if defined(HAVE_OPEN64) && !defined(__OSX_AVAILABLE_BUT_DEPRECATED) 3503bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org fd = open64(filename, O_RDONLY); 351cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org#else 3523bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org fd = open(filename, O_RDONLY); 3533bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org#endif 3543bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org if (fd < 0) { 3553bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org perror("open"); 3563bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org return; 3573bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org } 358422e81aeb1f4078367c85efe591c7df8c33874ecbsalomon@google.com 3593bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org#if defined(HAVE_FSTAT64) && !defined(__OSX_AVAILABLE_BUT_DEPRECATED) 360396e61fe440590744345e0c56970b26ab464591dbsalomon@google.com if (fstat64(fd, &st) < 0) { 3613bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org#else 3623bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org if (fstat(fd, &st) < 0) { 3630ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com#endif 3647938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org perror("stat"); 3650ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com return; 3660ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com } 3670ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com 3680ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com if (last_device != st.st_dev) { 369cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org if (fstatfs(fd, &fsinfo) < 0) { 3700ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com perror("fstatfs"); 3710ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com return; 3720ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com } 3738a252f79629b189a03de22cd8ff0312c5bccedd1bsalomon@google.com if (verbose) 37468b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com printf("Filesystem type is: %lx\n", 3757938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org (unsigned long) fsinfo.f_type); 3763bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org } 3773bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org st.st_blksize = fsinfo.f_bsize; 3783bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org if (ioctl(fd, EXT3_IOC_GETFLAGS, &flags) < 0) 3793bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org flags = 0; 380cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org if (!(flags & EXT4_EXTENTS_FL) && 3813bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org ((fsinfo.f_type == 0xef51) || (fsinfo.f_type == 0xef52) || 3823bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org (fsinfo.f_type == 0xef53))) 3833bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org is_ext2++; 384f271cc7183fe48ac64d2d9a454eb013c91b42d53bsalomon@google.com 3853bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org if (is_ext2) { 3863bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org long cylgroups = div_ceil(fsinfo.f_blocks, fsinfo.f_bsize * 8); 3873bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org 3883bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org if (verbose && last_device != st.st_dev) 38922a800a2578564a8b66bd4d9903ef4186c37f35cbsalomon@google.com printf("Filesystem cylinder groups approximately %ld\n", 3903bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org cylgroups); 391396e61fe440590744345e0c56970b26ab464591dbsalomon@google.com 392c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com data_blocks_per_cyl = fsinfo.f_bsize * 8 - 39322a800a2578564a8b66bd4d9903ef4186c37f35cbsalomon@google.com (fsinfo.f_files / 8 / cylgroups) - 3; 394c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com } 39522a800a2578564a8b66bd4d9903ef4186c37f35cbsalomon@google.com last_device = st.st_dev; 39622a800a2578564a8b66bd4d9903ef4186c37f35cbsalomon@google.com 39722a800a2578564a8b66bd4d9903ef4186c37f35cbsalomon@google.com width = int_log10(fsinfo.f_blocks); 39877af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com if (width > physical_width) 39922a800a2578564a8b66bd4d9903ef4186c37f35cbsalomon@google.com physical_width = width; 4003bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org 401c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com numblocks = (st.st_size + fsinfo.f_bsize - 1) / fsinfo.f_bsize; 4023bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org if (blocksize != 0) 403c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com blk_shift = int_log2(blocksize); 4043bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org else 4053bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org blk_shift = int_log2(fsinfo.f_bsize); 4063bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org 4073bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org width = int_log10(numblocks); 40817fc651dbe2e0624f6c85fb6e081d28a87d5a08bbsalomon@google.com if (width > logical_width) 40917fc651dbe2e0624f6c85fb6e081d28a87d5a08bbsalomon@google.com logical_width = width; 41017fc651dbe2e0624f6c85fb6e081d28a87d5a08bbsalomon@google.com if (verbose) 41117fc651dbe2e0624f6c85fb6e081d28a87d5a08bbsalomon@google.com printf("File size of %s is %llu (%lu block%s of %d bytes)\n", 4127938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org filename, (unsigned long long)st.st_size, 41317fc651dbe2e0624f6c85fb6e081d28a87d5a08bbsalomon@google.com numblocks * fsinfo.f_bsize >> blk_shift, 41417fc651dbe2e0624f6c85fb6e081d28a87d5a08bbsalomon@google.com numblocks == 1 ? "" : "s", 1 << blk_shift); 41584cd099704b3896ca66081a96508572a924f850ccommit-bot@chromium.org 41617fc651dbe2e0624f6c85fb6e081d28a87d5a08bbsalomon@google.com if (force_bmap || 41717fc651dbe2e0624f6c85fb6e081d28a87d5a08bbsalomon@google.com filefrag_fiemap(fd, blk_shift, &num_extents, &st) != 0) { 4183bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org expected = filefrag_fibmap(fd, blk_shift, &num_extents, 41922a800a2578564a8b66bd4d9903ef4186c37f35cbsalomon@google.com &st, numblocks, is_ext2); 4203bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org if (expected < 0) { 4213bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org if (errno == EINVAL || errno == ENOTTY) { 422396e61fe440590744345e0c56970b26ab464591dbsalomon@google.com fprintf(stderr, "%s: FIBMAP unsupported\n", 423c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com filename); 42477af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com } else if (errno != EPERM) { 425c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com fprintf(stderr, "%s: FIBMAP error: %s", 4263bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org filename, strerror(errno)); 4273bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org } 4283bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org goto out_close; 4293bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org } 4303bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org expected = expected / data_blocks_per_cyl + 1; 4313bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org } 4323bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org 4333bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org if (num_extents == 1) 4347938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org printf("%s: 1 extent found", filename); 4353bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org else 4363bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org printf("%s: %d extents found", filename, num_extents); 4373bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org /* count, and thus expected, only set for indirect FIBMAP'd files */ 4383bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org if (is_ext2 && expected && expected < num_extents) 4397938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org printf(", perfection would be %d extent%s\n", expected, 4403bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org (expected > 1) ? "s" : ""); 4413bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org else 4423bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org fputc('\n', stdout); 4437938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.orgout_close: 4443bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org close(fd); 4453bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org} 4463bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org 4477938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.orgstatic void usage(const char *progname) 4483bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org{ 4493bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org fprintf(stderr, "Usage: %s [-b{blocksize}] [-BeklsvxX] file ...\n", 45074a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org progname); 4513bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org exit(1); 4523bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org} 45322a800a2578564a8b66bd4d9903ef4186c37f35cbsalomon@google.com 454c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.comint main(int argc, char**argv) 45517fc651dbe2e0624f6c85fb6e081d28a87d5a08bbsalomon@google.com{ 45622a800a2578564a8b66bd4d9903ef4186c37f35cbsalomon@google.com char **cpp; 45722a800a2578564a8b66bd4d9903ef4186c37f35cbsalomon@google.com int c; 45877af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com 45922a800a2578564a8b66bd4d9903ef4186c37f35cbsalomon@google.com while ((c = getopt(argc, argv, "Bb::eksvxX")) != EOF) 460a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org switch (c) { 46177af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com case 'B': 4627938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org force_bmap++; 4637938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org break; 46474a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org case 'b': 46522a800a2578564a8b66bd4d9903ef4186c37f35cbsalomon@google.com if (optarg) { 46674a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org char *end; 4677938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org blocksize = strtoul(optarg, &end, 0); 4687938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org if (end) { 4697938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org switch (end[0]) { 47084cd099704b3896ca66081a96508572a924f850ccommit-bot@chromium.org case 'g': 47184cd099704b3896ca66081a96508572a924f850ccommit-bot@chromium.org case 'G': 47274a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org blocksize *= 1024; 47322a800a2578564a8b66bd4d9903ef4186c37f35cbsalomon@google.com /* no break */ 47474a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org case 'm': 47522a800a2578564a8b66bd4d9903ef4186c37f35cbsalomon@google.com case 'M': 47622a800a2578564a8b66bd4d9903ef4186c37f35cbsalomon@google.com blocksize *= 1024; 4777938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org /* no break */ 47884cd099704b3896ca66081a96508572a924f850ccommit-bot@chromium.org case 'k': 4793bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org case 'K': 4803bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org blocksize *= 1024; 4813bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org break; 4823bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org default: 4833bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org break; 4843bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org } 4853bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org } 486f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com } else { /* Allow -b without argument for compat. Remove 487cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org * this eventually so "-b {blocksize}" works */ 488f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com fprintf(stderr, "%s: -b needs a blocksize " 489f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com "option, assuming 1024-byte blocks.\n", 490f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com argv[0]); 491f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com blocksize = 1024; 492f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com } 4937938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org break; 494f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com case 'e': 4953bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org force_extent++; 496f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com if (!verbose) 4973bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org verbose++; 498f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com break; 499f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com case 'k': 500f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com blocksize = 1024; 5013bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org break; 502f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com case 's': 5037938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org sync_file++; 5047938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org break; 5053bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org case 'v': 506f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com verbose++; 5077938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org break; 508f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com case 'x': 509f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com xattr_map++; 510f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com break; 511f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com case 'X': 5123bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org ext_fmt = hex_fmt; 5133bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org break; 5143bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org default: 5153bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org usage(argv[0]); 5163bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org break; 5173bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org } 5183bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org if (optind == argc) 5193bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org usage(argv[0]); 5203bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org for (cpp=argv+optind; *cpp; cpp++) 521dda28c9bde2a34b98e1383532c210270dacb7ca8skia.committer@gmail.com frag_report(*cpp); 5223bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org return 0; 5233bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org} 5243bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org#endif 5253bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org