diff options
Diffstat (limited to 'net/rds/rdma.c')
-rw-r--r-- | net/rds/rdma.c | 37 |
1 files changed, 31 insertions, 6 deletions
diff --git a/net/rds/rdma.c b/net/rds/rdma.c index 8dc83d2caa58..5ce9437cad67 100644 --- a/net/rds/rdma.c +++ b/net/rds/rdma.c | |||
@@ -31,6 +31,7 @@ | |||
31 | * | 31 | * |
32 | */ | 32 | */ |
33 | #include <linux/pagemap.h> | 33 | #include <linux/pagemap.h> |
34 | #include <linux/slab.h> | ||
34 | #include <linux/rbtree.h> | 35 | #include <linux/rbtree.h> |
35 | #include <linux/dma-mapping.h> /* for DMA_*_DEVICE */ | 36 | #include <linux/dma-mapping.h> /* for DMA_*_DEVICE */ |
36 | 37 | ||
@@ -317,6 +318,30 @@ int rds_get_mr(struct rds_sock *rs, char __user *optval, int optlen) | |||
317 | return __rds_rdma_map(rs, &args, NULL, NULL); | 318 | return __rds_rdma_map(rs, &args, NULL, NULL); |
318 | } | 319 | } |
319 | 320 | ||
321 | int rds_get_mr_for_dest(struct rds_sock *rs, char __user *optval, int optlen) | ||
322 | { | ||
323 | struct rds_get_mr_for_dest_args args; | ||
324 | struct rds_get_mr_args new_args; | ||
325 | |||
326 | if (optlen != sizeof(struct rds_get_mr_for_dest_args)) | ||
327 | return -EINVAL; | ||
328 | |||
329 | if (copy_from_user(&args, (struct rds_get_mr_for_dest_args __user *)optval, | ||
330 | sizeof(struct rds_get_mr_for_dest_args))) | ||
331 | return -EFAULT; | ||
332 | |||
333 | /* | ||
334 | * Initially, just behave like get_mr(). | ||
335 | * TODO: Implement get_mr as wrapper around this | ||
336 | * and deprecate it. | ||
337 | */ | ||
338 | new_args.vec = args.vec; | ||
339 | new_args.cookie_addr = args.cookie_addr; | ||
340 | new_args.flags = args.flags; | ||
341 | |||
342 | return __rds_rdma_map(rs, &new_args, NULL, NULL); | ||
343 | } | ||
344 | |||
320 | /* | 345 | /* |
321 | * Free the MR indicated by the given R_Key | 346 | * Free the MR indicated by the given R_Key |
322 | */ | 347 | */ |
@@ -607,8 +632,8 @@ int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm, | |||
607 | { | 632 | { |
608 | struct rds_rdma_op *op; | 633 | struct rds_rdma_op *op; |
609 | 634 | ||
610 | if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct rds_rdma_args)) | 635 | if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct rds_rdma_args)) || |
611 | || rm->m_rdma_op != NULL) | 636 | rm->m_rdma_op != NULL) |
612 | return -EINVAL; | 637 | return -EINVAL; |
613 | 638 | ||
614 | op = rds_rdma_prepare(rs, CMSG_DATA(cmsg)); | 639 | op = rds_rdma_prepare(rs, CMSG_DATA(cmsg)); |
@@ -631,8 +656,8 @@ int rds_cmsg_rdma_dest(struct rds_sock *rs, struct rds_message *rm, | |||
631 | u32 r_key; | 656 | u32 r_key; |
632 | int err = 0; | 657 | int err = 0; |
633 | 658 | ||
634 | if (cmsg->cmsg_len < CMSG_LEN(sizeof(rds_rdma_cookie_t)) | 659 | if (cmsg->cmsg_len < CMSG_LEN(sizeof(rds_rdma_cookie_t)) || |
635 | || rm->m_rdma_cookie != 0) | 660 | rm->m_rdma_cookie != 0) |
636 | return -EINVAL; | 661 | return -EINVAL; |
637 | 662 | ||
638 | memcpy(&rm->m_rdma_cookie, CMSG_DATA(cmsg), sizeof(rm->m_rdma_cookie)); | 663 | memcpy(&rm->m_rdma_cookie, CMSG_DATA(cmsg), sizeof(rm->m_rdma_cookie)); |
@@ -668,8 +693,8 @@ int rds_cmsg_rdma_dest(struct rds_sock *rs, struct rds_message *rm, | |||
668 | int rds_cmsg_rdma_map(struct rds_sock *rs, struct rds_message *rm, | 693 | int rds_cmsg_rdma_map(struct rds_sock *rs, struct rds_message *rm, |
669 | struct cmsghdr *cmsg) | 694 | struct cmsghdr *cmsg) |
670 | { | 695 | { |
671 | if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct rds_get_mr_args)) | 696 | if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct rds_get_mr_args)) || |
672 | || rm->m_rdma_cookie != 0) | 697 | rm->m_rdma_cookie != 0) |
673 | return -EINVAL; | 698 | return -EINVAL; |
674 | 699 | ||
675 | return __rds_rdma_map(rs, CMSG_DATA(cmsg), &rm->m_rdma_cookie, &rm->m_rdma_mr); | 700 | return __rds_rdma_map(rs, CMSG_DATA(cmsg), &rm->m_rdma_cookie, &rm->m_rdma_mr); |