fadvise.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. /*
  2. * mm/fadvise.c
  3. *
  4. * Copyright (C) 2002, Linus Torvalds
  5. *
  6. * 11Jan2003 Andrew Morton
  7. * Initial version.
  8. */
  9. #include <linux/kernel.h>
  10. #include <linux/file.h>
  11. #include <linux/fs.h>
  12. #include <linux/mm.h>
  13. #include <linux/pagemap.h>
  14. #include <linux/backing-dev.h>
  15. #include <linux/pagevec.h>
  16. #include <linux/fadvise.h>
  17. #include <linux/writeback.h>
  18. #include <linux/syscalls.h>
  19. #include <linux/swap.h>
  20. #include <asm/unistd.h>
  21. /*
  22. * POSIX_FADV_WILLNEED could set PG_Referenced, and POSIX_FADV_NOREUSE could
  23. * deactivate the pages and clear PG_Referenced.
  24. */
  25. SYSCALL_DEFINE4(fadvise64_64, int, fd, loff_t, offset, loff_t, len, int, advice)
  26. {
  27. struct fd f = fdget(fd);
  28. struct inode *inode;
  29. struct address_space *mapping;
  30. struct backing_dev_info *bdi;
  31. loff_t endbyte; /* inclusive */
  32. pgoff_t start_index;
  33. pgoff_t end_index;
  34. unsigned long nrpages;
  35. int ret = 0;
  36. if (!f.file)
  37. return -EBADF;
  38. inode = file_inode(f.file);
  39. if (S_ISFIFO(inode->i_mode)) {
  40. ret = -ESPIPE;
  41. goto out;
  42. }
  43. mapping = f.file->f_mapping;
  44. if (!mapping || len < 0) {
  45. ret = -EINVAL;
  46. goto out;
  47. }
  48. if (IS_DAX(inode)) {
  49. switch (advice) {
  50. case POSIX_FADV_NORMAL:
  51. case POSIX_FADV_RANDOM:
  52. case POSIX_FADV_SEQUENTIAL:
  53. case POSIX_FADV_WILLNEED:
  54. case POSIX_FADV_NOREUSE:
  55. case POSIX_FADV_DONTNEED:
  56. /* no bad return value, but ignore advice */
  57. break;
  58. default:
  59. ret = -EINVAL;
  60. }
  61. goto out;
  62. }
  63. /* Careful about overflows. Len == 0 means "as much as possible" */
  64. endbyte = offset + len;
  65. if (!len || endbyte < len)
  66. endbyte = -1;
  67. else
  68. endbyte--; /* inclusive */
  69. bdi = inode_to_bdi(mapping->host);
  70. switch (advice) {
  71. case POSIX_FADV_NORMAL:
  72. f.file->f_ra.ra_pages = bdi->ra_pages;
  73. spin_lock(&f.file->f_lock);
  74. f.file->f_mode &= ~FMODE_RANDOM;
  75. spin_unlock(&f.file->f_lock);
  76. break;
  77. case POSIX_FADV_RANDOM:
  78. spin_lock(&f.file->f_lock);
  79. f.file->f_mode |= FMODE_RANDOM;
  80. spin_unlock(&f.file->f_lock);
  81. break;
  82. case POSIX_FADV_SEQUENTIAL:
  83. f.file->f_ra.ra_pages = bdi->ra_pages * 2;
  84. spin_lock(&f.file->f_lock);
  85. f.file->f_mode &= ~FMODE_RANDOM;
  86. spin_unlock(&f.file->f_lock);
  87. break;
  88. case POSIX_FADV_WILLNEED:
  89. /* First and last PARTIAL page! */
  90. start_index = offset >> PAGE_SHIFT;
  91. end_index = endbyte >> PAGE_SHIFT;
  92. /* Careful about overflow on the "+1" */
  93. nrpages = end_index - start_index + 1;
  94. if (!nrpages)
  95. nrpages = ~0UL;
  96. /*
  97. * Ignore return value because fadvise() shall return
  98. * success even if filesystem can't retrieve a hint,
  99. */
  100. force_page_cache_readahead(mapping, f.file, start_index,
  101. nrpages);
  102. break;
  103. case POSIX_FADV_NOREUSE:
  104. break;
  105. case POSIX_FADV_DONTNEED:
  106. if (!inode_write_congested(mapping->host))
  107. __filemap_fdatawrite_range(mapping, offset, endbyte,
  108. WB_SYNC_NONE);
  109. /*
  110. * First and last FULL page! Partial pages are deliberately
  111. * preserved on the expectation that it is better to preserve
  112. * needed memory than to discard unneeded memory.
  113. */
  114. start_index = (offset+(PAGE_SIZE-1)) >> PAGE_SHIFT;
  115. end_index = (endbyte >> PAGE_SHIFT);
  116. /*
  117. * The page at end_index will be inclusively discarded according
  118. * by invalidate_mapping_pages(), so subtracting 1 from
  119. * end_index means we will skip the last page. But if endbyte
  120. * is page aligned or is at the end of file, we should not skip
  121. * that page - discarding the last page is safe enough.
  122. */
  123. if ((endbyte & ~PAGE_MASK) != ~PAGE_MASK &&
  124. endbyte != inode->i_size - 1) {
  125. /* First page is tricky as 0 - 1 = -1, but pgoff_t
  126. * is unsigned, so the end_index >= start_index
  127. * check below would be true and we'll discard the whole
  128. * file cache which is not what was asked.
  129. */
  130. if (end_index == 0)
  131. break;
  132. end_index--;
  133. }
  134. if (end_index >= start_index) {
  135. unsigned long count = invalidate_mapping_pages(mapping,
  136. start_index, end_index);
  137. /*
  138. * If fewer pages were invalidated than expected then
  139. * it is possible that some of the pages were on
  140. * a per-cpu pagevec for a remote CPU. Drain all
  141. * pagevecs and try again.
  142. */
  143. if (count < (end_index - start_index + 1)) {
  144. lru_add_drain_all();
  145. invalidate_mapping_pages(mapping, start_index,
  146. end_index);
  147. }
  148. }
  149. break;
  150. default:
  151. ret = -EINVAL;
  152. }
  153. out:
  154. fdput(f);
  155. return ret;
  156. }
  157. #ifdef __ARCH_WANT_SYS_FADVISE64
  158. SYSCALL_DEFINE4(fadvise64, int, fd, loff_t, offset, size_t, len, int, advice)
  159. {
  160. return sys_fadvise64_64(fd, offset, len, advice);
  161. }
  162. #endif