xfs: kill xfs_zero_remaining_bytes
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>
This commit is contained in:
parent
bdb0d04fa6
commit
3c2bdc912a
@ -1089,101 +1089,6 @@ error1: /* Just cancel transaction */
|
|||||||
return error;
|
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
|
static int
|
||||||
xfs_unmap_extent(
|
xfs_unmap_extent(
|
||||||
struct xfs_inode *ip,
|
struct xfs_inode *ip,
|
||||||
@ -1309,7 +1214,7 @@ xfs_free_file_space(
|
|||||||
struct xfs_mount *mp = ip->i_mount;
|
struct xfs_mount *mp = ip->i_mount;
|
||||||
xfs_fileoff_t startoffset_fsb;
|
xfs_fileoff_t startoffset_fsb;
|
||||||
xfs_fileoff_t endoffset_fsb;
|
xfs_fileoff_t endoffset_fsb;
|
||||||
int done, error;
|
int done = 0, error;
|
||||||
|
|
||||||
trace_xfs_free_file_space(ip);
|
trace_xfs_free_file_space(ip);
|
||||||
|
|
||||||
@ -1341,31 +1246,21 @@ xfs_free_file_space(
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((done = (endoffset_fsb <= startoffset_fsb)))
|
if (endoffset_fsb > startoffset_fsb) {
|
||||||
/*
|
while (!done) {
|
||||||
* One contiguous piece to clear
|
error = xfs_unmap_extent(ip, startoffset_fsb,
|
||||||
*/
|
endoffset_fsb - startoffset_fsb, &done);
|
||||||
error = xfs_zero_remaining_bytes(ip, offset, offset + len - 1);
|
if (error)
|
||||||
else {
|
return error;
|
||||||
/*
|
}
|
||||||
* 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,
|
* Now that we've unmap all full blocks we'll have to zero out any
|
||||||
endoffset_fsb - startoffset_fsb, &done);
|
* partial block at the beginning and/or end. xfs_zero_range is
|
||||||
}
|
* smart enough to skip any holes, including those we just created.
|
||||||
|
*/
|
||||||
return error;
|
return xfs_zero_range(ip, offset, len, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user