diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/rds/page.c | 27 |
1 files changed, 7 insertions, 20 deletions
diff --git a/net/rds/page.c b/net/rds/page.c index 595a952d4b17..1dfbfea12e9b 100644 --- a/net/rds/page.c +++ b/net/rds/page.c | |||
@@ -57,30 +57,17 @@ int rds_page_copy_user(struct page *page, unsigned long offset, | |||
57 | unsigned long ret; | 57 | unsigned long ret; |
58 | void *addr; | 58 | void *addr; |
59 | 59 | ||
60 | if (to_user) | 60 | addr = kmap(page); |
61 | if (to_user) { | ||
61 | rds_stats_add(s_copy_to_user, bytes); | 62 | rds_stats_add(s_copy_to_user, bytes); |
62 | else | 63 | ret = copy_to_user(ptr, addr + offset, bytes); |
64 | } else { | ||
63 | rds_stats_add(s_copy_from_user, bytes); | 65 | rds_stats_add(s_copy_from_user, bytes); |
64 | 66 | ret = copy_from_user(addr + offset, ptr, bytes); | |
65 | addr = kmap_atomic(page, KM_USER0); | ||
66 | if (to_user) | ||
67 | ret = __copy_to_user_inatomic(ptr, addr + offset, bytes); | ||
68 | else | ||
69 | ret = __copy_from_user_inatomic(addr + offset, ptr, bytes); | ||
70 | kunmap_atomic(addr, KM_USER0); | ||
71 | |||
72 | if (ret) { | ||
73 | addr = kmap(page); | ||
74 | if (to_user) | ||
75 | ret = copy_to_user(ptr, addr + offset, bytes); | ||
76 | else | ||
77 | ret = copy_from_user(addr + offset, ptr, bytes); | ||
78 | kunmap(page); | ||
79 | if (ret) | ||
80 | return -EFAULT; | ||
81 | } | 67 | } |
68 | kunmap(page); | ||
82 | 69 | ||
83 | return 0; | 70 | return ret ? -EFAULT : 0; |
84 | } | 71 | } |
85 | EXPORT_SYMBOL_GPL(rds_page_copy_user); | 72 | EXPORT_SYMBOL_GPL(rds_page_copy_user); |
86 | 73 | ||