/* network stub calls */
#include <sys/time.h>
#include <vfscore/file.h>
+#include <vfscore/fs.h>
+#include <vfscore/vnode.h>
#include <uk/alloc.h>
#include <uk/essentials.h>
#include <uk/errptr.h>
return file;
}
-static int sock_fd_alloc(struct vfscore_fops *fops, int sock_fd)
+static int sock_fd_alloc(struct vnops *v_op, int sock_fd)
{
int ret = 0;
int vfs_fd;
struct sock_net_file *file = NULL;
+ struct dentry *s_dentry;
+ struct vnode *s_vnode;
- /* Allocate file descriptor */
+ /* Reserve file descriptor number */
vfs_fd = vfscore_alloc_fd();
if (vfs_fd < 0) {
ret = -ENFILE;
- LWIP_DEBUGF(SOCKETS_DEBUG, ("failed to allocate socket fd\n"));
- goto EXIT;
+ LWIP_DEBUGF(SOCKETS_DEBUG,
+ ("Failed to allocate file descriptor number\n"));
+ goto ERR_EXIT;
}
- file = uk_malloc(uk_alloc_get_default(), sizeof(*file));
+ /* Allocate file, dentry, and vnode */
+ file = uk_calloc(uk_alloc_get_default(), 1, sizeof(*file));
if (!file) {
ret = -ENOMEM;
LWIP_DEBUGF(SOCKETS_DEBUG,
- ("failed to allocate socket fd: no mem\n"));
- goto UK_MEM_ALLOC_ERR;
+ ("Failed to allocate socket file: Out of memory\n"));
+ goto ERR_MALLOC_FILE;
+ }
+ s_dentry = uk_calloc(uk_alloc_get_default(), 1, sizeof(*s_dentry));
+ if (!s_dentry) {
+ ret = -ENOMEM;
+ LWIP_DEBUGF(SOCKETS_DEBUG,
+ ("Failed to allocate socket dentry: Out of memory\n"));
+ goto ERR_MALLOC_DENTRY;
+ }
+ s_vnode = uk_calloc(uk_alloc_get_default(), 1, sizeof(*s_vnode));
+ if (!s_vnode) {
+ ret = -ENOMEM;
+ LWIP_DEBUGF(SOCKETS_DEBUG,
+ ("Failed to allocate socket vnode: Out of memory\n"));
+ goto ERR_MALLOC_VNODE;
}
- file->vfscore_file.fops = fops;
+
+ /* Put things together, and fill out necessary fields */
+ file->vfscore_file.fd = vfs_fd;
+ file->vfscore_file.f_flags = FWRITE | FREAD;
+ file->vfscore_file.f_count = 1;
+ file->vfscore_file.f_dentry = s_dentry;
+
+ s_dentry->d_vnode = s_vnode;
+
+ s_vnode->v_op = v_op;
+ uk_mutex_init(&s_vnode->v_lock);
+ s_vnode->v_refcnt = 1;
+ s_vnode->v_data = file;
+
file->sock_fd = sock_fd;
- LWIP_DEBUGF(SOCKETS_DEBUG, ("allocated socket %d (%x)\n",
+ LWIP_DEBUGF(SOCKETS_DEBUG, ("Allocated socket %d (%x)\n",
file->vfscore_file.fd,
file->sock_fd));
+
/* Storing the information within the vfs structure */
- vfscore_install_fd(vfs_fd, &file->vfscore_file);
- ret = vfs_fd;
-EXIT:
- return ret;
+ ret = vfscore_install_fd(vfs_fd, &file->vfscore_file);
+ if (ret) {
+ LWIP_DEBUGF(SOCKETS_DEBUG,
+ ("Failed to install socket fd\n"));
+ goto ERR_VFS_INSTALL;
+ }
+
+ /* Return file descriptor of our socket */
+ return vfs_fd;
-UK_MEM_ALLOC_ERR:
+ERR_VFS_INSTALL:
+ uk_free(uk_alloc_get_default(), s_vnode);
+ERR_MALLOC_VNODE:
+ uk_free(uk_alloc_get_default(), s_dentry);
+ERR_MALLOC_DENTRY:
+ uk_free(uk_alloc_get_default(), file);
+ERR_MALLOC_FILE:
vfscore_put_fd(vfs_fd);
- goto EXIT;
+ERR_EXIT:
+ UK_ASSERT(ret < 0);
+ return ret;
}
-static int sock_net_close(struct vfscore_file *vfscore_file)
+static int sock_net_close(struct vnode *s_vnode,
+ struct vfscore_file *vfscore_file __maybe_unused)
{
int ret = 0;
struct sock_net_file *file = NULL;
- file = __containerof(vfscore_file, struct sock_net_file, vfscore_file);
-
- LWIP_DEBUGF(SOCKETS_DEBUG, ("close %d (%x)\n",
+ file = s_vnode->v_data;
+ LWIP_DEBUGF(SOCKETS_DEBUG, ("%s fd:%d lwip_fd:%d\n",
+ __func__,
file->vfscore_file.fd,
file->sock_fd));
+ UK_ASSERT(vfscore_file->f_dentry->d_vnode == s_vnode);
+ UK_ASSERT(s_vnode->v_refcnt == 1);
+
/* Close and release the lwip socket */
ret = lwip_close(file->sock_fd);
- /* Release the file descriptor */
+ /* Release the file descriptor number */
vfscore_put_fd(file->vfscore_file.fd);
- /* Free the sock net structure */
+ /* Free socket vnode */
+ uk_free(uk_alloc_get_default(), file->vfscore_file.f_dentry->d_vnode);
+ /* Free socket dentry */
+ uk_free(uk_alloc_get_default(), file->vfscore_file.f_dentry);
+ /* Free socket file */
uk_free(uk_alloc_get_default(), file);
return ret;
}
-static ssize_t sock_net_write(struct vfscore_file *vfscore_file,
- const void *buf, size_t count)
+static ssize_t sock_net_write(struct vnode *s_vnode,
+ struct uio *buf, int ioflag __unused)
{
int ret = 0;
struct sock_net_file *file = NULL;
- file = __containerof(vfscore_file, struct sock_net_file,
- vfscore_file);
- LWIP_DEBUGF(SOCKETS_DEBUG, ("write %d (%x):%s\n",
+ file = s_vnode->v_data;
+ LWIP_DEBUGF(SOCKETS_DEBUG, ("%s fd:%d lwip_fd:%d\n",
+ __func__,
file->vfscore_file.fd,
- file->sock_fd,
- (char *) buf));
- ret = lwip_write(file->sock_fd, buf, count);
+ file->sock_fd));
+ ret = lwip_writev(file->sock_fd, buf->uio_iov, buf->uio_iovcnt);
return ret;
}
-static ssize_t sock_net_read(struct vfscore_file *vfscore_file, void *buf,
- size_t count)
+static ssize_t sock_net_read(struct vnode *s_vnode,
+ struct vfscore_file *vfscore_file __unused,
+ struct uio *buf, int ioflag __unused)
{
int ret = 0;
struct sock_net_file *file = NULL;
- file = __containerof(vfscore_file, struct sock_net_file,
- vfscore_file);
- LWIP_DEBUGF(SOCKETS_DEBUG, ("write %d (%x):%s\n",
+ file = s_vnode->v_data;
+ LWIP_DEBUGF(SOCKETS_DEBUG, ("%s fd:%d lwip_fd:%d\n",
+ __func__,
file->vfscore_file.fd,
- file->sock_fd,
- (char *) buf));
- ret = lwip_read(file->sock_fd, buf, count);
+ file->sock_fd));
+ ret = lwip_readv(file->sock_fd, buf->uio_iov, buf->uio_iovcnt);
return ret;
}
-static struct vfscore_fops sock_net_fops = {
- .close = sock_net_close,
- .write = sock_net_write,
- .read = sock_net_read,
+static struct vnops sock_net_fops = {
+ .vop_close = sock_net_close,
+ .vop_write = sock_net_write,
+ .vop_read = sock_net_read,
};
int socket(int domain, int type, int protocol)
file = sock_net_file_get(s);
if (PTRISERR(file)) {
LWIP_DEBUGF(SOCKETS_DEBUG,
- ("failed to accept incomingi connection\n"));
+ ("failed to accept incoming connection\n"));
ret = -1;
/* Setting the errno */
SOCK_NET_SET_ERRNO(PTR2ERR(file));
LWIP_DEBUGF(SOCKETS_DEBUG,
("failed to accept incoming connection\n"));
ret = -1;
- goto EXIT;
+ goto EXIT_FDROP;
}
/* Allocate the file descriptor for the accepted connection */
goto LWIP_SOCKET_CLEANUP;
}
ret = vfs_fd;
+EXIT_FDROP:
+ vfscore_put_file(&file->vfscore_file); /* release refcount */
EXIT:
return ret;
LWIP_SOCKET_CLEANUP:
lwip_close(sock_fd);
- goto EXIT;
+ goto EXIT_FDROP;
}
int bind(int s, const struct sockaddr *name, socklen_t namelen)
LWIP_DEBUGF(SOCKETS_DEBUG,
("failed to bind with socket\n"));
ret = -1;
- goto EXIT;
+ goto EXIT_FDROP;
}
+EXIT_FDROP:
+ vfscore_put_file(&file->vfscore_file); /* release refcount */
EXIT:
return ret;
}
}
/* Shutdown of the descriptor */
ret = lwip_shutdown(file->sock_fd, how);
+ vfscore_put_file(&file->vfscore_file); /* release refcount */
EXIT:
return ret;
}
goto EXIT;
}
ret = lwip_getpeername(file->sock_fd, name, namelen);
+ vfscore_put_file(&file->vfscore_file); /* release refcount */
EXIT:
return ret;
}
goto EXIT;
}
ret = lwip_getsockname(file->sock_fd, name, namelen);
+ vfscore_put_file(&file->vfscore_file); /* release refcount */
EXIT:
return ret;
}
goto EXIT;
}
ret = lwip_getsockopt(file->sock_fd, level, optname, optval, optlen);
+ vfscore_put_file(&file->vfscore_file); /* release refcount */
EXIT:
return ret;
}
goto EXIT;
}
ret = lwip_setsockopt(file->sock_fd, level, optname, optval, optlen);
+ vfscore_put_file(&file->vfscore_file); /* release refcount */
EXIT:
return ret;
}
goto EXIT;
}
ret = lwip_connect(file->sock_fd, name, namelen);
+ vfscore_put_file(&file->vfscore_file); /* release refcount */
EXIT:
return ret;
}
goto EXIT;
}
ret = lwip_listen(file->sock_fd, backlog);
+ vfscore_put_file(&file->vfscore_file); /* release refcount */
EXIT:
return ret;
}
goto EXIT;
}
ret = lwip_recv(file->sock_fd, mem, len, flags);
+ vfscore_put_file(&file->vfscore_file); /* release refcount */
EXIT:
return ret;
}
goto EXIT;
}
ret = lwip_recvfrom(file->sock_fd, mem, len, flags, from, fromlen);
+ vfscore_put_file(&file->vfscore_file); /* release refcount */
EXIT:
return ret;
}
goto EXIT;
}
ret = lwip_send(file->sock_fd, dataptr, size, flags);
+ vfscore_put_file(&file->vfscore_file); /* release refcount */
EXIT:
return ret;
}
goto EXIT;
}
ret = lwip_sendmsg(file->sock_fd, message, flags);
+ vfscore_put_file(&file->vfscore_file); /* release refcount */
EXIT:
return ret;
}
goto EXIT;
}
ret = lwip_sendto(file->sock_fd, dataptr, size, flags, to, tolen);
+ vfscore_put_file(&file->vfscore_file); /* release refcount */
EXIT:
return ret;
}