Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 94e4fe2c authored by Tom Van Braeckel's avatar Tom Van Braeckel Committed by Miklos Szeredi
Browse files

fuse: explicitly set /dev/fuse file's private_data

The misc subsystem (which is used for /dev/fuse) initializes private_data to
point to the misc device when a driver has registered a custom open file
operation, and initializes it to NULL when a custom open file operation has
*not* been provided.

This subtle quirk is confusing, to the point where kernel code registers
*empty* file open operations to have private_data point to the misc device
structure. And it leads to bugs, where the addition or removal of a custom open
file operation surprisingly changes the initial contents of a file's
private_data structure.

So to simplify things in the misc subsystem, a patch [1] has been proposed to
*always* set the private_data to point to the misc device, instead of only
doing this when a custom open file operation has been registered.

But before this patch can be applied we need to modify drivers that make the
assumption that a misc device file's private_data is initialized to NULL
because they didn't register a custom open file operation, so they don't rely
on this assumption anymore. FUSE uses private_data to store the fuse_conn and
errors out if this is not initialized to NULL at mount time.

Hence, we now set a file's private_data to NULL explicitly, to be independent
of whatever value the misc subsystem initializes it to by default.

[1] https://lkml.org/lkml/2014/12/4/939



Reported-by: default avatarGiedrius Statkevicius <giedriuswork@gmail.com>
Reported-by: default avatarThierry Reding <thierry.reding@gmail.com>
Signed-off-by: default avatarTom Van Braeckel <tomvanbraeckel@gmail.com>
Signed-off-by: default avatarMiklos Szeredi <mszeredi@suse.cz>
parent aa991b3b
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -1353,6 +1353,17 @@ static ssize_t fuse_dev_do_read(struct fuse_conn *fc, struct file *file,
	return err;
}

static int fuse_dev_open(struct inode *inode, struct file *file)
{
	/*
	 * The fuse device's file's private_data is used to hold
	 * the fuse_conn(ection) when it is mounted, and is used to
	 * keep track of whether the file has been mounted already.
	 */
	file->private_data = NULL;
	return 0;
}

static ssize_t fuse_dev_read(struct kiocb *iocb, const struct iovec *iov,
			      unsigned long nr_segs, loff_t pos)
{
@@ -2220,6 +2231,7 @@ static int fuse_dev_fasync(int fd, struct file *file, int on)

const struct file_operations fuse_dev_operations = {
	.owner		= THIS_MODULE,
	.open		= fuse_dev_open,
	.llseek		= no_llseek,
	.read		= do_sync_read,
	.aio_read	= fuse_dev_read,