diff options
| author | Pavel Emelyanov <xemul@openvz.org> | 2013-10-10 09:12:18 -0400 |
|---|---|---|
| committer | Miklos Szeredi <mszeredi@suse.cz> | 2014-04-02 09:38:50 -0400 |
| commit | 4d99ff8f12eb20c6cde292f185cb1c8c334ba0ed (patch) | |
| tree | a0668c9f45b4065ee935c1f653d32a11ae6ef788 | |
| parent | ea8cd33390fafc1eca06a26e6a9c7bf1d386526f (diff) | |
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>
| -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 |
