[Devel] [PATCH RHEL7 COMMIT] fs/ceph: honor kernel direct aio changes v2

Konstantin Khorenko khorenko at virtuozzo.com
Wed Jan 11 02:44:04 PST 2017


The commit is pushed to "branch-rh7-3.10.0-514.vz7.27.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-514.vz7.27.8
------>
commit dc5b3fbb992470c36ea83967aab4945648a980c0
Author: Dmitry Monakhov <dmonakhov at openvz.org>
Date:   Wed Jan 11 14:44:04 2017 +0400

    fs/ceph: honor kernel direct aio changes v2
    
    Base patches:
    fs/ceph: honor kernel direct aio changes
    fs/ceph: add BUG_ON to iov_iter access
    
    Changes: replace opencoded iter to iovec coversion with propper helper.
    
    This is done in the scope of fixing CEPH compilation after rebase to RHEL7.3.
    
    https://jira.sw.ru/browse/PSBM-54817
    
    Signed-off-by: Dmitry Monakhov <dmonakhov at openvz.org>
---
 fs/ceph/file.c | 30 ++++++++++++++++--------------
 1 file changed, 16 insertions(+), 14 deletions(-)

diff --git a/fs/ceph/file.c b/fs/ceph/file.c
index 82676fa..0b72417 100644
--- a/fs/ceph/file.c
+++ b/fs/ceph/file.c
@@ -40,8 +40,8 @@
  */
 static size_t dio_get_pagev_size(const struct iov_iter *it)
 {
-    const struct iovec *iov = it->iov;
-    const struct iovec *iovend = iov + it->nr_segs;
+    const struct iovec *iov = iov_iter_iovec(it);
+    size_t total = iov_iter_count(it);
     size_t size;
 
     size = iov->iov_len - it->iov_offset;
@@ -50,8 +50,10 @@ static size_t dio_get_pagev_size(const struct iov_iter *it)
      * and the next base are page aligned.
      */
     while (PAGE_ALIGNED((iov->iov_base + iov->iov_len)) &&
-           (++iov < iovend && PAGE_ALIGNED((iov->iov_base)))) {
-        size += iov->iov_len;
+           PAGE_ALIGNED(((iov++)->iov_base))) {
+	    size_t n =  min(iov->iov_len, total);
+	    size += n;
+	    total -= n;
     }
     dout("dio_get_pagevlen len = %zu\n", size);
     return size;
@@ -71,7 +73,7 @@ dio_get_pages_alloc(const struct iov_iter *it, size_t nbytes,
 	struct page **pages;
 	int ret = 0, idx, npages;
 
-	align = (unsigned long)(it->iov->iov_base + it->iov_offset) &
+	align = (unsigned long)(iov_iter_iovec(it)->iov_base + it->iov_offset) &
 		(PAGE_SIZE - 1);
 	npages = calc_pages_for(align, nbytes);
 	pages = kmalloc(sizeof(*pages) * npages, GFP_KERNEL);
@@ -82,10 +84,11 @@ dio_get_pages_alloc(const struct iov_iter *it, size_t nbytes,
 	}
 
 	for (idx = 0; idx < npages; ) {
-		void __user *data = tmp_it.iov->iov_base + tmp_it.iov_offset;
+		struct iovec *tmp_iov = iov_iter_iovec(&tmp_it);
+		void __user *data = tmp_iov->iov_base + tmp_it.iov_offset;
 		size_t off = (unsigned long)data & (PAGE_SIZE - 1);
 		size_t len = min_t(size_t, nbytes,
-				   tmp_it.iov->iov_len - tmp_it.iov_offset);
+				   tmp_iov->iov_len - tmp_it.iov_offset);
 		int n = (len + off + PAGE_SIZE - 1) >> PAGE_SHIFT;
 		ret = get_user_pages_fast((unsigned long)data, n, write,
 					   pages + idx);
@@ -522,10 +525,9 @@ static ssize_t ceph_sync_read(struct kiocb *iocb, struct iov_iter *i,
 		size_t left = len = ret;
 
 		while (left) {
-			void __user *data = i->iov[0].iov_base +
-					    i->iov_offset;
-			l = min(i->iov[0].iov_len - i->iov_offset,
-				left);
+			struct iovec *iov = (struct iovec *)i->data;
+			void __user *data = iov->iov_base + i->iov_offset;
+			l = min(iov->iov_len - i->iov_offset, left);
 
 			ret = ceph_copy_page_vector_to_user(&pages[k],
 							    data, off, l);
@@ -1121,7 +1123,7 @@ static ssize_t inline_to_iov(struct kiocb *iocb, struct iov_iter *i,
 
 		while (left) {
 			struct iovec *iov = iov_iter_iovec(i);
-			void __user *udata = iov->iov_base + i->iov_offset;
+			void __user *udata = iov->iov_base;
 			size_t n = min(iov->iov_len - i->iov_offset, left);
 
 			if (__copy_to_user(udata, kdata, n)) {
@@ -1139,8 +1141,8 @@ static ssize_t inline_to_iov(struct kiocb *iocb, struct iov_iter *i,
 		size_t left = min_t(loff_t, iocb->ki_pos + len, i_size) - pos;
 
 		while (left) {
-			struct iovec *iov = iov_iter_iovec(i);
-			void __user *udata = iov->iov_base + i->iov_offset;
+			struct iovec *iov = (struct iovec *)i->data;
+			void __user *udata = iov->iov_base;
 			size_t n = min(iov->iov_len - i->iov_offset, left);
 
 			if (__clear_user(udata, n)) {


More information about the Devel mailing list