/* See LICENSE file for copyright and license details. */ #include #include #include #define NANOSECONDS(X) X##L #define MICROSECONDS(X) NANOSECONDS(X##000) #define MILLISECONDS(X) MICROSECONDS(X##000) #define CENTISECONDS(X) MILLISECONDS(X##0) #define DECISECONDS(X) CENTISECONDS(X##0) #define WHOLE_SECOND DECISECONDS(10) #define WRAVG_STEPS 5 enum direction { FORWARDS = 0, BACKWARDS = 1 }; struct span { off_t start; off_t end; off_t bad; size_t blocksize; }; struct status { struct timespec now; off_t shredded; off_t bad_bytes; uintmax_t bad_writes; uintmax_t bad_sections; uintmax_t pass_nr; struct timespec last_success; enum direction direction; int write_average_i; struct timespec write_average_begin_times[WRAVG_STEPS]; off_t write_average_amounts[WRAVG_STEPS]; size_t nspans; size_t span_off; size_t spans_size; struct span *spans; }; #define STATUS_INIT {.pass_nr = 1, .last_success = {-1, 0}, .direction = FORWARDS} #define STATUS_TRANSFER_SIZE (offsetof(struct status, nspans) + sizeof(size_t)) /* io.c */ void writeall(int fd, const void *data, size_t n, const char *fname); void filecpy(int fd, off_t src, off_t len, const char *fname); off_t filesize(int fd, const char *fname); #if defined(__linux__) char *get_device_name(unsigned int devmajor, unsigned int devminor); #endif /* fmt.c */ const char *humansize1000(off_t s, char *buf); const char *humansize1024(off_t s, char *buf); #if defined(__GNUC__) __attribute__((__pure__)) #endif off_t unhumansize(const char *s, char flag); const char *durationstr(const struct timespec *dur, char *buf, int second_decimals); const char *humanbytespersecond(double bytes_per_second, char *buf); const char *exact_and_human_size(off_t bytes, char *buf, int with_unit); /* text.c */ int have_micro_symbol(void); /* avg.c */ void wravg_init(const struct timespec *start_time, struct status *s); void wravg_update_write(ssize_t amount, struct status *s); void wravg_update_time(struct status *s); const char *wravg_get(struct status *s); /* rnd.c */ void init_random(int fd, const char *fname, off_t blksize); void destroy_random(void); #if defined(__GNUC__) __attribute__((__pure__)) #endif size_t max_blksize(void); const char *get_random(size_t needed); void used_random(ssize_t amount); /* sig.c */ extern _Atomic volatile sig_atomic_t exiting; void setup_sighandler(void); void block_sigs(void); void unblock_sigs(void); /* ask.c */ int confirm(const char *device, off_t off, off_t len, off_t end); /* map.c */ void add_span(struct status *status, off_t off, off_t amount, size_t blocksize, int try_join); void dump_map(int fd, const struct status *status, const char *fname); off_t measure_map_dump(const struct status *status); off_t load_map(int fd, struct status *status, enum direction direction, const char *fname); void update_map(int fd, const struct status *status, const char *fname);