aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2
diff options
context:
space:
mode:
authorAndrew Price <anprice@redhat.com>2014-11-12 12:24:04 -0500
committerSteven Whitehouse <swhiteho@redhat.com>2014-11-14 09:15:04 -0500
commit1885867b84d58e3704ed175e0abac2f38889f34d (patch)
treed4b37a4e65553290d4c2323f14f10f8d9a621e5e /fs/gfs2
parent9c9f1159a54c6163dd0b9d2085985d3c98dad11f (diff)
GFS2: Update i_size properly on fallocate
This addresses an issue caught by fsx where the inode size was not being updated to the expected value after fallocate(2) with mode 0. The problem was caused by the offset and len parameters being converted to multiples of the file system's block size, so i_size would be rounded up to the nearest block size multiple instead of the requested size. This replaces the per-chunk i_size updates with a single i_size_write on successful completion of the operation. With this patch gfs2 gets through a complete run of fsx. For clarity, the check for (error == 0) following the loop is removed as all failures before that point jump to out_* labels or return. Signed-off-by: Andrew Price <anprice@redhat.com> Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2')
-rw-r--r--fs/gfs2/file.c15
1 files changed, 6 insertions, 9 deletions
diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c
index 3786579dd348..118216419cef 100644
--- a/fs/gfs2/file.c
+++ b/fs/gfs2/file.c
@@ -729,7 +729,6 @@ static int fallocate_chunk(struct inode *inode, loff_t offset, loff_t len,
729 struct gfs2_inode *ip = GFS2_I(inode); 729 struct gfs2_inode *ip = GFS2_I(inode);
730 struct buffer_head *dibh; 730 struct buffer_head *dibh;
731 int error; 731 int error;
732 loff_t size = len;
733 unsigned int nr_blks; 732 unsigned int nr_blks;
734 sector_t lblock = offset >> inode->i_blkbits; 733 sector_t lblock = offset >> inode->i_blkbits;
735 734
@@ -763,11 +762,6 @@ static int fallocate_chunk(struct inode *inode, loff_t offset, loff_t len,
763 goto out; 762 goto out;
764 } 763 }
765 } 764 }
766 if (offset + size > inode->i_size && !(mode & FALLOC_FL_KEEP_SIZE))
767 i_size_write(inode, offset + size);
768
769 mark_inode_dirty(inode);
770
771out: 765out:
772 brelse(dibh); 766 brelse(dibh);
773 return error; 767 return error;
@@ -878,9 +872,12 @@ retry:
878 gfs2_quota_unlock(ip); 872 gfs2_quota_unlock(ip);
879 } 873 }
880 874
881 if (error == 0) 875 if (!(mode & FALLOC_FL_KEEP_SIZE) && (pos + count) > inode->i_size) {
882 error = generic_write_sync(file, pos, count); 876 i_size_write(inode, pos + count);
883 return error; 877 mark_inode_dirty(inode);
878 }
879
880 return generic_write_sync(file, pos, count);
884 881
885out_trans_fail: 882out_trans_fail:
886 gfs2_inplace_release(ip); 883 gfs2_inplace_release(ip);