[RFC 04/12] WIP: fs/nfs.c: convert to picotcp
Antony Pavlov
antonynpavlov at gmail.com
Wed Jul 15 13:13:42 PDT 2015
Signed-off-by: Antony Pavlov <antonynpavlov at gmail.com>
---
fs/nfs.c | 150 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 133 insertions(+), 17 deletions(-)
diff --git a/fs/nfs.c b/fs/nfs.c
index 5bff54a..f4be54a 100644
--- a/fs/nfs.c
+++ b/fs/nfs.c
@@ -37,6 +37,10 @@
#include <byteorder.h>
#include <globalvar.h>
+#include <pico_socket.h>
+#include <pico_ipv4.h>
+#include <poller.h>
+
#include "parseopt.h"
#define SUNRPC_PORT 111
@@ -131,9 +135,14 @@ struct rpc_reply {
struct nfs_priv {
struct net_connection *con;
IPaddr_t server;
+
+ struct pico_socket *sock;
+ union pico_address remote_address;
+ uint8_t *pkt;
+
char *path;
- unsigned short mount_port;
- unsigned short nfs_port;
+ uint16_t mount_port;
+ uint16_t nfs_port;
uint32_t rpc_id;
uint32_t rootfh_len;
char rootfh[NFS3_FHSIZE];
@@ -383,10 +392,16 @@ static int rpc_req(struct nfs_priv *npriv, int rpc_prog, int rpc_proc,
struct rpc_call pkt;
unsigned short dport;
int ret;
- unsigned char *payload = net_udp_get_payload(npriv->con);
+ unsigned char *payload;
int nfserr;
int tries = 0;
+ if (IS_ENABLED(CONFIG_NET_LEGACY)) {
+ payload = net_udp_get_payload(npriv->con);
+ } else if (IS_ENABLED(CONFIG_NET_PICOTCP)) {
+ payload = npriv->pkt;
+ }
+
npriv->rpc_id++;
pkt.id = hton32(npriv->rpc_id);
@@ -398,7 +413,11 @@ static int rpc_req(struct nfs_priv *npriv, int rpc_prog, int rpc_proc,
debug("%s: prog: %d, proc: %d\n", __func__, rpc_prog, rpc_proc);
if (rpc_prog == PROG_PORTMAP) {
- dport = SUNRPC_PORT;
+ if (IS_ENABLED(CONFIG_NET_LEGACY)) {
+ dport = SUNRPC_PORT;
+ } else if (IS_ENABLED(CONFIG_NET_PICOTCP)) {
+ dport = hton16(SUNRPC_PORT);
+ }
pkt.vers = hton32(2);
} else if (rpc_prog == PROG_MOUNT) {
dport = npriv->mount_port;
@@ -408,14 +427,25 @@ static int rpc_req(struct nfs_priv *npriv, int rpc_prog, int rpc_proc,
pkt.vers = hton32(3);
}
+ /* FIXME: picotcp can skip extra copy here */
memcpy(payload, &pkt, sizeof(pkt));
memcpy(payload + sizeof(pkt), data, datalen * sizeof(uint32_t));
- npriv->con->udp->uh_dport = hton16(dport);
+ if (IS_ENABLED(CONFIG_NET_LEGACY)) {
+ npriv->con->udp->uh_dport = hton16(dport);
+ }
again:
- ret = net_udp_send(npriv->con,
+
+ if (IS_ENABLED(CONFIG_NET_LEGACY)) {
+ ret = net_udp_send(npriv->con,
sizeof(pkt) + datalen * sizeof(uint32_t));
+ } else if (IS_ENABLED(CONFIG_NET_PICOTCP)) {
+ /* FIXME: picotcp ret code meaning is different */
+ ret = pico_socket_sendto(npriv->sock, npriv->pkt,
+ sizeof(pkt) + datalen * sizeof(uint32_t),
+ &npriv->remote_address, dport);
+ }
nfs_timer_start = get_time_ns();
@@ -427,7 +457,13 @@ again:
ret = -EINTR;
break;
}
- net_poll();
+
+ if (IS_ENABLED(CONFIG_NET_LEGACY)) {
+ net_poll();
+ } else if (IS_ENABLED(CONFIG_NET_PICOTCP)) {
+ /* do we really need it? is_timeout() can do this work for us. */
+ poller_call();
+ }
if (is_timeout(nfs_timer_start, NFS_TIMEOUT)) {
tries++;
@@ -1324,6 +1360,48 @@ static void nfs_set_rootarg(struct nfs_priv *npriv, struct fs_device_d *fsdev)
free(str);
}
+static void nfs_cb(uint16_t ev, struct pico_socket *sock)
+{
+ struct nfs_priv *npriv = sock->priv;
+ char *pkt = npriv->pkt;
+ int len;
+ union pico_address ep;
+ uint16_t remote_port;
+
+ if (ev == PICO_SOCK_EV_ERR) {
+ printf(" >>>>>> PICO_SOCK_EV_ERR <<<<<<< \n");
+ return;
+ }
+
+ /* FIXME: 2000 */
+ len = pico_socket_recvfrom(sock, pkt, 2000, &ep, &remote_port);
+
+ nfs_state = STATE_DONE;
+ nfs_packet = pkt;
+ nfs_len = len;
+}
+
+static struct pico_socket *nfs_socket_open(uint16_t localport)
+{
+ struct pico_socket *sock;
+ union pico_address local_address;
+
+ sock = pico_socket_open(PICO_PROTO_IPV4, PICO_PROTO_UDP, nfs_cb);
+ if (!sock)
+ return NULL;
+
+ localport = short_be(localport);
+
+ /* FIXME: use local_address == PICO_IPV4_INADDR_ANY */
+ memset(&local_address, 0, sizeof(union pico_address));
+ if (pico_socket_bind(sock, &local_address, &localport) < 0) {
+ pico_socket_close(sock);
+ return NULL;
+ }
+
+ return sock;
+}
+
static int nfs_probe(struct device_d *dev)
{
struct fs_device_d *fsdev = dev_to_fs_device(dev);
@@ -1346,19 +1424,38 @@ static int nfs_probe(struct device_d *dev)
npriv->path = xstrdup(path + 1);
- npriv->server = resolv(tmp);
+ if (IS_ENABLED(CONFIG_NET_LEGACY)) {
+ npriv->server = resolv(tmp);
+ } else if (IS_ENABLED(CONFIG_NET_PICOTCP)) {
+ /* FIXME: check corectness */
+ npriv->remote_address.ip4.addr = resolv(tmp);
+ }
debug("nfs: server: %s path: %s\n", tmp, npriv->path);
- npriv->con = net_udp_new(npriv->server, 0, nfs_handler, npriv);
- if (IS_ERR(npriv->con)) {
- ret = PTR_ERR(npriv->con);
- goto err1;
+ if (IS_ENABLED(CONFIG_NET_LEGACY)) {
+ npriv->con = net_udp_new(npriv->server, 0, nfs_handler, npriv);
+ if (IS_ERR(npriv->con)) {
+ ret = PTR_ERR(npriv->con);
+ goto err1;
+ }
+
+ /* Need a priviliged source port */
+ net_udp_bind(npriv->con, 1000);
+ } else if (IS_ENABLED(CONFIG_NET_PICOTCP)) {
+ /* FIXME: 2048 */
+ npriv->pkt = xzalloc(2048);
+
+ /* Need a priviliged source port */
+ npriv->sock = nfs_socket_open(1000);
+ if (!npriv->sock) {
+ ret = -1;
+ goto err1;
+ }
+
+ npriv->sock->priv = npriv;
}
- /* Need a priviliged source port */
- net_udp_bind(npriv->con, 1000);
-
parseopt_hu(fsdev->options, "mountport", &npriv->mount_port);
if (!npriv->mount_port) {
ret = rpc_lookup_req(npriv, PROG_MOUNT, 3);
@@ -1381,6 +1478,11 @@ static int nfs_probe(struct device_d *dev)
}
debug("nfs port: %d\n", npriv->nfs_port);
+ if (IS_ENABLED(CONFIG_NET_PICOTCP)) {
+ npriv->mount_port = hton16(npriv->mount_port);
+ npriv->nfs_port = hton16(npriv->nfs_port);
+ }
+
ret = nfs_mount_req(npriv);
if (ret) {
printf("mounting failed with %d\n", ret);
@@ -1394,8 +1496,16 @@ static int nfs_probe(struct device_d *dev)
return 0;
err2:
- net_unregister(npriv->con);
+ if (IS_ENABLED(CONFIG_NET_LEGACY)) {
+ net_unregister(npriv->con);
+ } else if (IS_ENABLED(CONFIG_NET_PICOTCP)) {
+ pico_socket_close(npriv->sock);
+ }
+
err1:
+ if (IS_ENABLED(CONFIG_NET_PICOTCP)) {
+ free(npriv->pkt);
+ }
free(npriv->path);
err:
free(tmp);
@@ -1410,7 +1520,13 @@ static void nfs_remove(struct device_d *dev)
nfs_umount_req(npriv);
- net_unregister(npriv->con);
+ if (IS_ENABLED(CONFIG_NET_LEGACY)) {
+ net_unregister(npriv->con);
+ } else if (IS_ENABLED(CONFIG_NET_PICOTCP)) {
+ pico_socket_close(npriv->sock);
+ free(npriv->pkt);
+ }
+
free(npriv->path);
free(npriv);
}
--
2.1.4
More information about the barebox
mailing list