aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNick Piggin <npiggin@suse.de>2007-10-16 04:25:17 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-16 12:42:57 -0400
commit5e6f58a1d7ce2fd5ef099f9aec5b3e3f7ba176b4 (patch)
tree2a63f0587a60d30d00cbadb6d33756725173576f
parentfb53b3094888be0cf8ddf052277654268904bdf5 (diff)
fuse: convert to new aops
[mszeredi] - don't send zero length write requests - it is not legal for the filesystem to return with zero written bytes Signed-off-by: Nick Piggin <npiggin@suse.de> 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>
-rw-r--r--fs/fuse/file.c46
1 files changed, 32 insertions, 14 deletions
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index f79de7c8cdfa..11f22a3d728a 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -444,22 +444,25 @@ static size_t fuse_send_write(struct fuse_req *req, struct file *file,
444 return outarg.size; 444 return outarg.size;
445} 445}
446 446
447static int fuse_prepare_write(struct file *file, struct page *page, 447static int fuse_write_begin(struct file *file, struct address_space *mapping,
448 unsigned offset, unsigned to) 448 loff_t pos, unsigned len, unsigned flags,
449 struct page **pagep, void **fsdata)
449{ 450{
450 /* No op */ 451 pgoff_t index = pos >> PAGE_CACHE_SHIFT;
452
453 *pagep = __grab_cache_page(mapping, index);
454 if (!*pagep)
455 return -ENOMEM;
451 return 0; 456 return 0;
452} 457}
453 458
454static int fuse_commit_write(struct file *file, struct page *page, 459static int fuse_buffered_write(struct file *file, struct inode *inode,
455 unsigned offset, unsigned to) 460 loff_t pos, unsigned count, struct page *page)
456{ 461{
457 int err; 462 int err;
458 size_t nres; 463 size_t nres;
459 unsigned count = to - offset;
460 struct inode *inode = page->mapping->host;
461 struct fuse_conn *fc = get_fuse_conn(inode); 464 struct fuse_conn *fc = get_fuse_conn(inode);
462 loff_t pos = page_offset(page) + offset; 465 unsigned offset = pos & (PAGE_CACHE_SIZE - 1);
463 struct fuse_req *req; 466 struct fuse_req *req;
464 467
465 if (is_bad_inode(inode)) 468 if (is_bad_inode(inode))
@@ -475,20 +478,35 @@ static int fuse_commit_write(struct file *file, struct page *page,
475 nres = fuse_send_write(req, file, inode, pos, count); 478 nres = fuse_send_write(req, file, inode, pos, count);
476 err = req->out.h.error; 479 err = req->out.h.error;
477 fuse_put_request(fc, req); 480 fuse_put_request(fc, req);
478 if (!err && nres != count) 481 if (!err && !nres)
479 err = -EIO; 482 err = -EIO;
480 if (!err) { 483 if (!err) {
481 pos += count; 484 pos += nres;
482 spin_lock(&fc->lock); 485 spin_lock(&fc->lock);
483 if (pos > inode->i_size) 486 if (pos > inode->i_size)
484 i_size_write(inode, pos); 487 i_size_write(inode, pos);
485 spin_unlock(&fc->lock); 488 spin_unlock(&fc->lock);
486 489
487 if (offset == 0 && to == PAGE_CACHE_SIZE) 490 if (count == PAGE_CACHE_SIZE)
488 SetPageUptodate(page); 491 SetPageUptodate(page);
489 } 492 }
490 fuse_invalidate_attr(inode); 493 fuse_invalidate_attr(inode);
491 return err; 494 return err ? err : nres;
495}
496
497static int fuse_write_end(struct file *file, struct address_space *mapping,
498 loff_t pos, unsigned len, unsigned copied,
499 struct page *page, void *fsdata)
500{
501 struct inode *inode = mapping->host;
502 int res = 0;
503
504 if (copied)
505 res = fuse_buffered_write(file, inode, pos, copied, page);
506
507 unlock_page(page);
508 page_cache_release(page);
509 return res;
492} 510}
493 511
494static void fuse_release_user_pages(struct fuse_req *req, int write) 512static void fuse_release_user_pages(struct fuse_req *req, int write)
@@ -819,8 +837,8 @@ static const struct file_operations fuse_direct_io_file_operations = {
819 837
820static const struct address_space_operations fuse_file_aops = { 838static const struct address_space_operations fuse_file_aops = {
821 .readpage = fuse_readpage, 839 .readpage = fuse_readpage,
822 .prepare_write = fuse_prepare_write, 840 .write_begin = fuse_write_begin,
823 .commit_write = fuse_commit_write, 841 .write_end = fuse_write_end,
824 .readpages = fuse_readpages, 842 .readpages = fuse_readpages,
825 .set_page_dirty = fuse_set_page_dirty, 843 .set_page_dirty = fuse_set_page_dirty,
826 .bmap = fuse_bmap, 844 .bmap = fuse_bmap,