Use RTEMS API for file handling

This commit is contained in:
Sebastian Huber 2013-10-10 13:27:01 +02:00
parent 8eb42e8884
commit c9db0f5ecb
8 changed files with 276 additions and 7 deletions

View File

@ -57,6 +57,7 @@ LIB_C_FILES += rtemsbsd/rtems/rtems-bsd-conf.c
LIB_C_FILES += rtemsbsd/rtems/rtems-bsd-copyinout.c
LIB_C_FILES += rtemsbsd/rtems/rtems-bsd-delay.c
LIB_C_FILES += rtemsbsd/rtems/rtems-bsd-descrip.c
LIB_C_FILES += rtemsbsd/rtems/rtems-bsd-get-file.c
LIB_C_FILES += rtemsbsd/rtems/rtems-bsd-init.c
LIB_C_FILES += rtemsbsd/rtems/rtems-bsd-init-with-irq.c
LIB_C_FILES += rtemsbsd/rtems/rtems-bsd-jail.c

View File

@ -614,6 +614,7 @@ rtems.addRTEMSSourceFiles(
'rtems/rtems-bsd-copyinout.c',
'rtems/rtems-bsd-delay.c',
'rtems/rtems-bsd-descrip.c',
'rtems/rtems-bsd-get-file.c',
'rtems/rtems-bsd-init.c',
'rtems/rtems-bsd-init-with-irq.c',
'rtems/rtems-bsd-jail.c',

View File

@ -851,7 +851,9 @@ int
kern_select(struct thread *td, int nd, fd_set *fd_in, fd_set *fd_ou,
fd_set *fd_ex, struct timeval *tvp, int abi_nfdbits)
{
#ifndef __rtems__
struct filedesc *fdp;
#endif /* __rtems__ */
/*
* The magic 2048 here is chosen to be just enough for FD_SETSIZE
* infds with the new FD_SETSIZE of 1024, and more than enough for
@ -870,9 +872,14 @@ kern_select(struct thread *td, int nd, fd_set *fd_in, fd_set *fd_ou,
#endif /* __rtems__ */
if (nd < 0)
return (EINVAL);
#ifndef __rtems__
fdp = td->td_proc->p_fd;
if (nd > fdp->fd_lastfile + 1)
nd = fdp->fd_lastfile + 1;
#else /* __rtems__ */
if (nd > rtems_libio_number_iops)
nd = rtems_libio_number_iops;
#endif /* __rtems__ */
/*
* Allocate just enough bits for the non-null fd_sets. Use the

View File

@ -102,6 +102,10 @@ struct fileops {
#endif /* _KERNEL */
#if defined(_KERNEL) || defined(_WANT_FILE)
#ifdef __rtems__
#include <rtems/libio_.h>
#include <sys/fcntl.h>
#endif /* __rtems__ */
/*
* Kernel descriptor table.
* One entry for each open kernel vnode and socket.
@ -114,6 +118,7 @@ struct fileops {
*/
struct file {
#ifndef __rtems__
void *f_data; /* file descriptor specific data */
struct fileops *f_ops; /* File operations */
struct ucred *f_cred; /* associated credentials. */
@ -136,7 +141,87 @@ struct file {
* Mandatory Access control information.
*/
void *f_label; /* Place-holder for MAC label. */
#else /* __rtems__ */
rtems_libio_t f_io;
#endif /* __rtems__ */
};
#ifdef __rtems__
#define f_data f_io.pathinfo.node_access
static inline struct file *
rtems_bsd_iop_to_fp(rtems_libio_t *iop)
{
return (struct file *) iop;
}
static inline struct file *
rtems_bsd_fd_to_fp(int fd)
{
return rtems_bsd_iop_to_fp(&rtems_libio_iops[fd]);
}
static inline int
rtems_bsd_fp_to_fd(struct file *fp)
{
return fp - rtems_bsd_iop_to_fp(&rtems_libio_iops[0]);
}
static inline void *
rtems_bsd_loc_to_f_data(const rtems_filesystem_location_info_t *loc)
{
return loc->node_access;
}
static inline uint32_t
rtems_bsd_fflag_to_libio_flags(u_int fflag)
{
uint32_t libio_flags = 0;
if ((fflag & FREAD) == FREAD) {
libio_flags |= LIBIO_FLAGS_READ;
}
if ((fflag & FWRITE) == FWRITE) {
libio_flags |= LIBIO_FLAGS_WRITE;
}
if ((fflag & FNONBLOCK) == FNONBLOCK) {
libio_flags |= LIBIO_FLAGS_NO_DELAY;
}
return (libio_flags);
}
static inline u_int
rtems_bsd_libio_flags_to_fflag(uint32_t libio_flags)
{
u_int fflag = 0;
if ((libio_flags & LIBIO_FLAGS_READ) == LIBIO_FLAGS_READ) {
fflag |= FREAD;
}
if ((libio_flags & LIBIO_FLAGS_WRITE) == LIBIO_FLAGS_WRITE) {
fflag |= FWRITE;
}
if ((libio_flags & LIBIO_FLAGS_NO_DELAY) == LIBIO_FLAGS_NO_DELAY) {
fflag |= FNONBLOCK;
}
return (fflag);
}
static int inline
rtems_bsd_error_to_status_and_errno(int error)
{
if (error == 0) {
return 0;
} else {
rtems_set_errno_and_return_minus_one(error);
}
}
#endif /* __rtems__ */
#define FOFFSET_LOCKED 0x1
#define FOFFSET_LOCK_WAITING 0x2
@ -174,7 +259,23 @@ extern int maxfiles; /* kernel limit on number of open files */
extern int maxfilesperproc; /* per process limit on number of open files */
extern volatile int openfiles; /* actual number of open files */
#ifndef __rtems__
int fget(struct thread *td, int fd, struct file **fpp);
#else /* __rtems__ */
struct file *rtems_bsd_get_file(int fd);
static inline int
fget(struct thread *td, int fd, struct file **fpp)
{
struct file *fp = rtems_bsd_get_file(fd);
(void) td;
*fpp = fp;
return fp != NULL ? 0 : EBADF;
}
#endif /* __rtems__ */
int fget_read(struct thread *td, int fd, struct file **fpp);
int fget_write(struct thread *td, int fd, struct file **fpp);
int _fdrop(struct file *fp, struct thread *td);
@ -193,7 +294,25 @@ fo_kqfilter_t soo_kqfilter;
fo_stat_t soo_stat;
fo_close_t soo_close;
#ifndef __rtems__
void finit(struct file *, u_int, short, void *, struct fileops *);
#else /* __rtems__ */
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;
fp->f_data = data;
fp->f_io.flags |= rtems_bsd_fflag_to_libio_flags(fflag);
pathinfo->handlers = ops;
pathinfo->mt_entry = &rtems_filesystem_null_mt_entry;
rtems_filesystem_location_add_to_mt_entry(pathinfo);
}
#endif /* __rtems__ */
int fgetvp(struct thread *td, int fd, struct vnode **vpp);
int fgetvp_read(struct thread *td, int fd, struct vnode **vpp);
int fgetvp_write(struct thread *td, int fd, struct vnode **vpp);
@ -203,9 +322,14 @@ void fputsock(struct socket *sp);
#define fhold(fp) \
(refcount_acquire(&(fp)->f_count))
#ifndef __rtems__
#define fdrop(fp, td) \
(refcount_release(&(fp)->f_count) ? _fdrop((fp), (td)) : 0)
#else /* __rtems__ */
#define fdrop(fp, td) do { } while (0)
#endif /* __rtems__ */
#ifndef __rtems__
static __inline fo_rdwr_t fo_read;
static __inline fo_rdwr_t fo_write;
static __inline fo_truncate_t fo_truncate;
@ -249,6 +373,7 @@ fo_truncate(fp, length, active_cred, td)
return ((*fp->f_ops->fo_truncate)(fp, length, active_cred, td));
}
#endif /* __rtems__ */
static __inline int
fo_ioctl(fp, com, data, active_cred, td)
@ -259,9 +384,25 @@ fo_ioctl(fp, com, data, active_cred, td)
struct thread *td;
{
#ifndef __rtems__
return ((*fp->f_ops->fo_ioctl)(fp, com, data, active_cred, td));
#else /* __rtems__ */
int rv;
(void) active_cred;
(void) td;
errno = 0;
rv = ((*fp->f_io.pathinfo.handlers->ioctl_h)(&fp->f_io, com, data));
if (rv == 0) {
return (0);
} else {
return (errno);
}
#endif /* __rtems__ */
}
#ifndef __rtems__
static __inline int
fo_poll(fp, events, active_cred, td)
struct file *fp;
@ -301,6 +442,7 @@ fo_kqfilter(fp, kn)
return ((*fp->f_ops->fo_kqfilter)(fp, kn));
}
#endif /* __rtems__ */
#endif /* _KERNEL */

