aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fuse/file.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/fuse/file.c')
-rw-r--r--fs/fuse/file.c52
1 files changed, 38 insertions, 14 deletions
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 0fcdba9d47c0..bb05d227cf30 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -55,9 +55,10 @@ struct fuse_file *fuse_file_alloc(void)
55 if (!ff->reserved_req) { 55 if (!ff->reserved_req) {
56 kfree(ff); 56 kfree(ff);
57 ff = NULL; 57 ff = NULL;
58 } else {
59 INIT_LIST_HEAD(&ff->write_entry);
60 atomic_set(&ff->count, 0);
58 } 61 }
59 INIT_LIST_HEAD(&ff->write_entry);
60 atomic_set(&ff->count, 0);
61 } 62 }
62 return ff; 63 return ff;
63} 64}
@@ -288,14 +289,16 @@ static int fuse_fsync(struct file *file, struct dentry *de, int datasync)
288 return fuse_fsync_common(file, de, datasync, 0); 289 return fuse_fsync_common(file, de, datasync, 0);
289} 290}
290 291
291void fuse_read_fill(struct fuse_req *req, struct fuse_file *ff, 292void fuse_read_fill(struct fuse_req *req, struct file *file,
292 struct inode *inode, loff_t pos, size_t count, int opcode) 293 struct inode *inode, loff_t pos, size_t count, int opcode)
293{ 294{
294 struct fuse_read_in *inarg = &req->misc.read_in; 295 struct fuse_read_in *inarg = &req->misc.read_in;
296 struct fuse_file *ff = file->private_data;
295 297
296 inarg->fh = ff->fh; 298 inarg->fh = ff->fh;
297 inarg->offset = pos; 299 inarg->offset = pos;
298 inarg->size = count; 300 inarg->size = count;
301 inarg->flags = file->f_flags;
299 req->in.h.opcode = opcode; 302 req->in.h.opcode = opcode;
300 req->in.h.nodeid = get_node_id(inode); 303 req->in.h.nodeid = get_node_id(inode);
301 req->in.numargs = 1; 304 req->in.numargs = 1;
@@ -312,9 +315,8 @@ static size_t fuse_send_read(struct fuse_req *req, struct file *file,
312 fl_owner_t owner) 315 fl_owner_t owner)
313{ 316{
314 struct fuse_conn *fc = get_fuse_conn(inode); 317 struct fuse_conn *fc = get_fuse_conn(inode);
315 struct fuse_file *ff = file->private_data;
316 318
317 fuse_read_fill(req, ff, inode, pos, count, FUSE_READ); 319 fuse_read_fill(req, file, inode, pos, count, FUSE_READ);
318 if (owner != NULL) { 320 if (owner != NULL) {
319 struct fuse_read_in *inarg = &req->misc.read_in; 321 struct fuse_read_in *inarg = &req->misc.read_in;
320 322
@@ -375,15 +377,16 @@ static void fuse_readpages_end(struct fuse_conn *fc, struct fuse_req *req)
375 fuse_put_request(fc, req); 377 fuse_put_request(fc, req);
376} 378}
377 379
378static void fuse_send_readpages(struct fuse_req *req, struct fuse_file *ff, 380static void fuse_send_readpages(struct fuse_req *req, struct file *file,
379 struct inode *inode) 381 struct inode *inode)
380{ 382{
381 struct fuse_conn *fc = get_fuse_conn(inode); 383 struct fuse_conn *fc = get_fuse_conn(inode);
382 loff_t pos = page_offset(req->pages[0]); 384 loff_t pos = page_offset(req->pages[0]);
383 size_t count = req->num_pages << PAGE_CACHE_SHIFT; 385 size_t count = req->num_pages << PAGE_CACHE_SHIFT;
384 req->out.page_zeroing = 1; 386 req->out.page_zeroing = 1;
385 fuse_read_fill(req, ff, inode, pos, count, FUSE_READ); 387 fuse_read_fill(req, file, inode, pos, count, FUSE_READ);
386 if (fc->async_read) { 388 if (fc->async_read) {
389 struct fuse_file *ff = file->private_data;
387 req->ff = fuse_file_get(ff); 390 req->ff = fuse_file_get(ff);
388 req->end = fuse_readpages_end; 391 req->end = fuse_readpages_end;
389 request_send_background(fc, req); 392 request_send_background(fc, req);
@@ -395,7 +398,7 @@ static void fuse_send_readpages(struct fuse_req *req, struct fuse_file *ff,
395 398
396struct fuse_fill_data { 399struct fuse_fill_data {
397 struct fuse_req *req; 400 struct fuse_req *req;
398 struct fuse_file *ff; 401 struct file *file;
399 struct inode *inode; 402 struct inode *inode;
400}; 403};
401 404
@@ -410,7 +413,7 @@ static int fuse_readpages_fill(void *_data, struct page *page)
410 (req->num_pages == FUSE_MAX_PAGES_PER_REQ || 413 (req->num_pages == FUSE_MAX_PAGES_PER_REQ ||
411 (req->num_pages + 1) * PAGE_CACHE_SIZE > fc->max_read || 414 (req->num_pages + 1) * PAGE_CACHE_SIZE > fc->max_read ||
412 req->pages[req->num_pages - 1]->index + 1 != page->index)) { 415 req->pages[req->num_pages - 1]->index + 1 != page->index)) {
413 fuse_send_readpages(req, data->ff, inode); 416 fuse_send_readpages(req, data->file, inode);
414 data->req = req = fuse_get_req(fc); 417 data->req = req = fuse_get_req(fc);
415 if (IS_ERR(req)) { 418 if (IS_ERR(req)) {
416 unlock_page(page); 419 unlock_page(page);
@@ -434,7 +437,7 @@ static int fuse_readpages(struct file *file, struct address_space *mapping,
434 if (is_bad_inode(inode)) 437 if (is_bad_inode(inode))
435 goto out; 438 goto out;
436 439
437 data.ff = file->private_data; 440 data.file = file;
438 data.inode = inode; 441 data.inode = inode;
439 data.req = fuse_get_req(fc); 442 data.req = fuse_get_req(fc);
440 err = PTR_ERR(data.req); 443 err = PTR_ERR(data.req);
@@ -444,7 +447,7 @@ static int fuse_readpages(struct file *file, struct address_space *mapping,
444 err = read_cache_pages(mapping, pages, fuse_readpages_fill, &data); 447 err = read_cache_pages(mapping, pages, fuse_readpages_fill, &data);
445 if (!err) { 448 if (!err) {
446 if (data.req->num_pages) 449 if (data.req->num_pages)
447 fuse_send_readpages(data.req, data.ff, inode); 450 fuse_send_readpages(data.req, file, inode);
448 else 451 else
449 fuse_put_request(fc, data.req); 452 fuse_put_request(fc, data.req);
450 } 453 }
@@ -452,11 +455,31 @@ out:
452 return err; 455 return err;
453} 456}
454 457
455static void fuse_write_fill(struct fuse_req *req, struct fuse_file *ff, 458static ssize_t fuse_file_aio_read(struct kiocb *iocb, const struct iovec *iov,
459 unsigned long nr_segs, loff_t pos)
460{
461 struct inode *inode = iocb->ki_filp->f_mapping->host;
462
463 if (pos + iov_length(iov, nr_segs) > i_size_read(inode)) {
464 int err;
465 /*
466 * If trying to read past EOF, make sure the i_size
467 * attribute is up-to-date.
468 */
469 err = fuse_update_attributes(inode, NULL, iocb->ki_filp, NULL);
470 if (err)
471 return err;
472 }
473
474 return generic_file_aio_read(iocb, iov, nr_segs, pos);
475}
476
477static void fuse_write_fill(struct fuse_req *req, struct file *file,
456 struct inode *inode, loff_t pos, size_t count, 478 struct inode *inode, loff_t pos, size_t count,
457 int writepage) 479 int writepage)
458{ 480{
459 struct fuse_conn *fc = get_fuse_conn(inode); 481 struct fuse_conn *fc = get_fuse_conn(inode);
482 struct fuse_file *ff = file->private_data;
460 struct fuse_write_in *inarg = &req->misc.write.in; 483 struct fuse_write_in *inarg = &req->misc.write.in;
461 struct fuse_write_out *outarg = &req->misc.write.out; 484 struct fuse_write_out *outarg = &req->misc.write.out;
462 485
@@ -465,6 +488,7 @@ static void fuse_write_fill(struct fuse_req *req, struct fuse_file *ff,
465 inarg->offset = pos; 488 inarg->offset = pos;
466 inarg->size = count; 489 inarg->size = count;
467 inarg->write_flags = writepage ? FUSE_WRITE_CACHE : 0; 490 inarg->write_flags = writepage ? FUSE_WRITE_CACHE : 0;
491 inarg->flags = file->f_flags;
468 req->in.h.opcode = FUSE_WRITE; 492 req->in.h.opcode = FUSE_WRITE;
469 req->in.h.nodeid = get_node_id(inode); 493 req->in.h.nodeid = get_node_id(inode);
470 req->in.argpages = 1; 494 req->in.argpages = 1;
@@ -485,7 +509,7 @@ static size_t fuse_send_write(struct fuse_req *req, struct file *file,
485 fl_owner_t owner) 509 fl_owner_t owner)
486{ 510{
487 struct fuse_conn *fc = get_fuse_conn(inode); 511 struct fuse_conn *fc = get_fuse_conn(inode);
488 fuse_write_fill(req, file->private_data, inode, pos, count, 0); 512 fuse_write_fill(req, file, inode, pos, count, 0);
489 if (owner != NULL) { 513 if (owner != NULL) {
490 struct fuse_write_in *inarg = &req->misc.write.in; 514 struct fuse_write_in *inarg = &req->misc.write.in;
491 inarg->write_flags |= FUSE_WRITE_LOCKOWNER; 515 inarg->write_flags |= FUSE_WRITE_LOCKOWNER;
@@ -886,7 +910,7 @@ static sector_t fuse_bmap(struct address_space *mapping, sector_t block)
886static const struct file_operations fuse_file_operations = { 910static const struct file_operations fuse_file_operations = {
887 .llseek = generic_file_llseek, 911 .llseek = generic_file_llseek,
888 .read = do_sync_read, 912 .read = do_sync_read,
889 .aio_read = generic_file_aio_read, 913 .aio_read = fuse_file_aio_read,
890 .write = do_sync_write, 914 .write = do_sync_write,
891 .aio_write = generic_file_aio_write, 915 .aio_write = generic_file_aio_write,
892 .mmap = fuse_file_mmap, 916 .mmap = fuse_file_mmap,