Merge tag 'fuse-fixes-5.12-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 16 Mar 2021 17:29:45 +0000 (10:29 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 16 Mar 2021 17:29:45 +0000 (10:29 -0700)
Pull fuse fixes from Miklos Szeredi:
 "Fix a deadlock and a couple of other bugs"

* tag 'fuse-fixes-5.12-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse:
  fuse: 32-bit user space ioctl compat for fuse device
  virtiofs: Fail dax mount if device does not support it
  fuse: fix live lock in fuse_iget()

fs/fuse/dev.c
fs/fuse/fuse_i.h
fs/fuse/virtio_fs.c
include/uapi/linux/fuse.h

index c6636b4..c0fee83 100644 (file)
@@ -2229,19 +2229,21 @@ static int fuse_device_clone(struct fuse_conn *fc, struct file *new)
 static long fuse_dev_ioctl(struct file *file, unsigned int cmd,
                           unsigned long arg)
 {
-       int err = -ENOTTY;
+       int res;
+       int oldfd;
+       struct fuse_dev *fud = NULL;
 
-       if (cmd == FUSE_DEV_IOC_CLONE) {
-               int oldfd;
+       if (_IOC_TYPE(cmd) != FUSE_DEV_IOC_MAGIC)
+               return -ENOTTY;
 
-               err = -EFAULT;
-               if (!get_user(oldfd, (__u32 __user *) arg)) {
+       switch (_IOC_NR(cmd)) {
+       case _IOC_NR(FUSE_DEV_IOC_CLONE):
+               res = -EFAULT;
+               if (!get_user(oldfd, (__u32 __user *)arg)) {
                        struct file *old = fget(oldfd);
 
-                       err = -EINVAL;
+                       res = -EINVAL;
                        if (old) {
-                               struct fuse_dev *fud = NULL;
-
                                /*
                                 * Check against file->f_op because CUSE
                                 * uses the same ioctl handler.
@@ -2252,14 +2254,18 @@ static long fuse_dev_ioctl(struct file *file, unsigned int cmd,
 
                                if (fud) {
                                        mutex_lock(&fuse_mutex);
-                                       err = fuse_device_clone(fud->fc, file);
+                                       res = fuse_device_clone(fud->fc, file);
                                        mutex_unlock(&fuse_mutex);
                                }
                                fput(old);
                        }
                }
+               break;
+       default:
+               res = -ENOTTY;
+               break;
        }
-       return err;
+       return res;
 }
 
 const struct file_operations fuse_dev_operations = {
index 68cca8d..63d97a1 100644 (file)
@@ -863,6 +863,7 @@ static inline u64 fuse_get_attr_version(struct fuse_conn *fc)
 
 static inline void fuse_make_bad(struct inode *inode)
 {
+       remove_inode_hash(inode);
        set_bit(FUSE_I_BAD, &get_fuse_inode(inode)->state);
 }
 
index 8868ac3..4ee6f73 100644 (file)
@@ -1324,8 +1324,15 @@ static int virtio_fs_fill_super(struct super_block *sb, struct fs_context *fsc)
 
        /* virtiofs allocates and installs its own fuse devices */
        ctx->fudptr = NULL;
-       if (ctx->dax)
+       if (ctx->dax) {
+               if (!fs->dax_dev) {
+                       err = -EINVAL;
+                       pr_err("virtio-fs: dax can't be enabled as filesystem"
+                              " device does not support it.\n");
+                       goto err_free_fuse_devs;
+               }
                ctx->dax_dev = fs->dax_dev;
+       }
        err = fuse_fill_super_common(sb, ctx);
        if (err < 0)
                goto err_free_fuse_devs;
index 98ca64d..5444261 100644 (file)
@@ -903,7 +903,8 @@ struct fuse_notify_retrieve_in {
 };
 
 /* Device ioctls: */
-#define FUSE_DEV_IOC_CLONE     _IOR(229, 0, uint32_t)
+#define FUSE_DEV_IOC_MAGIC             229
+#define FUSE_DEV_IOC_CLONE             _IOR(FUSE_DEV_IOC_MAGIC, 0, uint32_t)
 
 struct fuse_lseek_in {
        uint64_t        fh;