This commit was manufactured by cvs2svn to create tag
[linux-2.6.git] / mm / filemap.c
index 4f2fb2c..7c4dbca 100644 (file)
@@ -685,15 +685,11 @@ void do_generic_mapping_read(struct address_space *mapping,
                             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;
@@ -701,9 +697,6 @@ void do_generic_mapping_read(struct address_space *mapping,
 
        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);
@@ -713,7 +706,7 @@ void do_generic_mapping_read(struct address_space *mapping,
        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;
@@ -728,21 +721,26 @@ void do_generic_mapping_read(struct address_space *mapping,
                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
@@ -753,12 +751,10 @@ page_ok:
                        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
@@ -805,21 +801,11 @@ readpage:
                        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);
                }
 
                /*
@@ -998,7 +984,7 @@ __generic_file_aio_read(struct kiocb *iocb, const struct iovec *iov,
                        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;
@@ -1072,7 +1058,7 @@ ssize_t generic_file_sendfile(struct file *in_file, loff_t *ppos,
        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;
@@ -1191,7 +1177,7 @@ retry_all:
         * 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?
@@ -1458,9 +1444,12 @@ err:
        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;
@@ -1520,7 +1509,6 @@ int generic_file_mmap(struct file * file, struct vm_area_struct * vma)
        vma->vm_ops = &generic_file_vm_ops;
        return 0;
 }
-EXPORT_SYMBOL(filemap_populate);
 
 /*
  * This is for filesystems which do not implement ->writepage.
@@ -1931,16 +1919,7 @@ generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov,
 
        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;
@@ -2078,8 +2057,6 @@ __generic_file_aio_write_nolock(struct kiocb *iocb, const struct iovec *iov,
        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;
@@ -2095,7 +2072,7 @@ __generic_file_aio_write_nolock(struct kiocb *iocb, const struct iovec *iov,
        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)) {
@@ -2183,7 +2160,7 @@ ssize_t generic_file_aio_write(struct kiocb *iocb, const char __user *buf,
        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);
 
@@ -2259,8 +2236,7 @@ ssize_t generic_file_writev(struct file *file, const struct iovec *iov,
 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,
@@ -2270,23 +2246,12 @@ 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;
 }