memcpy(skb_push(skb, MISDN_HEADER_LEN), mISDN_HEAD_P(skb),
               MISDN_HEADER_LEN);
 
-       err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
+       err = skb_copy_datagram_msg(skb, 0, msg, copied);
 
        mISDN_sock_cmsg(sk, msg, skb);
 
 
 
        if (skb) {
                total_len = min_t(size_t, total_len, skb->len);
-               error = skb_copy_datagram_iovec(skb, 0, m->msg_iov, total_len);
+               error = skb_copy_datagram_msg(skb, 0, m, total_len);
                if (error == 0) {
                        consume_skb(skb);
                        return total_len;
 
 #include <linux/bug.h>
 #include <linux/cache.h>
 #include <linux/rbtree.h>
+#include <linux/socket.h>
 
 #include <linux/atomic.h>
 #include <asm/types.h>
                           struct poll_table_struct *wait);
 int skb_copy_datagram_iovec(const struct sk_buff *from, int offset,
                            struct iovec *to, int size);
+static inline int skb_copy_datagram_msg(const struct sk_buff *from, int offset,
+                                       struct msghdr *msg, int size)
+{
+       return skb_copy_datagram_iovec(from, offset, msg->msg_iov, size);
+}
 int skb_copy_and_csum_datagram_iovec(struct sk_buff *skb, int hlen,
                                     struct iovec *iov);
 int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset,
 
                copied = size;
                msg->msg_flags |= MSG_TRUNC;
        }
-       err = skb_copy_datagram_iovec(skb, offset, msg->msg_iov, copied);
+       err = skb_copy_datagram_msg(skb, offset, msg, copied);
 
        if (!err && msg->msg_name) {
                DECLARE_SOCKADDR(struct sockaddr_at *, sat, msg->msg_name);
 
                msg->msg_flags |= MSG_TRUNC;
        }
 
-       error = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
+       error = skb_copy_datagram_msg(skb, 0, msg, copied);
        if (error)
                return error;
        sock_recv_ts_and_drops(msg, sk, skb);
 
                msg->msg_flags |= MSG_TRUNC;
        }
 
-       skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
+       skb_copy_datagram_msg(skb, 0, msg, copied);
 
        if (msg->msg_name) {
                ax25_digi digi;
 
        }
 
        skb_reset_transport_header(skb);
-       err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
+       err = skb_copy_datagram_msg(skb, 0, msg, copied);
        if (err == 0) {
                sock_recv_ts_and_drops(msg, sk, skb);
 
                }
 
                chunk = min_t(unsigned int, skb->len, size);
-               if (skb_copy_datagram_iovec(skb, 0, msg->msg_iov, chunk)) {
+               if (skb_copy_datagram_msg(skb, 0, msg, chunk)) {
                        skb_queue_head(&sk->sk_receive_queue, skb);
                        if (!copied)
                                copied = -EFAULT;
 
        }
 
        skb_reset_transport_header(skb);
-       err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
+       err = skb_copy_datagram_msg(skb, 0, msg, copied);
 
        switch (hci_pi(sk)->channel) {
        case HCI_CHANNEL_RAW:
 
                copylen = len;
        }
 
-       ret = skb_copy_datagram_iovec(skb, 0, m->msg_iov, copylen);
+       ret = skb_copy_datagram_msg(skb, 0, m, copylen);
        if (ret)
                goto out_free;
 
 
                msg->msg_flags |= MSG_TRUNC;
                copied = len;
        }
-       err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
+       err = skb_copy_datagram_msg(skb, 0, msg, copied);
        if (err)
                goto out_free_skb;
 
 
                else if (len < skb->len)
                        msg->msg_flags |= MSG_TRUNC;
 
-               if (skb_copy_datagram_iovec(skb, 0, msg->msg_iov, len)) {
+               if (skb_copy_datagram_msg(skb, 0, msg, len)) {
                        /* Exception. Bailout! */
                        len = -EFAULT;
                        break;
 
        }
 
        /* FIXME: skip headers if necessary ?! */
-       err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
+       err = skb_copy_datagram_msg(skb, 0, msg, copied);
        if (err)
                goto done;
 
 
                copied = len;
        }
 
-       err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
+       err = skb_copy_datagram_msg(skb, 0, msg, copied);
        if (err)
                goto done;
 
 
                msg->msg_flags |= MSG_TRUNC;
                copied = len;
        }
-       err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
+       err = skb_copy_datagram_msg(skb, 0, msg, copied);
        if (err)
                goto out_free_skb;
 
 
        }
 
        /* Don't bother checking the checksum */
-       err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
+       err = skb_copy_datagram_msg(skb, 0, msg, copied);
        if (err)
                goto done;
 
 
                copied = len;
        }
 
