mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-16 05:26:07 +00:00
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
@ -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);
|
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)
|
static bool update_mtime(unsigned ivalid)
|
||||||
{
|
{
|
||||||
/* Always update if mtime is explicitly set */
|
/* Always update if mtime is explicitly set */
|
||||||
@ -1596,6 +1620,8 @@ static const struct file_operations fuse_dir_operations = {
|
|||||||
.open = fuse_dir_open,
|
.open = fuse_dir_open,
|
||||||
.release = fuse_dir_release,
|
.release = fuse_dir_release,
|
||||||
.fsync = fuse_dir_fsync,
|
.fsync = fuse_dir_fsync,
|
||||||
|
.unlocked_ioctl = fuse_dir_ioctl,
|
||||||
|
.compat_ioctl = fuse_dir_compat_ioctl,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct inode_operations fuse_common_inode_operations = {
|
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);
|
EXPORT_SYMBOL_GPL(fuse_do_ioctl);
|
||||||
|
|
||||||
static long fuse_file_ioctl_common(struct file *file, unsigned int cmd,
|
long fuse_ioctl_common(struct file *file, unsigned int cmd,
|
||||||
unsigned long arg, unsigned int flags)
|
unsigned long arg, unsigned int flags)
|
||||||
{
|
{
|
||||||
struct inode *inode = file->f_dentry->d_inode;
|
struct inode *inode = file->f_dentry->d_inode;
|
||||||
struct fuse_conn *fc = get_fuse_conn(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,
|
static long fuse_file_ioctl(struct file *file, unsigned int cmd,
|
||||||
unsigned long arg)
|
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,
|
static long fuse_file_compat_ioctl(struct file *file, unsigned int cmd,
|
||||||
unsigned long arg)
|
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);
|
size_t count, loff_t *ppos, int write);
|
||||||
long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg,
|
long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg,
|
||||||
unsigned int flags);
|
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);
|
unsigned fuse_file_poll(struct file *file, poll_table *wait);
|
||||||
int fuse_dev_release(struct inode *inode, struct file *file);
|
int fuse_dev_release(struct inode *inode, struct file *file);
|
||||||
|
|
||||||
|
@ -50,6 +50,9 @@
|
|||||||
*
|
*
|
||||||
* 7.17
|
* 7.17
|
||||||
* - add FUSE_FLOCK_LOCKS and FUSE_RELEASE_FLOCK_UNLOCK
|
* - add FUSE_FLOCK_LOCKS and FUSE_RELEASE_FLOCK_UNLOCK
|
||||||
|
*
|
||||||
|
* 7.18
|
||||||
|
* - add FUSE_IOCTL_DIR flag
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _LINUX_FUSE_H
|
#ifndef _LINUX_FUSE_H
|
||||||
@ -81,7 +84,7 @@
|
|||||||
#define FUSE_KERNEL_VERSION 7
|
#define FUSE_KERNEL_VERSION 7
|
||||||
|
|
||||||
/** Minor version number of this interface */
|
/** 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 */
|
/** The node ID of the root inode */
|
||||||
#define FUSE_ROOT_ID 1
|
#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_UNRESTRICTED: not restricted to well-formed ioctls, retry allowed
|
||||||
* FUSE_IOCTL_RETRY: retry with new iovecs
|
* FUSE_IOCTL_RETRY: retry with new iovecs
|
||||||
* FUSE_IOCTL_32BIT: 32bit ioctl
|
* FUSE_IOCTL_32BIT: 32bit ioctl
|
||||||
|
* FUSE_IOCTL_DIR: is a directory
|
||||||
*
|
*
|
||||||
* FUSE_IOCTL_MAX_IOV: maximum of in_iovecs + out_iovecs
|
* 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_UNRESTRICTED (1 << 1)
|
||||||
#define FUSE_IOCTL_RETRY (1 << 2)
|
#define FUSE_IOCTL_RETRY (1 << 2)
|
||||||
#define FUSE_IOCTL_32BIT (1 << 3)
|
#define FUSE_IOCTL_32BIT (1 << 3)
|
||||||
|
#define FUSE_IOCTL_DIR (1 << 4)
|
||||||
|
|
||||||
#define FUSE_IOCTL_MAX_IOV 256
|
#define FUSE_IOCTL_MAX_IOV 256
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user