aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fuse
diff options
context:
space:
mode:
authorMiklos Szeredi <mszeredi@suse.cz>2011-12-13 05:58:49 -0500
committerMiklos Szeredi <mszeredi@suse.cz>2011-12-13 05:58:49 -0500
commitb18da0c56e9ff43a007b6c8e302c62e720964151 (patch)
treedca57bc1042c576474529768533d6efb88716f35 /fs/fuse
parentc411cc88d873b3f68635a04691f7f115c46bc39e (diff)
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>
Diffstat (limited to 'fs/fuse')
-rw-r--r--fs/fuse/dir.c26
-rw-r--r--fs/fuse/file.c8
-rw-r--r--fs/fuse/fuse_i.h2
3 files changed, 32 insertions, 4 deletions
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index 9f63e493a9b6..344577933f62 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -1182,6 +1182,30 @@ static int fuse_dir_fsync(struct file *file, loff_t start, loff_t end,
1182 return fuse_fsync_common(file, start, end, datasync, 1); 1182 return fuse_fsync_common(file, start, end, datasync, 1);
1183} 1183}
1184 1184
1185static long fuse_dir_ioctl(struct file *file, unsigned int cmd,
1186 unsigned long arg)
1187{
1188 struct fuse_conn *fc = get_fuse_conn(file->f_mapping->host);
1189
1190 /* FUSE_IOCTL_DIR only supported for API version >= 7.18 */
1191 if (fc->minor < 18)
1192 return -ENOTTY;
1193
1194 return fuse_ioctl_common(file, cmd, arg, FUSE_IOCTL_DIR);
1195}
1196
1197static long fuse_dir_compat_ioctl(struct file *file, unsigned int cmd,
1198 unsigned long arg)
1199{
1200 struct fuse_conn *fc = get_fuse_conn(file->f_mapping->host);
1201
1202 if (fc->minor < 18)
1203 return -ENOTTY;
1204
1205 return fuse_ioctl_common(file, cmd, arg,
1206 FUSE_IOCTL_COMPAT | FUSE_IOCTL_DIR);
1207}
1208
1185static bool update_mtime(unsigned ivalid) 1209static bool update_mtime(unsigned ivalid)
1186{ 1210{
1187 /* Always update if mtime is explicitly set */ 1211 /* Always update if mtime is explicitly set */
@@ -1596,6 +1620,8 @@ static const struct file_operations fuse_dir_operations = {
1596 .open = fuse_dir_open, 1620 .open = fuse_dir_open,
1597 .release = fuse_dir_release, 1621 .release = fuse_dir_release,
1598 .fsync = fuse_dir_fsync, 1622 .fsync = fuse_dir_fsync,
1623 .unlocked_ioctl = fuse_dir_ioctl,
1624 .compat_ioctl = fuse_dir_compat_ioctl,
1599}; 1625};
1600 1626
1601static const struct inode_operations fuse_common_inode_operations = { 1627static const struct inode_operations fuse_common_inode_operations = {
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index c297425cba71..4a199fd93fbd 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -1926,8 +1926,8 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg,
1926} 1926}
1927EXPORT_SYMBOL_GPL(fuse_do_ioctl); 1927EXPORT_SYMBOL_GPL(fuse_do_ioctl);
1928 1928
1929static long fuse_file_ioctl_common(struct file *file, unsigned int cmd, 1929long fuse_ioctl_common(struct file *file, unsigned int cmd,
1930 unsigned long arg, unsigned int flags) 1930 unsigned long arg, unsigned int flags)
1931{ 1931{
1932 struct inode *inode = file->f_dentry->d_inode; 1932 struct inode *inode = file->f_dentry->d_inode;
1933 struct fuse_conn *fc = get_fuse_conn(inode); 1933 struct fuse_conn *fc = get_fuse_conn(inode);
@@ -1944,13 +1944,13 @@ static long fuse_file_ioctl_common(struct file *file, unsigned int cmd,
1944static long fuse_file_ioctl(struct file *file, unsigned int cmd, 1944static long fuse_file_ioctl(struct file *file, unsigned int cmd,
1945 unsigned long arg) 1945 unsigned long arg)
1946{ 1946{
1947 return fuse_file_ioctl_common(file, cmd, arg, 0); 1947 return fuse_ioctl_common(file, cmd, arg, 0);
1948} 1948}
1949 1949
1950static long fuse_file_compat_ioctl(struct file *file, unsigned int cmd, 1950static long fuse_file_compat_ioctl(struct file *file, unsigned int cmd,
1951 unsigned long arg) 1951 unsigned long arg)
1952{ 1952{
1953 return fuse_file_ioctl_common(file, cmd, arg, FUSE_IOCTL_COMPAT); 1953 return fuse_ioctl_common(file, cmd, arg, FUSE_IOCTL_COMPAT);
1954} 1954}
1955 1955
1956/* 1956/*
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index cf6db0a93219..09337bcc2554 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -765,6 +765,8 @@ ssize_t fuse_direct_io(struct file *file, const char __user *buf,
765 size_t count, loff_t *ppos, int write); 765 size_t count, loff_t *ppos, int write);
766long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg, 766long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg,
767 unsigned int flags); 767 unsigned int flags);
768long fuse_ioctl_common(struct file *file, unsigned int cmd,
769 unsigned long arg, unsigned int flags);
768unsigned fuse_file_poll(struct file *file, poll_table *wait); 770unsigned fuse_file_poll(struct file *file, poll_table *wait);
769int fuse_dev_release(struct inode *inode, struct file *file); 771int fuse_dev_release(struct inode *inode, struct file *file);
770 772