Support reference counting for file descriptors

Close #3132.
This commit is contained in:
Sebastian Huber 2017-09-15 12:46:57 +02:00
parent 666a56883a
commit 894c965d95
5 changed files with 45 additions and 26 deletions

View File

@ -1614,6 +1614,9 @@ pollrescan(struct thread *td)
* POLLERR if appropriate. * POLLERR if appropriate.
*/ */
fd->revents = fo_poll(fp, fd->events, td->td_ucred, td); 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) if (fd->revents != 0)
n++; n++;
} }
@ -1671,7 +1674,7 @@ pollscan(td, fds, nfd)
#ifndef __rtems__ #ifndef __rtems__
if (fds->fd > fdp->fd_lastfile) { if (fds->fd > fdp->fd_lastfile) {
#else /* __rtems__ */ #else /* __rtems__ */
if (fds->fd >= rtems_libio_number_iops) { if ((uint32_t)fds->fd >= rtems_libio_number_iops) {
#endif /* __rtems__ */ #endif /* __rtems__ */
fds->revents = POLLNVAL; fds->revents = POLLNVAL;
n++; n++;
@ -1701,6 +1704,9 @@ pollscan(td, fds, nfd)
selfdalloc(td, fds); selfdalloc(td, fds);
fds->revents = fo_poll(fp, fds->events, fds->revents = fo_poll(fp, fds->events,
td->td_ucred, td); td->td_ucred, td);
#ifdef __rtems__
rtems_libio_iop_drop(&fp->f_io);
#endif /* __rtems__ */
/* /*
* POSIX requires POLLOUT to be never * POSIX requires POLLOUT to be never
* set simultaneously with POLLHUP. * set simultaneously with POLLHUP.

View File

@ -126,11 +126,16 @@ rtems_bsd_getsock(int fd, struct file **fpp, u_int *fflagp)
int error; int error;
if ((uint32_t) fd < rtems_libio_number_iops) { if ((uint32_t) fd < rtems_libio_number_iops) {
unsigned int flags;
fp = rtems_bsd_fd_to_fp(fd); 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; fp = NULL;
error = EBADF; error = EBADF;
} else if (fp->f_io.pathinfo.handlers != &socketops) { } else if (fp->f_io.pathinfo.handlers != &socketops) {
rtems_libio_iop_drop(&fp->f_io);
fp = NULL; fp = NULL;
error = ENOTSOCK; error = ENOTSOCK;
} else { } else {

View File

@ -330,11 +330,11 @@ struct file *rtems_bsd_get_file(int fd);
static inline int static inline int
rtems_bsd_do_fget(int fd, struct file **fpp) 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; *fpp = fp;
return (fp != NULL ? 0 : EBADF);
return fp != NULL ? 0 : EBADF;
} }
#define fget(td, fd, rights, fpp) rtems_bsd_do_fget(fd, fpp) #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, finit(struct file *fp, u_int fflag, short type, void *data,
const rtems_filesystem_file_handlers_r *ops) 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_data = data;
fp->f_io.flags |= rtems_bsd_fflag_to_libio_flags(fflag); fp->f_io.pathinfo.handlers = ops;
rtems_libio_iop_flags_set(&fp->f_io, LIBIO_FLAGS_OPEN |
pathinfo->handlers = ops; rtems_bsd_fflag_to_libio_flags(fflag));
} }
#endif /* __rtems__ */ #endif /* __rtems__ */
int fgetvp(struct thread *td, int fd, cap_rights_t *rightsp, int fgetvp(struct thread *td, int fd, cap_rights_t *rightsp,
@ -408,7 +406,14 @@ _fnoop(void)
#define fdrop(fp, td) \ #define fdrop(fp, td) \
(refcount_release(&(fp)->f_count) ? _fdrop((fp), (td)) : _fnoop()) (refcount_release(&(fp)->f_count) ? _fdrop((fp), (td)) : _fnoop())
#else /* __rtems__ */ #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__ */ #endif /* __rtems__ */
#ifndef __rtems__ #ifndef __rtems__

View File

@ -192,19 +192,20 @@ static inline int
falloc_caps(struct thread *td, struct file **resultfp, int *resultfd, falloc_caps(struct thread *td, struct file **resultfp, int *resultfd,
int flags, struct filecaps *fcaps) int flags, struct filecaps *fcaps)
{ {
rtems_libio_t *iop = rtems_libio_allocate(); rtems_libio_t *iop;
(void) td; (void)td;
(void) flags; (void)flags;
(void) fcaps; (void)fcaps;
iop = rtems_libio_allocate();
*resultfp = rtems_bsd_iop_to_fp(iop); *resultfp = rtems_bsd_iop_to_fp(iop);
if (iop != NULL) { if (iop != NULL) {
rtems_libio_iop_hold(iop);
iop->pathinfo.mt_entry = &rtems_filesystem_null_mt_entry; iop->pathinfo.mt_entry = &rtems_filesystem_null_mt_entry;
rtems_filesystem_location_add_to_mt_entry(&iop->pathinfo); rtems_filesystem_location_add_to_mt_entry(&iop->pathinfo);
*resultfd = rtems_libio_iop_to_descriptor(iop); *resultfd = rtems_libio_iop_to_descriptor(iop);
return (0); return (0);
} else { } else {
return (ENFILE); return (ENFILE);
@ -263,17 +264,14 @@ static inline int
fget_unlocked(struct filedesc *fdp, int fd, cap_rights_t *needrightsp, fget_unlocked(struct filedesc *fdp, int fd, cap_rights_t *needrightsp,
struct file **fpp, seq_t *seqp) struct file **fpp, seq_t *seqp)
{ {
struct file *fp;
(void)fdp; (void)fdp;
(void)needrightsp; (void)needrightsp;
(void)seqp; (void)seqp;
fp = rtems_bsd_get_file(fd);
*fpp = rtems_bsd_get_file(fd); *fpp = fp;
return (fp != NULL ? 0 : EBADF);
if (*fpp != NULL) {
return (0);
} else {
return (EBADF);
}
} }
#endif /* __rtems__ */ #endif /* __rtems__ */

View File

@ -47,8 +47,13 @@ rtems_bsd_get_file(int fd)
struct file *fp; struct file *fp;
if ((uint32_t) fd < rtems_libio_number_iops) { if ((uint32_t) fd < rtems_libio_number_iops) {
unsigned int flags;
fp = rtems_bsd_fd_to_fp(fd); 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; fp = NULL;
} }
} else { } else {