Commit fe38d7df230b022e72014ef7aa799a4f2acfecf3

Authored by Maxim Patlasov
Committed by Miklos Szeredi
1 parent 6b12c1b37e

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>

Showing 1 changed file with 23 additions and 15 deletions Side-by-side Diff

... ... @@ -401,6 +401,21 @@
401 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 + */
  413 +static void fuse_sync_writes(struct inode *inode)
  414 +{
  415 + fuse_set_nowrite(inode);
  416 + fuse_release_nowrite(inode);
  417 +}
  418 +
404 419 static int fuse_flush(struct file *file, fl_owner_t id)
405 420 {
406 421 struct inode *inode = file_inode(file);
... ... @@ -416,6 +431,14 @@
416 431 if (fc->no_flush)
417 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 442 req = fuse_get_req_nofail_nopages(fc, file);
420 443 memset(&inarg, 0, sizeof(inarg));
421 444 inarg.fh = ff->fh;
... ... @@ -434,21 +457,6 @@
434 457 err = 0;
435 458 }
436 459 return err;
437   -}
438   -
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   - */
448   -static void fuse_sync_writes(struct inode *inode)
449   -{
450   - fuse_set_nowrite(inode);
451   - fuse_release_nowrite(inode);
452 460 }
453 461  
454 462 int fuse_fsync_common(struct file *file, loff_t start, loff_t end,