Commit 4d99ff8f12eb20c6cde292f185cb1c8c334ba0ed

Authored by Pavel Emelyanov
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

... ... @@ -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  
... ... @@ -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