@@ -2272,6 +2272,22 @@ static long fuse_dev_ioctl(struct file *file, unsigned int cmd,
fput(old);
}
}
+ } else if (cmd == FUSE_DEV_IOC_SETAFF) {
+ if (arg >= num_online_cpus()) {
+ err = -EINVAL;
+ } else {
+ struct fuse_dev *fud = fuse_get_dev(file);
+ spin_lock(&fud->fc->lock);
+
+ fud->fiq->handled_by_fud--;
+ BUG_ON(fud->fiq->handled_by_fud < 0);
+
+ fud->fiq = per_cpu_ptr(fud->fc->iqs, arg);
+
+ fud->fiq->handled_by_fud++;
+ spin_unlock(&fud->fc->lock);
+ err = 0;
+ }
}
return err;
}
@@ -751,5 +751,6 @@ struct fuse_notify_inval_files_out {
/* Device ioctls: */
#define FUSE_DEV_IOC_CLONE _IOR(229, 0, uint32_t)
+#define FUSE_DEV_IOC_SETAFF _IOR(229, 1, uint32_t)
#endif /* _LINUX_FUSE_H */
By default all fuse devices refer to the main input queue: fc->main_iq. Userspace may change the mapping by: ioctl(fd, FUSE_DEV_IOC_SETAFF, i); where "fd" is clone file descriptor for "/dev/fuse" and "i" is an integer from zero to num_online_cpus-1. Signed-off-by: Maxim Patlasov <mpatlasov@virtuozzo.com> --- fs/fuse/dev.c | 16 ++++++++++++++++ include/uapi/linux/fuse.h | 1 + 2 files changed, 17 insertions(+)