summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2017-09-15 12:46:57 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2017-09-15 12:46:57 +0200
commit894c965d95d971392b14bd2e9c0abf380ba80f02 (patch)
tree81ec615823caf2b4a942358627b4ee114d07bff0
parent666a56883ad2ae7757689f28cee2b9b80582bcd6 (diff)
downloadrtems-libbsd-894c965d95d971392b14bd2e9c0abf380ba80f02.tar.bz2
Support reference counting for file descriptors
Close #3132.
-rw-r--r--freebsd/sys/kern/sys_generic.c8
-rw-r--r--freebsd/sys/kern/uipc_syscalls.c7
-rw-r--r--freebsd/sys/sys/file.h25
-rw-r--r--freebsd/sys/sys/filedesc.h24
-rw-r--r--rtemsbsd/rtems/rtems-kernel-get-file.c7
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 {