Commit 2fc0873f authored by Linus Torvalds's avatar Linus Torvalds

Fix fixed fadvice length handling

 - Correctly handle wraparound on offset+len
 - fix FADV_WILLNEED handling of non-page-aligned (offset+len)

Let's hope we don't need to fix the fixed fix.
parent 61a948c4
......@@ -25,8 +25,10 @@ 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)
......@@ -38,8 +40,10 @@ asmlinkage long sys_fadvise64_64(int fd, loff_t offset, loff_t len, int advice)
goto out;
}
if (len == 0) /* 0 == "all data following offset" */
len = -1;
/* Careful about overflows. Len == 0 means "as much as possible" */
endbyte = offset + len;
if (!len || endbyte < len)
endbyte = -1;
bdi = mapping->backing_dev_info;
......@@ -59,18 +63,32 @@ asmlinkage long sys_fadvise64_64(int fd, loff_t offset, loff_t len, int advice)
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,
offset >> PAGE_CACHE_SHIFT,
max_sane_readahead(len >> PAGE_CACHE_SHIFT));
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);
start_index = (offset + PAGE_CACHE_SIZE-1) >> PAGE_CACHE_SHIFT;
end_index = ((offset + len) >> PAGE_CACHE_SHIFT) - 1;
invalidate_mapping_pages(mapping, start_index, end_index);
/* 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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment