aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/file.c
diff options
context:
space:
mode:
authorBenjamin Marzinski <bmarzins@redhat.com>2012-03-08 14:16:32 -0500
committerSteven Whitehouse <swhiteho@redhat.com>2012-03-09 10:29:10 -0500
commit58a7d5fb8e31279b992db4027e44b053a84b7344 (patch)
tree7ba74a4d2955e698f650308b82aef225610eeb24 /fs/gfs2/file.c
parent34cc1781c2ae921107e89f6633cfab7436e355ba (diff)
GFS2: call gfs2_write_alloc_required for each chunk
gfs2_fallocate was calling gfs2_write_alloc_required() once at the start of the function. This caused problems since gfs2_write_alloc_required used a long unsigned int for the len, but gfs2_fallocate could allocate a much larger amount. This patch will move the call into the loop where the chunks are actually allocated and zeroed out. This will keep the allocation size under the limit, and also allow gfs2_fallocate to quickly skip over sections of the file that are already completely allocated. fallcate_chunk was also not correctly setting the file size. It was using the len veriable to find the last block written to, but by the time it was setting the size, the len variable had already been decremented to 0. Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com> Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2/file.c')
-rw-r--r--fs/gfs2/file.c13
1 files changed, 8 insertions, 5 deletions
diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c
index 310f2fb6f7ea..76834587a8a4 100644
--- a/fs/gfs2/file.c
+++ b/fs/gfs2/file.c
@@ -676,6 +676,7 @@ static int fallocate_chunk(struct inode *inode, loff_t offset, loff_t len,
676 struct gfs2_inode *ip = GFS2_I(inode); 676 struct gfs2_inode *ip = GFS2_I(inode);
677 struct buffer_head *dibh; 677 struct buffer_head *dibh;
678 int error; 678 int error;
679 loff_t size = len;
679 unsigned int nr_blks; 680 unsigned int nr_blks;
680 sector_t lblock = offset >> inode->i_blkbits; 681 sector_t lblock = offset >> inode->i_blkbits;
681 682
@@ -709,8 +710,8 @@ static int fallocate_chunk(struct inode *inode, loff_t offset, loff_t len,
709 goto out; 710 goto out;
710 } 711 }
711 } 712 }
712 if (offset + len > inode->i_size && !(mode & FALLOC_FL_KEEP_SIZE)) 713 if (offset + size > inode->i_size && !(mode & FALLOC_FL_KEEP_SIZE))
713 i_size_write(inode, offset + len); 714 i_size_write(inode, offset + size);
714 715
715 mark_inode_dirty(inode); 716 mark_inode_dirty(inode);
716 717
@@ -779,12 +780,14 @@ static long gfs2_fallocate(struct file *file, int mode, loff_t offset,
779 if (unlikely(error)) 780 if (unlikely(error))
780 goto out_uninit; 781 goto out_uninit;
781 782
782 if (!gfs2_write_alloc_required(ip, offset, len))
783 goto out_unlock;
784
785 while (len > 0) { 783 while (len > 0) {
786 if (len < bytes) 784 if (len < bytes)
787 bytes = len; 785 bytes = len;
786 if (!gfs2_write_alloc_required(ip, offset, bytes)) {
787 len -= bytes;
788 offset += bytes;
789 continue;
790 }
788 qa = gfs2_qadata_get(ip); 791 qa = gfs2_qadata_get(ip);
789 if (!qa) { 792 if (!qa) {
790 error = -ENOMEM; 793 error = -ENOMEM;