Commit b25e82e5673c750116e8b01a4fc7d09be7809f8c

Authored by Miklos Szeredi
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

... ... @@ -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,
... ... @@ -219,6 +219,10 @@
219 219 struct fuse_init_in init_in;
220 220 struct fuse_init_out init_out;
221 221 struct fuse_read_in read_in;
  222 + struct {
  223 + struct fuse_write_in in;
  224 + struct fuse_write_out out;
  225 + } write;
222 226 struct fuse_lk_in lk_in;
223 227 } misc;
224 228  
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 */