struct file *filp,
loff_t *ppos,
read_descriptor_t *desc,
- read_actor_t actor)
+ read_actor_t actor,
+ int nonblock)
{
struct inode *inode = mapping->host;
- unsigned long index;
- unsigned long end_index;
- unsigned long offset;
- unsigned long req_size;
- unsigned long next_index;
- unsigned long prev_index;
+ unsigned long index, end_index, offset;
loff_t isize;
struct page *cached_page;
int error;
cached_page = NULL;
index = *ppos >> PAGE_CACHE_SHIFT;
- next_index = index;
- prev_index = ra.prev_page;
- req_size = (desc->count + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
offset = *ppos & ~PAGE_CACHE_MASK;
isize = i_size_read(inode);
end_index = (isize - 1) >> PAGE_CACHE_SHIFT;
for (;;) {
struct page *page;
- unsigned long ret_size, nr, ret;
+ unsigned long nr, ret;
/* nr is the maximum number of bytes to copy from this page */
nr = PAGE_CACHE_SIZE;
nr = nr - offset;
cond_resched();
- if (index == next_index && req_size) {
- ret_size = page_cache_readahead(mapping, &ra,
- filp, index, req_size);
- next_index += ret_size;
- req_size -= ret_size;
- }
+ page_cache_readahead(mapping, &ra, filp, index);
find_page:
page = find_get_page(mapping, index);
if (unlikely(page == NULL)) {
+ if (nonblock) {
+ desc->error = -EWOULDBLOCKIO;
+ break;
+ }
handle_ra_miss(mapping, &ra, index);
goto no_cached_page;
}
- if (!PageUptodate(page))
+ if (!PageUptodate(page)) {
+ if (nonblock) {
+ page_cache_release(page);
+ desc->error = -EWOULDBLOCKIO;
+ break;
+ }
goto page_not_up_to_date;
+ }
page_ok:
/* If users can be writing to this page using arbitrary
flush_dcache_page(page);
/*
- * When (part of) the same page is read multiple times
- * in succession, only mark it as accessed the first time.
+ * Mark the page accessed if we read the beginning.
*/
- if (prev_index != index)
+ if (!offset)
mark_page_accessed(page);
- prev_index = index;
/*
* Ok, we have the page, and it's up-to-date, so
goto readpage_error;
if (!PageUptodate(page)) {
- lock_page(page);
+ wait_on_page_locked(page);
if (!PageUptodate(page)) {
- if (page->mapping == NULL) {
- /*
- * invalidate_inode_pages got it
- */
- unlock_page(page);
- page_cache_release(page);
- goto find_page;
- }
- unlock_page(page);
error = -EIO;
goto readpage_error;
}
- unlock_page(page);
}
/*
if (desc.count == 0)
continue;
desc.error = 0;
- do_generic_file_read(filp,ppos,&desc,file_read_actor);
+ do_generic_file_read(filp,ppos,&desc,file_read_actor,0);
retval += desc.written;
if (!retval) {
retval = desc.error;
desc.arg.data = target;
desc.error = 0;
- do_generic_file_read(in_file, ppos, &desc, actor);
+ do_generic_file_read(in_file, ppos, &desc, actor, 0);
if (desc.written)
return desc.written;
return desc.error;
* For sequential accesses, we use the generic readahead logic.
*/
if (VM_SequentialReadHint(area))
- page_cache_readahead(mapping, ra, file, pgoff, 1);
+ page_cache_readahead(mapping, ra, file, pgoff);
/*
* Do we have something in the page cache already?
return NULL;
}
-int filemap_populate(struct vm_area_struct *vma, unsigned long addr,
- unsigned long len, pgprot_t prot, unsigned long pgoff,
- int nonblock)
+static int filemap_populate(struct vm_area_struct *vma,
+ unsigned long addr,
+ unsigned long len,
+ pgprot_t prot,
+ unsigned long pgoff,
+ int nonblock)
{
struct file *file = vma->vm_file;
struct address_space *mapping = file->f_mapping;
vma->vm_ops = &generic_file_vm_ops;
return 0;
}
-EXPORT_SYMBOL(filemap_populate);
/*
* This is for filesystems which do not implement ->writepage.
pagevec_init(&lru_pvec, 0);
- /*
- * handle partial DIO write. Adjust cur_iov if needed.
- */
- if (likely(nr_segs == 1))
- buf = iov->iov_base + written;
- else {
- filemap_set_next_iovec(&cur_iov, &iov_base, written);
- buf = iov->iov_base + iov_base;
- }
-
+ buf = iov->iov_base + written; /* handle partial DIO write */
do {
unsigned long index;
unsigned long offset;
count = ocount;
pos = *ppos;
- vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE);
-
/* We can write back this queue in page reclaim */
current->backing_dev_info = mapping->backing_dev_info;
written = 0;
if (err)
goto out;
- inode_update_time(inode, 1);
+ inode_update_time(inode, file->f_vfsmnt, 1);
/* coalesce the iovecs and go direct-to-BIO for O_DIRECT */
if (unlikely(file->f_flags & O_DIRECT)) {
BUG_ON(iocb->ki_pos != pos);
down(&inode->i_sem);
- ret = __generic_file_aio_write_nolock(iocb, &local_iov, 1,
+ ret = generic_file_aio_write_nolock(iocb, &local_iov, 1,
&iocb->ki_pos);
up(&inode->i_sem);
EXPORT_SYMBOL(generic_file_writev);
/*
- * Called under i_sem for writes to S_ISREG files. Returns -EIO if something
- * went wrong during pagecache shootdown.
+ * Called under i_sem for writes to S_ISREG files
*/
ssize_t
generic_file_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
struct address_space *mapping = file->f_mapping;
ssize_t retval;
- /*
- * If it's a write, unmap all mmappings of the file up-front. This
- * will cause any pte dirty bits to be propagated into the pageframes
- * for the subsequent filemap_write_and_wait().
- */
- if (rw == WRITE && mapping_mapped(mapping))
- unmap_mapping_range(mapping, 0, -1, 0);
-
retval = filemap_write_and_wait(mapping);
if (retval == 0) {
retval = mapping->a_ops->direct_IO(rw, iocb, iov,
offset, nr_segs);
- if (rw == WRITE && mapping->nrpages) {
- int err = invalidate_inode_pages2(mapping);
- if (err)
- retval = err;
- }
+ if (rw == WRITE && mapping->nrpages)
+ invalidate_inode_pages2(mapping);
}
return retval;
}