// Copyright Purdea Andrei // released under the GNU GPL (v2 or later) #include #include #include #include #include #include int main(int argc, char ** argv) { int i; if (argc!=2) { printf("Usage: %s /dev/sdX\n", argv[0]); printf("WARNING! This Is Destructive!!!!\n"); return -1; } int fd = open(argv[1], O_WRONLY); if (fd<0) { perror("ERROR: Can't open device file"); return -2; } for (i=0;i<3;i++) { printf("THIS IS VERY DESTRUCTIVE!!!\n"); printf("\033[31mTHIS IS VERY DESTRUCTIVE!!!\033(B\033[m\n"); } printf("YOU ARE ABOUT TO OVERWRITE DATA ON %s\n", argv[1]); printf("Are you absolutely sure that you want to do this? (y/n) "); char resp; scanf("%c", &resp); if (resp!='y') return -100; // The first 4 GiB is going to be discarded. // First a 2GiB segment is discarded // then a 1GiB segment is discarded // then an 512 MiB segment is discarded, and so on... // the last segment discarded is an 512 byte segment. // before allt this the last 512 bytes of the file will be discarded (this time is not measured) __uint64_t range[2] = { ((1L << (32 - 9)) - 1) << 9, 1L << 9 }; // ^^ the default values point to the last sector // this is done because the absolute first discard in a series of discards is sometimes slower. if (ioctl(fd, BLKDISCARD, &range)==-1) { perror("ERROR: can't send BLKDISCARD ioctl"); return -3; } printf(" offset (sectors) , count (sectors) , time (microseconds)\n"); printf("-------------------,--------------------,------------------------\n"); range[0] = 0; range[1] = 1L << 31; struct timeval start, stop, result; for (i=31;i>=9;i--) { // go from 512-byte blocks, to 2 GiB gettimeofday(&start, NULL); if (ioctl(fd, BLKDISCARD, &range)==-1) { perror("ERROR: can't send BLKDISCARD ioctl"); return -3; } gettimeofday(&stop, NULL); timersub(&stop, &start, &result); printf(" %8d , %8d , %7d\n", range[0]>>9, range[1]>>9, result.tv_sec * 1000000 + result.tv_usec); range[0] = range[0] + range[1]; range[1] >>= 1; } return 0; }