On 21/04/15(Tue) 17:15, Vitaliy Makkoveev wrote:
> Now fd_getfile() function returns unacquired "struct file" instance
> [...]
> It is unacceptable on multiprocessor machine because the instance referenced
> by fp can be destroyed between fd_getfile() and FREF() calls. So I want
> fd_getfile() returns acquired fp. [...]

Your diff makes sense but sadly it is broken, could you send a diff that
can be applied?

> Index: share/man/man9/file.9
> ===================================================================
> RCS file: /cvs/src/share/man/man9/file.9,v
> retrieving revision 1.12
> diff -u -p -r1.12 file.9
> --- share/man/man9/file.9     4 Jun 2013 19:27:06 -0000       1.12
> +++ share/man/man9/file.9     21 Apr 2015 13:27:08 -0000
> @@ -42,7 +42,7 @@
> .Ft struct file *
> .Fn fd_getfile "struct filedesc *fdp" "int fd"
> .Ft int
> -.Fn getsock "struct filedesc *fdp" "int fd" "struct file **fpp"
> +.Fn getsock "struct proc *p" "int fd" "struct file **fpp"
> .In sys/file.h
> .In sys/filedesc.h
> .In sys/vnode.h
> @@ -74,21 +74,28 @@ recommended to make complicated kernel A
> .Pp
> The files are extracted from the file descriptor table using the
> functions
> -.Fn fd_getfile ,
> -.Fn getvnode
> +.Fn fd_getfile
> and
> -.Fn getsock .
> +.Fn getvnode .
> .Fn fd_getfile
> performs all necessary checks to see if the file descriptor number is
> within the range of file descriptor table, and if the descriptor is
> valid.
> -.Fn getsock
> -and
> .Fn getvnode
> -are special cases that besides doing
> +is special case that besides doing
> +.Fn fd_getfile
> +also checks if the descriptor is a vnode, returns the proper
> +errno on error and increases the use count with
> +.Fn FREF .
> +.Pp
> +The files are extracted from the process context using the
> +function
> +.Fn getsock .
> +.Fn getsock
> +is special case that besides doing
> .Fn fd_getfile
> -also check if the descriptor is a vnode or socket, return the proper
> -errno on error and increase the use count with
> +also checks if the descriptor is a socket, returns the proper
> +errno on error and increases the use count with
> .Fn FREF .
> .Sh CONCURRENT ACCESS
> Since multiple processes can share the same file descriptor table,
> Index: sys/compat/linux/linux_socket.c
> ===================================================================
> RCS file: /cvs/src/sys/compat/linux/linux_socket.c,v
> retrieving revision 1.60
> diff -u -p -r1.60 linux_socket.c
> --- sys/compat/linux/linux_socket.c   30 Jan 2015 23:38:49 -0000      1.60
> +++ sys/compat/linux/linux_socket.c   21 Apr 2015 13:28:23 -0000
> @@ -937,7 +937,7 @@ linux_setsockopt(p, v, retval)
>       if ((error = copyin((caddr_t) uap, (caddr_t) &lsa, sizeof lsa)))
>               return error;
> 
> -     if ((error = getsock(p->p_fd, lsa.s, &fp)) != 0)
> +     if ((error = getsock(p, lsa.s, &fp)) != 0)
>               return error;
>       
>       level = linux_to_bsd_sopt_level(lsa.level);
> Index: sys/kern/subr_log.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/subr_log.c,v
> retrieving revision 1.29
> diff -u -p -r1.29 subr_log.c
> --- sys/kern/subr_log.c       14 Mar 2015 03:38:50 -0000      1.29
> +++ sys/kern/subr_log.c       21 Apr 2015 13:28:42 -0000
> @@ -334,7 +334,7 @@ logioctl(dev_t dev, u_long com, caddr_t 
>       case LIOCSFD:
>               if ((error = suser(p, 0)) != 0)
>                       return (error);
> -             if ((error = getsock(p->p_fd, *(int *)data, &fp)) != 0)
> +             if ((error = getsock(p, *(int *)data, &fp)) != 0)
>                       return (error);
>               if (syslogf)
>                       FRELE(syslogf, p);
> Index: sys/kern/uipc_socket.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/uipc_socket.c,v
> retrieving revision 1.137
> diff -u -p -r1.137 uipc_socket.c
> --- sys/kern/uipc_socket.c    14 Mar 2015 03:38:51 -0000      1.137
> +++ sys/kern/uipc_socket.c    21 Apr 2015 13:28:42 -0000
> @@ -1076,7 +1076,7 @@ sosplice(struct socket *so, int fd, off_
>               return (EINVAL);
> 
>       /* Find sosp, the drain socket where data will be spliced into. */
> -     if ((error = getsock(curproc->p_fd, fd, &fp)) != 0)
> +     if ((error = getsock(curproc, fd, &fp)) != 0)
>               return (error);
>       sosp = fp->f_data;
>       if (sosp->so_sp == NULL)
> Index: sys/kern/uipc_syscalls.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/uipc_syscalls.c,v
> retrieving revision 1.100
> diff -u -p -r1.100 uipc_syscalls.c
> --- sys/kern/uipc_syscalls.c  14 Mar 2015 03:38:51 -0000      1.100
> +++ sys/kern/uipc_syscalls.c  21 Apr 2015 13:28:42 -0000
> @@ -120,7 +120,7 @@ sys_bind(struct proc *p, void *v, regist
>       struct mbuf *nam;
>       int error;
> 
> -     if ((error = getsock(p->p_fd, SCARG(uap, s), &fp)) != 0)
> +     if ((error = getsock(p, SCARG(uap, s), &fp)) != 0)
>               return (error);
>       error = sockargs(&nam, SCARG(uap, name), SCARG(uap, namelen),
>           MT_SONAME);
> @@ -147,7 +147,7 @@ sys_listen(struct proc *p, void *v, regi
>       struct file *fp;
>       int error;
> 
> -     if ((error = getsock(p->p_fd, SCARG(uap, s), &fp)) != 0)
> +     if ((error = getsock(p, SCARG(uap, s), &fp)) != 0)
>               return (error);
>       error = solisten(fp->f_data, SCARG(uap, backlog));
>       FRELE(fp, p);
> @@ -198,7 +198,7 @@ doaccept(struct proc *p, int sock, struc
> 
>       if (name && (error = copyin(anamelen, &namelen, sizeof (namelen))))
>               return (error);
> -     if ((error = getsock(fdp, sock, &fp)) != 0)
> +     if ((error = getsock(p, sock, &fp)) != 0)
>               return (error);
>       headfp = fp;
>       s = splsoftnet();
> @@ -315,7 +315,7 @@ sys_connect(struct proc *p, void *v, reg
>       struct mbuf *nam = NULL;
>       int error, s;
> 
> -     if ((error = getsock(p->p_fd, SCARG(uap, s), &fp)) != 0)
> +     if ((error = getsock(p, SCARG(uap, s), &fp)) != 0)
>               return (error);
>       so = fp->f_data;
>       if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) {
> @@ -518,7 +518,7 @@ sendit(struct proc *p, int s, struct msg
> 
>       to = NULL;
> 
> -     if ((error = getsock(p->p_fd, s, &fp)) != 0)
> +     if ((error = getsock(p, s, &fp)) != 0)
>               return (error);
>       auio.uio_iov = mp->msg_iov;
>       auio.uio_iovcnt = mp->msg_iovlen;
> @@ -684,7 +684,7 @@ recvit(struct proc *p, int s, struct msg
>       int iovlen = 0;
> #endif
> 
> -     if ((error = getsock(p->p_fd, s, &fp)) != 0)
> +     if ((error = getsock(p, s, &fp)) != 0)
>               return (error);
>       auio.uio_iov = mp->msg_iov;
>       auio.uio_iovcnt = mp->msg_iovlen;
> @@ -803,7 +803,7 @@ sys_shutdown(struct proc *p, void *v, re
>       struct file *fp;
>       int error;
> 
> -     if ((error = getsock(p->p_fd, SCARG(uap, s), &fp)) != 0)
> +     if ((error = getsock(p, SCARG(uap, s), &fp)) != 0)
>               return (error);
>       error = soshutdown(fp->f_data, SCARG(uap, how));
>       FRELE(fp, p);
> @@ -825,7 +825,7 @@ sys_setsockopt(struct proc *p, void *v, 
>       struct mbuf *m = NULL;
>       int error;
> 
> -     if ((error = getsock(p->p_fd, SCARG(uap, s), &fp)) != 0)
> +     if ((error = getsock(p, SCARG(uap, s), &fp)) != 0)
>               return (error);
>       if (SCARG(uap, valsize) > MCLBYTES) {
>               error = EINVAL;
> @@ -876,7 +876,7 @@ sys_getsockopt(struct proc *p, void *v, 
>       socklen_t valsize;
>       int error;
> 
> -     if ((error = getsock(p->p_fd, SCARG(uap, s), &fp)) != 0)
> +     if ((error = getsock(p, SCARG(uap, s), &fp)) != 0)
>               return (error);
>       if (SCARG(uap, val)) {
>               error = copyin(SCARG(uap, avalsize),
> @@ -920,7 +920,7 @@ sys_getsockname(struct proc *p, void *v,
>       socklen_t len;
>       int error;
> 
> -     if ((error = getsock(p->p_fd, SCARG(uap, fdes), &fp)) != 0)
> +     if ((error = getsock(p, SCARG(uap, fdes), &fp)) != 0)
>               return (error);
>       error = copyin(SCARG(uap, alen), &len, sizeof (len));
>       if (error)
> @@ -956,7 +956,7 @@ sys_getpeername(struct proc *p, void *v,
>       socklen_t len;
>       int error;
> 
> -     if ((error = getsock(p->p_fd, SCARG(uap, fdes), &fp)) != 0)
> +     if ((error = getsock(p, SCARG(uap, fdes), &fp)) != 0)
>               return (error);
>       so = fp->f_data;
>       if ((so->so_state & SS_ISCONNECTED) == 0) {
> @@ -1016,11 +1016,11 @@ sockargs(struct mbuf **mp, const void *b
> }
> 
> int
> -getsock(struct filedesc *fdp, int fdes, struct file **fpp)
> +getsock(struct proc *p, int fdes, struct file **fpp)
> {
>       struct file *fp;
> 
> -     if ((fp = fd_getfile(fdp, fdes)) == NULL)
> +     if ((fp = fd_getfile(p->p_fd, fdes)) == NULL)
>               return (EBADF);
>       if (fp->f_type != DTYPE_SOCKET)
>               return (ENOTSOCK);
> Index: sys/nfs/nfs_syscalls.c
> ===================================================================
> RCS file: /cvs/src/sys/nfs/nfs_syscalls.c,v
> retrieving revision 1.99
> diff -u -p -r1.99 nfs_syscalls.c
> --- sys/nfs/nfs_syscalls.c    14 Mar 2015 03:38:52 -0000      1.99
> +++ sys/nfs/nfs_syscalls.c    21 Apr 2015 13:28:51 -0000
> @@ -166,7 +166,7 @@ sys_nfssvc(struct proc *p, void *v, regi
>               if (error)
>                       return (error);
> 
> -             error = getsock(p->p_fd, nfsdarg.sock, &fp);
> +             error = getsock(p, nfsdarg.sock, &fp);
>               if (error)
>                       return (error);
> 
> Index: sys/sys/filedesc.h
> ===================================================================
> RCS file: /cvs/src/sys/sys/filedesc.h,v
> retrieving revision 1.28
> diff -u -p -r1.28 filedesc.h
> --- sys/sys/filedesc.h        15 May 2014 03:52:25 -0000      1.28
> +++ sys/sys/filedesc.h        21 Apr 2015 13:28:53 -0000
> @@ -135,7 +135,7 @@ void      fdcloseexec(struct proc *);
> struct file *fd_getfile(struct filedesc *, int fd);
> 
> int   closef(struct file *, struct proc *);
> -int  getsock(struct filedesc *, int, struct file **);
> +int  getsock(struct proc *, int, struct file **);
> 
> #define       fdplock(fdp)    rw_enter_write(&(fdp)->fd_lock)
> #define       fdpunlock(fdp)  rw_exit_write(&(fdp)->fd_lock)
> 

Reply via email to