query_port() directly accesses the datapath port array, without
using any kind of RCU dereference. It's OK, since it is holding
DP mutex but this adds an explicit check to make sparse happy.
It also simplifies the code path somewhat.
Found with sparse.
Signed-off-by: Jesse Gross <jesse@nicira.com>
Acked-by: Ben Pfaff <blp@nicira.com>
static int query_port(struct datapath *dp, struct odp_port __user *uport)
{
struct odp_port port;
static int query_port(struct datapath *dp, struct odp_port __user *uport)
{
struct odp_port port;
if (copy_from_user(&port, uport, sizeof port))
return -EFAULT;
if (port.devname[0]) {
if (copy_from_user(&port, uport, sizeof port))
return -EFAULT;
if (port.devname[0]) {
- struct vport *vport;
- int err = 0;
-
port.devname[IFNAMSIZ - 1] = '\0';
vport_lock();
port.devname[IFNAMSIZ - 1] = '\0';
vport_lock();
vport = vport_locate(port.devname);
vport = vport_locate(port.devname);
- if (!vport) {
- err = -ENODEV;
- goto error_unlock;
- }
- if (vport->dp != dp) {
- err = -ENOENT;
- goto error_unlock;
- }
-
- port.port = vport->port_no;
-
-error_unlock:
- rcu_read_unlock();
+ if (!vport)
+ return -ENODEV;
+ if (vport->dp != dp)
+ return -ENOENT;
} else {
if (port.port >= DP_MAX_PORTS)
return -EINVAL;
} else {
if (port.port >= DP_MAX_PORTS)
return -EINVAL;
- if (!dp->ports[port.port])
+
+ vport = get_vport_protected(dp, port.port);
+ if (!vport)
- return put_port(dp->ports[port.port], uport);
+ return put_port(vport, uport);
}
static int do_list_ports(struct datapath *dp, struct odp_port __user *uports,
}
static int do_list_ports(struct datapath *dp, struct odp_port __user *uports,