diff options
Diffstat (limited to 'fs/fuse/file.c')
-rw-r--r-- | fs/fuse/file.c | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/fs/fuse/file.c b/fs/fuse/file.c index fe191325fefa..a200a2d80377 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/compat.h> | 16 | #include <linux/compat.h> |
17 | #include <linux/swap.h> | 17 | #include <linux/swap.h> |
18 | #include <linux/aio.h> | 18 | #include <linux/aio.h> |
19 | #include <linux/falloc.h> | ||
19 | 20 | ||
20 | static const struct file_operations fuse_direct_io_file_operations; | 21 | static const struct file_operations fuse_direct_io_file_operations; |
21 | 22 | ||
@@ -2453,6 +2454,7 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset, | |||
2453 | loff_t length) | 2454 | loff_t length) |
2454 | { | 2455 | { |
2455 | struct fuse_file *ff = file->private_data; | 2456 | struct fuse_file *ff = file->private_data; |
2457 | struct inode *inode = file->f_inode; | ||
2456 | struct fuse_conn *fc = ff->fc; | 2458 | struct fuse_conn *fc = ff->fc; |
2457 | struct fuse_req *req; | 2459 | struct fuse_req *req; |
2458 | struct fuse_fallocate_in inarg = { | 2460 | struct fuse_fallocate_in inarg = { |
@@ -2466,9 +2468,16 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset, | |||
2466 | if (fc->no_fallocate) | 2468 | if (fc->no_fallocate) |
2467 | return -EOPNOTSUPP; | 2469 | return -EOPNOTSUPP; |
2468 | 2470 | ||
2471 | if (mode & FALLOC_FL_PUNCH_HOLE) { | ||
2472 | mutex_lock(&inode->i_mutex); | ||
2473 | fuse_set_nowrite(inode); | ||
2474 | } | ||
2475 | |||
2469 | req = fuse_get_req_nopages(fc); | 2476 | req = fuse_get_req_nopages(fc); |
2470 | if (IS_ERR(req)) | 2477 | if (IS_ERR(req)) { |
2471 | return PTR_ERR(req); | 2478 | err = PTR_ERR(req); |
2479 | goto out; | ||
2480 | } | ||
2472 | 2481 | ||
2473 | req->in.h.opcode = FUSE_FALLOCATE; | 2482 | req->in.h.opcode = FUSE_FALLOCATE; |
2474 | req->in.h.nodeid = ff->nodeid; | 2483 | req->in.h.nodeid = ff->nodeid; |
@@ -2483,6 +2492,15 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset, | |||
2483 | } | 2492 | } |
2484 | fuse_put_request(fc, req); | 2493 | fuse_put_request(fc, req); |
2485 | 2494 | ||
2495 | out: | ||
2496 | if (mode & FALLOC_FL_PUNCH_HOLE) { | ||
2497 | if (!err) | ||
2498 | truncate_pagecache_range(inode, offset, | ||
2499 | offset + length - 1); | ||
2500 | fuse_release_nowrite(inode); | ||
2501 | mutex_unlock(&inode->i_mutex); | ||
2502 | } | ||
2503 | |||
2486 | return err; | 2504 | return err; |
2487 | } | 2505 | } |
2488 | 2506 | ||