Skip to content

Commit

Permalink
GFS2: call gfs2_write_alloc_required for each chunk
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: Steven Whitehouse <[email protected]>
  • Loading branch information
bmarzins authored and swhiteho committed Mar 9, 2012
1 parent 34cc178 commit 58a7d5f
Showing 1 changed file with 8 additions and 5 deletions.
13 changes: 8 additions & 5 deletions fs/gfs2/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -676,6 +676,7 @@ static int fallocate_chunk(struct inode *inode, loff_t offset, loff_t len,
struct gfs2_inode *ip = GFS2_I(inode);
struct buffer_head *dibh;
int error;
loff_t size = len;
unsigned int nr_blks;
sector_t lblock = offset >> inode->i_blkbits;

Expand Down Expand Up @@ -709,8 +710,8 @@ static int fallocate_chunk(struct inode *inode, loff_t offset, loff_t len,
goto out;
}
}
if (offset + len > inode->i_size && !(mode & FALLOC_FL_KEEP_SIZE))
i_size_write(inode, offset + len);
if (offset + size > inode->i_size && !(mode & FALLOC_FL_KEEP_SIZE))
i_size_write(inode, offset + size);

mark_inode_dirty(inode);

Expand Down Expand Up @@ -779,12 +780,14 @@ static long gfs2_fallocate(struct file *file, int mode, loff_t offset,
if (unlikely(error))
goto out_uninit;

if (!gfs2_write_alloc_required(ip, offset, len))
goto out_unlock;

while (len > 0) {
if (len < bytes)
bytes = len;
if (!gfs2_write_alloc_required(ip, offset, bytes)) {
len -= bytes;
offset += bytes;
continue;
}
qa = gfs2_qadata_get(ip);
if (!qa) {
error = -ENOMEM;
Expand Down

0 comments on commit 58a7d5f

Please sign in to comment.