aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fuse
diff options
context:
space:
mode:
authorMaxim Patlasov <MPatlasov@parallels.com>2013-10-10 09:11:54 -0400
committerMiklos Szeredi <mszeredi@suse.cz>2014-04-02 09:38:50 -0400
commitfe38d7df230b022e72014ef7aa799a4f2acfecf3 (patch)
tree58ac02af5d0c373b85841f355dc0f4b5641fb885 /fs/fuse
parent6b12c1b37e5556af073c1ebfa04c1f9df3a2beaf (diff)
fuse: fuse_flush() should wait on writeback
The aim of .flush fop is to hint file-system that flushing its state or caches or any other important data to reliable storage would be desirable now. fuse_flush() passes this hint by sending FUSE_FLUSH request to userspace. However, dirty pages and pages under writeback may be not visible to userspace yet if we won't ensure it explicitly. Signed-off-by: Maxim Patlasov <MPatlasov@parallels.com> Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
Diffstat (limited to 'fs/fuse')
-rw-r--r--fs/fuse/file.c38
1 files changed, 23 insertions, 15 deletions
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index d8575304c062..d93f2a1aa7de 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -401,6 +401,21 @@ static int fuse_wait_on_page_writeback(struct inode *inode, pgoff_t index)
401 return 0; 401 return 0;
402} 402}
403 403
404/*
405 * Wait for all pending writepages on the inode to finish.
406 *
407 * This is currently done by blocking further writes with FUSE_NOWRITE
408 * and waiting for all sent writes to complete.
409 *
410 * This must be called under i_mutex, otherwise the FUSE_NOWRITE usage
411 * could conflict with truncation.
412 */
413static void fuse_sync_writes(struct inode *inode)
414{
415 fuse_set_nowrite(inode);
416 fuse_release_nowrite(inode);
417}
418
404static int fuse_flush(struct file *file, fl_owner_t id) 419static int fuse_flush(struct file *file, fl_owner_t id)
405{ 420{
406 struct inode *inode = file_inode(file); 421 struct inode *inode = file_inode(file);
@@ -416,6 +431,14 @@ static int fuse_flush(struct file *file, fl_owner_t id)
416 if (fc->no_flush) 431 if (fc->no_flush)
417 return 0; 432 return 0;
418 433
434 err = filemap_write_and_wait(file->f_mapping);
435 if (err)
436 return err;
437
438 mutex_lock(&inode->i_mutex);
439 fuse_sync_writes(inode);
440 mutex_unlock(&inode->i_mutex);
441
419 req = fuse_get_req_nofail_nopages(fc, file); 442 req = fuse_get_req_nofail_nopages(fc, file);
420 memset(&inarg, 0, sizeof(inarg)); 443 memset(&inarg, 0, sizeof(inarg));
421 inarg.fh = ff->fh; 444 inarg.fh = ff->fh;
@@ -436,21 +459,6 @@ static int fuse_flush(struct file *file, fl_owner_t id)
436 return err; 459 return err;
437} 460}
438 461
439/*
440 * Wait for all pending writepages on the inode to finish.
441 *
442 * This is currently done by blocking further writes with FUSE_NOWRITE
443 * and waiting for all sent writes to complete.
444 *
445 * This must be called under i_mutex, otherwise the FUSE_NOWRITE usage
446 * could conflict with truncation.
447 */
448static void fuse_sync_writes(struct inode *inode)
449{
450 fuse_set_nowrite(inode);
451 fuse_release_nowrite(inode);
452}
453
454int fuse_fsync_common(struct file *file, loff_t start, loff_t end, 462int fuse_fsync_common(struct file *file, loff_t start, loff_t end,
455 int datasync, int isdir) 463 int datasync, int isdir)
456{ 464{