Module: xenomai-forge Branch: next Commit: be576e39382ffab59ca53a0114cc08ddb4aee1bf URL: http://git.xenomai.org/?p=xenomai-forge.git;a=commit;h=be576e39382ffab59ca53a0114cc08ddb4aee1bf
Author: Philippe Gerum <r...@xenomai.org> Date: Sat Aug 23 10:25:35 2014 +0200 cobalt/rtdm: fix unwinding on fd_enter error path --- kernel/cobalt/rtdm/core.c | 23 +++++++++++++++++------ kernel/cobalt/rtdm/fd.c | 36 ++++++++++++------------------------ 2 files changed, 29 insertions(+), 30 deletions(-) diff --git a/kernel/cobalt/rtdm/core.c b/kernel/cobalt/rtdm/core.c index 41d368c..f89c6cd 100644 --- a/kernel/cobalt/rtdm/core.c +++ b/kernel/cobalt/rtdm/core.c @@ -108,7 +108,8 @@ static int create_instance(struct xnsys_ppd *p, int fd, if (unlikely(context->device != NULL)) { xnlock_put_irqrestore(&rt_dev_lock, s); - return -EBUSY; + err = -EBUSY; + goto fail; } context->device = device; @@ -117,21 +118,31 @@ static int create_instance(struct xnsys_ppd *p, int fd, } else { context = kmalloc(sizeof(struct rtdm_dev_context) + device->context_size, GFP_KERNEL); - if (unlikely(context == NULL)) - return -ENOMEM; + if (unlikely(context == NULL)) { + err = -ENOMEM; + goto fail; + } context->device = device; } context->reserved.close = device->reserved.close; + *context_ptr = context; err = rtdm_fd_enter(p, &context->fd, fd, RTDM_FD_MAGIC, &device->ops); if (err < 0) - return err; - - *context_ptr = context; + goto fail; return fd; +fail: + if (p == &__xnsys_global_ppd) { + xnlock_get_irqsave(&rt_fildes_lock, s); + __clear_bit(fd, used_fildes); + open_fildes--; + xnlock_put_irqrestore(&rt_fildes_lock, s); + } + + return err; } int __rt_dev_open(struct xnsys_ppd *p, int ufd, const char *path, int oflag) diff --git a/kernel/cobalt/rtdm/fd.c b/kernel/cobalt/rtdm/fd.c index 63bd54f..7bea06b 100644 --- a/kernel/cobalt/rtdm/fd.c +++ b/kernel/cobalt/rtdm/fd.c @@ -110,24 +110,20 @@ static struct rtdm_fd *rtdm_fd_fetch(struct xnsys_ppd *p, int ufd) while (0) int rtdm_fd_enter(struct xnsys_ppd *p, struct rtdm_fd *fd, int ufd, - unsigned int magic, struct rtdm_fd_ops *ops) + unsigned int magic, struct rtdm_fd_ops *ops) { struct rtdm_fd_index *idx; spl_t s; - int err; + int ret; secondary_mode_only(); - if (magic == XNFD_MAGIC_ANY) { - err = -EINVAL; - goto err; - } + if (magic == XNFD_MAGIC_ANY) + return -EINVAL; idx = kmalloc(sizeof(*idx), GFP_KERNEL); - if (idx == NULL) { - err = -ENOMEM; - goto err; - } + if (idx == NULL) + return -ENOMEM; assign_default_dual_handlers(ops->ioctl); assign_default_dual_handlers(ops->read); @@ -146,22 +142,14 @@ int rtdm_fd_enter(struct xnsys_ppd *p, struct rtdm_fd *fd, int ufd, idx->fd = fd; xnlock_get_irqsave(&__rtdm_fd_lock, s); - err = xnid_enter(&p->fds, &idx->id, ufd); - if (err < 0) { - xnlock_put_irqrestore(&__rtdm_fd_lock, s); - err = -EBUSY; - goto err_free_index; - } + ret = xnid_enter(&p->fds, &idx->id, ufd); xnlock_put_irqrestore(&__rtdm_fd_lock, s); + if (ret < 0) { + kfree(idx); + ret = -EBUSY; + } - return 0; - - err_free_index: - kfree(idx); - err: - if (ops->close) - ops->close(fd); - return err; + return ret; } /** _______________________________________________ Xenomai-git mailing list Xenomai-git@xenomai.org http://www.xenomai.org/mailman/listinfo/xenomai-git