@@ -3010,6 +3010,47 @@ out:
return err;
}
+static int fuse_do_setfl(unsigned int flags, struct file *file)
+{
+ struct inode *inode = file_inode(file);
+ struct fuse_conn *fc = get_fuse_conn(inode);
+ struct fuse_file *ff = file->private_data;
+ struct fuse_setfl_in inarg;
+ FUSE_ARGS(args);
+ int err;
+
+ if (is_bad_inode(inode))
+ return -EIO;
+
+ if (fc->no_setfl)
+ return 0;
+
+ inarg.fh = ff->fh;
+ inarg.flags = flags;
+ inarg.setting = 1;
+ args.in.h.opcode = FUSE_SETFL;
+ args.in.h.nodeid = get_node_id(inode);
+ args.in.numargs = 1;
+ args.in.args[0].size = sizeof(inarg);
+ args.in.args[0].value = &inarg;
+ err = fuse_simple_request(fc, &args);
+ if (err == -ENOSYS) {
+ fc->no_setfl = 1;
+ err = 0;
+ }
+
+ return err;
+}
+
+static int fuse_file_check_flags(unsigned int flags, struct file *file,
+ int setting)
+{
+ if (!setting)
+ return 0;
+
+ return fuse_do_setfl(flags, file);
+}
+
static const struct file_operations fuse_file_operations = {
.llseek = fuse_file_llseek,
.read_iter = fuse_file_read_iter,
@@ -3026,6 +3067,7 @@ static const struct file_operations fuse_file_operations = {
.compat_ioctl = fuse_file_compat_ioctl,
.poll = fuse_file_poll,
.fallocate = fuse_file_fallocate,
+ .check_flags = fuse_file_check_flags,
};
static const struct file_operations fuse_direct_io_file_operations = {
@@ -3044,6 +3086,7 @@ static const struct file_operations fuse_direct_io_file_operations = {
.poll = fuse_file_poll,
.fallocate = fuse_file_fallocate,
/* no splice_read */
+ .check_flags = fuse_file_check_flags,
};
static const struct address_space_operations fuse_file_aops = {
@@ -617,6 +617,9 @@ struct fuse_conn {
/** Is lseek not implemented by fs? */
unsigned no_lseek:1;
+ /** Is setfl implemented by fs? */
+ unsigned no_setfl:1;
+
/** The number of requests waiting for completion */
atomic_t num_waiting;
@@ -105,6 +105,9 @@
*
* 7.24
* - add FUSE_LSEEK for SEEK_HOLE and SEEK_DATA support
+ *
+ * 7.25
+ * - add FUSE_SETFL
*/
#ifndef _LINUX_FUSE_H
@@ -362,6 +365,7 @@ enum fuse_opcode {
FUSE_READDIRPLUS = 44,
FUSE_RENAME2 = 45,
FUSE_LSEEK = 46,
+ FUSE_SETFL = 47,
/* CUSE specific operations */
CUSE_INIT = 4096,
@@ -773,4 +777,10 @@ struct fuse_lseek_out {
uint64_t offset;
};
+struct fuse_setfl_in {
+ uint64_t fh;
+ uint32_t flags;
+ uint32_t setting;
+};
+
#endif /* _LINUX_FUSE_H */
This patch implement the "check_flags" operation that passes the flag setting by fcntl() and ioctl(fd, FIONBIO, &on) to fuse-based applications. This patch depends on the following: [PATCH] VFS: pass the flag setting by fcntl() to vfs Signed-off-by: Enke Chen <enkechen@cisco.com> Version: 4.6.0_rc6_next_20160505 fs/fuse/file.c | 43 +++++++++++++++++++++++++++++++++++++++++++ fs/fuse/fuse_i.h | 3 +++ include/uapi/linux/fuse.h | 10 ++++++++++ 3 files changed, 56 insertions(+) -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html