[rtems-libbsd commit] devfs: Fix some issues

Sebastian Huber sebh at rtems.org
Fri May 12 12:22:12 UTC 2017


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

Author:    Kevin Kirspel <kevin-kirspel at idexx.com>
Date:      Fri May 12 08:16:27 2017 -0400

devfs: Fix some issues

Fix issue with cdev private data usage with RTEMS iop structure. Add
support for cdev alias device names. Add support for cdev fstat.

---

 freebsd/sys/fs/devfs/devfs_vnops.c |   4 +
 freebsd/sys/kern/kern_conf.c       |   4 -
 freebsd/sys/sys/file.h             |   7 +-
 rtemsbsd/sys/fs/devfs/devfs_devs.c | 154 +++++++++++++++++++++++++++++++++----
 4 files changed, 145 insertions(+), 24 deletions(-)

diff --git a/freebsd/sys/fs/devfs/devfs_vnops.c b/freebsd/sys/fs/devfs/devfs_vnops.c
index b585178..31231fd 100644
--- a/freebsd/sys/fs/devfs/devfs_vnops.c
+++ b/freebsd/sys/fs/devfs/devfs_vnops.c
@@ -204,7 +204,11 @@ devfs_destroy_cdevpriv(struct cdev_privdata *p)
 	free(p, M_CDEVPDATA);
 }
 
+#ifndef __rtems__
 static void
+#else /* __rtems__ */
+void
+#endif /* __rtems__ */
 devfs_fpdrop(struct file *fp)
 {
 	struct cdev_privdata *p;
diff --git a/freebsd/sys/kern/kern_conf.c b/freebsd/sys/kern/kern_conf.c
index 20f2e2c..f008fc0 100644
--- a/freebsd/sys/kern/kern_conf.c
+++ b/freebsd/sys/kern/kern_conf.c
@@ -854,9 +854,7 @@ make_dev_sv(struct make_dev_args *args1, struct cdev **dres,
 #endif /* __rtems__ */
 
 	devfs_create(dev);
-#ifndef __rtems__
 	clean_unrhdrl(devfs_inos);
-#endif /* __rtems__ */
 	dev_unlock_and_free();
 
 	notify_create(dev, args.mda_flags);
@@ -1020,9 +1018,7 @@ make_dev_alias_v(int flags, struct cdev **cdev, struct cdev *pdev,
 	dev->si_flags |= SI_NAMED;
 	devfs_create(dev);
 	dev_dependsl(pdev, dev);
-#ifndef __rtems__
 	clean_unrhdrl(devfs_inos);
-#endif /* __rtems__ */
 	dev_unlock();
 
 	notify_create(dev, flags);
diff --git a/freebsd/sys/sys/file.h b/freebsd/sys/sys/file.h
index 8f91f52..c52dc7a 100644
--- a/freebsd/sys/sys/file.h
+++ b/freebsd/sys/sys/file.h
@@ -199,14 +199,11 @@ struct file {
 	void		*f_label;	/* Place-holder for MAC label. */
 #else /* __rtems__ */
 	rtems_libio_t	f_io;
-	union {
-		struct cdev_privdata *fvn_cdevpriv;
-					/* (d) Private data for the cdev. */
-	} f_vnun;
 #endif /* __rtems__ */
 };
 #ifdef __rtems__
 #define f_data f_io.pathinfo.node_access_2
+#define	f_cdevpriv	f_io.data1
 
 static inline struct file *
 rtems_bsd_iop_to_fp(rtems_libio_t *iop)
@@ -283,8 +280,10 @@ rtems_bsd_error_to_status_and_errno(int error)
 }
 #endif /* __rtems__ */
 
+#ifndef __rtems__
 #define	f_cdevpriv	f_vnun.fvn_cdevpriv
 #define	f_advice	f_vnun.fvn_advice
+#endif /* __rtems__ */
 
 #define	FOFFSET_LOCKED       0x1
 #define	FOFFSET_LOCK_WAITING 0x2
diff --git a/rtemsbsd/sys/fs/devfs/devfs_devs.c b/rtemsbsd/sys/fs/devfs/devfs_devs.c
index a91a02e..7d89c49 100644
--- a/rtemsbsd/sys/fs/devfs/devfs_devs.c
+++ b/rtemsbsd/sys/fs/devfs/devfs_devs.c
@@ -37,6 +37,7 @@
 #include <sys/file.h>
 #include <sys/malloc.h>
 #include <sys/proc.h>
+#include <sys/poll.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
@@ -74,20 +75,40 @@ devfs_imfs_open(rtems_libio_t *iop, const char *path, int oflag, mode_t mode)
 	struct file *fp = rtems_bsd_iop_to_fp(iop);
 	struct thread *td = rtems_bsd_get_curthread_or_null();
 	struct file *fpop;
-	int error;
+	struct cdevsw *dsw;
+	int error, ref;
 
 	if (td != NULL) {
+		if (cdev == NULL) {
+			error = ENXIO;
+			goto err;
+		}
+		if (cdev->si_flags & SI_ALIAS) {
+			cdev = cdev->si_parent;
+		}
+		dsw = dev_refthread(cdev, &ref);
+		if (dsw == NULL) {
+			error = ENXIO;
+			goto err;
+		}
+		if (fp == NULL) {
+			dev_relthread(cdev, ref);
+			error = ENXIO;
+			goto err;
+		}
 		fpop = td->td_fpop;
 		curthread->td_fpop = fp;
-		error = cdev->si_devsw->d_open(cdev, oflag, 0, td);
+		error = dsw->d_open(cdev, oflag + 1, 0, td);
 		/* Clean up any cdevpriv upon error. */
 		if (error != 0)
 			devfs_clear_cdevpriv();
 		curthread->td_fpop = fpop;
+		dev_relthread(cdev, ref);
 	} else {
 		error = ENOMEM;
 	}
 
+err:
 	return rtems_bsd_error_to_status_and_errno(error);
 }
 
@@ -99,17 +120,34 @@ devfs_imfs_close(rtems_libio_t *iop)
 	struct thread *td = rtems_bsd_get_curthread_or_null();
 	int flags = rtems_libio_to_fcntl_flags(iop->flags);
 	struct file *fpop;
-	int error;
+	struct cdevsw *dsw;
+	int error, ref;
 
 	if (td != NULL) {
+		if (cdev == NULL) {
+			error = ENXIO;
+			goto err;
+		}
+		if (cdev->si_flags & SI_ALIAS) {
+			cdev = cdev->si_parent;
+		}
+		dsw = dev_refthread(cdev, &ref);
+		if (dsw == NULL) {
+			error = ENXIO;
+			goto err;
+		}
 		fpop = td->td_fpop;
 		curthread->td_fpop = fp;
-		error = cdev->si_devsw->d_close(cdev, flags, 0, td);
+		error = dsw->d_close(cdev, flags, 0, td);
 		curthread->td_fpop = fpop;
+		dev_relthread(cdev, ref);
+		if (fp->f_cdevpriv != NULL)
+			devfs_fpdrop(fp);
 	} else {
 		error = ENOMEM;
 	}
 
+err:
 	return rtems_bsd_error_to_status_and_errno(error);
 }
 
