#include <net/sock.h> /* struct sock */
#include <linux/uaccess.h>
#include <linux/poll.h>
+#include <linux/uio.h>
#include <linux/atomic.h>
}
int vcc_getsockopt(struct socket *sock, int level, int optname,
- char __user *optval, int __user *optlen)
+ sockopt_t *opt)
{
struct atm_vcc *vcc;
+ int val;
int len;
- if (get_user(len, optlen))
- return -EFAULT;
+ len = opt->optlen;
if (__SO_LEVEL_MATCH(optname, level) && len != __SO_SIZE(optname))
return -EINVAL;
case SO_ATMQOS:
if (!test_bit(ATM_VF_HASQOS, &vcc->flags))
return -EINVAL;
- return copy_to_user(optval, &vcc->qos, sizeof(vcc->qos))
+ return copy_to_iter(&vcc->qos, sizeof(vcc->qos),
+ &opt->iter_out) != sizeof(vcc->qos)
? -EFAULT : 0;
case SO_SETCLP:
- return put_user(vcc->atm_options & ATM_ATMOPT_CLP ? 1 : 0,
- (unsigned long __user *)optval) ? -EFAULT : 0;
+ val = vcc->atm_options & ATM_ATMOPT_CLP ? 1 : 0;
+ return copy_to_iter(&val, sizeof(val), &opt->iter_out) !=
+ sizeof(val) ? -EFAULT : 0;
case SO_ATMPVC:
{
struct sockaddr_atmpvc pvc;
pvc.sap_addr.itf = vcc->dev->number;
pvc.sap_addr.vpi = vcc->vpi;
pvc.sap_addr.vci = vcc->vci;
- return copy_to_user(optval, &pvc, sizeof(pvc)) ? -EFAULT : 0;
+ return copy_to_iter(&pvc, sizeof(pvc), &opt->iter_out) !=
+ sizeof(pvc) ? -EFAULT : 0;
}
default:
return -EINVAL;
int vcc_setsockopt(struct socket *sock, int level, int optname,
sockptr_t optval, unsigned int optlen);
int vcc_getsockopt(struct socket *sock, int level, int optname,
- char __user *optval, int __user *optlen);
+ sockopt_t *opt);
void vcc_process_recv_queue(struct atm_vcc *vcc);
int atmpvc_init(void);
}
static int pvc_getsockopt(struct socket *sock, int level, int optname,
- char __user *optval, int __user *optlen)
+ sockopt_t *opt)
{
struct sock *sk = sock->sk;
int error;
lock_sock(sk);
- error = vcc_getsockopt(sock, level, optname, optval, optlen);
+ error = vcc_getsockopt(sock, level, optname, opt);
release_sock(sk);
return error;
}
.listen = sock_no_listen,
.shutdown = pvc_shutdown,
.setsockopt = pvc_setsockopt,
- .getsockopt = pvc_getsockopt,
+ .getsockopt_iter = pvc_getsockopt,
.sendmsg = vcc_sendmsg,
.recvmsg = vcc_recvmsg,
.mmap = sock_no_mmap,
#include <linux/bitops.h>
#include <net/sock.h> /* for sock_no_* */
#include <linux/uaccess.h>
+#include <linux/uio.h>
#include <linux/export.h>
#include "resources.h"
}
static int svc_getsockopt(struct socket *sock, int level, int optname,
- char __user *optval, int __user *optlen)
+ sockopt_t *opt)
{
struct sock *sk = sock->sk;
int error = 0, len;
lock_sock(sk);
if (!__SO_LEVEL_MATCH(optname, level) || optname != SO_ATMSAP) {
- error = vcc_getsockopt(sock, level, optname, optval, optlen);
- goto out;
- }
- if (get_user(len, optlen)) {
- error = -EFAULT;
+ error = vcc_getsockopt(sock, level, optname, opt);
goto out;
}
+ len = opt->optlen;
if (len != sizeof(struct atm_sap)) {
error = -EINVAL;
goto out;
}
- if (copy_to_user(optval, &ATM_SD(sock)->sap, sizeof(struct atm_sap))) {
+ if (copy_to_iter(&ATM_SD(sock)->sap, sizeof(struct atm_sap),
+ &opt->iter_out) != sizeof(struct atm_sap)) {
error = -EFAULT;
goto out;
}
.listen = svc_listen,
.shutdown = svc_shutdown,
.setsockopt = svc_setsockopt,
- .getsockopt = svc_getsockopt,
+ .getsockopt_iter = svc_getsockopt,
.sendmsg = vcc_sendmsg,
.recvmsg = vcc_recvmsg,
.mmap = sock_no_mmap,