aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/gfs2/file.c34
1 files changed, 24 insertions, 10 deletions
diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c
index edeb9e802903..92c3db424b40 100644
--- a/fs/gfs2/file.c
+++ b/fs/gfs2/file.c
@@ -551,8 +551,16 @@ static int gfs2_close(struct inode *inode, struct file *file)
551 * @end: the end position in the file to sync 551 * @end: the end position in the file to sync
552 * @datasync: set if we can ignore timestamp changes 552 * @datasync: set if we can ignore timestamp changes
553 * 553 *
554 * The VFS will flush data for us. We only need to worry 554 * We split the data flushing here so that we don't wait for the data
555 * about metadata here. 555 * until after we've also sent the metadata to disk. Note that for
556 * data=ordered, we will write & wait for the data at the log flush
557 * stage anyway, so this is unlikely to make much of a difference
558 * except in the data=writeback case.
559 *
560 * If the fdatawrite fails due to any reason except -EIO, we will
561 * continue the remainder of the fsync, although we'll still report
562 * the error at the end. This is to match filemap_write_and_wait_range()
563 * behaviour.
556 * 564 *
557 * Returns: errno 565 * Returns: errno
558 */ 566 */
@@ -560,30 +568,36 @@ static int gfs2_close(struct inode *inode, struct file *file)
560static int gfs2_fsync(struct file *file, loff_t start, loff_t end, 568static int gfs2_fsync(struct file *file, loff_t start, loff_t end,
561 int datasync) 569 int datasync)
562{ 570{
563 struct inode *inode = file->f_mapping->host; 571 struct address_space *mapping = file->f_mapping;
572 struct inode *inode = mapping->host;
564 int sync_state = inode->i_state & (I_DIRTY_SYNC|I_DIRTY_DATASYNC); 573 int sync_state = inode->i_state & (I_DIRTY_SYNC|I_DIRTY_DATASYNC);
565 struct gfs2_inode *ip = GFS2_I(inode); 574 struct gfs2_inode *ip = GFS2_I(inode);
566 int ret; 575 int ret, ret1 = 0;
567 576
568 ret = filemap_write_and_wait_range(inode->i_mapping, start, end); 577 if (mapping->nrpages) {
569 if (ret) 578 ret1 = filemap_fdatawrite_range(mapping, start, end);
570 return ret; 579 if (ret1 == -EIO)
571 mutex_lock(&inode->i_mutex); 580 return ret1;
581 }
572 582
573 if (datasync) 583 if (datasync)
574 sync_state &= ~I_DIRTY_SYNC; 584 sync_state &= ~I_DIRTY_SYNC;
575 585
576 if (sync_state) { 586 if (sync_state) {
587 mutex_lock(&inode->i_mutex);
577 ret = sync_inode_metadata(inode, 1); 588 ret = sync_inode_metadata(inode, 1);
578 if (ret) { 589 if (ret) {
579 mutex_unlock(&inode->i_mutex); 590 mutex_unlock(&inode->i_mutex);
580 return ret; 591 return ret;
581 } 592 }
582 gfs2_ail_flush(ip->i_gl); 593 gfs2_ail_flush(ip->i_gl);
594 mutex_unlock(&inode->i_mutex);
583 } 595 }
584 596
585 mutex_unlock(&inode->i_mutex); 597 if (mapping->nrpages)
586 return 0; 598 ret = filemap_fdatawait_range(mapping, start, end);
599
600 return ret ? ret : ret1;
587} 601}
588 602
589/** 603/**