Beispiel #1
0
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);
}
Beispiel #2
0
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;
}
Beispiel #3
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;
}
Beispiel #6
0
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);
}
Beispiel #9
0
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
}
Beispiel #11
0
/* 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);
}
Beispiel #12
0
/* 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");
}
Beispiel #13
0
static int libc_readahead(int fd, off_t offset, size_t len)
{
	return readahead(fd, offset, len);
}