Home | History | Annotate | Download | only in tools
      1 #define _LARGEFILE64_SOURCE
      2 #include <unistd.h>
      3 #include <string.h>
      4 #include <stdlib.h>
      5 #include <stdio.h>
      6 #include <fcntl.h>
      7 #include <errno.h>
      8 #include <sys/types.h>
      9 #include <sys/ioctl.h>
     10 #include <sys/stat.h>
     11 #include <libgen.h>
     12 #include <linux/hdreg.h>
     13 #include <linux/types.h>
     14 #include <linux/fs.h>
     15 
     16 struct file_ext {
     17 	__u32 f_pos;
     18 	__u32 start_blk;
     19 	__u32 end_blk;
     20 	__u32 blk_count;
     21 };
     22 
     23 void print_ext(struct file_ext *ext)
     24 {
     25 	if (ext->end_blk == 0)
     26 		printf("%8d    %8d    %8d    %8d\n", ext->f_pos, 0, 0, ext->blk_count);
     27 	else
     28 		printf("%8d    %8d    %8d    %8d\n", ext->f_pos, ext->start_blk,
     29 					ext->end_blk, ext->blk_count);
     30 }
     31 
     32 void print_stat(struct stat64 *st)
     33 {
     34 	printf("--------------------------------------------\n");
     35 	printf("dev       [%d:%d]\n", major(st->st_dev), minor(st->st_dev));
     36 	printf("ino       [0x%8lx : %ld]\n", st->st_ino, st->st_ino);
     37 	printf("mode      [0x%8x : %d]\n", st->st_mode, st->st_mode);
     38 	printf("nlink     [0x%8lx : %ld]\n", st->st_nlink, st->st_nlink);
     39 	printf("uid       [0x%8x : %d]\n", st->st_uid, st->st_uid);
     40 	printf("gid       [0x%8x : %d]\n", st->st_gid, st->st_gid);
     41 	printf("size      [0x%8lx : %ld]\n", st->st_size, st->st_size);
     42 	printf("blksize   [0x%8lx : %ld]\n", st->st_blksize, st->st_blksize);
     43 	printf("blocks    [0x%8lx : %ld]\n", st->st_blocks, st->st_blocks);
     44 	printf("--------------------------------------------\n\n");
     45 }
     46 
     47 void stat_bdev(struct stat64 *st, unsigned int *start_lba)
     48 {
     49 	struct stat bdev_stat;
     50 	struct hd_geometry geom;
     51 	char devname[32] = { 0, };
     52 	char linkname[32] = { 0, };
     53 	int fd;
     54 
     55 	sprintf(devname, "/dev/block/%d:%d", major(st->st_dev), minor(st->st_dev));
     56 
     57 	fd = open(devname, O_RDONLY);
     58 	if (fd < 0)
     59 		return;
     60 
     61 	if (fstat(fd, &bdev_stat) < 0)
     62 		goto out;
     63 
     64 	if (S_ISBLK(bdev_stat.st_mode)) {
     65 		if (ioctl(fd, HDIO_GETGEO, &geom) < 0)
     66 			*start_lba = 0;
     67 		else
     68 			*start_lba = geom.start;
     69 	}
     70 
     71 	if (readlink(devname, linkname, sizeof(linkname)) < 0)
     72 		goto out;
     73 
     74 	printf("----------------bdev info-------------------\n");
     75 	printf("devname = %s\n", basename(linkname));
     76 	printf("start_lba = %u\n", *start_lba);
     77 
     78 out:
     79 	close(fd);
     80 
     81 }
     82 
     83 int main(int argc, char *argv[])
     84 {
     85 	int fd;
     86 	int ret = 0;
     87 	char *filename;
     88 	struct stat64 st;
     89 	int total_blks;
     90 	unsigned int i;
     91 	struct file_ext ext;
     92 	__u32 start_lba;
     93 	__u32 blknum;
     94 
     95 	if (argc != 2) {
     96 		fprintf(stderr, "No filename\n");
     97 		exit(-1);
     98 	}
     99 	filename = argv[1];
    100 
    101 	fd = open(filename, O_RDONLY|O_LARGEFILE);
    102 	if (fd < 0) {
    103 		ret = errno;
    104 		perror(filename);
    105 		exit(-1);
    106 	}
    107 
    108 	fsync(fd);
    109 
    110 	if (fstat64(fd, &st) < 0) {
    111 		ret = errno;
    112 		perror(filename);
    113 		goto out;
    114 	}
    115 
    116 	stat_bdev(&st, &start_lba);
    117 
    118 	total_blks = (st.st_size + st.st_blksize - 1) / st.st_blksize;
    119 
    120 	printf("\n----------------file info-------------------\n");
    121 	printf("%s :\n", filename);
    122 	print_stat(&st);
    123 	printf("file_pos   start_blk     end_blk        blks\n");
    124 
    125 	blknum = 0;
    126 	if (ioctl(fd, FIBMAP, &blknum) < 0) {
    127 		ret = errno;
    128 		perror("ioctl(FIBMAP)");
    129 		goto out;
    130 	}
    131 	ext.f_pos = 0;
    132 	ext.start_blk = blknum;
    133 	ext.end_blk = blknum;
    134 	ext.blk_count = 1;
    135 
    136 	for (i = 1; i < total_blks; i++) {
    137 		blknum = i;
    138 
    139 		if (ioctl(fd, FIBMAP, &blknum) < 0) {
    140 			ret = errno;
    141 			perror("ioctl(FIBMAP)");
    142 			goto out;
    143 		}
    144 
    145 		if ((blknum == 0 && blknum == ext.end_blk) || (ext.end_blk + 1) == blknum) {
    146 			ext.end_blk = blknum;
    147 			ext.blk_count++;
    148 		} else {
    149 			print_ext(&ext);
    150 			ext.f_pos = i * st.st_blksize;
    151 			ext.start_blk = blknum;
    152 			ext.end_blk = blknum;
    153 			ext.blk_count = 1;
    154 		}
    155 	}
    156 
    157 	print_ext(&ext);
    158 out:
    159 	close(fd);
    160 	return ret;
    161 }
    162