mirror of
https://git.rtems.org/rtems-libbsd/
synced 2025-07-23 00:45:37 +08:00
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.
This commit is contained in:
parent
6afe73d8f4
commit
817cbf7201
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user