From 894c965d95d971392b14bd2e9c0abf380ba80f02 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Fri, 15 Sep 2017 12:46:57 +0200 Subject: Support reference counting for file descriptors Close #3132. --- freebsd/sys/kern/sys_generic.c | 8 +++++++- freebsd/sys/kern/uipc_syscalls.c | 7 ++++++- freebsd/sys/sys/file.h | 25 +++++++++++++++---------- freebsd/sys/sys/filedesc.h | 24 +++++++++++------------- rtemsbsd/rtems/rtems-kernel-get-file.c | 7 ++++++- 5 files changed, 45 insertions(+), 26 deletions(-) diff --git a/freebsd/sys/kern/sys_generic.c b/freebsd/sys/kern/sys_generic.c index 2ee0ae70..6b26dbeb 100644 --- a/freebsd/sys/kern/sys_generic.c +++ b/freebsd/sys/kern/sys_generic.c @@ -1614,6 +1614,9 @@ pollrescan(struct thread *td) * POLLERR if appropriate. */ fd->revents = fo_poll(fp, fd->events, td->td_ucred, td); +#ifdef __rtems__ + rtems_libio_iop_drop(&fp->f_io); +#endif /* __rtems__ */ if (fd->revents != 0) n++; } @@ -1671,7 +1674,7 @@ pollscan(td, fds, nfd) #ifndef __rtems__ if (fds->fd > fdp->fd_lastfile) { #else /* __rtems__ */ - if (fds->fd >= rtems_libio_number_iops) { + if ((uint32_t)fds->fd >= rtems_libio_number_iops) { #endif /* __rtems__ */ fds->revents = POLLNVAL; n++; @@ -1701,6 +1704,9 @@ pollscan(td, fds, nfd) selfdalloc(td, fds); fds->revents = fo_poll(fp, fds->events, td->td_ucred, td); +#ifdef __rtems__ + rtems_libio_iop_drop(&fp->f_io); +#endif /* __rtems__ */ /* * POSIX requires POLLOUT to be never * set simultaneously with POLLHUP. diff --git a/freebsd/sys/kern/uipc_syscalls.c b/freebsd/sys/kern/uipc_syscalls.c index fa948c78..3c6d7efd 100644 --- a/freebsd/sys/kern/uipc_syscalls.c +++ b/freebsd/sys/kern/uipc_syscalls.c @@ -126,11 +126,16 @@ rtems_bsd_getsock(int fd, struct file **fpp, u_int *fflagp) int error; if ((uint32_t) fd < rtems_libio_number_iops) { + unsigned int flags; + fp = rtems_bsd_fd_to_fp(fd); - if ((fp->f_io.flags & LIBIO_FLAGS_OPEN) != LIBIO_FLAGS_OPEN) { + flags = rtems_libio_iop_hold(&fp->f_io); + if ((flags & LIBIO_FLAGS_OPEN) == 0) { + rtems_libio_iop_drop(&fp->f_io); fp = NULL; error = EBADF; } else if (fp->f_io.pathinfo.handlers != &socketops) { + rtems_libio_iop_drop(&fp->f_io); fp = NULL; error = ENOTSOCK; } else { diff --git a/freebsd/sys/sys/file.h b/freebsd/sys/sys/file.h index c52dc7a9..18274d67 100644 --- a/freebsd/sys/sys/file.h +++ b/freebsd/sys/sys/file.h @@ -330,11 +330,11 @@ struct file *rtems_bsd_get_file(int fd); static inline int rtems_bsd_do_fget(int fd, struct file **fpp) { - struct file *fp = rtems_bsd_get_file(fd); + struct file *fp; + fp = rtems_bsd_get_file(fd); *fpp = fp; - - return fp != NULL ? 0 : EBADF; + return (fp != NULL ? 0 : EBADF); } #define fget(td, fd, rights, fpp) rtems_bsd_do_fget(fd, fpp) @@ -374,14 +374,12 @@ static inline void finit(struct file *fp, u_int fflag, short type, void *data, const rtems_filesystem_file_handlers_r *ops) { - rtems_filesystem_location_info_t *pathinfo = &fp->f_io.pathinfo; - - (void) type; + (void)type; fp->f_data = data; - fp->f_io.flags |= rtems_bsd_fflag_to_libio_flags(fflag); - - pathinfo->handlers = ops; + fp->f_io.pathinfo.handlers = ops; + rtems_libio_iop_flags_set(&fp->f_io, LIBIO_FLAGS_OPEN | + rtems_bsd_fflag_to_libio_flags(fflag)); } #endif /* __rtems__ */ int fgetvp(struct thread *td, int fd, cap_rights_t *rightsp, @@ -408,7 +406,14 @@ _fnoop(void) #define fdrop(fp, td) \ (refcount_release(&(fp)->f_count) ? _fdrop((fp), (td)) : _fnoop()) #else /* __rtems__ */ -#define fdrop(fp, td) do { } while (0) +static inline void +rtems_bsd_fdrop(struct file *fp) +{ + + rtems_libio_iop_drop(&fp->f_io); +} + +#define fdrop(fp, td) rtems_bsd_fdrop(fp) #endif /* __rtems__ */ #ifndef __rtems__ diff --git a/freebsd/sys/sys/filedesc.h b/freebsd/sys/sys/filedesc.h index 579e5213..b1c3e24b 100644 --- a/freebsd/sys/sys/filedesc.h +++ b/freebsd/sys/sys/filedesc.h @@ -192,19 +192,20 @@ static inline int falloc_caps(struct thread *td, struct file **resultfp, int *resultfd, int flags, struct filecaps *fcaps) { - rtems_libio_t *iop = rtems_libio_allocate(); + rtems_libio_t *iop; - (void) td; - (void) flags; - (void) fcaps; + (void)td; + (void)flags; + (void)fcaps; + iop = rtems_libio_allocate(); *resultfp = rtems_bsd_iop_to_fp(iop); if (iop != NULL) { + rtems_libio_iop_hold(iop); iop->pathinfo.mt_entry = &rtems_filesystem_null_mt_entry; rtems_filesystem_location_add_to_mt_entry(&iop->pathinfo); *resultfd = rtems_libio_iop_to_descriptor(iop); - return (0); } else { return (ENFILE); @@ -263,17 +264,14 @@ static inline int fget_unlocked(struct filedesc *fdp, int fd, cap_rights_t *needrightsp, struct file **fpp, seq_t *seqp) { + struct file *fp; + (void)fdp; (void)needrightsp; (void)seqp; - - *fpp = rtems_bsd_get_file(fd); - - if (*fpp != NULL) { - return (0); - } else { - return (EBADF); - } + fp = rtems_bsd_get_file(fd); + *fpp = fp; + return (fp != NULL ? 0 : EBADF); } #endif /* __rtems__ */ diff --git a/rtemsbsd/rtems/rtems-kernel-get-file.c b/rtemsbsd/rtems/rtems-kernel-get-file.c index 6d321c30..b3b39282 100644 --- a/rtemsbsd/rtems/rtems-kernel-get-file.c +++ b/rtemsbsd/rtems/rtems-kernel-get-file.c @@ -47,8 +47,13 @@ rtems_bsd_get_file(int fd) struct file *fp; if ((uint32_t) fd < rtems_libio_number_iops) { + unsigned int flags; + fp = rtems_bsd_fd_to_fp(fd); - if ((fp->f_io.flags & LIBIO_FLAGS_OPEN) != LIBIO_FLAGS_OPEN) { + flags = rtems_libio_iop_hold(&fp->f_io); + + if ((flags & LIBIO_FLAGS_OPEN) == 0) { + rtems_libio_iop_drop(&fp->f_io); fp = NULL; } } else { -- cgit v1.2.3