📄 integck.c
字号:
{ struct dir_entry_info *entry; entry = pick_entry(file); if (!entry) return; file_unlink(entry);}static void file_delete(struct file_info *file){ struct dir_entry_info *entry = file->links; file_close_all(file); while (entry) { struct dir_entry_info *next = entry->next_link; file_unlink(entry); entry = next; }}static void file_info_display(struct file_info *file){ struct dir_entry_info *entry; struct write_info *w; unsigned wcnt; fprintf(stderr, "File Info:\n"); fprintf(stderr, " Original name: %s\n", file->name); fprintf(stderr, " Link count: %d\n", file->link_count); fprintf(stderr, " Links:\n"); entry = file->links; while (entry) { fprintf(stderr, " Name: %s\n", entry->name); fprintf(stderr, " Directory: %s\n", entry->parent->name); entry = entry->next_link; } fprintf(stderr, " Length: %u\n", (unsigned) file->length); fprintf(stderr, " File was open: %s\n", (file->fds == NULL) ? "false" : "true"); fprintf(stderr, " File was deleted: %s\n", (file->deleted == 0) ? "false" : "true"); fprintf(stderr, " File was out of space: %s\n", (file->no_space_error == 0) ? "false" : "true"); fprintf(stderr, " File Data:\n"); wcnt = 0; w = file->writes; while (w) { fprintf(stderr, " Offset: %u Size: %u Seed: %u" " R.Off: %u\n", (unsigned) w->offset, (unsigned) w->size, (unsigned) w->random_seed, (unsigned) w->random_offset); wcnt += 1; w = w->next; } fprintf(stderr, " %u writes\n", wcnt); fprintf(stderr, " ============================================\n"); fprintf(stderr, " Write Info:\n"); wcnt = 0; w = file->raw_writes; while (w) { if (w->trunc) fprintf(stderr, " Trunc from %u to %u\n", (unsigned) w->offset, (unsigned) w->random_offset); else fprintf(stderr, " Offset: %u Size: %u Seed: %u" " R.Off: %u\n", (unsigned) w->offset, (unsigned) w->size, (unsigned) w->random_seed, (unsigned) w->random_offset); wcnt += 1; w = w->next; } fprintf(stderr, " %u writes or truncations\n", wcnt); fprintf(stderr, " ============================================\n");}static struct fd_info *file_open(struct file_info *file){ int fd, flags = O_RDWR; char *path; path = dir_path(file->links->parent, file->links->name); if (tests_random_no(100) == 1) flags |= O_SYNC; fd = open(path, flags); CHECK(fd != -1); free(path); return add_fd(file, fd);}#define BUFFER_SIZE 32768static size_t file_write_data( struct file_info *file, int fd, off_t offset, size_t size, unsigned seed){ size_t remains, actual, block; ssize_t written; char buf[BUFFER_SIZE]; srand(seed); CHECK(lseek(fd, offset, SEEK_SET) != (off_t) -1); remains = size; actual = 0; written = BUFFER_SIZE; while (remains) { /* Fill up buffer with random data */ if (written < BUFFER_SIZE) { memmove(buf, buf + written, BUFFER_SIZE - written); written = BUFFER_SIZE - written; } else written = 0; for (; written < BUFFER_SIZE; ++written) buf[written] = rand(); /* Write a block of data */ if (remains > BUFFER_SIZE) block = BUFFER_SIZE; else block = remains; written = write(fd, buf, block); if (written < 0) { CHECK(errno == ENOSPC); /* File system full */ full = 1; file->no_space_error = 1; break; } remains -= written; actual += written; } return actual;}static void file_write_info(struct file_info *file, off_t offset, size_t size, unsigned seed){ struct write_info *new_write, *w, **prev, *tmp; int inserted; size_t sz; off_t end, chg; /* Create struct write_info */ sz = sizeof(struct write_info); new_write = (struct write_info *) malloc(sz); CHECK(new_write != NULL); memset(new_write, 0, sz); new_write->offset = offset; new_write->size = size; new_write->random_seed = seed; w = (struct write_info *) malloc(sz); CHECK(w != NULL); memset(w, 0, sz); w->next = file->raw_writes; w->offset = offset; w->size = size; w->random_seed = seed; file->raw_writes = w; /* Insert it into file->writes */ inserted = 0; end = offset + size; w = file->writes; prev = &file->writes; while (w) { if (w->offset >= end) { /* w comes after new_write, so insert before it */ new_write->next = w; *prev = new_write; inserted = 1; break; } /* w does not come after new_write */ if (w->offset + w->size > offset) { /* w overlaps new_write */ if (w->offset < offset) { /* w begins before new_write begins */ if (w->offset + w->size <= end) /* w ends before new_write ends */ w->size = offset - w->offset; else { /* w ends after new_write ends */ /* Split w */ tmp = (struct write_info *) malloc(sz); CHECK(tmp != NULL); *tmp = *w; chg = end - tmp->offset; tmp->offset += chg; tmp->random_offset += chg; tmp->size -= chg; w->size = offset - w->offset; /* Insert new struct write_info */ w->next = new_write; new_write->next = tmp; inserted = 1; break; } } else { /* w begins after new_write begins */ if (w->offset + w->size <= end) { /* w is completely overlapped, so remove it */ *prev = w->next; tmp = w; w = w->next; free(tmp); continue; } /* w ends after new_write ends */ chg = end - w->offset; w->offset += chg; w->random_offset += chg; w->size -= chg; continue; } } prev = &w->next; w = w->next; } if (!inserted) *prev = new_write; /* Update file length */ if (end > file->length) file->length = end;}/* Randomly select offset and and size to write in a file */static void get_offset_and_size(struct file_info *file, off_t *offset, size_t *size){ size_t r, n; r = tests_random_no(100); if (r == 0 && grow) /* 1 time in 100, when growing, write off the end of the file */ *offset = file->length + tests_random_no(10000000); else if (r < 4) /* 3 (or 4) times in 100, write at the beginning of file */ *offset = 0; else if (r < 52 || !grow) /* 48 times in 100, write into the file */ *offset = tests_random_no(file->length); else /* 48 times in 100, write at the end of the file */ *offset = file->length; /* Distribute the size logarithmically */ if (tests_random_no(1000) == 0) r = tests_random_no(log10_initial_free_space + 2); else r = tests_random_no(log10_initial_free_space); n = 1; while (r--) n *= 10; *size = tests_random_no(n); if (!grow && *offset + *size > file->length) *size = file->length - *offset; if (*size == 0) *size = 1;}static void file_truncate_info(struct file_info *file, size_t new_length);static int file_ftruncate(struct file_info *file, int fd, off_t new_length){ if (ftruncate(fd, new_length) == -1) { CHECK(errno = ENOSPC); file->no_space_error = 1; /* Delete errored files */ if (!check_nospc_files) file_delete(file); return 0; } return 1;}static void file_mmap_write(struct file_info *file){ size_t write_cnt = 0, r, i, len, size; struct write_info *w = file->writes; void *addr; char *waddr; off_t offs, offset; unsigned seed; uint64_t free_space; int fd; char *path; if (!file->links) return; free_space = tests_get_free_space(); if (!free_space) return; /* Randomly pick a written area of the file */ if (!w) return; while (w) { write_cnt += 1; w = w->next; } r = tests_random_no(write_cnt); w = file->writes; for (i = 0; w && w->next && i < r; i++) w = w->next; offs = (w->offset / mem_page_size) * mem_page_size; len = w->size + (w->offset - offs); if (len > 1 << 24) len = 1 << 24; /* Open it */ path = dir_path(file->links->parent, file->links->name); fd = open(path, O_RDWR); CHECK(fd != -1); free(path); /* mmap it */ addr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, offs); CHECK(close(fd) != -1); CHECK(addr != MAP_FAILED); /* Randomly select a part of the mmapped area to write */ size = tests_random_no(w->size); if (size > free_space) size = free_space; if (size == 0) size = 1; offset = w->offset + tests_random_no(w->size - size); /* Write it */ seed = tests_random_no(10000000); srand(seed); waddr = addr + (offset - offs); for (i = 0; i < size; i++) waddr[i] = rand(); /* Unmap it */ CHECK(munmap(addr, len) != -1); /* Record what was written */ file_write_info(file, offset, size, seed);}static void file_write(struct file_info *file, int fd){ off_t offset; size_t size, actual; unsigned seed; int truncate = 0; if (can_mmap && !full && !file->deleted && tests_random_no(100) == 1) { file_mmap_write(file); return; } get_offset_and_size(file, &offset, &size); seed = tests_random_no(10000000); actual = file_write_data(file, fd, offset, size, seed); if (offset + actual <= file->length && shrink) /* 1 time in 100, when shrinking truncate after the write */ if (tests_random_no(100) == 0) truncate = 1; if (actual != 0) file_write_info(file, offset, actual, seed); /* Delete errored files */ if (!check_nospc_files && file->no_space_error) { file_delete(file); return; } if (truncate) { size_t new_length = offset + actual; if (file_ftruncate(file, fd, new_length)) file_truncate_info(file, new_length); }}static void file_write_file(struct file_info *file){ int fd; char *path; path = dir_path(file->links->parent, file->links->name); fd = open(path, O_WRONLY); CHECK(fd != -1); file_write(file, fd); CHECK(close(fd) != -1); free(path);}static void file_truncate_info(struct file_info *file, size_t new_length){ struct write_info *w, **prev, *tmp; size_t sz; /* Remove / truncate file->writes */ w = file->writes; prev = &file->writes; while (w) { if (w->offset >= new_length) { /* w comes after eof, so remove it */ *prev = w->next; tmp = w; w = w->next; free(tmp); continue; } if (w->offset + w->size > new_length) w->size = new_length - w->offset; prev = &w->next; w = w->next; } /* Add an entry in raw_writes for the truncation */ sz = sizeof(struct write_info); w = (struct write_info *) malloc(sz); CHECK(w != NULL); memset(w, 0, sz); w->next = file->raw_writes; w->offset = file->length; w->random_offset = new_length; /* Abuse random_offset */ w->trunc = 1; file->raw_writes = w; /* Update file length */ file->length = new_length;}static void file_truncate(struct file_info *file, int fd){ size_t new_length; new_length = tests_random_no(file->length); if (file_ftruncate(file, fd, new_length)) file_truncate_info(file, new_length);}static void file_truncate_file(struct file_info *file){ int fd; char *path; path = dir_path(file->links->parent, file->links->name); fd = open(path, O_WRONLY); CHECK(fd != -1); file_truncate(file, fd); CHECK(close(fd) != -1); free(path);}static void file_close(struct fd_info *fdi){ struct file_info *file; struct fd_info *fdp; struct fd_info **prev; /* Close file */ CHECK(close(fdi->fd) != -1); /* Remove struct fd_info */ open_file_remove(fdi); file = fdi->file; prev = &file->fds; for (fdp = file->fds; fdp; fdp = fdp->next) { if (fdp == fdi) { *prev = fdi->next; free(fdi); if (file->deleted && !file->fds) { /* Closing deleted file */ struct write_info *w, *next; w = file->writes; while (w) { next = w->next; free(w); w = next; } free(file->name); free(file); } return; } prev = &fdp->next; } CHECK(0); /* Didn't find struct fd_info */}static void file_rewrite_data(int fd, struct write_info *w, char *buf){ size_t remains, block; ssize_t written; off_t r; 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; written = BUFFER_SIZE; while (remains) { /* Fill up buffer with random data */ if (written < BUFFER_SIZE) memmove(buf, buf + written, BUFFER_SIZE - written); else written = 0; for (; written < BUFFER_SIZE; ++written)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -