|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Minios-devel] [UNIKRAFT LWIP PATCH v2 1/6] Use vfs functions to allocate/free the resources used for a socket (Part I)
This part changes LWIP so that it lets vfs to free the resources
used to integrate sockets in vfs.
Right now sock_net_close frees the vfscore_file, dentry and vnode
used for the socket. This can cause problems since vfs unlocks the
vnode after calling sock_net_close so it accesses freed memory.
We will let vfs handle the freeing of the resources used for a
socket by setting the dentry refcount to 1 such that, when a socket is
closed (so its vfscore_file is also closed), the dentry's refcount
hits 0, the dentry is deleted so the vnode refcount hits 0
and it is also deleted.
Signed-off-by: Mihai Pogonaru <pogonarumihai@xxxxxxxxx>
---
sockets.c | 123 ++++++++++++++++++++++++++++++++++++++++++--------------------
1 file changed, 83 insertions(+), 40 deletions(-)
diff --git a/sockets.c b/sockets.c
index e95758d..cbe3030 100644
--- a/sockets.c
+++ b/sockets.c
@@ -37,6 +37,7 @@
#include <sys/time.h>
#include <vfscore/file.h>
#include <vfscore/fs.h>
+#include <vfscore/mount.h>
#include <vfscore/vnode.h>
#include <uk/alloc.h>
#include <uk/essentials.h>
@@ -48,8 +49,16 @@
#define SOCK_NET_SET_ERRNO(errcode) \
(errno = -(errcode))
+/*
+ * Bogus mount point used by all sockets
+ *
+ * We need this because when deleting a vnode
+ * vfs calls vfs_unbusy on its mount point
+ */
+static struct mount s_mount;
+
struct sock_net_file {
- struct vfscore_file vfscore_file;
+ struct vfscore_file *vfscore_file;
int sock_fd;
};
@@ -58,7 +67,7 @@ static inline struct sock_net_file *sock_net_file_get(int fd)
struct sock_net_file *file = NULL;
struct vfscore_file *fos;
- fos = vfscore_get_file(fd);
+ fos = vfscore_get_file(fd);
if (!fos) {
LWIP_DEBUGF(SOCKETS_DEBUG,
("failed with invalid descriptor\n"));
@@ -71,7 +80,7 @@ static inline struct sock_net_file *sock_net_file_get(int fd)
file = ERR2PTR(-EBADF);
goto EXIT;
}
- file = __containerof(fos, struct sock_net_file, vfscore_file);
+ file = fos->f_data;
EXIT:
return file;
}
@@ -81,6 +90,7 @@ 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 vfscore_file *vfs_file = NULL;
struct dentry *s_dentry;
struct vnode *s_vnode;
@@ -101,6 +111,13 @@ static int sock_fd_alloc(struct vnops *v_op, int sock_fd)
("Failed to allocate socket file: Out of
memory\n"));
goto ERR_MALLOC_FILE;
}
+ vfs_file = uk_calloc(uk_alloc_get_default(), 1, sizeof(*vfs_file));
+ if (!vfs_file) {
+ ret = -ENOMEM;
+ LWIP_DEBUGF(SOCKETS_DEBUG,
+ ("Failed to allocate socket vfs_file: Out of
memory\n"));
+ goto ERR_MALLOC_VFS_FILE;
+ }
s_dentry = uk_calloc(uk_alloc_get_default(), 1, sizeof(*s_dentry));
if (!s_dentry) {
ret = -ENOMEM;
@@ -117,26 +134,46 @@ static int sock_fd_alloc(struct vnops *v_op, int sock_fd)
}
/* Put things together, and fill out necessary fields */
- file->vfscore_file.fd = vfs_fd;
- file->vfscore_file.f_flags = UK_FWRITE | UK_FREAD;
- file->vfscore_file.f_count = 1;
- file->vfscore_file.f_dentry = s_dentry;
+ vfs_file->fd = vfs_fd;
+ vfs_file->f_flags = UK_FWRITE | UK_FREAD;
+ vfs_file->f_count = 1;
+ vfs_file->f_data = file;
+ vfs_file->f_dentry = s_dentry;
+ s_dentry->d_refcnt = 1;
s_dentry->d_vnode = s_vnode;
+ /*
+ * Provide bogus but valid addresses to allow
+ * vfs to remove nodes from lists
+ */
+ s_dentry->d_link.pprev = &s_dentry->d_link.next;
+ s_dentry->d_names_link.next = &s_dentry->d_names_link;
+ s_dentry->d_names_link.prev = &s_dentry->d_names_link;
+
s_vnode->v_op = v_op;
uk_mutex_init(&s_vnode->v_lock);
s_vnode->v_refcnt = 1;
s_vnode->v_data = file;
s_vnode->v_type = VSOCK;
+ s_vnode->v_mount = &s_mount;
+ s_mount.m_count++;
+ /*
+ * Provide bogus but valid addresses to allow
+ * vfs to remove nodes from lists
+ */
+ s_vnode->v_link.next = &s_vnode->v_link;
+ s_vnode->v_link.prev = &s_vnode->v_link;
+
+ file->vfscore_file = vfs_file;
file->sock_fd = sock_fd;
LWIP_DEBUGF(SOCKETS_DEBUG, ("Allocated socket %d (%x)\n",
- file->vfscore_file.fd,
+ file->vfscore_file->fd,
file->sock_fd));
/* Storing the information within the vfs structure */
- ret = vfscore_install_fd(vfs_fd, &file->vfscore_file);
+ ret = vfscore_install_fd(vfs_fd, file->vfscore_file);
if (ret) {
LWIP_DEBUGF(SOCKETS_DEBUG,
("Failed to install socket fd\n"));
@@ -151,6 +188,8 @@ ERR_VFS_INSTALL:
ERR_MALLOC_VNODE:
uk_free(uk_alloc_get_default(), s_dentry);
ERR_MALLOC_DENTRY:
+ uk_free(uk_alloc_get_default(), vfs_file);
+ERR_MALLOC_VFS_FILE:
uk_free(uk_alloc_get_default(), file);
ERR_MALLOC_FILE:
vfscore_put_fd(vfs_fd);
@@ -160,15 +199,15 @@ ERR_EXIT:
}
static int sock_net_close(struct vnode *s_vnode,
- struct vfscore_file *vfscore_file __maybe_unused)
+ struct vfscore_file *vfscore_file)
{
- int ret = 0;
+ int ret;
struct sock_net_file *file = NULL;
file = s_vnode->v_data;
LWIP_DEBUGF(SOCKETS_DEBUG, ("%s fd:%d lwip_fd:%d\n",
__func__,
- file->vfscore_file.fd,
+ file->vfscore_file->fd,
file->sock_fd));
UK_ASSERT(vfscore_file->f_dentry->d_vnode == s_vnode);
@@ -176,12 +215,13 @@ static int sock_net_close(struct vnode *s_vnode,
/* Close and release the lwip socket */
ret = lwip_close(file->sock_fd);
- /* 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 */
+
+ /*
+ * Free socket file
+ * The rest of the resources will be freed by vfs
+ */
uk_free(uk_alloc_get_default(), file);
+
return ret;
}
@@ -194,7 +234,7 @@ static ssize_t sock_net_write(struct vnode *s_vnode,
file = s_vnode->v_data;
LWIP_DEBUGF(SOCKETS_DEBUG, ("%s fd:%d lwip_fd:%d\n",
__func__,
- file->vfscore_file.fd,
+ file->vfscore_file->fd,
file->sock_fd));
ret = lwip_writev(file->sock_fd, buf->uio_iov, buf->uio_iovcnt);
return ret;
@@ -210,16 +250,19 @@ static ssize_t sock_net_read(struct vnode *s_vnode,
file = s_vnode->v_data;
LWIP_DEBUGF(SOCKETS_DEBUG, ("%s fd:%d lwip_fd:%d\n",
__func__,
- file->vfscore_file.fd,
+ file->vfscore_file->fd,
file->sock_fd));
ret = lwip_readv(file->sock_fd, buf->uio_iov, buf->uio_iovcnt);
return ret;
}
+#define sock_net_inactive ((vnop_inactive_t) vfscore_vop_nullop)
+
static struct vnops sock_net_fops = {
.vop_close = sock_net_close,
.vop_write = sock_net_write,
.vop_read = sock_net_read,
+ .vop_inactive = sock_net_inactive
};
int socket(int domain, int type, int protocol)
@@ -296,7 +339,7 @@ int accept(int s, struct sockaddr *addr, socklen_t *addrlen)
}
ret = vfs_fd;
EXIT_FDROP:
- vfscore_put_file(&file->vfscore_file); /* release refcount */
+ vfscore_put_file(file->vfscore_file); /* release refcount */
EXIT:
return ret;
@@ -328,7 +371,7 @@ int bind(int s, const struct sockaddr *name, socklen_t
namelen)
goto EXIT_FDROP;
}
EXIT_FDROP:
- vfscore_put_file(&file->vfscore_file); /* release refcount */
+ vfscore_put_file(file->vfscore_file); /* release refcount */
EXIT:
return ret;
}
@@ -355,7 +398,7 @@ int poll(struct pollfd fds[], nfds_t nfds, int timeout)
}
lwip_fds[i].fd = file->sock_fd;
lwip_fds[i].events = fds[i].events;
- vfscore_put_file(&file->vfscore_file); /* release
refcount */
+ vfscore_put_file(file->vfscore_file); /* release
refcount */
}
}
@@ -408,7 +451,7 @@ int select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds,
if (maxfd < file->sock_fd)
maxfd = file->sock_fd;
FD_SET(file->sock_fd, &rd);
- vfscore_put_file(&file->vfscore_file); /* release
refcount */
+ vfscore_put_file(file->vfscore_file); /* release
refcount */
}
if (writefds && FD_ISSET(i, writefds)) {
file = sock_net_file_get(i);
@@ -423,7 +466,7 @@ int select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds,
if (maxfd < file->sock_fd)
maxfd = file->sock_fd;
FD_SET(file->sock_fd, &wr);
- vfscore_put_file(&file->vfscore_file); /* release
refcount */
+ vfscore_put_file(file->vfscore_file); /* release
refcount */
}
if (exceptfds && FD_ISSET(i, exceptfds)) {
file = sock_net_file_get(i);
@@ -438,7 +481,7 @@ int select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds,
if (maxfd < file->sock_fd)
maxfd = file->sock_fd;
FD_SET(file->sock_fd, &xc);
- vfscore_put_file(&file->vfscore_file); /* release
refcount */
+ vfscore_put_file(file->vfscore_file); /* release
refcount */
}
}
@@ -459,7 +502,7 @@ int select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds,
file = sock_net_file_get(i);
if (!FD_ISSET(file->sock_fd, &rd))
FD_CLR(i, readfds);
- vfscore_put_file(&file->vfscore_file); /* release
refcount */
+ vfscore_put_file(file->vfscore_file); /* release
refcount */
}
if (writefds && FD_ISSET(i, writefds)) {
/* This lookup can't fail, or it would already have
@@ -468,7 +511,7 @@ int select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds,
file = sock_net_file_get(i);
if (!FD_ISSET(file->sock_fd, &wr))
FD_CLR(i, writefds);
- vfscore_put_file(&file->vfscore_file); /* release
refcount */
+ vfscore_put_file(file->vfscore_file); /* release
refcount */
}
if (exceptfds && FD_ISSET(i, exceptfds)) {
/* This lookup can't fail, or it would already have
@@ -477,7 +520,7 @@ int select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds,
file = sock_net_file_get(i);
if (!FD_ISSET(file->sock_fd, &xc))
FD_CLR(i, exceptfds);
- vfscore_put_file(&file->vfscore_file); /* release
refcount */
+ vfscore_put_file(file->vfscore_file); /* release
refcount */
}
}
@@ -501,7 +544,7 @@ int shutdown(int s, int how)
}
/* Shutdown of the descriptor */
ret = lwip_shutdown(file->sock_fd, how);
- vfscore_put_file(&file->vfscore_file); /* release refcount */
+ vfscore_put_file(file->vfscore_file); /* release refcount */
EXIT:
return ret;
}
@@ -519,7 +562,7 @@ int getpeername(int s, struct sockaddr *name, socklen_t
*namelen)
goto EXIT;
}
ret = lwip_getpeername(file->sock_fd, name, namelen);
- vfscore_put_file(&file->vfscore_file); /* release refcount */
+ vfscore_put_file(file->vfscore_file); /* release refcount */
EXIT:
return ret;
}
@@ -537,7 +580,7 @@ int getsockname(int s, struct sockaddr *name, socklen_t
*namelen)
goto EXIT;
}
ret = lwip_getsockname(file->sock_fd, name, namelen);
- vfscore_put_file(&file->vfscore_file); /* release refcount */
+ vfscore_put_file(file->vfscore_file); /* release refcount */
EXIT:
return ret;
}
@@ -556,7 +599,7 @@ int getsockopt(int s, int level, int optname, void *optval,
socklen_t *optlen)
goto EXIT;
}
ret = lwip_getsockopt(file->sock_fd, level, optname, optval, optlen);
- vfscore_put_file(&file->vfscore_file); /* release refcount */
+ vfscore_put_file(file->vfscore_file); /* release refcount */
EXIT:
return ret;
}
@@ -576,7 +619,7 @@ int setsockopt(int s, int level, int optname, const void
*optval,
goto EXIT;
}
ret = lwip_setsockopt(file->sock_fd, level, optname, optval, optlen);
- vfscore_put_file(&file->vfscore_file); /* release refcount */
+ vfscore_put_file(file->vfscore_file); /* release refcount */
EXIT:
return ret;
}
@@ -595,7 +638,7 @@ int connect(int s, const struct sockaddr *name, socklen_t
namelen)
goto EXIT;
}
ret = lwip_connect(file->sock_fd, name, namelen);
- vfscore_put_file(&file->vfscore_file); /* release refcount */
+ vfscore_put_file(file->vfscore_file); /* release refcount */
EXIT:
return ret;
}
@@ -614,7 +657,7 @@ int listen(int s, int backlog)
goto EXIT;
}
ret = lwip_listen(file->sock_fd, backlog);
- vfscore_put_file(&file->vfscore_file); /* release refcount */
+ vfscore_put_file(file->vfscore_file); /* release refcount */
EXIT:
return ret;
}
@@ -633,7 +676,7 @@ int recv(int s, void *mem, size_t len, int flags)
goto EXIT;
}
ret = lwip_recv(file->sock_fd, mem, len, flags);
- vfscore_put_file(&file->vfscore_file); /* release refcount */
+ vfscore_put_file(file->vfscore_file); /* release refcount */
EXIT:
return ret;
}
@@ -653,7 +696,7 @@ int recvfrom(int s, void *mem, size_t len, int flags,
goto EXIT;
}
ret = lwip_recvfrom(file->sock_fd, mem, len, flags, from, fromlen);
- vfscore_put_file(&file->vfscore_file); /* release refcount */
+ vfscore_put_file(file->vfscore_file); /* release refcount */
EXIT:
return ret;
}
@@ -672,7 +715,7 @@ int send(int s, const void *dataptr, size_t size, int flags)
goto EXIT;
}
ret = lwip_send(file->sock_fd, dataptr, size, flags);
- vfscore_put_file(&file->vfscore_file); /* release refcount */
+ vfscore_put_file(file->vfscore_file); /* release refcount */
EXIT:
return ret;
}
@@ -691,7 +734,7 @@ int sendmsg(int s, const struct msghdr *message, int flags)
goto EXIT;
}
ret = lwip_sendmsg(file->sock_fd, message, flags);
- vfscore_put_file(&file->vfscore_file); /* release refcount */
+ vfscore_put_file(file->vfscore_file); /* release refcount */
EXIT:
return ret;
}
@@ -711,7 +754,7 @@ int sendto(int s, const void *dataptr, size_t size, int
flags,
goto EXIT;
}
ret = lwip_sendto(file->sock_fd, dataptr, size, flags, to, tolen);
- vfscore_put_file(&file->vfscore_file); /* release refcount */
+ vfscore_put_file(file->vfscore_file); /* release refcount */
EXIT:
return ret;
}
--
2.11.0
_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |