diff options
author | Miklos Szeredi <mszeredi@suse.cz> | 2011-12-13 05:58:49 -0500 |
---|---|---|
committer | Miklos Szeredi <mszeredi@suse.cz> | 2011-12-13 05:58:49 -0500 |
commit | b18da0c56e9ff43a007b6c8e302c62e720964151 (patch) | |
tree | dca57bc1042c576474529768533d6efb88716f35 /fs/fuse | |
parent | c411cc88d873b3f68635a04691f7f115c46bc39e (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.c | 26 | ||||
-rw-r--r-- | fs/fuse/file.c | 8 | ||||
-rw-r--r-- | fs/fuse/fuse_i.h | 2 |
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 | ||
1185 | static 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 | |||
1197 | static 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 | |||
1185 | static bool update_mtime(unsigned ivalid) | 1209 | static 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 | ||
1601 | static const struct inode_operations fuse_common_inode_operations = { | 1627 | static 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 | } |
1927 | EXPORT_SYMBOL_GPL(fuse_do_ioctl); | 1927 | EXPORT_SYMBOL_GPL(fuse_do_ioctl); |
1928 | 1928 | ||
1929 | static long fuse_file_ioctl_common(struct file *file, unsigned int cmd, | 1929 | long 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, | |||
1944 | static long fuse_file_ioctl(struct file *file, unsigned int cmd, | 1944 | static 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 | ||
1950 | static long fuse_file_compat_ioctl(struct file *file, unsigned int cmd, | 1950 | static 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); |
766 | long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg, | 766 | long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg, |
767 | unsigned int flags); | 767 | unsigned int flags); |
768 | long fuse_ioctl_common(struct file *file, unsigned int cmd, | ||
769 | unsigned long arg, unsigned int flags); | ||
768 | unsigned fuse_file_poll(struct file *file, poll_table *wait); | 770 | unsigned fuse_file_poll(struct file *file, poll_table *wait); |
769 | int fuse_dev_release(struct inode *inode, struct file *file); | 771 | int fuse_dev_release(struct inode *inode, struct file *file); |
770 | 772 | ||