#include #include #include #include #include /* Preload the OS's cache with all files of one branch for recursive diffs */ #define __NR_readahead 225 asm( "__readahead:\n\t" "pushl %ebx\n\t" "pushl %esi\n\t" "movl 12(%esp),%ebx\n\t" "movl 16(%esp),%ecx\n\t" "movl 20(%esp),%edx\n\t" "movl 24(%esp),%esi\n\t" "movl $225,%eax\n\t" "int $0x80\n\t" "popl %esi\n\t" "popl %ebx\n\t" "ret" ); extern ssize_t __readahead(int fd, loff_t offset, size_t size); void preread (dir) const char *dir; { DIR *d; struct dirent *dent; d = opendir(dir); if (d == NULL) return; while ((dent = readdir(d)) != NULL) { int fd; struct stat st; char *name, *path; name = dent->d_name; if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0))) continue; path = malloc(strlen(dir)+strlen(name)+2); strcpy(path, dir); strcat(path, "/"); strcat(path, name); fd = open(path, O_RDONLY); if (fd >= 0) { if (fstat(fd, &st) == 0) { if (S_ISDIR(st.st_mode)) preread(path); else if (S_ISREG(st.st_mode)) { __readahead(fd, 0, ~0UL); } } close(fd); } free(path); } closedir(d); } int main(int argc, char **argv) { preread(argv[1]); return 0; }