[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1374774659-13121-8-git-send-email-dave.kleikamp@oracle.com>
Date: Thu, 25 Jul 2013 12:50:33 -0500
From: Dave Kleikamp <dave.kleikamp@...cle.com>
To: linux-kernel@...r.kernel.org
Cc: linux-fsdevel@...r.kernel.org,
Andrew Morton <akpm@...ux-foundation.org>,
"Maxim V. Patlasov" <mpatlasov@...allels.com>,
Zach Brown <zab@...bo.net>,
Dave Kleikamp <dave.kleikamp@...cle.com>
Subject: [PATCH V8 07/33] iov_iter: ii_iovec_copy_to_user should pre-fault user pages
This duplicates the optimization in file_read_actor as a later patch
will replace it with a call to __iov_iter_copy_to_user().
Signed-off-by: Dave Kleikamp <dave.kleikamp@...cle.com>
---
fs/iov-iter.c | 19 +++++++++++++++++--
1 file changed, 17 insertions(+), 2 deletions(-)
diff --git a/fs/iov-iter.c b/fs/iov-iter.c
index 6cb6be0..59f9556 100644
--- a/fs/iov-iter.c
+++ b/fs/iov-iter.c
@@ -80,17 +80,32 @@ static size_t ii_iovec_copy_to_user(struct page *page,
return 0;
}
- kaddr = kmap(page);
if (likely(i->nr_segs == 1)) {
int left;
char __user *buf = iov->iov_base + i->iov_offset;
+ /*
+ * Faults on the destination of a read are common, so do it
+ * before taking the kmap.
+ */
+ if (!fault_in_pages_writeable(buf, bytes)) {
+ kaddr = kmap_atomic(page);
+ left = __copy_to_user_inatomic(buf, kaddr + offset,
+ bytes);
+ kunmap_atomic(kaddr);
+ if (left == 0)
+ goto success;
+ }
+ kaddr = kmap(page);
left = copy_to_user(buf, kaddr + offset, bytes);
+ kunmap(page);
+success:
copied = bytes - left;
} else {
+ kaddr = kmap(page);
copied = __iovec_copy_to_user(kaddr + offset, iov,
i->iov_offset, bytes, 0);
+ kunmap(page);
}
- kunmap(page);
return copied;
}
--
1.8.3.4
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists