Commit b25e82e5673c750116e8b01a4fc7d09be7809f8c
Committed by
Linus Torvalds
1 parent
93a8c3cd9e
fuse: add helper for asynchronous writes
This patch adds a new helper function fuse_write_fill() which makes it possible to send WRITE requests asynchronously. A new flag for WRITE requests is also added which indicates that this a write from the page cache, and not a "normal" file write. This patch is in preparation for writable mmap support. Signed-off-by: Miklos Szeredi <mszeredi@suse.cz> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 3 changed files with 31 additions and 13 deletions Side-by-side Diff
fs/fuse/file.c
... | ... | @@ -443,30 +443,37 @@ |
443 | 443 | return err; |
444 | 444 | } |
445 | 445 | |
446 | -static size_t fuse_send_write(struct fuse_req *req, struct file *file, | |
447 | - struct inode *inode, loff_t pos, size_t count) | |
446 | +static void fuse_write_fill(struct fuse_req *req, struct fuse_file *ff, | |
447 | + struct inode *inode, loff_t pos, size_t count, | |
448 | + int writepage) | |
448 | 449 | { |
449 | - struct fuse_conn *fc = get_fuse_conn(inode); | |
450 | - struct fuse_file *ff = file->private_data; | |
451 | - struct fuse_write_in inarg; | |
452 | - struct fuse_write_out outarg; | |
450 | + struct fuse_write_in *inarg = &req->misc.write.in; | |
451 | + struct fuse_write_out *outarg = &req->misc.write.out; | |
453 | 452 | |
454 | - memset(&inarg, 0, sizeof(struct fuse_write_in)); | |
455 | - inarg.fh = ff->fh; | |
456 | - inarg.offset = pos; | |
457 | - inarg.size = count; | |
453 | + memset(inarg, 0, sizeof(struct fuse_write_in)); | |
454 | + inarg->fh = ff->fh; | |
455 | + inarg->offset = pos; | |
456 | + inarg->size = count; | |
457 | + inarg->write_flags = writepage ? FUSE_WRITE_CACHE : 0; | |
458 | 458 | req->in.h.opcode = FUSE_WRITE; |
459 | 459 | req->in.h.nodeid = get_node_id(inode); |
460 | 460 | req->in.argpages = 1; |
461 | 461 | req->in.numargs = 2; |
462 | 462 | req->in.args[0].size = sizeof(struct fuse_write_in); |
463 | - req->in.args[0].value = &inarg; | |
463 | + req->in.args[0].value = inarg; | |
464 | 464 | req->in.args[1].size = count; |
465 | 465 | req->out.numargs = 1; |
466 | 466 | req->out.args[0].size = sizeof(struct fuse_write_out); |
467 | - req->out.args[0].value = &outarg; | |
467 | + req->out.args[0].value = outarg; | |
468 | +} | |
469 | + | |
470 | +static size_t fuse_send_write(struct fuse_req *req, struct file *file, | |
471 | + struct inode *inode, loff_t pos, size_t count) | |
472 | +{ | |
473 | + struct fuse_conn *fc = get_fuse_conn(inode); | |
474 | + fuse_write_fill(req, file->private_data, inode, pos, count, 0); | |
468 | 475 | request_send(fc, req); |
469 | - return outarg.size; | |
476 | + return req->misc.write.out.size; | |
470 | 477 | } |
471 | 478 | |
472 | 479 | static int fuse_write_begin(struct file *file, struct address_space *mapping, |
fs/fuse/fuse_i.h
include/linux/fuse.h
... | ... | @@ -119,6 +119,13 @@ |
119 | 119 | */ |
120 | 120 | #define FUSE_LK_FLOCK (1 << 0) |
121 | 121 | |
122 | +/** | |
123 | + * WRITE flags | |
124 | + * | |
125 | + * FUSE_WRITE_CACHE: delayed write from page cache, file handle is guessed | |
126 | + */ | |
127 | +#define FUSE_WRITE_CACHE (1 << 0) | |
128 | + | |
122 | 129 | enum fuse_opcode { |
123 | 130 | FUSE_LOOKUP = 1, |
124 | 131 | FUSE_FORGET = 2, /* no reply */ |