netlink: fix for too early rmmod
[safe/jmp/linux-2.6] / net / rds / rdma.c
index e390dc7..4c64daa 100644 (file)
@@ -150,10 +150,7 @@ static int rds_pin_pages(unsigned long user_addr, unsigned int nr_pages,
 {
        int ret;
 
-       down_read(&current->mm->mmap_sem);
-       ret = get_user_pages(current, current->mm, user_addr,
-                            nr_pages, write, 0, pages, NULL);
-       up_read(&current->mm->mmap_sem);
+       ret = get_user_pages_fast(user_addr, nr_pages, write, pages);
 
        if (ret >= 0 && ret < nr_pages) {
                while (ret--)
@@ -320,6 +317,30 @@ int rds_get_mr(struct rds_sock *rs, char __user *optval, int optlen)
        return __rds_rdma_map(rs, &args, NULL, NULL);
 }
 
+int rds_get_mr_for_dest(struct rds_sock *rs, char __user *optval, int optlen)
+{
+       struct rds_get_mr_for_dest_args args;
+       struct rds_get_mr_args new_args;
+
+       if (optlen != sizeof(struct rds_get_mr_for_dest_args))
+               return -EINVAL;
+
+       if (copy_from_user(&args, (struct rds_get_mr_for_dest_args __user *)optval,
+                          sizeof(struct rds_get_mr_for_dest_args)))
+               return -EFAULT;
+
+       /*
+        * Initially, just behave like get_mr().
+        * TODO: Implement get_mr as wrapper around this
+        *       and deprecate it.
+        */
+       new_args.vec = args.vec;
+       new_args.cookie_addr = args.cookie_addr;
+       new_args.flags = args.flags;
+
+       return __rds_rdma_map(rs, &new_args, NULL, NULL);
+}
+
 /*
  * Free the MR indicated by the given R_Key
  */
@@ -610,8 +631,8 @@ int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm,
 {
        struct rds_rdma_op *op;
 
-       if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct rds_rdma_args))
-        || rm->m_rdma_op != NULL)
+       if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct rds_rdma_args)) ||
+           rm->m_rdma_op != NULL)
                return -EINVAL;
 
        op = rds_rdma_prepare(rs, CMSG_DATA(cmsg));
@@ -634,8 +655,8 @@ int rds_cmsg_rdma_dest(struct rds_sock *rs, struct rds_message *rm,
        u32 r_key;
        int err = 0;
 
-       if (cmsg->cmsg_len < CMSG_LEN(sizeof(rds_rdma_cookie_t))
-        || rm->m_rdma_cookie != 0)
+       if (cmsg->cmsg_len < CMSG_LEN(sizeof(rds_rdma_cookie_t)) ||
+           rm->m_rdma_cookie != 0)
                return -EINVAL;
 
        memcpy(&rm->m_rdma_cookie, CMSG_DATA(cmsg), sizeof(rm->m_rdma_cookie));
@@ -671,8 +692,8 @@ int rds_cmsg_rdma_dest(struct rds_sock *rs, struct rds_message *rm,
 int rds_cmsg_rdma_map(struct rds_sock *rs, struct rds_message *rm,
                          struct cmsghdr *cmsg)
 {
-       if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct rds_get_mr_args))
-        || rm->m_rdma_cookie != 0)
+       if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct rds_get_mr_args)) ||
+           rm->m_rdma_cookie != 0)
                return -EINVAL;
 
        return __rds_rdma_map(rs, CMSG_DATA(cmsg), &rm->m_rdma_cookie, &rm->m_rdma_mr);