[dpdk-dev,v6,2/3] vhost: add EVENTFD_COPY2 ioctl
Commit Message
Signed-off-by: Pavel Boldin <pboldin@mirantis.com>
---
lib/librte_vhost/eventfd_link/eventfd_link.c | 61 ++++++++++++++++++++++++++++
lib/librte_vhost/eventfd_link/eventfd_link.h | 28 ++++++++++---
2 files changed, 84 insertions(+), 5 deletions(-)
@@ -78,6 +78,64 @@ fget_from_files(struct files_struct *files, unsigned fd)
}
static long
+eventfd_link_ioctl_copy2(unsigned long arg)
+{
+ void __user *argp = (void __user *) arg;
+ struct task_struct *task_target = NULL;
+ struct file *file;
+ struct files_struct *files;
+ struct eventfd_copy2 eventfd_copy2;
+ long ret = -EFAULT;
+
+ if (copy_from_user(&eventfd_copy2, argp, sizeof(struct eventfd_copy2)))
+ goto out;
+
+ /*
+ * Find the task struct for the target pid
+ */
+ ret = -ESRCH;
+
+ task_target =
+ get_pid_task(find_vpid(eventfd_copy2.pid), PIDTYPE_PID);
+ if (task_target == NULL) {
+ pr_info("Unable to find pid %d\n", eventfd_copy2.pid);
+ goto out;
+ }
+
+ ret = -ESTALE;
+ files = get_files_struct(task_target);
+ if (files == NULL) {
+ pr_info("Failed to get target files struct\n");
+ goto out_task;
+ }
+
+ ret = -EBADF;
+ file = fget_from_files(files, eventfd_copy2.fd);
+ put_files_struct(files);
+
+ if (file == NULL) {
+ pr_info("Failed to get fd %d from target\n", eventfd_copy2.fd);
+ goto out_task;
+ }
+
+ /*
+ * Install the file struct from the target process into the
+ * newly allocated file desciptor of the source process.
+ */
+ ret = get_unused_fd_flags(eventfd_copy2.flags);
+ if (ret < 0) {
+ fput(file);
+ goto out_task;
+ }
+ fd_install(ret, file);
+
+out_task:
+ put_task_struct(task_target);
+out:
+ return ret;
+}
+
+static long
eventfd_link_ioctl_copy(unsigned long arg)
{
void __user *argp = (void __user *) arg;
@@ -176,6 +234,9 @@ eventfd_link_ioctl(struct file *f, unsigned int ioctl, unsigned long arg)
case EVENTFD_COPY:
ret = eventfd_link_ioctl_copy(arg);
break;
+ case EVENTFD_COPY2:
+ ret = eventfd_link_ioctl_copy2(arg);
+ break;
}
return ret;
@@ -61,11 +61,6 @@
#define _EVENTFD_LINK_H_
/*
- * ioctl to copy an fd entry in calling process to an fd in a target process
- */
-#define EVENTFD_COPY 1
-
-/*
* arguements for the EVENTFD_COPY ioctl
*/
struct eventfd_copy {
@@ -73,4 +68,27 @@ struct eventfd_copy {
unsigned source_fd; /* fd in the calling pid */
pid_t target_pid; /* pid of the target pid */
};
+
+/*
+ * ioctl to copy an fd entry in calling process to an fd in a target process
+ * NOTE: this one should be
+ * #define EVENTFD_COPY _IOWR('D', 1, struct eventfd_copy) actually
+ */
+#define EVENTFD_COPY 1
+
+/*
+ * arguments for the EVENTFD_COPY2 ioctl
+ */
+struct eventfd_copy2 {
+ unsigned fd; /* fd to steal */
+ pid_t pid; /* pid of the process to steal from */
+ unsigned flags; /* flags to allocate new fd with */
+};
+
+/*
+ * ioctl to copy an fd entry from the target process into newly allocated
+ * fd in the calling process
+ */
+#define EVENTFD_COPY2 _IOW('D', 2, struct eventfd_copy2)
+
#endif /* _EVENTFD_LINK_H_ */