[Xenomai] [PATCH] Split rtdm_fd_enter up
Greg Gallagher
greg at embeddedgreg.com
Mon Dec 4 14:35:48 CET 2017
---
split rtdm_fd_enter, move the functionality where we store
the fd until after the open() call succeeds. Calls where open() fail a fd is
left in the tree even after the cleanup code is executed. If this fd number
is used again we will fail the call to open until a different fd is used.
This patch addresses this situation by not adding the fd into the tree until
open has succeeded and the fd is valid.
---
include/cobalt/kernel/rtdm/fd.h | 2 ++
kernel/cobalt/posix/mqueue.c | 7 ++++++-
kernel/cobalt/posix/timerfd.c | 4 ++++
kernel/cobalt/rtdm/core.c | 12 +++++++++---
kernel/cobalt/rtdm/fd.c | 24 ++++++++++++++++--------
5 files changed, 37 insertions(+), 12 deletions(-)
diff --git a/include/cobalt/kernel/rtdm/fd.h b/include/cobalt/kernel/rtdm/fd.h
index 086b04b..e504c0c 100644
--- a/include/cobalt/kernel/rtdm/fd.h
+++ b/include/cobalt/kernel/rtdm/fd.h
@@ -345,6 +345,8 @@ static inline int rtdm_fd_is_compat(const struct rtdm_fd *fd)
int rtdm_fd_enter(struct rtdm_fd *rtdm_fd, int ufd,
unsigned int magic, struct rtdm_fd_ops *ops);
+int rtdm_fd_register(struct rtdm_fd *fd, int ufd);
+
struct rtdm_fd *rtdm_fd_get(int ufd, unsigned int magic);
int rtdm_fd_lock(struct rtdm_fd *fd);
diff --git a/kernel/cobalt/posix/mqueue.c b/kernel/cobalt/posix/mqueue.c
index 6357d22..859e12e 100644
--- a/kernel/cobalt/posix/mqueue.c
+++ b/kernel/cobalt/posix/mqueue.c
@@ -267,6 +267,7 @@ static struct rtdm_fd_ops mqd_ops = {
static inline int mqd_create(struct cobalt_mq *mq, unsigned long flags, int ufd)
{
struct cobalt_mqd *mqd;
+ int ret;
if (cobalt_ppd_get(0) == &cobalt_kernel_ppd)
return -EPERM;
@@ -278,7 +279,11 @@ static inline int mqd_create(struct cobalt_mq *mq, unsigned long flags, int ufd)
mqd->fd.oflags = flags;
mqd->mq = mq;
- return rtdm_fd_enter(&mqd->fd, ufd, COBALT_MQD_MAGIC, &mqd_ops);
+ ret = rtdm_fd_enter(&mqd->fd, ufd, COBALT_MQD_MAGIC, &mqd_ops);
+ if (ret < 0)
+ return ret;
+
+ return rtdm_fd_register(&mqd->fd, ufd);
}
static int mq_open(int uqd, const char *name, int oflags,
diff --git a/kernel/cobalt/posix/timerfd.c b/kernel/cobalt/posix/timerfd.c
index 51e7605..217e68a 100644
--- a/kernel/cobalt/posix/timerfd.c
+++ b/kernel/cobalt/posix/timerfd.c
@@ -202,6 +202,10 @@ COBALT_SYSCALL(timerfd_create, lostage, (int clockid, int flags))
if (ret < 0)
goto fail;
+ ret = rtdm_fd_register(&tfd->fd, ufd);
+ if (ret < 0)
+ goto fail;
+
return ufd;
fail:
xnselect_destroy(&tfd->read_select);
diff --git a/kernel/cobalt/rtdm/core.c b/kernel/cobalt/rtdm/core.c
index 05f273f..01d9caf 100644
--- a/kernel/cobalt/rtdm/core.c
+++ b/kernel/cobalt/rtdm/core.c
@@ -174,7 +174,7 @@ int __rtdm_dev_open(const char *path, int oflag)
context->fd.minor = dev->minor;
context->fd.oflags = oflag;
-
+
trace_cobalt_fd_open(current, &context->fd, ufd, oflag);
if (dev->ops.open) {
@@ -185,9 +185,12 @@ int __rtdm_dev_open(const char *path, int oflag)
goto fail_open;
}
- fd_install(ufd, filp);
-
trace_cobalt_fd_created(&context->fd, ufd);
+ ret = rtdm_fd_register(&context->fd, ufd);
+ if (ret < 0)
+ goto fail_open;
+
+ fd_install(ufd, filp);
return ufd;
@@ -238,6 +241,9 @@ int __rtdm_dev_socket(int protocol_family, int socket_type,
}
trace_cobalt_fd_created(&context->fd, ufd);
+ ret = rtdm_fd_register(&context->fd, ufd);
+ if (ret < 0)
+ goto fail_socket;
return ufd;
diff --git a/kernel/cobalt/rtdm/fd.c b/kernel/cobalt/rtdm/fd.c
index ffcd3aa..e355526 100644
--- a/kernel/cobalt/rtdm/fd.c
+++ b/kernel/cobalt/rtdm/fd.c
@@ -145,20 +145,13 @@ static inline void set_compat_bit(struct rtdm_fd *fd)
int rtdm_fd_enter(struct rtdm_fd *fd, int ufd, unsigned int magic,
struct rtdm_fd_ops *ops)
{
- struct rtdm_fd_index *idx;
struct cobalt_ppd *ppd;
- spl_t s;
- int ret;
-
+
secondary_mode_only();
if (magic == 0)
return -EINVAL;
- idx = kmalloc(sizeof(*idx), GFP_KERNEL);
- if (idx == NULL)
- return -ENOMEM;
-
assign_default_dual_handlers(ops->ioctl);
assign_default_dual_handlers(ops->read);
assign_default_dual_handlers(ops->write);
@@ -175,6 +168,21 @@ int rtdm_fd_enter(struct rtdm_fd *fd, int ufd, unsigned int magic,
fd->refs = 1;
set_compat_bit(fd);
+ return 0;
+}
+
+int rtdm_fd_register(struct rtdm_fd *fd, int ufd)
+{
+ struct rtdm_fd_index *idx;
+ struct cobalt_ppd *ppd;
+ spl_t s;
+ int ret = 0;
+
+ ppd = cobalt_ppd_get(0);
+ idx = kmalloc(sizeof(*idx), GFP_KERNEL);
+ if (idx == NULL)
+ return -ENOMEM;
+
idx->fd = fd;
xnlock_get_irqsave(&fdtree_lock, s);
--
2.7.4
More information about the Xenomai
mailing list