From 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sat, 16 Apr 2005 15:20:36 -0700 Subject: Linux-2.6.12-rc2 Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip! --- mm/fadvise.c | 111 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 mm/fadvise.c (limited to 'mm/fadvise.c') diff --git a/mm/fadvise.c b/mm/fadvise.c new file mode 100644 index 00000000000..57264d74b8b --- /dev/null +++ b/mm/fadvise.c @@ -0,0 +1,111 @@ +/* + * mm/fadvise.c + * + * Copyright (C) 2002, Linus Torvalds + * + * 11Jan2003 akpm@digeo.com + * Initial version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* + * POSIX_FADV_WILLNEED could set PG_Referenced, and POSIX_FADV_NOREUSE could + * deactivate the pages and clear PG_Referenced. + */ +asmlinkage long sys_fadvise64_64(int fd, loff_t offset, loff_t len, int advice) +{ + struct file *file = fget(fd); + struct address_space *mapping; + struct backing_dev_info *bdi; + loff_t endbyte; + pgoff_t start_index; + pgoff_t end_index; + unsigned long nrpages; + int ret = 0; + + if (!file) + return -EBADF; + + mapping = file->f_mapping; + if (!mapping || len < 0) { + ret = -EINVAL; + goto out; + } + + /* Careful about overflows. Len == 0 means "as much as possible" */ + endbyte = offset + len; + if (!len || endbyte < len) + endbyte = -1; + + bdi = mapping->backing_dev_info; + + switch (advice) { + case POSIX_FADV_NORMAL: + file->f_ra.ra_pages = bdi->ra_pages; + break; + case POSIX_FADV_RANDOM: + file->f_ra.ra_pages = 0; + break; + case POSIX_FADV_SEQUENTIAL: + file->f_ra.ra_pages = bdi->ra_pages * 2; + break; + case POSIX_FADV_WILLNEED: + case POSIX_FADV_NOREUSE: + if (!mapping->a_ops->readpage) { + ret = -EINVAL; + break; + } + + /* First and last PARTIAL page! */ + start_index = offset >> PAGE_CACHE_SHIFT; + end_index = (endbyte-1) >> PAGE_CACHE_SHIFT; + + /* Careful about overflow on the "+1" */ + nrpages = end_index - start_index + 1; + if (!nrpages) + nrpages = ~0UL; + + ret = force_page_cache_readahead(mapping, file, + start_index, + max_sane_readahead(nrpages)); + if (ret > 0) + ret = 0; + break; + case POSIX_FADV_DONTNEED: + if (!bdi_write_congested(mapping->backing_dev_info)) + filemap_flush(mapping); + + /* First and last FULL page! */ + start_index = (offset + (PAGE_CACHE_SIZE-1)) >> PAGE_CACHE_SHIFT; + end_index = (endbyte >> PAGE_CACHE_SHIFT); + + if (end_index > start_index) + invalidate_mapping_pages(mapping, start_index, end_index-1); + break; + default: + ret = -EINVAL; + } +out: + fput(file); + return ret; +} + +#ifdef __ARCH_WANT_SYS_FADVISE64 + +asmlinkage long sys_fadvise64(int fd, loff_t offset, size_t len, int advice) +{ + return sys_fadvise64_64(fd, offset, len, advice); +} + +#endif -- cgit v1.2.3