[rds-commits] zab commits r77 - trunk/linux/net/rds
svn-commits@oss.oracle.com
svn-commits at oss.oracle.com
Thu May 25 18:38:47 CDT 2006
Author: zab
Date: 2006-05-25 18:38:46 -0500 (Thu, 25 May 2006)
New Revision: 77
Modified:
trunk/linux/net/rds/message.c
trunk/linux/net/rds/rds.h
Log:
Fix three bad bugs when copying to and from pages and user iovecs.
1) copy into the page at the offset in the current page.
2) 'ret' was being stomped on as a temporary return from copy_to_user, add
an explitic 'copied'.
3) size doesn't need to be dropped now that we're comparing it with copied
Modified: trunk/linux/net/rds/message.c
===================================================================
--- trunk/linux/net/rds/message.c 2006-05-25 22:44:12 UTC (rev 76)
+++ trunk/linux/net/rds/message.c 2006-05-25 23:38:46 UTC (rev 77)
@@ -203,13 +203,16 @@
}
to_copy = min(iov->iov_len - iov_off, PAGE_SIZE - vec->v_len);
+ to_copy = min_t(size_t, to_copy, total_len);
- pr_debug("iov %p iov_off %lu vec len %u total_len %zu\n",
- iov, iov_off, vec->v_len, total_len);
+ pr_debug("copying %lu bytes from user %p (base %p len %zu "
+ "off %lu) to vec %p page %p off %u\n", to_copy,
+ iov->iov_base + iov_off, iov->iov_base, iov->iov_len,
+ iov_off, vec, page, vec->v_len);
/* XXX could look more like filemap_copy_from_user() */
- ret = copy_from_user(kmap(page), iov->iov_base + iov_off,
- to_copy);
+ ret = copy_from_user(kmap(page) + vec->v_len,
+ iov->iov_base + iov_off, to_copy);
kunmap(page);
if (ret) {
ret = -EFAULT;
@@ -245,43 +248,47 @@
unsigned long to_copy;
unsigned long iov_off = 0;
unsigned long vec_off = 0;
- int ret = 0;
+ int ret, copied = 0;
rm = container_of(inc, struct rds_message, m_inc);
- while (ret < size && ret < rm->m_len) {
+ while (copied < size && copied < rm->m_len) {
while (iov_off == iov->iov_len) {
iov_off = 0;
iov++;
}
to_copy = min(iov->iov_len - iov_off, vec->v_len - vec_off);
- to_copy = min_t(size_t, to_copy, size - ret);
- to_copy = min_t(unsigned long, to_copy, rm->m_len - ret);
+ to_copy = min_t(size_t, to_copy, size - copied);
+ to_copy = min_t(unsigned long, to_copy, rm->m_len - copied);
+ pr_debug("copying %lu bytes to user %p (base %p len %zu "
+ "off %lu) from vec %p page %p voff %u off %lu\n",
+ to_copy, iov->iov_base + iov_off, iov->iov_base,
+ iov->iov_len, iov_off, vec, vec->v_page, vec->v_off,
+ vec_off);
+
/* XXX could look more like filemap_copy_from_user() */
ret = copy_to_user(iov->iov_base + iov_off,
kmap(vec->v_page) + vec->v_off + vec_off,
to_copy);
kunmap(vec->v_page);
if (ret) {
- ret = -EFAULT;
+ copied = -EFAULT;
break;
}
iov_off += to_copy;
vec_off += to_copy;
- ret += to_copy;
- size -= to_copy;
- if (size == 0)
- break;
+ copied += to_copy;
+
if (vec_off == vec->v_len) {
vec_off = 0;
vec++;
}
}
- return ret;
+ return copied;
}
/*
Modified: trunk/linux/net/rds/rds.h
===================================================================
--- trunk/linux/net/rds/rds.h 2006-05-25 22:44:12 UTC (rev 76)
+++ trunk/linux/net/rds/rds.h 2006-05-25 23:38:46 UTC (rev 77)
@@ -26,7 +26,6 @@
unsigned int v_len;
};
-
struct rds_connection {
struct hlist_node c_hash_node;
__be32 c_laddr;
More information about the Rds-commits
mailing list