diff options
Diffstat (limited to 'fs/xfs')
-rw-r--r-- | fs/xfs/xfs_vnodeops.c | 25 |
1 files changed, 24 insertions, 1 deletions
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 401cb00a55d6..1a5ad8cd97b0 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c | |||
@@ -589,7 +589,30 @@ xfs_setattr( | |||
589 | code = xfs_igrow_start(ip, vap->va_size, credp); | 589 | code = xfs_igrow_start(ip, vap->va_size, credp); |
590 | } | 590 | } |
591 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | 591 | xfs_iunlock(ip, XFS_ILOCK_EXCL); |
592 | vn_iowait(vp); /* wait for the completion of any pending DIOs */ | 592 | |
593 | /* | ||
594 | * We are going to log the inode size change in this | ||
595 | * transaction so any previous writes that are beyond the on | ||
596 | * disk EOF and the new EOF that have not been written out need | ||
597 | * to be written here. If we do not write the data out, we | ||
598 | * expose ourselves to the null files problem. | ||
599 | * | ||
600 | * Only flush from the on disk size to the smaller of the in | ||
601 | * memory file size or the new size as that's the range we | ||
602 | * really care about here and prevents waiting for other data | ||
603 | * not within the range we care about here. | ||
604 | */ | ||
605 | if (!code && | ||
606 | (ip->i_size != ip->i_d.di_size) && | ||
607 | (vap->va_size > ip->i_d.di_size)) { | ||
608 | code = bhv_vop_flush_pages(XFS_ITOV(ip), | ||
609 | ip->i_d.di_size, vap->va_size, | ||
610 | XFS_B_ASYNC, FI_NONE); | ||
611 | } | ||
612 | |||
613 | /* wait for all I/O to complete */ | ||
614 | vn_iowait(vp); | ||
615 | |||
593 | if (!code) | 616 | if (!code) |
594 | code = xfs_itruncate_data(ip, vap->va_size); | 617 | code = xfs_itruncate_data(ip, vap->va_size); |
595 | if (code) { | 618 | if (code) { |