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

Reply via email to