-       err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
+       err = skb_copy_datagram_msg(skb, 0, msg, copied);
        if (err)
                goto done;
 
 
        /* XXX -- need to support SO_PEEK_OFF */
 
        skb_queue_walk(&sk->sk_write_queue, skb) {
-               err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, skb->len);
+               err = skb_copy_datagram_msg(skb, 0, msg, skb->len);
                if (err)
                        break;
 
                }
 
                if (!(flags & MSG_TRUNC)) {
-                       err = skb_copy_datagram_iovec(skb, offset,
-                                                     msg->msg_iov, used);
+                       err = skb_copy_datagram_msg(skb, offset, msg, used);
                        if (err) {
                                /* Exception. Bailout! */
                                if (!copied)
 
        }
 
        if (skb_csum_unnecessary(skb))
-               err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr),
-                                             msg->msg_iov, copied);
+               err = skb_copy_datagram_msg(skb, sizeof(struct udphdr),
+                                           msg, copied);
        else {
                err = skb_copy_and_csum_datagram_iovec(skb,
                                                       sizeof(struct udphdr),
 
                msg->msg_flags |= MSG_TRUNC;
                copied = len;
        }
-       err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
+       err = skb_copy_datagram_msg(skb, 0, msg, copied);
        if (err)
                goto out_free_skb;
 
                msg->msg_flags |= MSG_TRUNC;
                copied = len;
        }
-       err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
+       err = skb_copy_datagram_msg(skb, 0, msg, copied);
        if (err)
                goto out_free_skb;
 
 
        }
 
        if (skb_csum_unnecessary(skb)) {
-               err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
+               err = skb_copy_datagram_msg(skb, 0, msg, copied);
        } else if (msg->msg_flags&MSG_TRUNC) {
                if (__skb_checksum_complete(skb))
                        goto csum_copy_err;
-               err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
+               err = skb_copy_datagram_msg(skb, 0, msg, copied);
        } else {
                err = skb_copy_and_csum_datagram_iovec(skb, 0, msg->msg_iov);
                if (err == -EINVAL)
 
        }
 
        if (skb_csum_unnecessary(skb))
-               err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr),
-                                             msg->msg_iov, copied);
+               err = skb_copy_datagram_msg(skb, sizeof(struct udphdr),
+                                           msg, copied);
        else {
                err = skb_copy_and_csum_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov);
                if (err == -EINVAL)
 
                msg->msg_flags |= MSG_TRUNC;
        }
 
-       rc = skb_copy_datagram_iovec(skb, sizeof(struct ipxhdr), msg->msg_iov,
-                                    copied);
+       rc = skb_copy_datagram_msg(skb, sizeof(struct ipxhdr), msg, copied);
        if (rc)
                goto out_free;
        if (skb->tstamp.tv64)
 
                copied = size;
                msg->msg_flags |= MSG_TRUNC;
        }
-       skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
+       skb_copy_datagram_msg(skb, 0, msg, copied);
 
        skb_free_datagram(sk, skb);
 
 
                sk->sk_shutdown = sk->sk_shutdown | RCV_SHUTDOWN;
 
        cskb = skb;
-       if (skb_copy_datagram_iovec(cskb, offset, msg->msg_iov, copied)) {
+       if (skb_copy_datagram_msg(cskb, offset, msg, copied)) {
                if (!(flags & MSG_PEEK))
                        skb_queue_head(&sk->sk_receive_queue, skb);
                return -EFAULT;
 
        }
 
        skb_reset_transport_header(skb);
-       err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
+       err = skb_copy_datagram_msg(skb, 0, msg, copied);
        if (err)
                goto out_free;
 
 
                copied = len;
        }
 
-       err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
+       err = skb_copy_datagram_msg(skb, 0, msg, copied);
        if (err)
                goto done;
 
 
                copied = len;
        }
 
-       err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
+       err = skb_copy_datagram_msg(skb, 0, msg, copied);
        if (err)
                goto done;
 
 
        else if (len < skb->len)
                msg->msg_flags |= MSG_TRUNC;
 
