[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

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.