Loading fs/ceph/file.c +18 −28 Original line number Original line Diff line number Diff line Loading @@ -418,7 +418,7 @@ static ssize_t ceph_sync_read(struct kiocb *iocb, struct iov_iter *i, struct page **pages; struct page **pages; u64 off = iocb->ki_pos; u64 off = iocb->ki_pos; int num_pages, ret; int num_pages, ret; size_t len = i->count; size_t len = iov_iter_count(i); dout("sync_read on file %p %llu~%u %s\n", file, off, dout("sync_read on file %p %llu~%u %s\n", file, off, (unsigned)len, (unsigned)len, Loading @@ -436,25 +436,26 @@ static ssize_t ceph_sync_read(struct kiocb *iocb, struct iov_iter *i, if (file->f_flags & O_DIRECT) { if (file->f_flags & O_DIRECT) { while (iov_iter_count(i)) { while (iov_iter_count(i)) { void __user *data = i->iov[0].iov_base + i->iov_offset; size_t start; size_t len = i->iov[0].iov_len - i->iov_offset; ssize_t n; num_pages = calc_pages_for((unsigned long)data, len); n = iov_iter_get_pages_alloc(i, &pages, INT_MAX, &start); pages = ceph_get_direct_page_vector(data, if (n < 0) num_pages, true); return n; if (IS_ERR(pages)) return PTR_ERR(pages); num_pages = (n + start + PAGE_SIZE - 1) / PAGE_SIZE; ret = striped_read(inode, off, len, ret = striped_read(inode, off, n, pages, num_pages, checkeof, pages, num_pages, checkeof, 1, (unsigned long)data & ~PAGE_MASK); 1, start); ceph_put_page_vector(pages, num_pages, true); ceph_put_page_vector(pages, num_pages, true); if (ret <= 0) if (ret <= 0) break; break; off += ret; off += ret; iov_iter_advance(i, ret); iov_iter_advance(i, ret); if (ret < len) if (ret < n) break; break; } } } else { } else { Loading @@ -466,25 +467,14 @@ static ssize_t ceph_sync_read(struct kiocb *iocb, struct iov_iter *i, num_pages, checkeof, 0, 0); num_pages, checkeof, 0, 0); if (ret > 0) { if (ret > 0) { int l, k = 0; int l, k = 0; size_t left = len = ret; size_t left = ret; while (left) { while (left) { void __user *data = i->iov[0].iov_base int copy = min_t(size_t, PAGE_SIZE, left); + i->iov_offset; l = copy_page_to_iter(pages[k++], 0, copy, i); l = min(i->iov[0].iov_len - i->iov_offset, off += l; left); left -= l; if (l < copy) ret = ceph_copy_page_vector_to_user(&pages[k], data, off, l); if (ret > 0) { iov_iter_advance(i, ret); left -= ret; off += ret; k = calc_pages_for(iocb->ki_pos, len - left + 1) - 1; BUG_ON(k >= num_pages && left); } else break; break; } } } } Loading include/linux/ceph/libceph.h +0 −2 Original line number Original line Diff line number Diff line Loading @@ -222,8 +222,6 @@ extern void ceph_copy_to_page_vector(struct page **pages, extern void ceph_copy_from_page_vector(struct page **pages, extern void ceph_copy_from_page_vector(struct page **pages, void *data, void *data, loff_t off, size_t len); loff_t off, size_t len); extern int ceph_copy_page_vector_to_user(struct page **pages, void __user *data, loff_t off, size_t len); extern void ceph_zero_page_vector_range(int off, int len, struct page **pages); extern void ceph_zero_page_vector_range(int off, int len, struct page **pages); Loading net/ceph/pagevec.c +4 −31 Original line number Original line Diff line number Diff line Loading @@ -53,6 +53,9 @@ void ceph_put_page_vector(struct page **pages, int num_pages, bool dirty) set_page_dirty_lock(pages[i]); set_page_dirty_lock(pages[i]); put_page(pages[i]); put_page(pages[i]); } } if (is_vmalloc_addr(pages)) vfree(pages); else kfree(pages); kfree(pages); } } EXPORT_SYMBOL(ceph_put_page_vector); EXPORT_SYMBOL(ceph_put_page_vector); Loading Loading @@ -164,36 +167,6 @@ void ceph_copy_from_page_vector(struct page **pages, } } EXPORT_SYMBOL(ceph_copy_from_page_vector); EXPORT_SYMBOL(ceph_copy_from_page_vector); /* * copy user data from a page vector into a user pointer */ int ceph_copy_page_vector_to_user(struct page **pages, void __user *data, loff_t off, size_t len) { int i = 0; int po = off & ~PAGE_CACHE_MASK; int left = len; int l, bad; while (left > 0) { l = min_t(int, left, PAGE_CACHE_SIZE-po); bad = copy_to_user(data, page_address(pages[i]) + po, l); if (bad == l) return -EFAULT; data += l - bad; left -= l - bad; if (po) { po += l - bad; if (po == PAGE_CACHE_SIZE) po = 0; } i++; } return len; } EXPORT_SYMBOL(ceph_copy_page_vector_to_user); /* /* * Zero an extent within a page vector. Offset is relative to the * Zero an extent within a page vector. Offset is relative to the * start of the first page. * start of the first page. Loading Loading
fs/ceph/file.c +18 −28 Original line number Original line Diff line number Diff line Loading @@ -418,7 +418,7 @@ static ssize_t ceph_sync_read(struct kiocb *iocb, struct iov_iter *i, struct page **pages; struct page **pages; u64 off = iocb->ki_pos; u64 off = iocb->ki_pos; int num_pages, ret; int num_pages, ret; size_t len = i->count; size_t len = iov_iter_count(i); dout("sync_read on file %p %llu~%u %s\n", file, off, dout("sync_read on file %p %llu~%u %s\n", file, off, (unsigned)len, (unsigned)len, Loading @@ -436,25 +436,26 @@ static ssize_t ceph_sync_read(struct kiocb *iocb, struct iov_iter *i, if (file->f_flags & O_DIRECT) { if (file->f_flags & O_DIRECT) { while (iov_iter_count(i)) { while (iov_iter_count(i)) { void __user *data = i->iov[0].iov_base + i->iov_offset; size_t start; size_t len = i->iov[0].iov_len - i->iov_offset; ssize_t n; num_pages = calc_pages_for((unsigned long)data, len); n = iov_iter_get_pages_alloc(i, &pages, INT_MAX, &start); pages = ceph_get_direct_page_vector(data, if (n < 0) num_pages, true); return n; if (IS_ERR(pages)) return PTR_ERR(pages); num_pages = (n + start + PAGE_SIZE - 1) / PAGE_SIZE; ret = striped_read(inode, off, len, ret = striped_read(inode, off, n, pages, num_pages, checkeof, pages, num_pages, checkeof, 1, (unsigned long)data & ~PAGE_MASK); 1, start); ceph_put_page_vector(pages, num_pages, true); ceph_put_page_vector(pages, num_pages, true); if (ret <= 0) if (ret <= 0) break; break; off += ret; off += ret; iov_iter_advance(i, ret); iov_iter_advance(i, ret); if (ret < len) if (ret < n) break; break; } } } else { } else { Loading @@ -466,25 +467,14 @@ static ssize_t ceph_sync_read(struct kiocb *iocb, struct iov_iter *i, num_pages, checkeof, 0, 0); num_pages, checkeof, 0, 0); if (ret > 0) { if (ret > 0) { int l, k = 0; int l, k = 0; size_t left = len = ret; size_t left = ret; while (left) { while (left) { void __user *data = i->iov[0].iov_base int copy = min_t(size_t, PAGE_SIZE, left); + i->iov_offset; l = copy_page_to_iter(pages[k++], 0, copy, i); l = min(i->iov[0].iov_len - i->iov_offset, off += l; left); left -= l; if (l < copy) ret = ceph_copy_page_vector_to_user(&pages[k], data, off, l); if (ret > 0) { iov_iter_advance(i, ret); left -= ret; off += ret; k = calc_pages_for(iocb->ki_pos, len - left + 1) - 1; BUG_ON(k >= num_pages && left); } else break; break; } } } } Loading
include/linux/ceph/libceph.h +0 −2 Original line number Original line Diff line number Diff line Loading @@ -222,8 +222,6 @@ extern void ceph_copy_to_page_vector(struct page **pages, extern void ceph_copy_from_page_vector(struct page **pages, extern void ceph_copy_from_page_vector(struct page **pages, void *data, void *data, loff_t off, size_t len); loff_t off, size_t len); extern int ceph_copy_page_vector_to_user(struct page **pages, void __user *data, loff_t off, size_t len); extern void ceph_zero_page_vector_range(int off, int len, struct page **pages); extern void ceph_zero_page_vector_range(int off, int len, struct page **pages); Loading
net/ceph/pagevec.c +4 −31 Original line number Original line Diff line number Diff line Loading @@ -53,6 +53,9 @@ void ceph_put_page_vector(struct page **pages, int num_pages, bool dirty) set_page_dirty_lock(pages[i]); set_page_dirty_lock(pages[i]); put_page(pages[i]); put_page(pages[i]); } } if (is_vmalloc_addr(pages)) vfree(pages); else kfree(pages); kfree(pages); } } EXPORT_SYMBOL(ceph_put_page_vector); EXPORT_SYMBOL(ceph_put_page_vector); Loading Loading @@ -164,36 +167,6 @@ void ceph_copy_from_page_vector(struct page **pages, } } EXPORT_SYMBOL(ceph_copy_from_page_vector); EXPORT_SYMBOL(ceph_copy_from_page_vector); /* * copy user data from a page vector into a user pointer */ int ceph_copy_page_vector_to_user(struct page **pages, void __user *data, loff_t off, size_t len) { int i = 0; int po = off & ~PAGE_CACHE_MASK; int left = len; int l, bad; while (left > 0) { l = min_t(int, left, PAGE_CACHE_SIZE-po); bad = copy_to_user(data, page_address(pages[i]) + po, l); if (bad == l) return -EFAULT; data += l - bad; left -= l - bad; if (po) { po += l - bad; if (po == PAGE_CACHE_SIZE) po = 0; } i++; } return len; } EXPORT_SYMBOL(ceph_copy_page_vector_to_user); /* /* * Zero an extent within a page vector. Offset is relative to the * Zero an extent within a page vector. Offset is relative to the * start of the first page. * start of the first page. Loading