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.c24
1 files changed, 18 insertions, 6 deletions
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 73b89df2085..7bb685cdd00 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -400,7 +400,8 @@ static void fuse_sync_writes(struct inode *inode)
400 fuse_release_nowrite(inode); 400 fuse_release_nowrite(inode);
401} 401}
402 402
403int fuse_fsync_common(struct file *file, int datasync, int isdir) 403int fuse_fsync_common(struct file *file, loff_t start, loff_t end,
404 int datasync, int isdir)
404{ 405{
405 struct inode *inode = file->f_mapping->host; 406 struct inode *inode = file->f_mapping->host;
406 struct fuse_conn *fc = get_fuse_conn(inode); 407 struct fuse_conn *fc = get_fuse_conn(inode);
@@ -412,9 +413,15 @@ int fuse_fsync_common(struct file *file, int datasync, int isdir)
412 if (is_bad_inode(inode)) 413 if (is_bad_inode(inode))
413 return -EIO; 414 return -EIO;
414 415
416 err = filemap_write_and_wait_range(inode->i_mapping, start, end);
417 if (err)
418 return err;
419
415 if ((!isdir && fc->no_fsync) || (isdir && fc->no_fsyncdir)) 420 if ((!isdir && fc->no_fsync) || (isdir && fc->no_fsyncdir))
416 return 0; 421 return 0;
417 422
423 mutex_lock(&inode->i_mutex);
424
418 /* 425 /*
419 * Start writeback against all dirty pages of the inode, then 426 * Start writeback against all dirty pages of the inode, then
420 * wait for all outstanding writes, before sending the FSYNC 427 * wait for all outstanding writes, before sending the FSYNC
@@ -422,13 +429,15 @@ int fuse_fsync_common(struct file *file, int datasync, int isdir)
422 */ 429 */
423 err = write_inode_now(inode, 0); 430 err = write_inode_now(inode, 0);
424 if (err) 431 if (err)
425 return err; 432 goto out;
426 433
427 fuse_sync_writes(inode); 434 fuse_sync_writes(inode);
428 435
429 req = fuse_get_req(fc); 436 req = fuse_get_req(fc);
430 if (IS_ERR(req)) 437 if (IS_ERR(req)) {
431 return PTR_ERR(req); 438 err = PTR_ERR(req);
439 goto out;
440 }
432 441
433 memset(&inarg, 0, sizeof(inarg)); 442 memset(&inarg, 0, sizeof(inarg));
434 inarg.fh = ff->fh; 443 inarg.fh = ff->fh;
@@ -448,12 +457,15 @@ int fuse_fsync_common(struct file *file, int datasync, int isdir)
448 fc->no_fsync = 1; 457 fc->no_fsync = 1;
449 err = 0; 458 err = 0;
450 } 459 }
460out:
461 mutex_unlock(&inode->i_mutex);
451 return err; 462 return err;
452} 463}
453 464
454static int fuse_fsync(struct file *file, int datasync) 465static int fuse_fsync(struct file *file, loff_t start, loff_t end,
466 int datasync)
455{ 467{
456 return fuse_fsync_common(file, datasync, 0); 468 return fuse_fsync_common(file, start, end, datasync, 0);
457} 469}
458 470
459void fuse_read_fill(struct fuse_req *req, struct file *file, loff_t pos, 471void fuse_read_fill(struct fuse_req *req, struct file *file, loff_t pos,