static void file_check_hole( struct file_info *file, int fd, off_t offset, size_t size) { size_t remains, block, i; char buf[BUFFER_SIZE]; CHECK(lseek(fd, offset, SEEK_SET) != (off_t) -1); remains = size; while (remains) { if (remains > BUFFER_SIZE) block = BUFFER_SIZE; else block = remains; CHECK(read(fd, buf, block) == block); for (i = 0; i < block; ++i) { if (buf[i] != 0) { fprintf(stderr, "file_check_hole failed at %u " "checking hole at %u size %u\n", (unsigned) (size - remains + i), (unsigned) offset, (unsigned) size); file_info_display(file); save_file(fd, file); } CHECK(buf[i] == 0); } remains -= block; } }
static void file_check_data( struct file_info *file, int fd, struct write_info *w) { size_t remains, block, i; off_t r; char buf[BUFFER_SIZE]; srand(w->random_seed); for (r = 0; r < w->random_offset; ++r) rand(); CHECK(lseek(fd, w->offset, SEEK_SET) != (off_t) -1); remains = w->size; while (remains) { if (remains > BUFFER_SIZE) block = BUFFER_SIZE; else block = remains; CHECK(read(fd, buf, block) == block); for (i = 0; i < block; ++i) { char c = (char) rand(); if (buf[i] != c) { fprintf(stderr, "file_check_data failed at %u " "checking data at %u size %u\n", (unsigned) (w->size - remains + i), (unsigned) w->offset, (unsigned) w->size); file_info_display(file); save_file(fd, file); } CHECK(buf[i] == c); } remains -= block; } }
static void file_check(struct file_info *file, int fd) { int open_and_close = 0, link_count = 0; char *path = NULL; off_t pos; struct write_info *w; struct dir_entry_info *entry; struct stat st; /* Do not check files that have errored */ if (!check_nospc_files && file->no_space_error) return; /* Do not check the same file twice */ if (file->check_run_no == check_run_no) return; file->check_run_no = check_run_no; if (fd == -1) open_and_close = 1; if (open_and_close) { /* Open file */ path = dir_path(file->links->parent, file->links->name); fd = open(path, O_RDONLY); CHECK(fd != -1); } /* Check length */ pos = lseek(fd, 0, SEEK_END); if (pos != file->length) { fprintf(stderr, "file_check failed checking length " "expected %u actual %u\n", (unsigned) file->length, (unsigned) pos); file_info_display(file); save_file(fd, file); } CHECK(pos == file->length); /* Check each write */ pos = 0; for (w = file->writes; w; w = w->next) { if (w->offset > pos) file_check_hole(file, fd, pos, w->offset - pos); file_check_data(file, fd, w); pos = w->offset + w->size; } if (file->length > pos) file_check_hole(file, fd, pos, file->length - pos); CHECK(fstat(fd, &st) != -1); CHECK(file->link_count == st.st_nlink); if (open_and_close) { CHECK(close(fd) != -1); free(path); } entry = file->links; while (entry) { link_count += 1; entry = entry->next_link; } CHECK(link_count == file->link_count); }
static void file_check(struct file_info *file, int fd) { int open_and_close = 0; char *path = NULL; off_t pos; struct write_info *w; /* Do not check files that have errored */ if (file->no_space_error) return; if (fd == -1) open_and_close = 1; if (open_and_close) { /* Open file */ path = dir_path(file->parent, file->name); fd = open(path, O_RDONLY); CHECK(fd != -1); } /* Check length */ pos = lseek(fd, 0, SEEK_END); if (pos != file->length) { fprintf(stderr, "file_check failed checking length " "expected %u actual %u\n", (unsigned) file->length, (unsigned) pos); file_info_display(file); save_file(fd, file); } CHECK(pos == file->length); /* Check each write */ pos = 0; for (w = file->writes; w; w = w->next) { if (w->offset > pos) file_check_hole(file, fd, pos, w->offset - pos); file_check_data(file, fd, w); pos = w->offset + w->size; } if (file->length > pos) file_check_hole(file, fd, pos, file->length - pos); if (open_and_close) { CHECK(close(fd) != -1); free(path); } }