aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/rds.h8
-rw-r--r--net/rds/af_rds.c3
-rw-r--r--net/rds/rdma.c24
-rw-r--r--net/rds/rdma.h1
4 files changed, 36 insertions, 0 deletions
diff --git a/include/linux/rds.h b/include/linux/rds.h
index 89d46e1afbb1..cab4994c2f63 100644
--- a/include/linux/rds.h
+++ b/include/linux/rds.h
@@ -56,6 +56,7 @@
56/* deprecated: RDS_BARRIER 4 */ 56/* deprecated: RDS_BARRIER 4 */
57#define RDS_RECVERR 5 57#define RDS_RECVERR 5
58#define RDS_CONG_MONITOR 6 58#define RDS_CONG_MONITOR 6
59#define RDS_GET_MR_FOR_DEST 7
59 60
60/* 61/*
61 * Control message types for SOL_RDS. 62 * Control message types for SOL_RDS.
@@ -224,6 +225,13 @@ struct rds_get_mr_args {
224 uint64_t flags; 225 uint64_t flags;
225}; 226};
226 227
228struct rds_get_mr_for_dest_args {
229 struct sockaddr_storage dest_addr;
230 struct rds_iovec vec;
231 u_int64_t cookie_addr;
232 uint64_t flags;
233};
234
227struct rds_free_mr_args { 235struct rds_free_mr_args {
228 rds_rdma_cookie_t cookie; 236 rds_rdma_cookie_t cookie;
229 u_int64_t flags; 237 u_int64_t flags;
diff --git a/net/rds/af_rds.c b/net/rds/af_rds.c
index a202e5b36079..2b978dc6e75d 100644
--- a/net/rds/af_rds.c
+++ b/net/rds/af_rds.c
@@ -265,6 +265,9 @@ static int rds_setsockopt(struct socket *sock, int level, int optname,
265 case RDS_GET_MR: 265 case RDS_GET_MR:
266 ret = rds_get_mr(rs, optval, optlen); 266 ret = rds_get_mr(rs, optval, optlen);
267 break; 267 break;
268 case RDS_GET_MR_FOR_DEST:
269 ret = rds_get_mr_for_dest(rs, optval, optlen);
270 break;
268 case RDS_FREE_MR: 271 case RDS_FREE_MR:
269 ret = rds_free_mr(rs, optval, optlen); 272 ret = rds_free_mr(rs, optval, optlen);
270 break; 273 break;
diff --git a/net/rds/rdma.c b/net/rds/rdma.c
index 8dc83d2caa58..971b5a668458 100644
--- a/net/rds/rdma.c
+++ b/net/rds/rdma.c
@@ -317,6 +317,30 @@ int rds_get_mr(struct rds_sock *rs, char __user *optval, int optlen)
317 return __rds_rdma_map(rs, &args, NULL, NULL); 317 return __rds_rdma_map(rs, &args, NULL, NULL);
318} 318}
319 319
320int rds_get_mr_for_dest(struct rds_sock *rs, char __user *optval, int optlen)
321{
322 struct rds_get_mr_for_dest_args args;
323 struct rds_get_mr_args new_args;
324
325 if (optlen != sizeof(struct rds_get_mr_for_dest_args))
326 return -EINVAL;
327
328 if (copy_from_user(&args, (struct rds_get_mr_for_dest_args __user *)optval,
329 sizeof(struct rds_get_mr_for_dest_args)))
330 return -EFAULT;
331
332 /*
333 * Initially, just behave like get_mr().
334 * TODO: Implement get_mr as wrapper around this
335 * and deprecate it.
336 */
337 new_args.vec = args.vec;
338 new_args.cookie_addr = args.cookie_addr;
339 new_args.flags = args.flags;
340
341 return __rds_rdma_map(rs, &new_args, NULL, NULL);
342}
343
320/* 344/*
321 * Free the MR indicated by the given R_Key 345 * Free the MR indicated by the given R_Key
322 */ 346 */
diff --git a/net/rds/rdma.h b/net/rds/rdma.h
index 425512098b0b..909c39835a5d 100644
--- a/net/rds/rdma.h
+++ b/net/rds/rdma.h
@@ -61,6 +61,7 @@ static inline u32 rds_rdma_cookie_offset(rds_rdma_cookie_t cookie)
61} 61}
62 62
63int rds_get_mr(struct rds_sock *rs, char __user *optval, int optlen); 63int rds_get_mr(struct rds_sock *rs, char __user *optval, int optlen);
64int rds_get_mr_for_dest(struct rds_sock *rs, char __user *optval, int optlen);
64int rds_free_mr(struct rds_sock *rs, char __user *optval, int optlen); 65int rds_free_mr(struct rds_sock *rs, char __user *optval, int optlen);
65void rds_rdma_drop_keys(struct rds_sock *rs); 66void rds_rdma_drop_keys(struct rds_sock *rs);
66int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm, 67int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm,