|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Minios-devel] [UNIKRAFT LWIP PATCH v2 1/6] Use vfs functions to allocate/free the resources used for a socket (Part I)
Reviewed-by: Costin Lupu <costin.lupu@xxxxxxxxx>
On 6/29/19 4:54 PM, Mihai Pogonaru wrote:
> 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;
> }
>
_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |