diff options
-rw-r--r-- | fs/fuse/file.c | 11 | ||||
-rw-r--r-- | fs/fuse/inode.c | 5 | ||||
-rw-r--r-- | include/uapi/linux/fuse.h | 7 |
3 files changed, 21 insertions, 2 deletions
diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 276433021561..d03a35d3197e 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c | |||
@@ -224,6 +224,8 @@ void fuse_finish_open(struct inode *inode, struct file *file) | |||
224 | spin_unlock(&fc->lock); | 224 | spin_unlock(&fc->lock); |
225 | fuse_invalidate_attr(inode); | 225 | fuse_invalidate_attr(inode); |
226 | } | 226 | } |
227 | if ((file->f_mode & FMODE_WRITE) && fc->writeback_cache) | ||
228 | fuse_link_write_file(file); | ||
227 | } | 229 | } |
228 | 230 | ||
229 | int fuse_open_common(struct inode *inode, struct file *file, bool isdir) | 231 | int fuse_open_common(struct inode *inode, struct file *file, bool isdir) |
@@ -1197,6 +1199,15 @@ static ssize_t fuse_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
1197 | struct iov_iter i; | 1199 | struct iov_iter i; |
1198 | loff_t endbyte = 0; | 1200 | loff_t endbyte = 0; |
1199 | 1201 | ||
1202 | if (get_fuse_conn(inode)->writeback_cache) { | ||
1203 | /* Update size (EOF optimization) and mode (SUID clearing) */ | ||
1204 | err = fuse_update_attributes(mapping->host, NULL, file, NULL); | ||
1205 | if (err) | ||
1206 | return err; | ||
1207 | |||
1208 | return generic_file_aio_write(iocb, iov, nr_segs, pos); | ||
1209 | } | ||
1210 | |||
1200 | WARN_ON(iocb->ki_pos != pos); | 1211 | WARN_ON(iocb->ki_pos != pos); |
1201 | 1212 | ||
1202 | ocount = 0; | 1213 | ocount = 0; |
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 1061b0d9b86d..9ba191917415 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c | |||
@@ -887,6 +887,8 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req) | |||
887 | } | 887 | } |
888 | if (arg->flags & FUSE_ASYNC_DIO) | 888 | if (arg->flags & FUSE_ASYNC_DIO) |
889 | fc->async_dio = 1; | 889 | fc->async_dio = 1; |
890 | if (arg->flags & FUSE_WRITEBACK_CACHE) | ||
891 | fc->writeback_cache = 1; | ||
890 | } else { | 892 | } else { |
891 | ra_pages = fc->max_read / PAGE_CACHE_SIZE; | 893 | ra_pages = fc->max_read / PAGE_CACHE_SIZE; |
892 | fc->no_lock = 1; | 894 | fc->no_lock = 1; |
@@ -914,7 +916,8 @@ static void fuse_send_init(struct fuse_conn *fc, struct fuse_req *req) | |||
914 | FUSE_EXPORT_SUPPORT | FUSE_BIG_WRITES | FUSE_DONT_MASK | | 916 | FUSE_EXPORT_SUPPORT | FUSE_BIG_WRITES | FUSE_DONT_MASK | |
915 | FUSE_SPLICE_WRITE | FUSE_SPLICE_MOVE | FUSE_SPLICE_READ | | 917 | FUSE_SPLICE_WRITE | FUSE_SPLICE_MOVE | FUSE_SPLICE_READ | |
916 | FUSE_FLOCK_LOCKS | FUSE_IOCTL_DIR | FUSE_AUTO_INVAL_DATA | | 918 | FUSE_FLOCK_LOCKS | FUSE_IOCTL_DIR | FUSE_AUTO_INVAL_DATA | |
917 | FUSE_DO_READDIRPLUS | FUSE_READDIRPLUS_AUTO | FUSE_ASYNC_DIO; | 919 | FUSE_DO_READDIRPLUS | FUSE_READDIRPLUS_AUTO | FUSE_ASYNC_DIO | |
920 | FUSE_WRITEBACK_CACHE; | ||
918 | req->in.h.opcode = FUSE_INIT; | 921 | req->in.h.opcode = FUSE_INIT; |
919 | req->in.numargs = 1; | 922 | req->in.numargs = 1; |
920 | req->in.args[0].size = sizeof(*arg); | 923 | req->in.args[0].size = sizeof(*arg); |
diff --git a/include/uapi/linux/fuse.h b/include/uapi/linux/fuse.h index 60bb2f9f7b74..cf4750e1bb49 100644 --- a/include/uapi/linux/fuse.h +++ b/include/uapi/linux/fuse.h | |||
@@ -93,6 +93,9 @@ | |||
93 | * | 93 | * |
94 | * 7.22 | 94 | * 7.22 |
95 | * - add FUSE_ASYNC_DIO | 95 | * - add FUSE_ASYNC_DIO |
96 | * | ||
97 | * 7.23 | ||
98 | * - add FUSE_WRITEBACK_CACHE | ||
96 | */ | 99 | */ |
97 | 100 | ||
98 | #ifndef _LINUX_FUSE_H | 101 | #ifndef _LINUX_FUSE_H |
@@ -128,7 +131,7 @@ | |||
128 | #define FUSE_KERNEL_VERSION 7 | 131 | #define FUSE_KERNEL_VERSION 7 |
129 | 132 | ||
130 | /** Minor version number of this interface */ | 133 | /** Minor version number of this interface */ |
131 | #define FUSE_KERNEL_MINOR_VERSION 22 | 134 | #define FUSE_KERNEL_MINOR_VERSION 23 |
132 | 135 | ||
133 | /** The node ID of the root inode */ | 136 | /** The node ID of the root inode */ |
134 | #define FUSE_ROOT_ID 1 | 137 | #define FUSE_ROOT_ID 1 |
@@ -219,6 +222,7 @@ struct fuse_file_lock { | |||
219 | * FUSE_DO_READDIRPLUS: do READDIRPLUS (READDIR+LOOKUP in one) | 222 | * FUSE_DO_READDIRPLUS: do READDIRPLUS (READDIR+LOOKUP in one) |
220 | * FUSE_READDIRPLUS_AUTO: adaptive readdirplus | 223 | * FUSE_READDIRPLUS_AUTO: adaptive readdirplus |
221 | * FUSE_ASYNC_DIO: asynchronous direct I/O submission | 224 | * FUSE_ASYNC_DIO: asynchronous direct I/O submission |
225 | * FUSE_WRITEBACK_CACHE: use writeback cache for buffered writes | ||
222 | */ | 226 | */ |
223 | #define FUSE_ASYNC_READ (1 << 0) | 227 | #define FUSE_ASYNC_READ (1 << 0) |
224 | #define FUSE_POSIX_LOCKS (1 << 1) | 228 | #define FUSE_POSIX_LOCKS (1 << 1) |
@@ -236,6 +240,7 @@ struct fuse_file_lock { | |||
236 | #define FUSE_DO_READDIRPLUS (1 << 13) | 240 | #define FUSE_DO_READDIRPLUS (1 << 13) |
237 | #define FUSE_READDIRPLUS_AUTO (1 << 14) | 241 | #define FUSE_READDIRPLUS_AUTO (1 << 14) |
238 | #define FUSE_ASYNC_DIO (1 << 15) | 242 | #define FUSE_ASYNC_DIO (1 << 15) |
243 | #define FUSE_WRITEBACK_CACHE (1 << 16) | ||
239 | 244 | ||
240 | /** | 245 | /** |
241 | * CUSE INIT request/reply flags | 246 | * CUSE INIT request/reply flags |