[Devel] [PATCH vz7 40/46] fuse: device fd clone
Maxim Patlasov
mpatlasov at virtuozzo.com
Fri Mar 24 19:28:47 PDT 2017
Backport from ml:
commit 00c570f4ba43ae73b41fa0a2269c3b0ac20386ef
Author: Miklos Szeredi <mszeredi at suse.cz>
Date: Wed Jul 1 16:26:08 2015 +0200
fuse: device fd clone
Allow an open fuse device to be "cloned". Userspace can create a clone by:
newfd = open("/dev/fuse", O_RDWR)
ioctl(newfd, FUSE_DEV_IOC_CLONE, &oldfd);
At this point newfd will refer to the same fuse connection as oldfd.
Signed-off-by: Miklos Szeredi <mszeredi at suse.cz>
Reviewed-by: Ashish Samant <ashish.samant at oracle.com>
Signed-off-by: Maxim Patlasov <mpatlasov at virtuozzo.com>
---
Documentation/ioctl/ioctl-number.txt | 1 +
fs/fuse/dev.c | 40 ++++++++++++++++++++++++++++++++++
include/uapi/linux/fuse.h | 3 +++
3 files changed, 44 insertions(+)
diff --git a/Documentation/ioctl/ioctl-number.txt b/Documentation/ioctl/ioctl-number.txt
index cc47d4e..ddaa510 100644
--- a/Documentation/ioctl/ioctl-number.txt
+++ b/Documentation/ioctl/ioctl-number.txt
@@ -323,6 +323,7 @@ Code Seq#(hex) Include File Comments
0xDB 00-0F drivers/char/mwave/mwavepub.h
0xDD 00-3F ZFCP device driver see drivers/s390/scsi/
<mailto:aherrman at de.ibm.com>
+0xE5 00-3F linux/fuse.h
0xF3 00-3F drivers/usb/misc/sisusbvga/sisusb.h sisfb (in development)
<mailto:thomas at winischhofer.net>
0xF4 00-1F video/mbxfb.h mbxfb
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index 70694ed..c2aac08 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -2192,6 +2192,44 @@ static int fuse_dev_fasync(int fd, struct file *file, int on)
return fasync_helper(fd, file, on, &fc->iq.fasync);
}
+static int fuse_device_clone(struct fuse_conn *fc, struct file *new)
+{
+ if (new->private_data)
+ return -EINVAL;
+
+ new->private_data = fuse_conn_get(fc);
+
+ return 0;
+}
+
+static long fuse_dev_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ int err = -ENOTTY;
+
+ if (cmd == FUSE_DEV_IOC_CLONE) {
+ int oldfd;
+
+ err = -EFAULT;
+ if (!get_user(oldfd, (__u32 __user *) arg)) {
+ struct file *old = fget(oldfd);
+
+ err = -EINVAL;
+ if (old) {
+ struct fuse_conn *fc = fuse_get_conn(old);
+
+ if (fc) {
+ mutex_lock(&fuse_mutex);
+ err = fuse_device_clone(fc, file);
+ mutex_unlock(&fuse_mutex);
+ }
+ fput(old);
+ }
+ }
+ }
+ return err;
+}
+
const struct file_operations fuse_dev_operations = {
.owner = THIS_MODULE,
.llseek = no_llseek,
@@ -2204,6 +2242,8 @@ const struct file_operations fuse_dev_operations = {
.poll = fuse_dev_poll,
.release = fuse_dev_release,
.fasync = fuse_dev_fasync,
+ .unlocked_ioctl = fuse_dev_ioctl,
+ .compat_ioctl = fuse_dev_ioctl,
};
EXPORT_SYMBOL_GPL(fuse_dev_operations);
diff --git a/include/uapi/linux/fuse.h b/include/uapi/linux/fuse.h
index cb3cd15..3262980 100644
--- a/include/uapi/linux/fuse.h
+++ b/include/uapi/linux/fuse.h
@@ -749,4 +749,7 @@ struct fuse_notify_inval_files_out {
__u64 ino;
};
+/* Device ioctls: */
+#define FUSE_DEV_IOC_CLONE _IOR(229, 0, uint32_t)
+
#endif /* _LINUX_FUSE_H */
More information about the Devel
mailing list