Merge tag 'pull-work.iov_iter-rebased' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 9 Aug 2022 03:04:35 +0000 (20:04 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 9 Aug 2022 03:04:35 +0000 (20:04 -0700)
Pull more iov_iter updates from Al Viro:

 - more new_sync_{read,write}() speedups - ITER_UBUF introduction

 - ITER_PIPE cleanups

 - unification of iov_iter_get_pages/iov_iter_get_pages_alloc and
   switching them to advancing semantics

 - making ITER_PIPE take high-order pages without splitting them

 - handling copy_page_from_iter() for high-order pages properly

* tag 'pull-work.iov_iter-rebased' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (32 commits)
  fix copy_page_from_iter() for compound destinations
  hugetlbfs: copy_page_to_iter() can deal with compound pages
  copy_page_to_iter(): don't split high-order page in case of ITER_PIPE
  expand those iov_iter_advance()...
  pipe_get_pages(): switch to append_pipe()
  get rid of non-advancing variants
  ceph: switch the last caller of iov_iter_get_pages_alloc()
  9p: convert to advancing variant of iov_iter_get_pages_alloc()
  af_alg_make_sg(): switch to advancing variant of iov_iter_get_pages()
  iter_to_pipe(): switch to advancing variant of iov_iter_get_pages()
  block: convert to advancing variants of iov_iter_get_pages{,_alloc}()
  iov_iter: advancing variants of iov_iter_get_pages{,_alloc}()
  iov_iter: saner helper for page array allocation
  fold __pipe_get_pages() into pipe_get_pages()
  ITER_XARRAY: don't open-code DIV_ROUND_UP()
  unify the rest of iov_iter_get_pages()/iov_iter_get_pages_alloc() guts
  unify xarray_get_pages() and xarray_get_pages_alloc()
  unify pipe_get_pages() and pipe_get_pages_alloc()
  iov_iter_get_pages(): sanity-check arguments
  iov_iter_get_pages_alloc(): lift freeing pages array on failure exits into wrapper
  ...

1  2 
fs/cifs/file.c
fs/cifs/misc.c
fs/fuse/file.c
fs/gfs2/file.c
fs/hugetlbfs/inode.c
mm/shmem.c
net/9p/client.c
net/9p/trans_virtio.c

diff --cc fs/cifs/file.c
Simple merge
diff --cc fs/cifs/misc.c
Simple merge
diff --cc fs/fuse/file.c
Simple merge
diff --cc fs/gfs2/file.c
Simple merge
@@@ -282,38 -284,10 +282,9 @@@ hugetlb_get_unmapped_area(struct file *
  }
  #endif
  
- static size_t
- hugetlbfs_read_actor(struct page *page, unsigned long offset,
-                       struct iov_iter *to, unsigned long size)
- {
-       size_t copied = 0;
-       int i, chunksize;
-       /* Find which 4k chunk and offset with in that chunk */
-       i = offset >> PAGE_SHIFT;
-       offset = offset & ~PAGE_MASK;
-       while (size) {
-               size_t n;
-               chunksize = PAGE_SIZE;
-               if (offset)
-                       chunksize -= offset;
-               if (chunksize > size)
-                       chunksize = size;
-               n = copy_page_to_iter(&page[i], offset, chunksize, to);
-               copied += n;
-               if (n != chunksize)
-                       return copied;
-               offset = 0;
-               size -= chunksize;
-               i++;
-       }
-       return copied;
- }
  /*
   * Support for read() - Find the page attached to f_mapping and copy out the
 - * data. Its *very* similar to generic_file_buffered_read(), we can't use that
 - * since it has PAGE_SIZE assumptions.
 + * data. This provides functionality similar to filemap_read().
   */
  static ssize_t hugetlbfs_read_iter(struct kiocb *iocb, struct iov_iter *to)
  {
diff --cc mm/shmem.c
Simple merge
diff --cc net/9p/client.c
@@@ -1528,32 -1526,34 +1530,34 @@@ p9_client_read_once(struct p9_fid *fid
        }
  
        *err = p9pdu_readf(&req->rc, clnt->proto_version,
-                          "D", &count, &dataptr);
+                          "D", &received, &dataptr);
        if (*err) {
+               if (!non_zc)
+                       iov_iter_revert(to, count - iov_iter_count(to));
                trace_9p_protocol_dump(clnt, &req->rc);
 -              p9_tag_remove(clnt, req);
 +              p9_req_put(clnt, req);
                return 0;
        }
-       if (rsize < count) {
-               pr_err("bogus RREAD count (%d > %d)\n", count, rsize);
-               count = rsize;
+       if (rsize < received) {
+               pr_err("bogus RREAD count (%d > %d)\n", received, rsize);
+               received = rsize;
        }
  
        p9_debug(P9_DEBUG_9P, "<<< RREAD count %d\n", count);
  
        if (non_zc) {
-               int n = copy_to_iter(dataptr, count, to);
+               int n = copy_to_iter(dataptr, received, to);
  
-               if (n != count) {
+               if (n != received) {
                        *err = -EFAULT;
 -                      p9_tag_remove(clnt, req);
 +                      p9_req_put(clnt, req);
                        return n;
                }
        } else {
-               iov_iter_advance(to, count);
+               iov_iter_revert(to, count - received - iov_iter_count(to));
        }
 -      p9_tag_remove(clnt, req);
 +      p9_req_put(clnt, req);
-       return count;
+       return received;
  }
  EXPORT_SYMBOL(p9_client_read_once);
  
@@@ -1592,23 -1594,24 +1598,24 @@@ p9_client_write(struct p9_fid *fid, u6
                        break;
                }
  
-               *err = p9pdu_readf(&req->rc, clnt->proto_version, "d", &count);
+               *err = p9pdu_readf(&req->rc, clnt->proto_version, "d", &written);
                if (*err) {
+                       iov_iter_revert(from, count - iov_iter_count(from));
                        trace_9p_protocol_dump(clnt, &req->rc);
 -                      p9_tag_remove(clnt, req);
 +                      p9_req_put(clnt, req);
                        break;
                }
-               if (rsize < count) {
-                       pr_err("bogus RWRITE count (%d > %d)\n", count, rsize);
-                       count = rsize;
+               if (rsize < written) {
+                       pr_err("bogus RWRITE count (%d > %d)\n", written, rsize);
+                       written = rsize;
                }
  
                p9_debug(P9_DEBUG_9P, "<<< RWRITE count %d\n", count);
  
 -              p9_tag_remove(clnt, req);
 +              p9_req_put(clnt, req);
-               iov_iter_advance(from, count);
-               total += count;
-               offset += count;
+               iov_iter_revert(from, count - written - iov_iter_count(from));
+               total += written;
+               offset += written;
        }
        return total;
  }
Simple merge