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@suse.cz> Reviewed-by: Ashish Samant <ashish.samant@oracle.com>
This commit is contained in:
parent
ee314a870e
commit
00c570f4ba
@ -321,6 +321,7 @@ Code Seq#(hex) Include File Comments
|
|||||||
0xDB 00-0F drivers/char/mwave/mwavepub.h
|
0xDB 00-0F drivers/char/mwave/mwavepub.h
|
||||||
0xDD 00-3F ZFCP device driver see drivers/s390/scsi/
|
0xDD 00-3F ZFCP device driver see drivers/s390/scsi/
|
||||||
<mailto:aherrman@de.ibm.com>
|
<mailto:aherrman@de.ibm.com>
|
||||||
|
0xE5 00-3F linux/fuse.h
|
||||||
0xEC 00-01 drivers/platform/chrome/cros_ec_dev.h ChromeOS EC driver
|
0xEC 00-01 drivers/platform/chrome/cros_ec_dev.h ChromeOS EC driver
|
||||||
0xF3 00-3F drivers/usb/misc/sisusbvga/sisusb.h sisfb (in development)
|
0xF3 00-3F drivers/usb/misc/sisusbvga/sisusb.h sisfb (in development)
|
||||||
<mailto:thomas@winischhofer.net>
|
<mailto:thomas@winischhofer.net>
|
||||||
|
@ -2197,6 +2197,44 @@ static int fuse_dev_fasync(int fd, struct file *file, int on)
|
|||||||
return fasync_helper(fd, file, on, &fc->iq.fasync);
|
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 = {
|
const struct file_operations fuse_dev_operations = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.open = fuse_dev_open,
|
.open = fuse_dev_open,
|
||||||
@ -2208,6 +2246,8 @@ const struct file_operations fuse_dev_operations = {
|
|||||||
.poll = fuse_dev_poll,
|
.poll = fuse_dev_poll,
|
||||||
.release = fuse_dev_release,
|
.release = fuse_dev_release,
|
||||||
.fasync = fuse_dev_fasync,
|
.fasync = fuse_dev_fasync,
|
||||||
|
.unlocked_ioctl = fuse_dev_ioctl,
|
||||||
|
.compat_ioctl = fuse_dev_ioctl,
|
||||||
};
|
};
|
||||||
EXPORT_SYMBOL_GPL(fuse_dev_operations);
|
EXPORT_SYMBOL_GPL(fuse_dev_operations);
|
||||||
|
|
||||||
|
@ -755,4 +755,7 @@ struct fuse_notify_retrieve_in {
|
|||||||
uint64_t dummy4;
|
uint64_t dummy4;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Device ioctls: */
|
||||||
|
#define FUSE_DEV_IOC_CLONE _IOR(229, 0, uint32_t)
|
||||||
|
|
||||||
#endif /* _LINUX_FUSE_H */
|
#endif /* _LINUX_FUSE_H */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user