/* * mm/fadvise.c * * Copyright (C) 2002, Linus Torvalds * * 11Jan2003 akpm@digeo.com * Initial version. */ #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. */ long sys_fadvise64(int fd, loff_t offset, size_t len, int advice) { struct file *file = fget(fd); struct inode *inode; struct address_space *mapping; struct backing_dev_info *bdi; int ret = 0; if (!file) return -EBADF; inode = file->f_dentry->d_inode; mapping = inode->i_mapping; if (!mapping) { ret = -EINVAL; goto out; } 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; } ret = do_page_cache_readahead(mapping, file, offset >> PAGE_CACHE_SHIFT, max_sane_readahead(len >> PAGE_CACHE_SHIFT)); if (ret > 0) ret = 0; break; case POSIX_FADV_DONTNEED: if (!bdi_write_congested(mapping->backing_dev_info)) filemap_flush(mapping); invalidate_mapping_pages(mapping, offset >> PAGE_CACHE_SHIFT, (len >> PAGE_CACHE_SHIFT) + 1); break; default: ret = -EINVAL; } out: fput(file); return ret; }