diff options
author | Pavel Emelyanov <xemul@openvz.org> | 2013-06-29 13:42:48 -0400 |
---|---|---|
committer | Miklos Szeredi <mszeredi@suse.cz> | 2013-10-01 10:44:51 -0400 |
commit | 385b126815d9278cf347504cf17ba62fb57e00ca (patch) | |
tree | dbdff16b9251ad8a0d20bd3ef0af3cd5c610fe21 /fs/fuse/file.c | |
parent | adcadfa8f373f301e9f622fbf45957adf2d98622 (diff) |
fuse: Prepare to handle multiple pages in writeback
The .writepages callback will issue writeback requests with more than one
page aboard. Make existing end/check code be aware of this.
Signed-off-by: Maxim Patlasov <MPatlasov@parallels.com>
Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
Diffstat (limited to 'fs/fuse/file.c')
-rw-r--r-- | fs/fuse/file.c | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/fs/fuse/file.c b/fs/fuse/file.c index aab6d05355e4..944acc096752 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c | |||
@@ -334,7 +334,8 @@ static bool fuse_page_is_writeback(struct inode *inode, pgoff_t index) | |||
334 | 334 | ||
335 | BUG_ON(req->inode != inode); | 335 | BUG_ON(req->inode != inode); |
336 | curr_index = req->misc.write.in.offset >> PAGE_CACHE_SHIFT; | 336 | curr_index = req->misc.write.in.offset >> PAGE_CACHE_SHIFT; |
337 | if (curr_index == index) { | 337 | if (curr_index <= index && |
338 | index < curr_index + req->num_pages) { | ||
338 | found = true; | 339 | found = true; |
339 | break; | 340 | break; |
340 | } | 341 | } |
@@ -1409,7 +1410,10 @@ static ssize_t fuse_direct_write(struct file *file, const char __user *buf, | |||
1409 | 1410 | ||
1410 | static void fuse_writepage_free(struct fuse_conn *fc, struct fuse_req *req) | 1411 | static void fuse_writepage_free(struct fuse_conn *fc, struct fuse_req *req) |
1411 | { | 1412 | { |
1412 | __free_page(req->pages[0]); | 1413 | int i; |
1414 | |||
1415 | for (i = 0; i < req->num_pages; i++) | ||
1416 | __free_page(req->pages[i]); | ||
1413 | fuse_file_put(req->ff, false); | 1417 | fuse_file_put(req->ff, false); |
1414 | } | 1418 | } |
1415 | 1419 | ||
@@ -1418,11 +1422,14 @@ static void fuse_writepage_finish(struct fuse_conn *fc, struct fuse_req *req) | |||
1418 | struct inode *inode = req->inode; | 1422 | struct inode *inode = req->inode; |
1419 | struct fuse_inode *fi = get_fuse_inode(inode); | 1423 | struct fuse_inode *fi = get_fuse_inode(inode); |
1420 | struct backing_dev_info *bdi = inode->i_mapping->backing_dev_info; | 1424 | struct backing_dev_info *bdi = inode->i_mapping->backing_dev_info; |
1425 | int i; | ||
1421 | 1426 | ||
1422 | list_del(&req->writepages_entry); | 1427 | list_del(&req->writepages_entry); |
1423 | dec_bdi_stat(bdi, BDI_WRITEBACK); | 1428 | for (i = 0; i < req->num_pages; i++) { |
1424 | dec_zone_page_state(req->pages[0], NR_WRITEBACK_TEMP); | 1429 | dec_bdi_stat(bdi, BDI_WRITEBACK); |
1425 | bdi_writeout_inc(bdi); | 1430 | dec_zone_page_state(req->pages[i], NR_WRITEBACK_TEMP); |
1431 | bdi_writeout_inc(bdi); | ||
1432 | } | ||
1426 | wake_up(&fi->page_waitq); | 1433 | wake_up(&fi->page_waitq); |
1427 | } | 1434 | } |
1428 | 1435 | ||
@@ -1434,14 +1441,15 @@ __acquires(fc->lock) | |||
1434 | struct fuse_inode *fi = get_fuse_inode(req->inode); | 1441 | struct fuse_inode *fi = get_fuse_inode(req->inode); |
1435 | loff_t size = i_size_read(req->inode); | 1442 | loff_t size = i_size_read(req->inode); |
1436 | struct fuse_write_in *inarg = &req->misc.write.in; | 1443 | struct fuse_write_in *inarg = &req->misc.write.in; |
1444 | __u64 data_size = req->num_pages * PAGE_CACHE_SIZE; | ||
1437 | 1445 | ||
1438 | if (!fc->connected) | 1446 | if (!fc->connected) |
1439 | goto out_free; | 1447 | goto out_free; |
1440 | 1448 | ||
1441 | if (inarg->offset + PAGE_CACHE_SIZE <= size) { | 1449 | if (inarg->offset + data_size <= size) { |
1442 | inarg->size = PAGE_CACHE_SIZE; | 1450 | inarg->size = data_size; |
1443 | } else if (inarg->offset < size) { | 1451 | } else if (inarg->offset < size) { |
1444 | inarg->size = size & (PAGE_CACHE_SIZE - 1); | 1452 | inarg->size = size - inarg->offset; |
1445 | } else { | 1453 | } else { |
1446 | /* Got truncated off completely */ | 1454 | /* Got truncated off completely */ |
1447 | goto out_free; | 1455 | goto out_free; |