diff options
| -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; |