View File

@ -47,6 +47,7 @@
*/
#define NDSLOTTYPE u_long
#ifndef __rtems__
struct filedesc {
struct file **fd_ofiles; /* file structures for open files */
char *fd_ofileflags; /* per-process open file flags */
@ -65,6 +66,9 @@ struct filedesc {
int fd_holdleaderscount; /* block fdfree() for shared close() */
int fd_holdleaderswakeup; /* fdfree() needs wakeup */
};
#else /* __rtems__ */
struct filedesc;
#endif /* __rtems__ */
/*
* Structure to keep track of (process leader, struct fildedesc) tuples.
@ -75,6 +79,7 @@ struct filedesc {
*
* fdl_refcount and fdl_holdcount are protected by struct filedesc mtx.
*/
#ifndef __rtems__
struct filedesc_to_leader {
int fdl_refcount; /* references from struct proc */
int fdl_holdcount; /* temporary hold during closef */
@ -84,6 +89,9 @@ struct filedesc_to_leader {
struct filedesc_to_leader *fdl_prev;
struct filedesc_to_leader *fdl_next;
};
#else /* __rtems__ */
struct filedesc_to_leader;
#endif /* __rtems__ */
/*
* Per-process open flags.
@ -91,15 +99,26 @@ struct filedesc_to_leader {
#define UF_EXCLOSE 0x01 /* auto-close on exec */
#ifdef _KERNEL
#ifdef __rtems__
#include <sys/file.h>
#include <rtems/libio_.h>
#endif /* __rtems__ */
/* Lock a file descriptor table. */
#define FILEDESC_LOCK_INIT(fdp) sx_init(&(fdp)->fd_sx, "filedesc structure")
#define FILEDESC_LOCK_DESTROY(fdp) sx_destroy(&(fdp)->fd_sx)
#define FILEDESC_LOCK(fdp) (&(fdp)->fd_sx)
#ifndef __rtems__
#define FILEDESC_XLOCK(fdp) sx_xlock(&(fdp)->fd_sx)
#define FILEDESC_XUNLOCK(fdp) sx_xunlock(&(fdp)->fd_sx)
#define FILEDESC_SLOCK(fdp) sx_slock(&(fdp)->fd_sx)
#define FILEDESC_SUNLOCK(fdp) sx_sunlock(&(fdp)->fd_sx)
#else /* __rtems__ */
#define FILEDESC_XLOCK(fdp) do { } while (0)
#define FILEDESC_XUNLOCK(fdp) do { } while (0)
#define FILEDESC_SLOCK(fdp) do { } while (0)
#define FILEDESC_SUNLOCK(fdp) do { } while (0)
#endif /* __rtems__ */
#define FILEDESC_LOCK_ASSERT(fdp) sx_assert(&(fdp)->fd_sx, SX_LOCKED | \
SX_NOTRECURSED)
@ -111,11 +130,46 @@ struct thread;
int closef(struct file *fp, struct thread *td);
int dupfdopen(struct thread *td, struct filedesc *fdp, int indx, int dfd,
int mode, int error);
#ifndef __rtems__
int falloc(struct thread *td, struct file **resultfp, int *resultfd);
#else /* __rtems__ */
static inline int
falloc(struct thread *td, struct file **resultfp, int *resultfd)
{
rtems_libio_t *iop = rtems_libio_allocate();
(void) td;
*resultfp = rtems_bsd_iop_to_fp(iop);
if (iop != NULL) {
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);
}
}
#endif /* __rtems__ */
int fdalloc(struct thread *td, int minfd, int *result);
int fdavail(struct thread *td, int n);
int fdcheckstd(struct thread *td);
#ifndef __rtems__
void fdclose(struct filedesc *fdp, struct file *fp, int idx, struct thread *td);
#else /* __rtems__ */
static inline void
rtems_bsd_fdclose(struct file *fp, int idx, struct thread *td)
{
(void) idx;
(void) td;
rtems_libio_free(&fp->f_io);
}
#define fdclose(fdp, fp, idx, td) rtems_bsd_fdclose(fp, idx, td)
#endif /* __rtems__ */
void fdcloseexec(struct thread *td);
struct filedesc *fdcopy(struct filedesc *fdp);
void fdunshare(struct proc *p, struct thread *td);
@ -130,8 +184,19 @@ void mountcheckdirs(struct vnode *olddp, struct vnode *newdp);
void setugidsafety(struct thread *td);
/* Return a referenced file from an unlocked descriptor. */
#ifndef __rtems__
struct file *fget_unlocked(struct filedesc *fdp, int fd);
#else /* __rtems__ */
static inline struct file *
fget_unlocked(struct filedesc *fdp, int fd)
{
(void) fdp;
return rtems_bsd_get_file(fd);
}
#endif /* __rtems__ */
#ifndef __rtems__
/* Requires a FILEDESC_{S,X}LOCK held and returns without a ref. */
static __inline struct file *
fget_locked(struct filedesc *fdp, int fd)
@ -139,6 +204,7 @@ fget_locked(struct filedesc *fdp, int fd)
return (fd < 0 || fd >= fdp->fd_nfiles ? NULL : fdp->fd_ofiles[fd]);
}
#endif /* __rtems__ */
#endif /* _KERNEL */

