xfs: reduce stack usage in xfs_iomap

xfs_iomap passes a xfs_bmbt_irec pointer to xfs_iomap_write_direct and
xfs_iomap_write_allocate to give them the results of our read-only
xfs_bmapi query.  Instead of allocating a new xfs_bmbt_irec on stack
for the next call to xfs_bmapi re use the one we got passed as it's not
used after this point.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
This commit is contained in:
Christoph Hellwig 2010-06-24 11:42:19 +10:00 committed by Alex Elder
parent 7a36c8a98a
commit 3070451eea

View file

@ -242,7 +242,7 @@ xfs_iomap_write_direct(
xfs_off_t offset, xfs_off_t offset,
size_t count, size_t count,
int flags, int flags,
xfs_bmbt_irec_t *ret_imap, xfs_bmbt_irec_t *imap,
int *nmaps) int *nmaps)
{ {
xfs_mount_t *mp = ip->i_mount; xfs_mount_t *mp = ip->i_mount;
@ -256,7 +256,6 @@ xfs_iomap_write_direct(
int quota_flag; int quota_flag;
int rt; int rt;
xfs_trans_t *tp; xfs_trans_t *tp;
xfs_bmbt_irec_t imap;
xfs_bmap_free_t free_list; xfs_bmap_free_t free_list;
uint qblocks, resblks, resrtextents; uint qblocks, resblks, resrtextents;
int committed; int committed;
@ -280,10 +279,10 @@ xfs_iomap_write_direct(
if (error) if (error)
goto error_out; goto error_out;
} else { } else {
if (*nmaps && (ret_imap->br_startblock == HOLESTARTBLOCK)) if (*nmaps && (imap->br_startblock == HOLESTARTBLOCK))
last_fsb = MIN(last_fsb, (xfs_fileoff_t) last_fsb = MIN(last_fsb, (xfs_fileoff_t)
ret_imap->br_blockcount + imap->br_blockcount +
ret_imap->br_startoff); imap->br_startoff);
} }
count_fsb = last_fsb - offset_fsb; count_fsb = last_fsb - offset_fsb;
ASSERT(count_fsb > 0); ASSERT(count_fsb > 0);
@ -336,12 +335,15 @@ xfs_iomap_write_direct(
bmapi_flag |= XFS_BMAPI_PREALLOC; bmapi_flag |= XFS_BMAPI_PREALLOC;
/* /*
* Issue the xfs_bmapi() call to allocate the blocks * Issue the xfs_bmapi() call to allocate the blocks.
*
* From this point onwards we overwrite the imap pointer that the
* caller gave to us.
*/ */
xfs_bmap_init(&free_list, &firstfsb); xfs_bmap_init(&free_list, &firstfsb);
nimaps = 1; nimaps = 1;
error = xfs_bmapi(tp, ip, offset_fsb, count_fsb, bmapi_flag, error = xfs_bmapi(tp, ip, offset_fsb, count_fsb, bmapi_flag,
&firstfsb, 0, &imap, &nimaps, &free_list); &firstfsb, 0, imap, &nimaps, &free_list);
if (error) if (error)
goto error0; goto error0;
@ -363,12 +365,11 @@ xfs_iomap_write_direct(
goto error_out; goto error_out;
} }
if (!(imap.br_startblock || XFS_IS_REALTIME_INODE(ip))) { if (!(imap->br_startblock || XFS_IS_REALTIME_INODE(ip))) {
error = xfs_cmn_err_fsblock_zero(ip, &imap); error = xfs_cmn_err_fsblock_zero(ip, imap);
goto error_out; goto error_out;
} }
*ret_imap = imap;
*nmaps = 1; *nmaps = 1;
return 0; return 0;
@ -542,7 +543,7 @@ xfs_iomap_write_allocate(
xfs_inode_t *ip, xfs_inode_t *ip,
xfs_off_t offset, xfs_off_t offset,
size_t count, size_t count,
xfs_bmbt_irec_t *map, xfs_bmbt_irec_t *imap,
int *retmap) int *retmap)
{ {
xfs_mount_t *mp = ip->i_mount; xfs_mount_t *mp = ip->i_mount;
@ -551,7 +552,6 @@ xfs_iomap_write_allocate(
xfs_fsblock_t first_block; xfs_fsblock_t first_block;
xfs_bmap_free_t free_list; xfs_bmap_free_t free_list;
xfs_filblks_t count_fsb; xfs_filblks_t count_fsb;
xfs_bmbt_irec_t imap;
xfs_trans_t *tp; xfs_trans_t *tp;
int nimaps, committed; int nimaps, committed;
int error = 0; int error = 0;
@ -567,8 +567,8 @@ xfs_iomap_write_allocate(
return XFS_ERROR(error); return XFS_ERROR(error);
offset_fsb = XFS_B_TO_FSBT(mp, offset); offset_fsb = XFS_B_TO_FSBT(mp, offset);
count_fsb = map->br_blockcount; count_fsb = imap->br_blockcount;
map_start_fsb = map->br_startoff; map_start_fsb = imap->br_startoff;
XFS_STATS_ADD(xs_xstrat_bytes, XFS_FSB_TO_B(mp, count_fsb)); XFS_STATS_ADD(xs_xstrat_bytes, XFS_FSB_TO_B(mp, count_fsb));
@ -647,10 +647,15 @@ xfs_iomap_write_allocate(
} }
} }
/* Go get the actual blocks */ /*
* Go get the actual blocks.
*
* From this point onwards we overwrite the imap
* pointer that the caller gave to us.
*/
error = xfs_bmapi(tp, ip, map_start_fsb, count_fsb, error = xfs_bmapi(tp, ip, map_start_fsb, count_fsb,
XFS_BMAPI_WRITE, &first_block, 1, XFS_BMAPI_WRITE, &first_block, 1,
&imap, &nimaps, &free_list); imap, &nimaps, &free_list);
if (error) if (error)
goto trans_cancel; goto trans_cancel;
@ -669,13 +674,12 @@ xfs_iomap_write_allocate(
* See if we were able to allocate an extent that * See if we were able to allocate an extent that
* covers at least part of the callers request * covers at least part of the callers request
*/ */
if (!(imap.br_startblock || XFS_IS_REALTIME_INODE(ip))) if (!(imap->br_startblock || XFS_IS_REALTIME_INODE(ip)))
return xfs_cmn_err_fsblock_zero(ip, &imap); return xfs_cmn_err_fsblock_zero(ip, imap);
if ((offset_fsb >= imap.br_startoff) && if ((offset_fsb >= imap->br_startoff) &&
(offset_fsb < (imap.br_startoff + (offset_fsb < (imap->br_startoff +
imap.br_blockcount))) { imap->br_blockcount))) {
*map = imap;
*retmap = 1; *retmap = 1;
XFS_STATS_INC(xs_xstrat_quick); XFS_STATS_INC(xs_xstrat_quick);
return 0; return 0;
@ -685,8 +689,8 @@ xfs_iomap_write_allocate(
* So far we have not mapped the requested part of the * So far we have not mapped the requested part of the
* file, just surrounding data, try again. * file, just surrounding data, try again.
*/ */
count_fsb -= imap.br_blockcount; count_fsb -= imap->br_blockcount;
map_start_fsb = imap.br_startoff + imap.br_blockcount; map_start_fsb = imap->br_startoff + imap->br_blockcount;
} }
trans_cancel: trans_cancel: