aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-05-14 11:59:14 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2019-05-14 11:59:14 -0400
commit4856118f4953627e9a087253766b9e7361f5f4a0 (patch)
tree9a3a5a42580a2dfab8bc75aee29a034ed425bb21
parent0d28544117fa9dcd0d202aeb4459bb15f42bb7de (diff)
parent9031a69cf9f024a3040c0ed8b8ab01aecd196388 (diff)
Merge tag 'fuse-update-5.2' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse
Pull fuse update from Miklos Szeredi: "Add more caching controls for userspace filesystems to use, as well as bug fixes and cleanups" * tag 'fuse-update-5.2' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse: fuse: clean up fuse_alloc_inode fuse: Add ioctl flag for x32 compat ioctl fuse: Convert fusectl to use the new mount API fuse: fix changelog entry for protocol 7.9 fuse: fix changelog entry for protocol 7.12 fuse: document fuse_fsync_in.fsync_flags fuse: Add FOPEN_STREAM to use stream_open() fuse: require /dev/fuse reads to have enough buffer capacity fuse: retrieve: cap requested size to negotiated max_write fuse: allow filesystems to have precise control over data cache fuse: convert printk -> pr_* fuse: honor RLIMIT_FSIZE in fuse_file_fallocate fuse: fix writepages on 32bit
-rw-r--r--fs/fuse/control.c20
-rw-r--r--fs/fuse/cuse.c13
-rw-r--r--fs/fuse/dev.c16
-rw-r--r--fs/fuse/file.c22
-rw-r--r--fs/fuse/fuse_i.h7
-rw-r--r--fs/fuse/inode.c23
-rw-r--r--include/uapi/linux/fuse.h22
7 files changed, 92 insertions, 31 deletions
diff --git a/fs/fuse/control.c b/fs/fuse/control.c
index fe80bea4ad89..14ce1e47f980 100644
--- a/fs/fuse/control.c
+++ b/fs/fuse/control.c
@@ -10,6 +10,7 @@
10 10
11#include <linux/init.h> 11#include <linux/init.h>
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/fs_context.h>
13 14
14#define FUSE_CTL_SUPER_MAGIC 0x65735543 15#define FUSE_CTL_SUPER_MAGIC 0x65735543
15 16
@@ -317,7 +318,7 @@ void fuse_ctl_remove_conn(struct fuse_conn *fc)
317 drop_nlink(d_inode(fuse_control_sb->s_root)); 318 drop_nlink(d_inode(fuse_control_sb->s_root));
318} 319}
319 320
320static int fuse_ctl_fill_super(struct super_block *sb, void *data, int silent) 321static int fuse_ctl_fill_super(struct super_block *sb, struct fs_context *fctx)
321{ 322{
322 static const struct tree_descr empty_descr = {""}; 323 static const struct tree_descr empty_descr = {""};
323 struct fuse_conn *fc; 324 struct fuse_conn *fc;
@@ -343,10 +344,19 @@ static int fuse_ctl_fill_super(struct super_block *sb, void *data, int silent)
343 return 0; 344 return 0;
344} 345}
345 346
346static struct dentry *fuse_ctl_mount(struct file_system_type *fs_type, 347static int fuse_ctl_get_tree(struct fs_context *fc)
347 int flags, const char *dev_name, void *raw_data)
348{ 348{
349 return mount_single(fs_type, flags, raw_data, fuse_ctl_fill_super); 349 return vfs_get_super(fc, vfs_get_single_super, fuse_ctl_fill_super);
350}
351
352static const struct fs_context_operations fuse_ctl_context_ops = {
353 .get_tree = fuse_ctl_get_tree,
354};
355
356static int fuse_ctl_init_fs_context(struct fs_context *fc)
357{
358 fc->ops = &fuse_ctl_context_ops;
359 return 0;
350} 360}
351 361
352static void fuse_ctl_kill_sb(struct super_block *sb) 362static void fuse_ctl_kill_sb(struct super_block *sb)
@@ -365,7 +375,7 @@ static void fuse_ctl_kill_sb(struct super_block *sb)
365static struct file_system_type fuse_ctl_fs_type = { 375static struct file_system_type fuse_ctl_fs_type = {
366 .owner = THIS_MODULE, 376 .owner = THIS_MODULE,
367 .name = "fusectl", 377 .name = "fusectl",
368 .mount = fuse_ctl_mount, 378 .init_fs_context = fuse_ctl_init_fs_context,
369 .kill_sb = fuse_ctl_kill_sb, 379 .kill_sb = fuse_ctl_kill_sb,
370}; 380};
371MODULE_ALIAS_FS("fusectl"); 381MODULE_ALIAS_FS("fusectl");
diff --git a/fs/fuse/cuse.c b/fs/fuse/cuse.c
index 55a26f351467..4b41df1d4642 100644
--- a/fs/fuse/cuse.c
+++ b/fs/fuse/cuse.c
@@ -33,6 +33,8 @@
33 * closed. 33 * closed.
34 */ 34 */
35 35
36#define pr_fmt(fmt) "CUSE: " fmt
37
36#include <linux/fuse.h> 38#include <linux/fuse.h>
37#include <linux/cdev.h> 39#include <linux/cdev.h>
38#include <linux/device.h> 40#include <linux/device.h>
@@ -225,7 +227,7 @@ static int cuse_parse_one(char **pp, char *end, char **keyp, char **valp)
225 return 0; 227 return 0;
226 228
227 if (end[-1] != '\0') { 229 if (end[-1] != '\0') {
228 printk(KERN_ERR "CUSE: info not properly terminated\n"); 230 pr_err("info not properly terminated\n");
229 return -EINVAL; 231 return -EINVAL;
230 } 232 }
231 233
@@ -242,7 +244,7 @@ static int cuse_parse_one(char **pp, char *end, char **keyp, char **valp)
242 key = strstrip(key); 244 key = strstrip(key);
243 245
244 if (!strlen(key)) { 246 if (!strlen(key)) {
245 printk(KERN_ERR "CUSE: zero length info key specified\n"); 247 pr_err("zero length info key specified\n");
246 return -EINVAL; 248 return -EINVAL;
247 } 249 }
248 250
@@ -282,12 +284,11 @@ static int cuse_parse_devinfo(char *p, size_t len, struct cuse_devinfo *devinfo)
282 if (strcmp(key, "DEVNAME") == 0) 284 if (strcmp(key, "DEVNAME") == 0)
283 devinfo->name = val; 285 devinfo->name = val;
284 else 286 else
285 printk(KERN_WARNING "CUSE: unknown device info \"%s\"\n", 287 pr_warn("unknown device info \"%s\"\n", key);
286 key);
287 } 288 }
288 289
289 if (!devinfo->name || !strlen(devinfo->name)) { 290 if (!devinfo->name || !strlen(devinfo->name)) {
290 printk(KERN_ERR "CUSE: DEVNAME unspecified\n"); 291 pr_err("DEVNAME unspecified\n");
291 return -EINVAL; 292 return -EINVAL;
292 } 293 }
293 294
@@ -341,7 +342,7 @@ static void cuse_process_init_reply(struct fuse_conn *fc, struct fuse_req *req)
341 else 342 else
342 rc = register_chrdev_region(devt, 1, devinfo.name); 343 rc = register_chrdev_region(devt, 1, devinfo.name);
343 if (rc) { 344 if (rc) {
344 printk(KERN_ERR "CUSE: failed to register chrdev region\n"); 345 pr_err("failed to register chrdev region\n");
345 goto err; 346 goto err;
346 } 347 }
347 348
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index 9971a35cf1ef..24ea19cfe07e 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -906,8 +906,8 @@ static int fuse_check_page(struct page *page)
906 1 << PG_lru | 906 1 << PG_lru |
907 1 << PG_active | 907 1 << PG_active |
908 1 << PG_reclaim))) { 908 1 << PG_reclaim))) {
909 printk(KERN_WARNING "fuse: trying to steal weird page\n"); 909 pr_warn("trying to steal weird page\n");
910 printk(KERN_WARNING " page=%p index=%li flags=%08lx, count=%i, mapcount=%i, mapping=%p\n", page, page->index, page->flags, page_count(page), page_mapcount(page), page->mapping); 910 pr_warn(" page=%p index=%li flags=%08lx, count=%i, mapcount=%i, mapping=%p\n", page, page->index, page->flags, page_count(page), page_mapcount(page), page->mapping);
911 return 1; 911 return 1;
912 } 912 }
913 return 0; 913 return 0;
@@ -1317,6 +1317,16 @@ static ssize_t fuse_dev_do_read(struct fuse_dev *fud, struct file *file,
1317 unsigned reqsize; 1317 unsigned reqsize;
1318 unsigned int hash; 1318 unsigned int hash;
1319 1319
1320 /*
1321 * Require sane minimum read buffer - that has capacity for fixed part
1322 * of any request header + negotated max_write room for data. If the
1323 * requirement is not satisfied return EINVAL to the filesystem server
1324 * to indicate that it is not following FUSE server/client contract.
1325 * Don't dequeue / abort any request.
1326 */
1327 if (nbytes < max_t(size_t, FUSE_MIN_READ_BUFFER, 4096 + fc->max_write))
1328 return -EINVAL;
1329
1320 restart: 1330 restart:
1321 spin_lock(&fiq->waitq.lock); 1331 spin_lock(&fiq->waitq.lock);
1322 err = -EAGAIN; 1332 err = -EAGAIN;
@@ -1749,7 +1759,7 @@ static int fuse_retrieve(struct fuse_conn *fc, struct inode *inode,
1749 offset = outarg->offset & ~PAGE_MASK; 1759 offset = outarg->offset & ~PAGE_MASK;
1750 file_size = i_size_read(inode); 1760 file_size = i_size_read(inode);
1751 1761
1752 num = outarg->size; 1762 num = min(outarg->size, fc->max_write);
1753 if (outarg->offset > file_size) 1763 if (outarg->offset > file_size)
1754 num = 0; 1764 num = 0;
1755 else if (outarg->offset + num > file_size) 1765 else if (outarg->offset + num > file_size)
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 06096b60f1df..3959f08279e6 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -178,7 +178,9 @@ void fuse_finish_open(struct inode *inode, struct file *file)
178 178
179 if (!(ff->open_flags & FOPEN_KEEP_CACHE)) 179 if (!(ff->open_flags & FOPEN_KEEP_CACHE))
180 invalidate_inode_pages2(inode->i_mapping); 180 invalidate_inode_pages2(inode->i_mapping);
181 if (ff->open_flags & FOPEN_NONSEEKABLE) 181 if (ff->open_flags & FOPEN_STREAM)
182 stream_open(inode, file);
183 else if (ff->open_flags & FOPEN_NONSEEKABLE)
182 nonseekable_open(inode, file); 184 nonseekable_open(inode, file);
183 if (fc->atomic_o_trunc && (file->f_flags & O_TRUNC)) { 185 if (fc->atomic_o_trunc && (file->f_flags & O_TRUNC)) {
184 struct fuse_inode *fi = get_fuse_inode(inode); 186 struct fuse_inode *fi = get_fuse_inode(inode);
@@ -462,7 +464,7 @@ int fuse_fsync_common(struct file *file, loff_t start, loff_t end,
462 464
463 memset(&inarg, 0, sizeof(inarg)); 465 memset(&inarg, 0, sizeof(inarg));
464 inarg.fh = ff->fh; 466 inarg.fh = ff->fh;
465 inarg.fsync_flags = datasync ? 1 : 0; 467 inarg.fsync_flags = datasync ? FUSE_FSYNC_FDATASYNC : 0;
466 args.in.h.opcode = opcode; 468 args.in.h.opcode = opcode;
467 args.in.h.nodeid = get_node_id(inode); 469 args.in.h.nodeid = get_node_id(inode);
468 args.in.numargs = 1; 470 args.in.numargs = 1;
@@ -1586,7 +1588,7 @@ __acquires(fi->lock)
1586{ 1588{
1587 struct fuse_conn *fc = get_fuse_conn(inode); 1589 struct fuse_conn *fc = get_fuse_conn(inode);
1588 struct fuse_inode *fi = get_fuse_inode(inode); 1590 struct fuse_inode *fi = get_fuse_inode(inode);
1589 size_t crop = i_size_read(inode); 1591 loff_t crop = i_size_read(inode);
1590 struct fuse_req *req; 1592 struct fuse_req *req;
1591 1593
1592 while (fi->writectr >= 0 && !list_empty(&fi->queued_writes)) { 1594 while (fi->writectr >= 0 && !list_empty(&fi->queued_writes)) {
@@ -2576,8 +2578,13 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg,
2576#if BITS_PER_LONG == 32 2578#if BITS_PER_LONG == 32
2577 inarg.flags |= FUSE_IOCTL_32BIT; 2579 inarg.flags |= FUSE_IOCTL_32BIT;
2578#else 2580#else
2579 if (flags & FUSE_IOCTL_COMPAT) 2581 if (flags & FUSE_IOCTL_COMPAT) {
2580 inarg.flags |= FUSE_IOCTL_32BIT; 2582 inarg.flags |= FUSE_IOCTL_32BIT;
2583#ifdef CONFIG_X86_X32
2584 if (in_x32_syscall())
2585 inarg.flags |= FUSE_IOCTL_COMPAT_X32;
2586#endif
2587 }
2581#endif 2588#endif
2582 2589
2583 /* assume all the iovs returned by client always fits in a page */ 2590 /* assume all the iovs returned by client always fits in a page */
@@ -3044,6 +3051,13 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset,
3044 } 3051 }
3045 } 3052 }
3046 3053
3054 if (!(mode & FALLOC_FL_KEEP_SIZE) &&
3055 offset + length > i_size_read(inode)) {
3056 err = inode_newsize_ok(inode, offset + length);
3057 if (err)
3058 return err;
3059 }
3060
3047 if (!(mode & FALLOC_FL_KEEP_SIZE)) 3061 if (!(mode & FALLOC_FL_KEEP_SIZE))
3048 set_bit(FUSE_I_SIZE_UNSTABLE, &fi->state); 3062 set_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
3049 3063
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index 0920c0c032a0..24dbca777775 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -9,6 +9,10 @@
9#ifndef _FS_FUSE_I_H 9#ifndef _FS_FUSE_I_H
10#define _FS_FUSE_I_H 10#define _FS_FUSE_I_H
11 11
12#ifndef pr_fmt
13# define pr_fmt(fmt) "fuse: " fmt
14#endif
15
12#include <linux/fuse.h> 16#include <linux/fuse.h>
13#include <linux/fs.h> 17#include <linux/fs.h>
14#include <linux/mount.h> 18#include <linux/mount.h>
@@ -690,6 +694,9 @@ struct fuse_conn {
690 /** Use enhanced/automatic page cache invalidation. */ 694 /** Use enhanced/automatic page cache invalidation. */
691 unsigned auto_inval_data:1; 695 unsigned auto_inval_data:1;
692 696
697 /** Filesystem is fully reponsible for page cache invalidation. */
698 unsigned explicit_inval_data:1;
699
693 /** Does the filesystem support readdirplus? */ 700 /** Does the filesystem support readdirplus? */
694 unsigned do_readdirplus:1; 701 unsigned do_readdirplus:1;
695 702
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index f485d09d14df..4bb885b0f032 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -81,14 +81,12 @@ struct fuse_forget_link *fuse_alloc_forget(void)
81 81
82static struct inode *fuse_alloc_inode(struct super_block *sb) 82static struct inode *fuse_alloc_inode(struct super_block *sb)
83{ 83{
84 struct inode *inode;
85 struct fuse_inode *fi; 84 struct fuse_inode *fi;
86 85
87 inode = kmem_cache_alloc(fuse_inode_cachep, GFP_KERNEL); 86 fi = kmem_cache_alloc(fuse_inode_cachep, GFP_KERNEL);
88 if (!inode) 87 if (!fi)
89 return NULL; 88 return NULL;
90 89
91 fi = get_fuse_inode(inode);
92 fi->i_time = 0; 90 fi->i_time = 0;
93 fi->inval_mask = 0; 91 fi->inval_mask = 0;
94 fi->nodeid = 0; 92 fi->nodeid = 0;
@@ -100,11 +98,11 @@ static struct inode *fuse_alloc_inode(struct super_block *sb)
100 spin_lock_init(&fi->lock); 98 spin_lock_init(&fi->lock);
101 fi->forget = fuse_alloc_forget(); 99 fi->forget = fuse_alloc_forget();
102 if (!fi->forget) { 100 if (!fi->forget) {
103 kmem_cache_free(fuse_inode_cachep, inode); 101 kmem_cache_free(fuse_inode_cachep, fi);
104 return NULL; 102 return NULL;
105 } 103 }
106 104
107 return inode; 105 return &fi->inode;
108} 106}
109 107
110static void fuse_free_inode(struct inode *inode) 108static void fuse_free_inode(struct inode *inode)
@@ -233,7 +231,8 @@ void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr,
233 231
234 if (oldsize != attr->size) { 232 if (oldsize != attr->size) {
235 truncate_pagecache(inode, attr->size); 233 truncate_pagecache(inode, attr->size);
236 inval = true; 234 if (!fc->explicit_inval_data)
235 inval = true;
237 } else if (fc->auto_inval_data) { 236 } else if (fc->auto_inval_data) {
238 struct timespec64 new_mtime = { 237 struct timespec64 new_mtime = {
239 .tv_sec = attr->mtime, 238 .tv_sec = attr->mtime,
@@ -908,6 +907,8 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req)
908 fc->dont_mask = 1; 907 fc->dont_mask = 1;
909 if (arg->flags & FUSE_AUTO_INVAL_DATA) 908 if (arg->flags & FUSE_AUTO_INVAL_DATA)
910 fc->auto_inval_data = 1; 909 fc->auto_inval_data = 1;
910 else if (arg->flags & FUSE_EXPLICIT_INVAL_DATA)
911 fc->explicit_inval_data = 1;
911 if (arg->flags & FUSE_DO_READDIRPLUS) { 912 if (arg->flags & FUSE_DO_READDIRPLUS) {
912 fc->do_readdirplus = 1; 913 fc->do_readdirplus = 1;
913 if (arg->flags & FUSE_READDIRPLUS_AUTO) 914 if (arg->flags & FUSE_READDIRPLUS_AUTO)
@@ -969,7 +970,7 @@ static void fuse_send_init(struct fuse_conn *fc, struct fuse_req *req)
969 FUSE_WRITEBACK_CACHE | FUSE_NO_OPEN_SUPPORT | 970 FUSE_WRITEBACK_CACHE | FUSE_NO_OPEN_SUPPORT |
970 FUSE_PARALLEL_DIROPS | FUSE_HANDLE_KILLPRIV | FUSE_POSIX_ACL | 971 FUSE_PARALLEL_DIROPS | FUSE_HANDLE_KILLPRIV | FUSE_POSIX_ACL |
971 FUSE_ABORT_ERROR | FUSE_MAX_PAGES | FUSE_CACHE_SYMLINKS | 972 FUSE_ABORT_ERROR | FUSE_MAX_PAGES | FUSE_CACHE_SYMLINKS |
972 FUSE_NO_OPENDIR_SUPPORT; 973 FUSE_NO_OPENDIR_SUPPORT | FUSE_EXPLICIT_INVAL_DATA;
973 req->in.h.opcode = FUSE_INIT; 974 req->in.h.opcode = FUSE_INIT;
974 req->in.numargs = 1; 975 req->in.numargs = 1;
975 req->in.args[0].size = sizeof(*arg); 976 req->in.args[0].size = sizeof(*arg);
@@ -1393,8 +1394,8 @@ static int __init fuse_init(void)
1393{ 1394{
1394 int res; 1395 int res;
1395 1396
1396 printk(KERN_INFO "fuse init (API version %i.%i)\n", 1397 pr_info("init (API version %i.%i)\n",
1397 FUSE_KERNEL_VERSION, FUSE_KERNEL_MINOR_VERSION); 1398 FUSE_KERNEL_VERSION, FUSE_KERNEL_MINOR_VERSION);
1398 1399
1399 INIT_LIST_HEAD(&fuse_conn_list); 1400 INIT_LIST_HEAD(&fuse_conn_list);
1400 res = fuse_fs_init(); 1401 res = fuse_fs_init();
@@ -1430,7 +1431,7 @@ static int __init fuse_init(void)
1430 1431
1431static void __exit fuse_exit(void) 1432static void __exit fuse_exit(void)
1432{ 1433{
1433 printk(KERN_DEBUG "fuse exit\n"); 1434 pr_debug("exit\n");
1434 1435
1435 fuse_ctl_cleanup(); 1436 fuse_ctl_cleanup();
1436 fuse_sysfs_cleanup(); 1437 fuse_sysfs_cleanup();
diff --git a/include/uapi/linux/fuse.h b/include/uapi/linux/fuse.h
index 2ac598614a8f..19fb55e3c73e 100644
--- a/include/uapi/linux/fuse.h
+++ b/include/uapi/linux/fuse.h
@@ -44,6 +44,7 @@
44 * - add lock_owner field to fuse_setattr_in, fuse_read_in and fuse_write_in 44 * - add lock_owner field to fuse_setattr_in, fuse_read_in and fuse_write_in
45 * - add blksize field to fuse_attr 45 * - add blksize field to fuse_attr
46 * - add file flags field to fuse_read_in and fuse_write_in 46 * - add file flags field to fuse_read_in and fuse_write_in
47 * - Add ATIME_NOW and MTIME_NOW flags to fuse_setattr_in
47 * 48 *
48 * 7.10 49 * 7.10
49 * - add nonseekable open flag 50 * - add nonseekable open flag
@@ -54,7 +55,7 @@
54 * - add POLL message and NOTIFY_POLL notification 55 * - add POLL message and NOTIFY_POLL notification
55 * 56 *
56 * 7.12 57 * 7.12
57 * - add umask flag to input argument of open, mknod and mkdir 58 * - add umask flag to input argument of create, mknod and mkdir
58 * - add notification messages for invalidation of inodes and 59 * - add notification messages for invalidation of inodes and
59 * directory entries 60 * directory entries
60 * 61 *
@@ -125,6 +126,10 @@
125 * 126 *
126 * 7.29 127 * 7.29
127 * - add FUSE_NO_OPENDIR_SUPPORT flag 128 * - add FUSE_NO_OPENDIR_SUPPORT flag
129 *
130 * 7.30
131 * - add FUSE_EXPLICIT_INVAL_DATA
132 * - add FUSE_IOCTL_COMPAT_X32
128 */ 133 */
129 134
130#ifndef _LINUX_FUSE_H 135#ifndef _LINUX_FUSE_H
@@ -160,7 +165,7 @@
160#define FUSE_KERNEL_VERSION 7 165#define FUSE_KERNEL_VERSION 7
161 166
162/** Minor version number of this interface */ 167/** Minor version number of this interface */
163#define FUSE_KERNEL_MINOR_VERSION 29 168#define FUSE_KERNEL_MINOR_VERSION 30
164 169
165/** The node ID of the root inode */ 170/** The node ID of the root inode */
166#define FUSE_ROOT_ID 1 171#define FUSE_ROOT_ID 1
@@ -229,11 +234,13 @@ struct fuse_file_lock {
229 * FOPEN_KEEP_CACHE: don't invalidate the data cache on open 234 * FOPEN_KEEP_CACHE: don't invalidate the data cache on open
230 * FOPEN_NONSEEKABLE: the file is not seekable 235 * FOPEN_NONSEEKABLE: the file is not seekable
231 * FOPEN_CACHE_DIR: allow caching this directory 236 * FOPEN_CACHE_DIR: allow caching this directory
237 * FOPEN_STREAM: the file is stream-like (no file position at all)
232 */ 238 */
233#define FOPEN_DIRECT_IO (1 << 0) 239#define FOPEN_DIRECT_IO (1 << 0)
234#define FOPEN_KEEP_CACHE (1 << 1) 240#define FOPEN_KEEP_CACHE (1 << 1)
235#define FOPEN_NONSEEKABLE (1 << 2) 241#define FOPEN_NONSEEKABLE (1 << 2)
236#define FOPEN_CACHE_DIR (1 << 3) 242#define FOPEN_CACHE_DIR (1 << 3)
243#define FOPEN_STREAM (1 << 4)
237 244
238/** 245/**
239 * INIT request/reply flags 246 * INIT request/reply flags
@@ -263,6 +270,7 @@ struct fuse_file_lock {
263 * FUSE_MAX_PAGES: init_out.max_pages contains the max number of req pages 270 * FUSE_MAX_PAGES: init_out.max_pages contains the max number of req pages
264 * FUSE_CACHE_SYMLINKS: cache READLINK responses 271 * FUSE_CACHE_SYMLINKS: cache READLINK responses
265 * FUSE_NO_OPENDIR_SUPPORT: kernel supports zero-message opendir 272 * FUSE_NO_OPENDIR_SUPPORT: kernel supports zero-message opendir
273 * FUSE_EXPLICIT_INVAL_DATA: only invalidate cached pages on explicit request
266 */ 274 */
267#define FUSE_ASYNC_READ (1 << 0) 275#define FUSE_ASYNC_READ (1 << 0)
268#define FUSE_POSIX_LOCKS (1 << 1) 276#define FUSE_POSIX_LOCKS (1 << 1)
@@ -289,6 +297,7 @@ struct fuse_file_lock {
289#define FUSE_MAX_PAGES (1 << 22) 297#define FUSE_MAX_PAGES (1 << 22)
290#define FUSE_CACHE_SYMLINKS (1 << 23) 298#define FUSE_CACHE_SYMLINKS (1 << 23)
291#define FUSE_NO_OPENDIR_SUPPORT (1 << 24) 299#define FUSE_NO_OPENDIR_SUPPORT (1 << 24)
300#define FUSE_EXPLICIT_INVAL_DATA (1 << 25)
292 301
293/** 302/**
294 * CUSE INIT request/reply flags 303 * CUSE INIT request/reply flags
@@ -335,6 +344,7 @@ struct fuse_file_lock {
335 * FUSE_IOCTL_RETRY: retry with new iovecs 344 * FUSE_IOCTL_RETRY: retry with new iovecs
336 * FUSE_IOCTL_32BIT: 32bit ioctl 345 * FUSE_IOCTL_32BIT: 32bit ioctl
337 * FUSE_IOCTL_DIR: is a directory 346 * FUSE_IOCTL_DIR: is a directory
347 * FUSE_IOCTL_COMPAT_X32: x32 compat ioctl on 64bit machine (64bit time_t)
338 * 348 *
339 * FUSE_IOCTL_MAX_IOV: maximum of in_iovecs + out_iovecs 349 * FUSE_IOCTL_MAX_IOV: maximum of in_iovecs + out_iovecs
340 */ 350 */
@@ -343,6 +353,7 @@ struct fuse_file_lock {
343#define FUSE_IOCTL_RETRY (1 << 2) 353#define FUSE_IOCTL_RETRY (1 << 2)
344#define FUSE_IOCTL_32BIT (1 << 3) 354#define FUSE_IOCTL_32BIT (1 << 3)
345#define FUSE_IOCTL_DIR (1 << 4) 355#define FUSE_IOCTL_DIR (1 << 4)
356#define FUSE_IOCTL_COMPAT_X32 (1 << 5)
346 357
347#define FUSE_IOCTL_MAX_IOV 256 358#define FUSE_IOCTL_MAX_IOV 256
348 359
@@ -353,6 +364,13 @@ struct fuse_file_lock {
353 */ 364 */
354#define FUSE_POLL_SCHEDULE_NOTIFY (1 << 0) 365#define FUSE_POLL_SCHEDULE_NOTIFY (1 << 0)
355 366
367/**
368 * Fsync flags
369 *
370 * FUSE_FSYNC_FDATASYNC: Sync data only, not metadata
371 */
372#define FUSE_FSYNC_FDATASYNC (1 << 0)
373
356enum fuse_opcode { 374enum fuse_opcode {
357 FUSE_LOOKUP = 1, 375 FUSE_LOOKUP = 1,
358 FUSE_FORGET = 2, /* no reply */ 376 FUSE_FORGET = 2, /* no reply */