aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_iops.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_iops.c')
-rw-r--r--fs/xfs/xfs_iops.c36
1 files changed, 14 insertions, 22 deletions
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
index d919ad7b16bf..e53a90331422 100644
--- a/fs/xfs/xfs_iops.c
+++ b/fs/xfs/xfs_iops.c
@@ -751,6 +751,7 @@ xfs_setattr_size(
751 int error; 751 int error;
752 uint lock_flags = 0; 752 uint lock_flags = 0;
753 uint commit_flags = 0; 753 uint commit_flags = 0;
754 bool did_zeroing = false;
754 755
755 trace_xfs_setattr(ip); 756 trace_xfs_setattr(ip);
756 757
@@ -794,20 +795,16 @@ xfs_setattr_size(
794 return error; 795 return error;
795 796
796 /* 797 /*
797 * Now we can make the changes. Before we join the inode to the 798 * File data changes must be complete before we start the transaction to
798 * transaction, take care of the part of the truncation that must be 799 * modify the inode. This needs to be done before joining the inode to
799 * done without the inode lock. This needs to be done before joining 800 * the transaction because the inode cannot be unlocked once it is a
800 * the inode to the transaction, because the inode cannot be unlocked 801 * part of the transaction.
801 * once it is a part of the transaction. 802 *
803 * Start with zeroing any data block beyond EOF that we may expose on
804 * file extension.
802 */ 805 */
803 if (newsize > oldsize) { 806 if (newsize > oldsize) {
804 /* 807 error = xfs_zero_eof(ip, newsize, oldsize, &did_zeroing);
805 * Do the first part of growing a file: zero any data in the
806 * last block that is beyond the old EOF. We need to do this
807 * before the inode is joined to the transaction to modify
808 * i_size.
809 */
810 error = xfs_zero_eof(ip, newsize, oldsize);
811 if (error) 808 if (error)
812 return error; 809 return error;
813 } 810 }
@@ -817,23 +814,18 @@ xfs_setattr_size(
817 * any previous writes that are beyond the on disk EOF and the new 814 * any previous writes that are beyond the on disk EOF and the new
818 * EOF that have not been written out need to be written here. If we 815 * EOF that have not been written out need to be written here. If we
819 * do not write the data out, we expose ourselves to the null files 816 * do not write the data out, we expose ourselves to the null files
820 * problem. 817 * problem. Note that this includes any block zeroing we did above;
821 * 818 * otherwise those blocks may not be zeroed after a crash.
822 * Only flush from the on disk size to the smaller of the in memory
823 * file size or the new size as that's the range we really care about
824 * here and prevents waiting for other data not within the range we
825 * care about here.
826 */ 819 */
827 if (oldsize != ip->i_d.di_size && newsize > ip->i_d.di_size) { 820 if (newsize > ip->i_d.di_size &&
821 (oldsize != ip->i_d.di_size || did_zeroing)) {
828 error = filemap_write_and_wait_range(VFS_I(ip)->i_mapping, 822 error = filemap_write_and_wait_range(VFS_I(ip)->i_mapping,
829 ip->i_d.di_size, newsize); 823 ip->i_d.di_size, newsize);
830 if (error) 824 if (error)
831 return error; 825 return error;
832 } 826 }
833 827
834 /* 828 /* Now wait for all direct I/O to complete. */
835 * Wait for all direct I/O to complete.
836 */
837 inode_dio_wait(inode); 829 inode_dio_wait(inode);
838 830
839 /* 831 /*