Skip to content

Commit

Permalink
gfs2: Fix filesystem block deallocation for short writes
Browse files Browse the repository at this point in the history
When a write cannot be carried out in full, gfs2_iomap_end() releases
blocks that have been allocated for this write but haven't been used.

To compute the end of the allocation, gfs2_iomap_end() incorrectly
rounded the end of the attempted write down to the next block boundary
to arrive at the end of the allocation.  It would have to round up, but
the end of the allocation is also available as iomap->offset +
iomap->length, so just use that instead.

In addition, use round_up() for computing the start of the unused range.

Fixes: 64bc06b ("gfs2: iomap buffered write support")
Signed-off-by: Andreas Gruenbacher <[email protected]>
  • Loading branch information
Andreas Gruenbacher committed May 13, 2022
1 parent 4a2316a commit d031a88
Showing 1 changed file with 5 additions and 6 deletions.
11 changes: 5 additions & 6 deletions fs/gfs2/bmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -1153,13 +1153,12 @@ static int gfs2_iomap_end(struct inode *inode, loff_t pos, loff_t length,

if (length != written && (iomap->flags & IOMAP_F_NEW)) {
/* Deallocate blocks that were just allocated. */
loff_t blockmask = i_blocksize(inode) - 1;
loff_t end = (pos + length) & ~blockmask;
loff_t hstart = round_up(pos + written, i_blocksize(inode));
loff_t hend = iomap->offset + iomap->length;

pos = (pos + written + blockmask) & ~blockmask;
if (pos < end) {
truncate_pagecache_range(inode, pos, end - 1);
punch_hole(ip, pos, end - pos);
if (hstart < hend) {
truncate_pagecache_range(inode, hstart, hend - 1);
punch_hole(ip, hstart, hend - hstart);
}
}

Expand Down

0 comments on commit d031a88

Please sign in to comment.