fuse: support ioctl on directories
Multiplexing filesystems may want to support ioctls on the underlying files and directores (e.g. FS_IOC_{GET,SET}FLAGS). Ioctl support on directories was missing so add it now. Reported-by: Antonio SJ Musumeci <bile@landofbile.com> Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
This commit is contained in:
parent
c411cc88d8
commit
b18da0c56e
4 changed files with 38 additions and 5 deletions
|
@ -1182,6 +1182,30 @@ static int fuse_dir_fsync(struct file *file, loff_t start, loff_t end,
|
|||
return fuse_fsync_common(file, start, end, datasync, 1);
|
||||
}
|
||||
|
||||
static long fuse_dir_ioctl(struct file *file, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
struct fuse_conn *fc = get_fuse_conn(file->f_mapping->host);
|
||||
|
||||
/* FUSE_IOCTL_DIR only supported for API version >= 7.18 */
|
||||
if (fc->minor < 18)
|
||||
return -ENOTTY;
|
||||
|
||||
return fuse_ioctl_common(file, cmd, arg, FUSE_IOCTL_DIR);
|
||||
}
|
||||
|
||||
static long fuse_dir_compat_ioctl(struct file *file, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
struct fuse_conn *fc = get_fuse_conn(file->f_mapping->host);
|
||||
|
||||
if (fc->minor < 18)
|
||||
return -ENOTTY;
|
||||
|
||||
return fuse_ioctl_common(file, cmd, arg,
|
||||
FUSE_IOCTL_COMPAT | FUSE_IOCTL_DIR);
|
||||
}
|
||||
|
||||
static bool update_mtime(unsigned ivalid)
|
||||
{
|
||||
/* Always update if mtime is explicitly set */
|
||||
|
@ -1596,6 +1620,8 @@ static const struct file_operations fuse_dir_operations = {
|
|||
.open = fuse_dir_open,
|
||||
.release = fuse_dir_release,
|
||||
.fsync = fuse_dir_fsync,
|
||||
.unlocked_ioctl = fuse_dir_ioctl,
|
||||
.compat_ioctl = fuse_dir_compat_ioctl,
|
||||
};
|
||||
|
||||
static const struct inode_operations fuse_common_inode_operations = {
|
||||
|
|
|
@ -1926,8 +1926,8 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(fuse_do_ioctl);
|
||||
|
||||
static long fuse_file_ioctl_common(struct file *file, unsigned int cmd,
|
||||
unsigned long arg, unsigned int flags)
|
||||
long fuse_ioctl_common(struct file *file, unsigned int cmd,
|
||||
unsigned long arg, unsigned int flags)
|
||||
{
|
||||
struct inode *inode = file->f_dentry->d_inode;
|
||||
struct fuse_conn *fc = get_fuse_conn(inode);
|
||||
|
@ -1944,13 +1944,13 @@ static long fuse_file_ioctl_common(struct file *file, unsigned int cmd,
|
|||
static long fuse_file_ioctl(struct file *file, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
return fuse_file_ioctl_common(file, cmd, arg, 0);
|
||||
return fuse_ioctl_common(file, cmd, arg, 0);
|
||||
}
|
||||
|
||||
static long fuse_file_compat_ioctl(struct file *file, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
return fuse_file_ioctl_common(file, cmd, arg, FUSE_IOCTL_COMPAT);
|
||||
return fuse_ioctl_common(file, cmd, arg, FUSE_IOCTL_COMPAT);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -765,6 +765,8 @@ ssize_t fuse_direct_io(struct file *file, const char __user *buf,
|
|||
size_t count, loff_t *ppos, int write);
|
||||
long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg,
|
||||
unsigned int flags);
|
||||
long fuse_ioctl_common(struct file *file, unsigned int cmd,
|
||||
unsigned long arg, unsigned int flags);
|
||||
unsigned fuse_file_poll(struct file *file, poll_table *wait);
|
||||
int fuse_dev_release(struct inode *inode, struct file *file);
|
||||
|
||||
|
|
|
@ -50,6 +50,9 @@
|
|||
*
|
||||
* 7.17
|
||||
* - add FUSE_FLOCK_LOCKS and FUSE_RELEASE_FLOCK_UNLOCK
|
||||
*
|
||||
* 7.18
|
||||
* - add FUSE_IOCTL_DIR flag
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_FUSE_H
|
||||
|
@ -81,7 +84,7 @@
|
|||
#define FUSE_KERNEL_VERSION 7
|
||||
|
||||
/** Minor version number of this interface */
|
||||
#define FUSE_KERNEL_MINOR_VERSION 17
|
||||
#define FUSE_KERNEL_MINOR_VERSION 18
|
||||
|
||||
/** The node ID of the root inode */
|
||||
#define FUSE_ROOT_ID 1
|
||||
|
@ -214,6 +217,7 @@ struct fuse_file_lock {
|
|||
* FUSE_IOCTL_UNRESTRICTED: not restricted to well-formed ioctls, retry allowed
|
||||
* FUSE_IOCTL_RETRY: retry with new iovecs
|
||||
* FUSE_IOCTL_32BIT: 32bit ioctl
|
||||
* FUSE_IOCTL_DIR: is a directory
|
||||
*
|
||||
* FUSE_IOCTL_MAX_IOV: maximum of in_iovecs + out_iovecs
|
||||
*/
|
||||
|
@ -221,6 +225,7 @@ struct fuse_file_lock {
|
|||
#define FUSE_IOCTL_UNRESTRICTED (1 << 1)
|
||||
#define FUSE_IOCTL_RETRY (1 << 2)
|
||||
#define FUSE_IOCTL_32BIT (1 << 3)
|
||||
#define FUSE_IOCTL_DIR (1 << 4)
|
||||
|
||||
#define FUSE_IOCTL_MAX_IOV 256
|
||||
|
||||
|
|
Loading…
Reference in a new issue