]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Merge branch 'work.iov_iter' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 9 May 2017 16:01:21 +0000 (09:01 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 9 May 2017 16:01:21 +0000 (09:01 -0700)
Pull vfs fix from Al Viro:
 "Braino fix for iov_iter_revert() misuse"

* 'work.iov_iter' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
  fix braino in generic_file_read_iter()

1  2 
lib/iov_iter.c
mm/filemap.c

diff --combined lib/iov_iter.c
index ae82d9cea5533647181cea7b6c3d005838bfc0f8,fc9fb29d00eba257c99fa63de7c990a80bf075a4..f835964c9485f147699609bf2c2dc1ffecb8833b
@@@ -413,7 -413,7 +413,7 @@@ void iov_iter_init(struct iov_iter *i, 
                        size_t count)
  {
        /* It will get better.  Eventually... */
 -      if (segment_eq(get_fs(), KERNEL_DS)) {
 +      if (uaccess_kernel()) {
                direction |= ITER_KVEC;
                i->type = direction;
                i->kvec = (struct kvec *)iov;
@@@ -604,7 -604,7 +604,7 @@@ size_t copy_from_iter_nocache(void *add
                return 0;
        }
        iterate_and_advance(i, bytes, v,
 -              __copy_from_user_nocache((to += v.iov_len) - v.iov_len,
 +              __copy_from_user_inatomic_nocache((to += v.iov_len) - v.iov_len,
                                         v.iov_base, v.iov_len),
                memcpy_from_page((to += v.bv_len) - v.bv_len, v.bv_page,
                                 v.bv_offset, v.bv_len),
@@@ -625,7 -625,7 +625,7 @@@ bool copy_from_iter_full_nocache(void *
        if (unlikely(i->count < bytes))
                return false;
        iterate_all_kinds(i, bytes, v, ({
 -              if (__copy_from_user_nocache((to += v.iov_len) - v.iov_len,
 +              if (__copy_from_user_inatomic_nocache((to += v.iov_len) - v.iov_len,
                                             v.iov_base, v.iov_len))
                        return false;
                0;}),
@@@ -790,6 -790,8 +790,8 @@@ void iov_iter_revert(struct iov_iter *i
  {
        if (!unroll)
                return;
+       if (WARN_ON(unroll > MAX_RW_COUNT))
+               return;
        i->count += unroll;
        if (unlikely(i->type & ITER_PIPE)) {
                struct pipe_inode_info *pipe = i->pipe;
                while (1) {
                        size_t n = off - pipe->bufs[idx].offset;
                        if (unroll < n) {
 -                              off -= (n - unroll);
 +                              off -= unroll;
                                break;
                        }
                        unroll -= n;
@@@ -1028,7 -1030,10 +1030,7 @@@ EXPORT_SYMBOL(iov_iter_get_pages)
  
  static struct page **get_pages_array(size_t n)
  {
 -      struct page **p = kmalloc(n * sizeof(struct page *), GFP_KERNEL);
 -      if (!p)
 -              p = vmalloc(n * sizeof(struct page *));
 -      return p;
 +      return kvmalloc_array(n, sizeof(struct page *), GFP_KERNEL);
  }
  
  static ssize_t pipe_get_pages_alloc(struct iov_iter *i,
diff --combined mm/filemap.c
index b7b973b47d8d9c498d9cafc83bfa2a21ea33e757,d6e67be1802ef5290a3d49ebbc8464eaf0353a90..6f1be573a5e60fbb0c4a6cbcf85df9b32b0fc673
@@@ -519,7 -519,7 +519,7 @@@ EXPORT_SYMBOL(filemap_write_and_wait)
   *
   * Write out and wait upon file offsets lstart->lend, inclusive.
   *
 - * Note that `lend' is inclusive (describes the last byte to be written) so
 + * Note that @lend is inclusive (describes the last byte to be written) so
   * that this function can be used to write to the very end-of-file (end = -1).
   */
  int filemap_write_and_wait_range(struct address_space *mapping,
@@@ -1277,14 -1277,12 +1277,14 @@@ EXPORT_SYMBOL(find_lock_entry)
   *
   * PCG flags modify how the page is returned.
   *
 - * FGP_ACCESSED: the page will be marked accessed
 - * FGP_LOCK: Page is return locked
 - * FGP_CREAT: If page is not present then a new page is allocated using
 - *            @gfp_mask and added to the page cache and the VM's LRU
 - *            list. The page is returned locked and with an increased
 - *            refcount. Otherwise, %NULL is returned.
 + * @fgp_flags can be:
 + *
 + * - FGP_ACCESSED: the page will be marked accessed
 + * - FGP_LOCK: Page is return locked
 + * - FGP_CREAT: If page is not present then a new page is allocated using
 + *   @gfp_mask and added to the page cache and the VM's LRU
 + *   list. The page is returned locked and with an increased
 + *   refcount. Otherwise, NULL is returned.
   *
   * If FGP_LOCK or FGP_CREAT are specified then the function may sleep even
   * if the GFP flags specified for FGP_CREAT are atomic.
@@@ -2050,7 -2048,7 +2050,7 @@@ generic_file_read_iter(struct kiocb *io
                        iocb->ki_pos += retval;
                        count -= retval;
                }
-               iov_iter_revert(iter, iov_iter_count(iter) - count);
+               iov_iter_revert(iter, count - iov_iter_count(iter));
  
                /*
                 * Btrfs can have a short DIO read if we encounter
@@@ -2204,12 -2202,12 +2204,12 @@@ int filemap_fault(struct vm_fault *vmf
        struct file_ra_state *ra = &file->f_ra;
        struct inode *inode = mapping->host;
        pgoff_t offset = vmf->pgoff;
 +      pgoff_t max_off;
        struct page *page;
 -      loff_t size;
        int ret = 0;
  
 -      size = round_up(i_size_read(inode), PAGE_SIZE);
 -      if (offset >= size >> PAGE_SHIFT)
 +      max_off = DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE);
 +      if (unlikely(offset >= max_off))
                return VM_FAULT_SIGBUS;
  
        /*
@@@ -2258,8 -2256,8 +2258,8 @@@ retry_find
         * Found the page and have a reference on it.
         * We must recheck i_size under page lock.
         */
 -      size = round_up(i_size_read(inode), PAGE_SIZE);
 -      if (unlikely(offset >= size >> PAGE_SHIFT)) {
 +      max_off = DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE);
 +      if (unlikely(offset >= max_off)) {
                unlock_page(page);
                put_page(page);
                return VM_FAULT_SIGBUS;
@@@ -2325,7 -2323,7 +2325,7 @@@ void filemap_map_pages(struct vm_fault 
        struct file *file = vmf->vma->vm_file;
        struct address_space *mapping = file->f_mapping;
        pgoff_t last_pgoff = start_pgoff;
 -      loff_t size;
 +      unsigned long max_idx;
        struct page *head, *page;
  
        rcu_read_lock();
@@@ -2371,8 -2369,8 +2371,8 @@@ repeat
                if (page->mapping != mapping || !PageUptodate(page))
                        goto unlock;
  
 -              size = round_up(i_size_read(mapping->host), PAGE_SIZE);
 -              if (page->index >= size >> PAGE_SHIFT)
 +              max_idx = DIV_ROUND_UP(i_size_read(mapping->host), PAGE_SIZE);
 +              if (page->index >= max_idx)
                        goto unlock;
  
                if (file->f_ra.mmap_miss > 0)
@@@ -2720,16 -2718,18 +2720,16 @@@ generic_file_direct_write(struct kiocb 
         * about to write.  We do this *before* the write so that we can return
         * without clobbering -EIOCBQUEUED from ->direct_IO().
         */
 -      if (mapping->nrpages) {
 -              written = invalidate_inode_pages2_range(mapping,
 +      written = invalidate_inode_pages2_range(mapping,
                                        pos >> PAGE_SHIFT, end);
 -              /*
 -               * If a page can not be invalidated, return 0 to fall back
 -               * to buffered write.
 -               */
 -              if (written) {
 -                      if (written == -EBUSY)
 -                              return 0;
 -                      goto out;
 -              }
 +      /*
 +       * If a page can not be invalidated, return 0 to fall back
 +       * to buffered write.
 +       */
 +      if (written) {
 +              if (written == -EBUSY)
 +                      return 0;
 +              goto out;
        }
  
        written = mapping->a_ops->direct_IO(iocb, from);
         * so we don't support it 100%.  If this invalidation
         * fails, tough, the write still worked...
         */
 -      if (mapping->nrpages) {
 -              invalidate_inode_pages2_range(mapping,
 -                                            pos >> PAGE_SHIFT, end);
 -      }
 +      invalidate_inode_pages2_range(mapping,
 +                              pos >> PAGE_SHIFT, end);
  
        if (written > 0) {
                pos += written;
@@@ -2791,6 -2793,12 +2791,6 @@@ ssize_t generic_perform_write(struct fi
        ssize_t written = 0;
        unsigned int flags = 0;
  
 -      /*
 -       * Copies from kernel address space cannot fail (NFSD is a big user).
 -       */
 -      if (!iter_is_iovec(i))
 -              flags |= AOP_FLAG_UNINTERRUPTIBLE;
 -
        do {
                struct page *page;
                unsigned long offset;   /* Offset into pagecache page */
@@@ -2992,7 -3000,7 +2992,7 @@@ EXPORT_SYMBOL(generic_file_write_iter)
   * @gfp_mask: memory allocation flags (and I/O mode)
   *
   * The address_space is to try to release any data against the page
 - * (presumably at page->private).  If the release was successful, return `1'.
 + * (presumably at page->private).  If the release was successful, return '1'.
   * Otherwise return zero.
   *
   * This may also be called if PG_fscache is set on a page, indicating that the