static ssize_t readahead_pread(vfs_handle_struct *handle, files_struct *fsp, void *data, size_t count, off_t offset) { struct readahead_data *rhd = (struct readahead_data *)handle->data; if ( offset % rhd->off_bound == 0) { #if defined(HAVE_LINUX_READAHEAD) int err = readahead(fsp->fh->fd, offset, (size_t)rhd->len); DEBUG(10,("readahead_pread: readahead on fd %u, offset %llu, len %u returned %d\n", (unsigned int)fsp->fh->fd, (unsigned long long)offset, (unsigned int)rhd->len, err )); #elif defined(HAVE_POSIX_FADVISE) int err = posix_fadvise(fsp->fh->fd, offset, (off_t)rhd->len, POSIX_FADV_WILLNEED); DEBUG(10,("readahead_pread: posix_fadvise on fd %u, offset %llu, len %u returned %d\n", (unsigned int)fsp->fh->fd, (unsigned long long)offset, (unsigned int)rhd->len, err )); #else if (!rhd->didmsg) { DEBUG(0,("readahead_pread: no readahead on this platform\n")); rhd->didmsg = True; } #endif } return SMB_VFS_NEXT_PREAD(handle, fsp, data, count, offset); }
int readahead_tree_block(struct btrfs_root *root, u64 bytenr, u32 blocksize, u64 parent_transid) { int ret; struct extent_buffer *eb; u64 length; struct btrfs_multi_bio *multi = NULL; struct btrfs_device *device; eb = btrfs_find_tree_block(root, bytenr, blocksize); if (eb && btrfs_buffer_uptodate(eb, parent_transid)) { free_extent_buffer(eb); return 0; } length = blocksize; ret = btrfs_map_block(&root->fs_info->mapping_tree, READ, bytenr, &length, &multi, 0, NULL); BUG_ON(ret); device = multi->stripes[0].dev; device->total_ios++; blocksize = min(blocksize, (u32)(64 * 1024)); readahead(device->fd, multi->stripes[0].physical, blocksize); kfree(multi); return 0; }
int readahead_main(int argc UNUSED_PARAM, char **argv) { int retval = EXIT_SUCCESS; if (!argv[1]) { bb_show_usage(); } while (*++argv) { int fd = open_or_warn(*argv, O_RDONLY); if (fd >= 0) { off_t len; int r; /* fdlength was reported to be unreliable - use seek */ len = xlseek(fd, 0, SEEK_END); xlseek(fd, 0, SEEK_SET); r = readahead(fd, 0, len); close(fd); if (r >= 0) continue; } retval = EXIT_FAILURE; } return retval; }
void touch_pages( HANDLE fd, int offset, size_t length, const Extent* ext ) { if ( -1 == readahead(fd, offset, length) ) { massert( 16237, str::stream() << "readahead failed on fd " << fd << " offset " << offset << " len " << length << " : " << errnoWithDescription(errno), 0 ); } }
int readahead_main(int argc, char **argv) { int retval = EXIT_SUCCESS; if (argc == 1) bb_show_usage(); while (*++argv) { int fd = open_or_warn(*argv, O_RDONLY); if (fd >= 0) { int r = readahead(fd, 0, fdlength(fd)); close(fd); if (r >= 0) continue; } retval = EXIT_FAILURE; } return retval; }
int main(int argc, char* argv[]) { if (argc < 2) return 1; int fd = open (argv[1], O_RDWR|O_CREAT); if (fd < 0) { perror ("open"); return 1; } off_t start = 0; off_t end = lseek(fd, start, SEEK_END); lseek (fd, start, SEEK_SET); int ch=0; if (argc == 3) ch = atoi (argv[2]); if (ch == 1) posix_fadvise (fd, start, end, POSIX_FADV_SEQUENTIAL); if (ch == 2) posix_fadvise (fd, start, end, POSIX_FADV_RANDOM); if (readahead (fd, start, end) < 0) perror ("readahead"); struct timeval tvstart, tvend; gettimeofday (&tvstart, NULL); int len, totallen=0; char buffer[1024]; while ((len = read (fd, buffer, sizeof(buffer))) > 0) { totallen += len; // printf ("read len = %d\n", len); } printf ("total length = %d\n", totallen); gettimeofday (&tvend, NULL); double tv = (tvend.tv_sec - tvstart.tv_sec) + 1.0*(tvend.tv_usec - tvstart.tv_usec)/1000000; printf ("time cost: %lf\n", tv); return 0; }
int readahead_main(int argc, char **argv) { FILE *f; int retval = EXIT_SUCCESS; if (argc == 1) bb_show_usage(); while (*++argv) { if ((f = fopen_or_warn(*argv, "r")) != NULL) { int r, fd=fileno(f); r = readahead(fd, 0, fdlength(fd)); fclose(f); if (r >= 0) continue; } retval = EXIT_FAILURE; } return retval; }
static void preload(const char *file) { union { char buf[bufsize]; Elf_Ehdr ehdr; } elf; int fd = open(file, O_RDONLY); if (fd < 0) return; // Read ELF header (ehdr) and program header table (phdr). // We check that the ELF magic is found, that the ELF class matches // our own, and that the program header table as defined in the ELF // headers fits in the buffer we read. if ((read(fd, elf.buf, bufsize) <= 0) || (memcmp(elf.buf, ELFMAG, 4)) || (elf.ehdr.e_ident[EI_CLASS] != ELFCLASS) || (elf.ehdr.e_phoff + elf.ehdr.e_phentsize * elf.ehdr.e_phnum >= bufsize)) { close(fd); return; } // The program header table contains segment definitions. One such // segment type is PT_LOAD, which describes how the dynamic loader // is going to map the file in memory. We use that information to // find the biggest offset from the library that will be mapped in // memory. Elf_Phdr *phdr = (Elf_Phdr *)&elf.buf[elf.ehdr.e_phoff]; Elf_Off end = 0; for (int phnum = elf.ehdr.e_phnum; phnum; phdr++, phnum--) if ((phdr->p_type == PT_LOAD) && (end < phdr->p_offset + phdr->p_filesz)) end = phdr->p_offset + phdr->p_filesz; // Let the kernel read ahead what the dynamic loader is going to // map in memory soon after. if (end > 0) { readahead(fd, 0, end); } close(fd); }
static ssize_t readahead_sendfile(struct vfs_handle_struct *handle, int tofd, files_struct *fromfsp, const DATA_BLOB *header, off_t offset, size_t count) { struct readahead_data *rhd = (struct readahead_data *)handle->data; if ( offset % rhd->off_bound == 0) { #if defined(HAVE_LINUX_READAHEAD) int err = readahead(fromfsp->fh->fd, offset, (size_t)rhd->len); DEBUG(10,("readahead_sendfile: readahead on fd %u, offset %llu, len %u returned %d\n", (unsigned int)fromfsp->fh->fd, (unsigned long long)offset, (unsigned int)rhd->len, err )); #elif defined(HAVE_POSIX_FADVISE) int err = posix_fadvise(fromfsp->fh->fd, offset, (off_t)rhd->len, POSIX_FADV_WILLNEED); DEBUG(10,("readahead_sendfile: posix_fadvise on fd %u, offset %llu, len %u returned %d\n", (unsigned int)fromfsp->fh->fd, (unsigned long long)offset, (unsigned int)rhd->len, err )); #else if (!rhd->didmsg) { DEBUG(0,("readahead_sendfile: no readahead on this platform\n")); rhd->didmsg = True; } #endif } return SMB_VFS_NEXT_SENDFILE(handle, tofd, fromfsp, header, offset, count); }
void mozilla::ReadAhead(mozilla::filedesc_t aFd, const size_t aOffset, const size_t aCount) { #if defined(XP_WIN) LARGE_INTEGER fpOriginal; LARGE_INTEGER fpOffset; #if defined(HAVE_LONG_LONG) fpOffset.QuadPart = 0; #else fpOffset.u.LowPart = 0; fpOffset.u.HighPart = 0; #endif // Get the current file pointer so that we can restore it. This isn't // really necessary other than to provide the same semantics regarding the // file pointer that other platforms do if (!SetFilePointerEx(aFd, fpOffset, &fpOriginal, FILE_CURRENT)) { return; } if (aOffset) { #if defined(HAVE_LONG_LONG) fpOffset.QuadPart = static_cast<LONGLONG>(aOffset); #else fpOffset.u.LowPart = aOffset; fpOffset.u.HighPart = 0; #endif if (!SetFilePointerEx(aFd, fpOffset, nullptr, FILE_BEGIN)) { return; } } char buf[64 * 1024]; size_t totalBytesRead = 0; DWORD dwBytesRead; // Do dummy reads to trigger kernel-side readhead via FILE_FLAG_SEQUENTIAL_SCAN. // Abort when underfilling because during testing the buffers are read fully // A buffer that's not keeping up would imply that readahead isn't working right while (totalBytesRead < aCount && ReadFile(aFd, buf, sizeof(buf), &dwBytesRead, nullptr) && dwBytesRead == sizeof(buf)) { totalBytesRead += dwBytesRead; } // Restore the file pointer SetFilePointerEx(aFd, fpOriginal, nullptr, FILE_BEGIN); #elif defined(LINUX) && !defined(ANDROID) readahead(aFd, aOffset, aCount); #elif defined(XP_MACOSX) struct radvisory ra; ra.ra_offset = aOffset; ra.ra_count = aCount; // The F_RDADVISE fcntl is equivalent to Linux' readahead() system call. fcntl(aFd, F_RDADVISE, &ra); #endif }
/* read_testfile - mmap testfile and read every page. * This functions measures how many I/O and time it takes to fully * read contents of test file. * * @do_readahead: call readahead prior to reading file content? * @fname: name of file to test * @fsize: how many bytes to read/mmap * @read_bytes: returns difference of bytes read, parsed from /proc/<pid>/io * @usec: returns how many microsecond it took to go over fsize bytes * @cached: returns cached kB from /proc/meminfo */ static void read_testfile(int do_readahead, const char *fname, size_t fsize, unsigned long *read_bytes, long *usec, unsigned long *cached) { int fd; size_t i = 0; long read_bytes_start; unsigned char *p, tmp; unsigned long time_start_usec, time_end_usec; unsigned long cached_start, max_ra_estimate = 0; off_t offset = 0; struct timeval now; fd = SAFE_OPEN(cleanup, fname, O_RDONLY); if (do_readahead) { cached_start = get_cached_size(); do { TEST(readahead(fd, offset, fsize - offset)); if (TEST_RETURN != 0) { check_ret(0); break; } /* estimate max readahead size based on first call */ if (!max_ra_estimate) { *cached = get_cached_size(); if (*cached > cached_start) { max_ra_estimate = (1024 * (*cached - cached_start)); tst_resm(TINFO, "max ra estimate: %lu", max_ra_estimate); } max_ra_estimate = MAX(max_ra_estimate, MIN_SANE_READAHEAD); } i++; offset += max_ra_estimate; } while ((size_t)offset < fsize); tst_resm(TINFO, "readahead calls made: %zu", i); *cached = get_cached_size(); /* offset of file shouldn't change after readahead */ offset = lseek(fd, 0, SEEK_CUR); if (offset == (off_t) - 1) tst_brkm(TBROK | TERRNO, cleanup, "lseek failed"); if (offset == 0) tst_resm(TPASS, "offset is still at 0 as expected"); else tst_resm(TFAIL, "offset has changed to: %lu", offset); } if (gettimeofday(&now, NULL) == -1) tst_brkm(TBROK | TERRNO, cleanup, "gettimeofday failed"); time_start_usec = now.tv_sec * 1000000 + now.tv_usec; read_bytes_start = get_bytes_read(); p = mmap(NULL, fsize, PROT_READ, MAP_SHARED | MAP_POPULATE, fd, 0); if (p == MAP_FAILED) tst_brkm(TBROK | TERRNO, cleanup, "mmap failed"); /* for old kernels, where MAP_POPULATE doesn't work, touch each page */ tmp = 0; for (i = 0; i < fsize; i += pagesize) tmp = tmp ^ p[i]; /* prevent gcc from optimizing out loop above */ if (tmp != 0) tst_brkm(TBROK, NULL, "This line should not be reached"); if (!do_readahead) *cached = get_cached_size(); SAFE_MUNMAP(cleanup, p, fsize); *read_bytes = get_bytes_read() - read_bytes_start; if (gettimeofday(&now, NULL) == -1) tst_brkm(TBROK | TERRNO, cleanup, "gettimeofday failed"); time_end_usec = now.tv_sec * 1000000 + now.tv_usec; *usec = time_end_usec - time_start_usec; SAFE_CLOSE(cleanup, fd); }
/* read_testfile - mmap testfile and read every page. * This functions measures how many I/O and time it takes to fully * read contents of test file. * * @do_readahead: call readahead prior to reading file content? * @fname: name of file to test * @fsize: how many bytes to read/mmap * @read_bytes: returns difference of bytes read, parsed from /proc/<pid>/io * @usec: returns how many microsecond it took to go over fsize bytes * @cached: returns cached kB from /proc/meminfo */ static void read_testfile(int do_readahead, const char *fname, size_t fsize, unsigned long *read_bytes, long *usec, unsigned long *cached) { int fd; size_t i; long read_bytes_start; unsigned char *p, tmp; unsigned long time_start_usec, time_end_usec; off_t offset; struct timeval now; long readahead_size; /* use bdi limit for 4.4 and older, otherwise default to 2M */ if ((tst_kvercmp(4, 4, 0)) >= 0) readahead_size = get_device_readahead(fname); else readahead_size = 2 * 1024 * 1024; tst_resm(TINFO, "max readahead size is: %ld", readahead_size); fd = open(fname, O_RDONLY); if (fd < 0) tst_brkm(TBROK | TERRNO, cleanup, "Failed to open %s", fname); if (do_readahead) { for (i = 0; i < fsize; i += readahead_size) { TEST(readahead(fd, (off64_t) i, readahead_size)); if (TEST_RETURN != 0) break; } check_ret(0); *cached = get_cached_size(); /* offset of file shouldn't change after readahead */ offset = lseek(fd, 0, SEEK_CUR); if (offset == (off_t) - 1) tst_brkm(TBROK | TERRNO, cleanup, "lseek failed"); if (offset == 0) tst_resm(TPASS, "offset is still at 0 as expected"); else tst_resm(TFAIL, "offset has changed to: %lu", offset); } if (gettimeofday(&now, NULL) == -1) tst_brkm(TBROK | TERRNO, cleanup, "gettimeofday failed"); time_start_usec = now.tv_sec * 1000000 + now.tv_usec; read_bytes_start = get_bytes_read(); p = mmap(NULL, fsize, PROT_READ, MAP_SHARED | MAP_POPULATE, fd, 0); if (p == MAP_FAILED) tst_brkm(TBROK | TERRNO, cleanup, "mmap failed"); /* for old kernels, where MAP_POPULATE doesn't work, touch each page */ tmp = 0; for (i = 0; i < fsize; i += pagesize) tmp = tmp ^ p[i]; /* prevent gcc from optimizing out loop above */ if (tmp != 0) tst_brkm(TBROK, NULL, "This line should not be reached"); if (!do_readahead) *cached = get_cached_size(); if (munmap(p, fsize) == -1) tst_brkm(TBROK | TERRNO, cleanup, "munmap failed"); *read_bytes = get_bytes_read() - read_bytes_start; if (gettimeofday(&now, NULL) == -1) tst_brkm(TBROK | TERRNO, cleanup, "gettimeofday failed"); time_end_usec = now.tv_sec * 1000000 + now.tv_usec; *usec = time_end_usec - time_start_usec; if (close(fd) == -1) tst_brkm(TBROK | TERRNO, cleanup, "close failed"); }
static int libc_readahead(int fd, off_t offset, size_t len) { return readahead(fd, offset, len); }