[rtems-libbsd commit] Support reference counting for file descriptors

Sebastian Huber sebh at rtems.org
Fri Sep 15 10:49:52 UTC 2017


Module:    rtems-libbsd
Branch:    master
Commit:    894c965d95d971392b14bd2e9c0abf380ba80f02
Changeset: http://git.rtems.org/rtems-libbsd/commit/?id=894c965d95d971392b14bd2e9c0abf380ba80f02

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Fri Sep 15 12:46:57 2017 +0200

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 2ee0ae7..6b26dbe 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 fa948c7..3c6d7ef 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 c52dc7a..18274d6 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 579e521..b1c3e24 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 6d321c3..b3b3928 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 {



More information about the vc mailing list