Commit 4d99ff8f12eb20c6cde292f185cb1c8c334ba0ed
Committed by
Miklos Szeredi
1 parent
ea8cd33390
fuse: Turn writeback cache on
Introduce a bit kernel and userspace exchange between each-other on the init stage and turn writeback on if the userspace want this and mount option 'allow_wbcache' is present (controlled by fusermount). Also add each writable file into per-inode write list and call the generic_file_aio_write to make use of the Linux page cache engine. Signed-off-by: Maxim Patlasov <MPatlasov@parallels.com> Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
Showing 3 changed files with 21 additions and 2 deletions Side-by-side Diff
fs/fuse/file.c
... | ... | @@ -224,6 +224,8 @@ |
224 | 224 | spin_unlock(&fc->lock); |
225 | 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 | 231 | int fuse_open_common(struct inode *inode, struct file *file, bool isdir) |
... | ... | @@ -1196,6 +1198,15 @@ |
1196 | 1198 | ssize_t err; |
1197 | 1199 | struct iov_iter i; |
1198 | 1200 | loff_t endbyte = 0; |
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 | + } | |
1199 | 1210 | |
1200 | 1211 | WARN_ON(iocb->ki_pos != pos); |
1201 | 1212 |
fs/fuse/inode.c
... | ... | @@ -887,6 +887,8 @@ |
887 | 887 | } |
888 | 888 | if (arg->flags & FUSE_ASYNC_DIO) |
889 | 889 | fc->async_dio = 1; |
890 | + if (arg->flags & FUSE_WRITEBACK_CACHE) | |
891 | + fc->writeback_cache = 1; | |
890 | 892 | } else { |
891 | 893 | ra_pages = fc->max_read / PAGE_CACHE_SIZE; |
892 | 894 | fc->no_lock = 1; |
... | ... | @@ -914,7 +916,8 @@ |
914 | 916 | FUSE_EXPORT_SUPPORT | FUSE_BIG_WRITES | FUSE_DONT_MASK | |
915 | 917 | FUSE_SPLICE_WRITE | FUSE_SPLICE_MOVE | FUSE_SPLICE_READ | |
916 | 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 | 921 | req->in.h.opcode = FUSE_INIT; |
919 | 922 | req->in.numargs = 1; |
920 | 923 | req->in.args[0].size = sizeof(*arg); |
include/uapi/linux/fuse.h
... | ... | @@ -93,6 +93,9 @@ |
93 | 93 | * |
94 | 94 | * 7.22 |
95 | 95 | * - add FUSE_ASYNC_DIO |
96 | + * | |
97 | + * 7.23 | |
98 | + * - add FUSE_WRITEBACK_CACHE | |
96 | 99 | */ |
97 | 100 | |
98 | 101 | #ifndef _LINUX_FUSE_H |
... | ... | @@ -128,7 +131,7 @@ |
128 | 131 | #define FUSE_KERNEL_VERSION 7 |
129 | 132 | |
130 | 133 | /** Minor version number of this interface */ |
131 | -#define FUSE_KERNEL_MINOR_VERSION 22 | |
134 | +#define FUSE_KERNEL_MINOR_VERSION 23 | |
132 | 135 | |
133 | 136 | /** The node ID of the root inode */ |
134 | 137 | #define FUSE_ROOT_ID 1 |
... | ... | @@ -219,6 +222,7 @@ |
219 | 222 | * FUSE_DO_READDIRPLUS: do READDIRPLUS (READDIR+LOOKUP in one) |
220 | 223 | * FUSE_READDIRPLUS_AUTO: adaptive readdirplus |
221 | 224 | * FUSE_ASYNC_DIO: asynchronous direct I/O submission |
225 | + * FUSE_WRITEBACK_CACHE: use writeback cache for buffered writes | |
222 | 226 | */ |
223 | 227 | #define FUSE_ASYNC_READ (1 << 0) |
224 | 228 | #define FUSE_POSIX_LOCKS (1 << 1) |
... | ... | @@ -236,6 +240,7 @@ |
236 | 240 | #define FUSE_DO_READDIRPLUS (1 << 13) |
237 | 241 | #define FUSE_READDIRPLUS_AUTO (1 << 14) |
238 | 242 | #define FUSE_ASYNC_DIO (1 << 15) |
243 | +#define FUSE_WRITEBACK_CACHE (1 << 16) | |
239 | 244 | |
240 | 245 | /** |
241 | 246 | * CUSE INIT request/reply flags |