View File

@ -481,9 +481,7 @@ struct proc {
TAILQ_HEAD(, thread) p_threads; /* (c) all threads. */
struct mtx p_slock; /* process spin lock */
struct ucred *p_ucred; /* (c) Process owner's identity. */
#endif /* __rtems__ */
struct filedesc *p_fd; /* (b) Open files. */
#ifndef __rtems__
struct filedesc_to_leader *p_fdtol; /* (b) Tracking node */
struct pstats *p_stats; /* (b) Accounting/statistics (CPU). */
struct plimit *p_limit; /* (c) Process limits. */

View File

@ -0,0 +1,59 @@
/**
* @file
*
* @ingroup rtems_bsd_rtems
*
* @brief TODO.
*/
/*
* Copyright (c) 2013 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
* Dornierstr. 4
* 82178 Puchheim
* Germany
* <rtems@embedded-brains.de>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <machine/rtems-bsd-config.h>
#include <sys/file.h>
struct file *
rtems_bsd_get_file(int fd)
{
struct file *fp;
if ((uint32_t) fd < rtems_libio_number_iops) {
fp = rtems_bsd_fd_to_fp(fd);
if ((fp->f_io.flags & LIBIO_FLAGS_OPEN) != LIBIO_FLAGS_OPEN) {
fp = NULL;
}
} else {
fp = NULL;
}
return fp;
}

View File

@ -61,9 +61,6 @@ RTEMS_CHAIN_DEFINE_EMPTY(rtems_bsd_thread_chain);
static struct ucred FIXME_ucred = {
.cr_ref = 1 /* reference count */
};
static struct filedesc FIXME_fd = {
.fd_ofiles = NULL /* file structures for open files */
};
static struct proc FIXME_proc = {
.p_ucred = NULL /* (c) Process owner's identity. */
};
@ -222,8 +219,6 @@ rtems_bsd_threads_init(void *arg __unused)
mtx_init(&FIXME_proc.p_mtx, "process lock", NULL, MTX_DEF | MTX_DUPOK);
FIXME_proc.p_pid = getpid();
FIXME_proc.p_fibnum = 0;
FIXME_proc.p_fd = &FIXME_fd;
sx_init_flags(&FIXME_fd.fd_sx, "config SX thread lock", SX_DUPOK);
}
SYSINIT(rtems_bsd_threads, SI_SUB_INTRINSIC, SI_ORDER_ANY, rtems_bsd_threads_init, NULL);