1 #if !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__OpenBSD__) 2 #define _XOPEN_SOURCE 600 3 #define _DARWIN_C_SOURCE 4 #define _FILE_OFFSET_BITS 64 5 #ifndef _LARGEFILE_SOURCE 6 #define _LARGEFILE_SOURCE 7 #endif 8 #ifndef _LARGEFILE64_SOURCE 9 #define _LARGEFILE64_SOURCE 10 #endif 11 #ifndef _GNU_SOURCE 12 #define _GNU_SOURCE 13 #endif 14 #endif 15 #ifndef O_LARGEFILE 16 #define O_LARGEFILE 0 17 #endif 18 #include <f2fs_fs.h> 19 #include <unistd.h> 20 #include <string.h> 21 #include <stdlib.h> 22 #include <stdio.h> 23 #include <fcntl.h> 24 #include <errno.h> 25 #include <sys/types.h> 26 #include <sys/ioctl.h> 27 #include <sys/stat.h> 28 #ifdef HAVE_SYS_SYSMACROS_H 29 #include <sys/sysmacros.h> 30 #endif 31 #include <libgen.h> 32 #ifdef HAVE_LINUX_HDREG_H 33 #include <linux/hdreg.h> 34 #endif 35 #ifdef HAVE_LINUX_TYPES_H 36 #include <linux/types.h> 37 #endif 38 #ifdef __KERNEL__ 39 #include <linux/fs.h> 40 #endif 41 #include <inttypes.h> 42 43 #ifndef FIBMAP 44 #define FIBMAP _IO(0x00, 1) /* bmap access */ 45 #endif 46 47 struct file_ext { 48 __u32 f_pos; 49 __u32 start_blk; 50 __u32 end_blk; 51 __u32 blk_count; 52 }; 53 54 void print_ext(struct file_ext *ext) 55 { 56 if (ext->end_blk == 0) 57 printf("%8d %8d %8d %8d\n", ext->f_pos, 0, 0, ext->blk_count); 58 else 59 printf("%8d %8d %8d %8d\n", ext->f_pos, ext->start_blk, 60 ext->end_blk, ext->blk_count); 61 } 62 63 #if defined(HAVE_FSTAT64) && !defined(__OSX_AVAILABLE_BUT_DEPRECATED) 64 void print_stat(struct stat64 *st) 65 #else 66 void print_stat(struct stat *st) 67 #endif 68 { 69 printf("--------------------------------------------\n"); 70 printf("dev [%d:%d]\n", major(st->st_dev), minor(st->st_dev)); 71 printf("ino [0x%8"PRIx64" : %"PRIu64"]\n", 72 st->st_ino, st->st_ino); 73 printf("mode [0x%8x : %d]\n", st->st_mode, st->st_mode); 74 printf("nlink [0x%8lx : %ld]\n", 75 (unsigned long)st->st_nlink, 76 (long)st->st_nlink); 77 printf("uid [0x%8x : %d]\n", st->st_uid, st->st_uid); 78 printf("gid [0x%8x : %d]\n", st->st_gid, st->st_gid); 79 printf("size [0x%8"PRIx64" : %"PRIu64"]\n", 80 (u64)st->st_size, (u64)st->st_size); 81 printf("blksize [0x%8lx : %ld]\n", 82 (unsigned long)st->st_blksize, 83 (long)st->st_blksize); 84 printf("blocks [0x%8"PRIx64" : %"PRIu64"]\n", 85 (u64)st->st_blocks, (u64)st->st_blocks); 86 printf("--------------------------------------------\n\n"); 87 } 88 89 #if defined(HAVE_FSTAT64) && !defined(__OSX_AVAILABLE_BUT_DEPRECATED) 90 static void stat_bdev(struct stat64 *st, unsigned int *start_lba) 91 #else 92 static void stat_bdev(struct stat *st, unsigned int *start_lba) 93 #endif 94 { 95 struct stat bdev_stat; 96 #ifdef HDIO_GETGIO 97 struct hd_geometry geom; 98 #endif 99 char devname[32] = { 0, }; 100 char linkname[32] = { 0, }; 101 int fd; 102 103 sprintf(devname, "/dev/block/%d:%d", major(st->st_dev), minor(st->st_dev)); 104 105 fd = open(devname, O_RDONLY); 106 if (fd < 0) 107 return; 108 109 if (fstat(fd, &bdev_stat) < 0) 110 goto out; 111 112 if (S_ISBLK(bdev_stat.st_mode)) { 113 #ifdef HDIO_GETGIO 114 if (ioctl(fd, HDIO_GETGEO, &geom) < 0) 115 *start_lba = 0; 116 else 117 *start_lba = geom.start; 118 #else 119 *start_lba = 0; 120 #endif 121 } 122 123 if (readlink(devname, linkname, sizeof(linkname)) < 0) 124 goto out; 125 126 printf("----------------bdev info-------------------\n"); 127 printf("devname = %s\n", basename(linkname)); 128 printf("start_lba = %u\n", *start_lba); 129 130 out: 131 close(fd); 132 133 } 134 135 int main(int argc, char *argv[]) 136 { 137 int fd; 138 int ret = 0; 139 char *filename; 140 #if defined(HAVE_FSTAT64) && !defined(__OSX_AVAILABLE_BUT_DEPRECATED) 141 struct stat64 st; 142 #else 143 struct stat st; 144 #endif 145 int total_blks; 146 unsigned int i; 147 struct file_ext ext; 148 __u32 start_lba; 149 __u32 blknum; 150 151 if (argc != 2) { 152 fprintf(stderr, "No filename\n"); 153 exit(-1); 154 } 155 filename = argv[1]; 156 157 fd = open(filename, O_RDONLY|O_LARGEFILE); 158 if (fd < 0) { 159 ret = errno; 160 perror(filename); 161 exit(-1); 162 } 163 164 fsync(fd); 165 166 #if defined(HAVE_FSTAT64) && !defined(__OSX_AVAILABLE_BUT_DEPRECATED) 167 if (fstat64(fd, &st) < 0) { 168 #else 169 if (fstat(fd, &st) < 0) { 170 #endif 171 ret = errno; 172 perror(filename); 173 goto out; 174 } 175 176 stat_bdev(&st, &start_lba); 177 178 total_blks = (st.st_size + st.st_blksize - 1) / st.st_blksize; 179 180 printf("\n----------------file info-------------------\n"); 181 printf("%s :\n", filename); 182 print_stat(&st); 183 printf("file_pos start_blk end_blk blks\n"); 184 185 blknum = 0; 186 if (ioctl(fd, FIBMAP, &blknum) < 0) { 187 ret = errno; 188 perror("ioctl(FIBMAP)"); 189 goto out; 190 } 191 ext.f_pos = 0; 192 ext.start_blk = blknum; 193 ext.end_blk = blknum; 194 ext.blk_count = 1; 195 196 for (i = 1; i < total_blks; i++) { 197 blknum = i; 198 199 if (ioctl(fd, FIBMAP, &blknum) < 0) { 200 ret = errno; 201 perror("ioctl(FIBMAP)"); 202 goto out; 203 } 204 205 if ((blknum == 0 && blknum == ext.end_blk) || (ext.end_blk + 1) == blknum) { 206 ext.end_blk = blknum; 207 ext.blk_count++; 208 } else { 209 print_ext(&ext); 210 ext.f_pos = i * st.st_blksize; 211 ext.start_blk = blknum; 212 ext.end_blk = blknum; 213 ext.blk_count = 1; 214 } 215 } 216 217 print_ext(&ext); 218 out: 219 close(fd); 220 return ret; 221 } 222