From: Ben Pfaff Date: Wed, 17 Jun 2009 21:28:07 +0000 (-0700) Subject: datapath: Change ODP_PORT_LIST semantics. X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f4ba4c4f954f565facc204c2f42947a37704eb1e;p=openvswitch datapath: Change ODP_PORT_LIST semantics. Until now, ODP_PORT_LIST has reported the number of ports actually copied out. It's better for the caller, however, if it reports the number of ports that were available to be copied out. --- diff --git a/datapath/datapath.c b/datapath/datapath.c index e545cda0..14779a60 100644 --- a/datapath/datapath.c +++ b/datapath/datapath.c @@ -1260,7 +1260,7 @@ list_ports(struct datapath *dp, struct odp_portvec __user *pvp) break; } } - return put_user(idx, &pvp->n_ports); + return put_user(dp->n_ports, &pvp->n_ports); } /* RCU callback for freeing a dp_port_group */ diff --git a/lib/dpif.c b/lib/dpif.c index e0e5f364..85d05bb7 100644 --- a/lib/dpif.c +++ b/lib/dpif.c @@ -337,33 +337,48 @@ dpif_port_get_name(struct dpif *dpif, uint16_t port_no, int dpif_port_list(const struct dpif *dpif, - struct odp_port **ports, size_t *n_ports) + struct odp_port **portsp, size_t *n_portsp) { - struct odp_portvec pv; - struct odp_stats stats; + struct odp_port *ports; + size_t n_ports; int error; - do { + for (;;) { + struct odp_stats stats; + struct odp_portvec pv; + error = dpif_get_dp_stats(dpif, &stats); if (error) { - goto error; + goto exit; } - *ports = xcalloc(1, stats.n_ports * sizeof **ports); - pv.ports = *ports; + ports = xcalloc(stats.n_ports, sizeof *ports); + pv.ports = ports; pv.n_ports = stats.n_ports; error = do_ioctl(dpif, ODP_PORT_LIST, "ODP_PORT_LIST", &pv); if (error) { - free(*ports); - goto error; + /* Hard error. */ + free(ports); + goto exit; + } else if (pv.n_ports <= stats.n_ports) { + /* Success. */ + error = 0; + n_ports = pv.n_ports; + goto exit; + } else { + /* Soft error: port count increased behind our back. Try again. */ + free(ports); } - } while (pv.n_ports != stats.n_ports); - *n_ports = pv.n_ports; - return 0; + } -error: - *ports = NULL; - *n_ports = 0; +exit: + if (error) { + *portsp = NULL; + *n_portsp = 0; + } else { + *portsp = ports; + *n_portsp = n_ports; + } return error; }