@@ -130,18 +168,33 @@ devfs_imfs_readv(rtems_libio_t *iop, const struct iovec *iov, int iovcnt,
 		.uio_td = td
 	};
 	struct file *fpop;
-	int error;
+	struct cdevsw *dsw;
+	int error, ref;
 
 	if (td != NULL) {
+		if (cdev == NULL) {
+			error = ENXIO;
+			goto err;
+		}
+		if (cdev->si_flags & SI_ALIAS) {
+			cdev = cdev->si_parent;
+		}
+		dsw = dev_refthread(cdev, &ref);
+		if (dsw == NULL) {
+			error = ENXIO;
+			goto err;
+		}
 		fpop = td->td_fpop;
 		curthread->td_fpop = fp;
-		error = cdev->si_devsw->d_read(cdev, &uio,
+		error = dsw->d_read(cdev, &uio,
 		    rtems_libio_to_fcntl_flags(iop->flags));
 		td->td_fpop = fpop;
+		dev_relthread(cdev, ref);
 	} else {
 		error = ENOMEM;
 	}
 
+err:
 	if (error == 0) {
 		return (total - uio.uio_resid);
 	} else {
@@ -177,18 +230,33 @@ devfs_imfs_writev(rtems_libio_t *iop, const struct iovec *iov, int iovcnt,
 		.uio_td = td
 	};
 	struct file *fpop;
-	int error;
+	struct cdevsw *dsw;
+	int error, ref;
 
 	if (td != NULL) {
+		if (cdev == NULL) {
+			error = ENXIO;
+			goto err;
+		}
+		if (cdev->si_flags & SI_ALIAS) {
+			cdev = cdev->si_parent;
+		}
+		dsw = dev_refthread(cdev, &ref);
+		if (dsw == NULL) {
+			error = ENXIO;
+			goto err;
+		}
 		fpop = td->td_fpop;
 		curthread->td_fpop = fp;
-		error = cdev->si_devsw->d_write(cdev, &uio,
+		error = dsw->d_write(cdev, &uio,
 		    rtems_libio_to_fcntl_flags(iop->flags));
 		td->td_fpop = fpop;
+		dev_relthread(cdev, ref);
 	} else {
 		error = ENOMEM;
 	}
 
+err:
 	if (error == 0) {
 		return (total - uio.uio_resid);
 	} else {
@@ -214,20 +282,50 @@ devfs_imfs_ioctl(rtems_libio_t *iop, ioctl_command_t request, void *buffer)
 	struct file *fp = rtems_bsd_iop_to_fp(iop);
 	struct thread *td = rtems_bsd_get_curthread_or_null();
 	struct file *fpop;
-	int error;
+	struct cdevsw *dsw;
+	int error, ref;
 	int flags = rtems_libio_to_fcntl_flags(iop->flags);
 
 	if (td != 0) {
+		if (cdev == NULL) {
+			error = ENXIO;
+			goto err;
+		}
+		if (cdev->si_flags & SI_ALIAS) {
+			cdev = cdev->si_parent;
+		}
+		dsw = dev_refthread(cdev, &ref);
+		if (dsw == NULL) {
+			error = ENXIO;
+			goto err;
+		}
 		fpop = td->td_fpop;
 		curthread->td_fpop = fp;
-		error = cdev->si_devsw->d_ioctl(cdev, request, buffer, flags,
+		error = dsw->d_ioctl(cdev, request, buffer, flags,
 		    td);
 		td->td_fpop = fpop;
+		dev_relthread(cdev, ref);
 	} else {
 		error = ENOMEM;
 	}
 
-	return (rtems_bsd_error_to_status_and_errno(error));
+err:
+	return rtems_bsd_error_to_status_and_errno(error);
+}
+
+static int
+devfs_imfs_fstat(const rtems_filesystem_location_info_t *loc, struct stat *buf)
+{
+	int rv = 0;
+	const IMFS_jnode_t *the_dev = loc->node_access;
+
+	if (the_dev != NULL) {
+		buf->st_mode = the_dev->st_mode;
+	} else {
+		rv = rtems_filesystem_default_fstat(loc, buf);
+	}
+
+	return rv;
 }
 
 static int
@@ -237,12 +335,24 @@ devfs_imfs_poll(rtems_libio_t *iop, int events)
 	struct file *fp = rtems_bsd_iop_to_fp(iop);
 	struct thread *td = rtems_bsd_get_curthread_or_wait_forever();
 	struct file *fpop;
-	int error;
+	struct cdevsw *dsw;
+	int error, ref;
 
+	if (cdev == NULL) {
+		return POLLERR;
+	}
+	if (cdev->si_flags & SI_ALIAS) {
+		cdev = cdev->si_parent;
+	}
+	dsw = dev_refthread(cdev, &ref);
+	if (dsw == NULL) {
+		return POLLERR;
+	}
 	fpop = td->td_fpop;
 	curthread->td_fpop = fp;
-	error = cdev->si_devsw->d_poll(cdev, events, td);
+	error = dsw->d_poll(cdev, events, td);
 	td->td_fpop = fpop;
+	dev_relthread(cdev, ref);
 
 	return error;
 }
@@ -254,12 +364,24 @@ devfs_imfs_kqfilter(rtems_libio_t *iop, struct knote *kn)
 	struct file *fp = rtems_bsd_iop_to_fp(iop);
 	struct thread *td = rtems_bsd_get_curthread_or_wait_forever();
 	struct file *fpop;
-	int error;
+	struct cdevsw *dsw;
+	int error, ref;
 
+	if (cdev == NULL) {
+		return EINVAL;
+	}
+	if (cdev->si_flags & SI_ALIAS) {
+		cdev = cdev->si_parent;
+	}
+	dsw = dev_refthread(cdev, &ref);
+	if (dsw == NULL) {
+		return EINVAL;
+	}
 	fpop = td->td_fpop;
 	curthread->td_fpop = fp;
-	error = cdev->si_devsw->d_kqfilter(cdev, kn);
+	error = dsw->d_kqfilter(cdev, kn);
 	td->td_fpop = fpop;
+	dev_relthread(cdev, ref);
 
 	return error;
 }
@@ -271,7 +393,7 @@ static const rtems_filesystem_file_handlers_r devfs_imfs_handlers = {
 	.write_h = devfs_imfs_write,
 	.ioctl_h = devfs_imfs_ioctl,
 	.lseek_h = rtems_filesystem_default_lseek_file,
-	.fstat_h = rtems_filesystem_default_fstat,
+	.fstat_h = devfs_imfs_fstat,
 	.ftruncate_h = rtems_filesystem_default_ftruncate,
 	.fsync_h = rtems_filesystem_default_fsync_or_fdatasync,
 	.fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync,




More information about the vc mailing list