Skip to content

Commit

Permalink
xfs: kill xfs_zero_remaining_bytes
Browse files Browse the repository at this point in the history
Instead punch the whole first, and the use the our zeroing helper
to punch out the edge blocks.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
  • Loading branch information
Christoph Hellwig authored and Dave Chinner committed Jun 21, 2016
1 parent bdb0d04 commit 3c2bdc9
Showing 1 changed file with 14 additions and 119 deletions.
133 changes: 14 additions & 119 deletions fs/xfs/xfs_bmap_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -1089,101 +1089,6 @@ xfs_alloc_file_space(
return error;
}

/*
* Zero file bytes between startoff and endoff inclusive.
* The iolock is held exclusive and no blocks are buffered.
*
* This function is used by xfs_free_file_space() to zero
* partial blocks when the range to free is not block aligned.
* When unreserving space with boundaries that are not block
* aligned we round up the start and round down the end
* boundaries and then use this function to zero the parts of
* the blocks that got dropped during the rounding.
*/
STATIC int
xfs_zero_remaining_bytes(
xfs_inode_t *ip,
xfs_off_t startoff,
xfs_off_t endoff)
{
xfs_bmbt_irec_t imap;
xfs_fileoff_t offset_fsb;
xfs_off_t lastoffset;
xfs_off_t offset;
xfs_buf_t *bp;
xfs_mount_t *mp = ip->i_mount;
int nimap;
int error = 0;

/*
* Avoid doing I/O beyond eof - it's not necessary
* since nothing can read beyond eof. The space will
* be zeroed when the file is extended anyway.
*/
if (startoff >= XFS_ISIZE(ip))
return 0;

if (endoff > XFS_ISIZE(ip))
endoff = XFS_ISIZE(ip);

for (offset = startoff; offset <= endoff; offset = lastoffset + 1) {
uint lock_mode;

offset_fsb = XFS_B_TO_FSBT(mp, offset);
nimap = 1;

lock_mode = xfs_ilock_data_map_shared(ip);
error = xfs_bmapi_read(ip, offset_fsb, 1, &imap, &nimap, 0);
xfs_iunlock(ip, lock_mode);

if (error || nimap < 1)
break;
ASSERT(imap.br_blockcount >= 1);
ASSERT(imap.br_startoff == offset_fsb);
ASSERT(imap.br_startblock != DELAYSTARTBLOCK);

if (imap.br_startblock == HOLESTARTBLOCK ||
imap.br_state == XFS_EXT_UNWRITTEN) {
/* skip the entire extent */
lastoffset = XFS_FSB_TO_B(mp, imap.br_startoff +
imap.br_blockcount) - 1;
continue;
}

lastoffset = XFS_FSB_TO_B(mp, imap.br_startoff + 1) - 1;
if (lastoffset > endoff)
lastoffset = endoff;

/* DAX can just zero the backing device directly */
if (IS_DAX(VFS_I(ip))) {
error = dax_zero_page_range(VFS_I(ip), offset,
lastoffset - offset + 1,
xfs_get_blocks_direct);
if (error)
return error;
continue;
}

error = xfs_buf_read_uncached(XFS_IS_REALTIME_INODE(ip) ?
mp->m_rtdev_targp : mp->m_ddev_targp,
xfs_fsb_to_db(ip, imap.br_startblock),
BTOBB(mp->m_sb.sb_blocksize),
0, &bp, NULL);
if (error)
return error;

memset(bp->b_addr +
(offset - XFS_FSB_TO_B(mp, imap.br_startoff)),
0, lastoffset - offset + 1);

error = xfs_bwrite(bp);
xfs_buf_relse(bp);
if (error)
return error;
}
return error;
}

static int
xfs_unmap_extent(
struct xfs_inode *ip,
Expand Down Expand Up @@ -1309,7 +1214,7 @@ xfs_free_file_space(
struct xfs_mount *mp = ip->i_mount;
xfs_fileoff_t startoffset_fsb;
xfs_fileoff_t endoffset_fsb;
int done, error;
int done = 0, error;

trace_xfs_free_file_space(ip);

Expand Down Expand Up @@ -1341,31 +1246,21 @@ xfs_free_file_space(
return error;
}

if ((done = (endoffset_fsb <= startoffset_fsb)))
/*
* One contiguous piece to clear
*/
error = xfs_zero_remaining_bytes(ip, offset, offset + len - 1);
else {
/*
* Some full blocks, possibly two pieces to clear
*/
if (offset < XFS_FSB_TO_B(mp, startoffset_fsb))
error = xfs_zero_remaining_bytes(ip, offset,
XFS_FSB_TO_B(mp, startoffset_fsb) - 1);
if (!error &&
XFS_FSB_TO_B(mp, endoffset_fsb) < offset + len)
error = xfs_zero_remaining_bytes(ip,
XFS_FSB_TO_B(mp, endoffset_fsb),
offset + len - 1);
}

while (!error && !done) {
error = xfs_unmap_extent(ip, startoffset_fsb,
endoffset_fsb - startoffset_fsb, &done);
if (endoffset_fsb > startoffset_fsb) {
while (!done) {
error = xfs_unmap_extent(ip, startoffset_fsb,
endoffset_fsb - startoffset_fsb, &done);
if (error)
return error;
}
}

return error;
/*
* Now that we've unmap all full blocks we'll have to zero out any
* partial block at the beginning and/or end. xfs_zero_range is
* smart enough to skip any holes, including those we just created.
*/
return xfs_zero_range(ip, offset, len, NULL);
}

/*
Expand Down

0 comments on commit 3c2bdc9

Please sign in to comment.