-       err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, len);
+       err = skb_copy_datagram_msg(skb, 0, msg, len);
        if (likely(err == 0))
                err = len;
 
 
                        used = len;
 
                if (!(flags & MSG_TRUNC)) {
-                       int rc = skb_copy_datagram_iovec(skb, offset,
-                                                        msg->msg_iov, used);
+                       int rc = skb_copy_datagram_msg(skb, offset, msg, used);
                        if (rc) {
                                /* Exception. Bailout! */
                                if (!copied)
 
        }
 
        skb_reset_transport_header(data_skb);
-       err = skb_copy_datagram_iovec(data_skb, 0, msg->msg_iov, copied);
+       err = skb_copy_datagram_msg(data_skb, 0, msg, copied);
 
        if (msg->msg_name) {
                DECLARE_SOCKADDR(struct sockaddr_nl *, addr, msg->msg_name);
 
                msg->msg_flags |= MSG_TRUNC;
        }
 
-       er = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
+       er = skb_copy_datagram_msg(skb, 0, msg, copied);
        if (er < 0) {
                skb_free_datagram(sk, skb);
                release_sock(sk);
 
        copied = min_t(unsigned int, rlen, len);
 
        cskb = skb;
-       if (skb_copy_datagram_iovec(cskb, 0, msg->msg_iov, copied)) {
+       if (skb_copy_datagram_msg(cskb, 0, msg, copied)) {
                if (!(flags & MSG_PEEK))
                        skb_queue_head(&sk->sk_receive_queue, skb);
                return -EFAULT;
 
                copied = len;
        }
 
-       rc = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
+       rc = skb_copy_datagram_msg(skb, 0, msg, copied);
 
        skb_free_datagram(sk, skb);
 
 
                msg->msg_flags |= MSG_TRUNC;
        }
 
-       err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
+       err = skb_copy_datagram_msg(skb, 0, msg, copied);
        if (err)
                goto out_free;
 
 
                copylen = len;
        }
 
-       rval = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copylen);
+       rval = skb_copy_datagram_msg(skb, 0, msg, copylen);
        if (rval) {
                rval = -EFAULT;
                goto out;
 
        else
                len = skb->len;
 
-       err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, len);
+       err = skb_copy_datagram_msg(skb, 0, msg, len);
        if (!err)
                err = (flags & MSG_TRUNC) ? skb->len : len;
 
 
                msg->msg_flags |= MSG_TRUNC;
        }
 
-       skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
+       skb_copy_datagram_msg(skb, 0, msg, copied);
 
        if (msg->msg_name) {
                struct sockaddr_rose *srose;
 
                if (copy > len - copied)
                        copy = len - copied;
 
-               ret = skb_copy_datagram_iovec(skb, offset, msg->msg_iov, copy);
+               ret = skb_copy_datagram_msg(skb, offset, msg, copy);
 
                if (ret < 0)
                        goto copy_error;
 
        if (copied > len)
                copied = len;
 
-       err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
+       err = skb_copy_datagram_msg(skb, 0, msg, copied);
 
        event = sctp_skb2event(skb);
 
 
                        sz = buf_len;
                        m->msg_flags |= MSG_TRUNC;
                }
-               res = skb_copy_datagram_iovec(buf, msg_hdr_sz(msg),
-                                             m->msg_iov, sz);
+               res = skb_copy_datagram_msg(buf, msg_hdr_sz(msg), m, sz);
                if (res)
                        goto exit;
                res = sz;
                needed = (buf_len - sz_copied);
                sz_to_copy = (sz <= needed) ? sz : needed;
 
-               res = skb_copy_datagram_iovec(buf, msg_hdr_sz(msg) + offset,
-                                             m->msg_iov, sz_to_copy);
+               res = skb_copy_datagram_msg(buf, msg_hdr_sz(msg) + offset,
+                                           m, sz_to_copy);
                if (res)
                        goto exit;
 
 
        else if (size < skb->len - skip)
                msg->msg_flags |= MSG_TRUNC;
 
-       err = skb_copy_datagram_iovec(skb, skip, msg->msg_iov, size);
+       err = skb_copy_datagram_msg(skb, skip, msg, size);
        if (err)
                goto out_free;
 
                }
 
                chunk = min_t(unsigned int, unix_skb_len(skb) - skip, size);
-               if (skb_copy_datagram_iovec(skb, UNIXCB(skb).consumed + skip,
-                                           msg->msg_iov, chunk)) {
+               if (skb_copy_datagram_msg(skb, UNIXCB(skb).consumed + skip,
+                                         msg, chunk)) {
                        if (copied == 0)
                                copied = -EFAULT;
                        break;
 
        }
 
        /* Place the datagram payload in the user's iovec. */
-       err = skb_copy_datagram_iovec(skb, sizeof(*dg), msg->msg_iov,
-               payload_len);
+       err = skb_copy_datagram_msg(skb, sizeof(*dg), msg, payload_len);
        if (err)
                goto out;
 
 
        /* Currently, each datagram always contains a complete record */
        msg->msg_flags |= MSG_EOR;
 
-       rc = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
+       rc = skb_copy_datagram_msg(skb, 0, msg, copied);
        if (rc)
                goto out_free_dgram;