Signed-off-by: Christian Brauner --- drivers/gpio/gpiolib-cdev.c | 58 +++++++++++++++++++-------------------------- 1 file changed, 24 insertions(+), 34 deletions(-) diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c index 175836467f21..d24cae0c0022 100644 --- a/drivers/gpio/gpiolib-cdev.c +++ b/drivers/gpio/gpiolib-cdev.c @@ -298,12 +298,32 @@ static const struct file_operations linehandle_fileops = { #endif }; +static int linehandle_fd_create(struct gpio_device *gdev, + struct linehandle_state *lh, + struct gpiohandle_request *handlereq, + void __user *ip) +{ + FD_PREPARE(fdf, O_RDONLY | O_CLOEXEC, + anon_inode_getfile("gpio-linehandle", &linehandle_fileops, + lh, O_RDONLY | O_CLOEXEC)); + if (fdf.err) + return fdf.err; + + handlereq->fd = fd_prepare_fd(fdf); + if (copy_to_user(ip, handlereq, sizeof(*handlereq))) + return -EFAULT; + + dev_dbg(&gdev->dev, "registered chardev handle for %d lines\n", lh->num_descs); + + fd_publish(fdf); + return 0; +} + static int linehandle_create(struct gpio_device *gdev, void __user *ip) { struct gpiohandle_request handlereq; struct linehandle_state *lh; - struct file *file; - int fd, i, ret; + int i, ret; u32 lflags; if (copy_from_user(&handlereq, ip, sizeof(handlereq))) @@ -377,41 +397,11 @@ static int linehandle_create(struct gpio_device *gdev, void __user *ip) offset); } - fd = get_unused_fd_flags(O_RDONLY | O_CLOEXEC); - if (fd < 0) { - ret = fd; + ret = linehandle_fd_create(gdev, lh, &handlereq, ip); + if (ret) goto out_free_lh; - } - - file = anon_inode_getfile("gpio-linehandle", - &linehandle_fileops, - lh, - O_RDONLY | O_CLOEXEC); - if (IS_ERR(file)) { - ret = PTR_ERR(file); - goto out_put_unused_fd; - } - - handlereq.fd = fd; - if (copy_to_user(ip, &handlereq, sizeof(handlereq))) { - /* - * fput() will trigger the release() callback, so do not go onto - * the regular error cleanup path here. - */ - fput(file); - put_unused_fd(fd); - return -EFAULT; - } - - fd_install(fd, file); - - dev_dbg(&gdev->dev, "registered chardev handle for %d lines\n", - lh->num_descs); - return 0; -out_put_unused_fd: - put_unused_fd(fd); out_free_lh: linehandle_free(lh); return ret; -- 2.47.3