in sync_file.c [323:376]
static long sync_file_ioctl_merge(struct sync_file *sync_file,
unsigned long arg)
{
int fd = get_unused_fd_flags(O_CLOEXEC);
int err;
struct sync_file *fence2, *fence3;
struct sync_merge_data data;
if (fd < 0)
return fd;
if (copy_from_user(&data, (void __user *)arg, sizeof(data))) {
err = -EFAULT;
goto err_put_fd;
}
if (data.flags || data.pad) {
err = -EINVAL;
goto err_put_fd;
}
fence2 = sync_file_fdget(data.fd2);
if (!fence2) {
err = -ENOENT;
goto err_put_fd;
}
data.name[sizeof(data.name) - 1] = '\0';
fence3 = sync_file_merge(data.name, sync_file, fence2);
if (!fence3) {
err = -ENOMEM;
goto err_put_fence2;
}
data.fence = fd;
if (copy_to_user((void __user *)arg, &data, sizeof(data))) {
err = -EFAULT;
goto err_put_fence3;
}
fd_install(fd, fence3->file);
fput(fence2->file);
return 0;
err_put_fence3:
fput(fence3->file);
err_put_fence2:
fput(fence2->file);
err_put_fd:
put_unused_fd(fd);
return err;
}