diff options
author | Christoph Hellwig <hch@infradead.org> | 2010-06-23 21:42:19 -0400 |
---|---|---|
committer | Alex Elder <aelder@sgi.com> | 2010-07-26 14:16:42 -0400 |
commit | 3070451eea1ed8e3bde0573183c7d8ac25fd5e97 (patch) | |
tree | 667aee111d96e885021e261647fe4ec3cdb1f08a /fs/xfs/xfs_iomap.c | |
parent | 7a36c8a98a7dd05756bb147be2ac350325ff5830 (diff) |
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>
Diffstat (limited to 'fs/xfs/xfs_iomap.c')
-rw-r--r-- | fs/xfs/xfs_iomap.c | 52 |
1 files changed, 28 insertions, 24 deletions
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index 39ad46b3ed46..a0dbcaff911a 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c | |||
@@ -242,7 +242,7 @@ xfs_iomap_write_direct( | |||
242 | xfs_off_t offset, | 242 | xfs_off_t offset, |
243 | size_t count, | 243 | size_t count, |
244 | int flags, | 244 | int flags, |
245 | xfs_bmbt_irec_t *ret_imap, | 245 | xfs_bmbt_irec_t *imap, |
246 | int *nmaps) | 246 | int *nmaps) |
247 | { | 247 | { |
248 | xfs_mount_t *mp = ip->i_mount; | 248 | xfs_mount_t *mp = ip->i_mount; |
@@ -256,7 +256,6 @@ xfs_iomap_write_direct( | |||
256 | int quota_flag; | 256 | int quota_flag; |
257 | int rt; | 257 | int rt; |
258 | xfs_trans_t *tp; | 258 | xfs_trans_t *tp; |
259 | xfs_bmbt_irec_t imap; | ||
260 | xfs_bmap_free_t free_list; | 259 | xfs_bmap_free_t free_list; |
261 | uint qblocks, resblks, resrtextents; | 260 | uint qblocks, resblks, resrtextents; |
262 | int committed; | 261 | int committed; |
@@ -280,10 +279,10 @@ xfs_iomap_write_direct( | |||
280 | if (error) | 279 | if (error) |
281 | goto error_out; | 280 | goto error_out; |
282 | } else { | 281 | } else { |
283 | if (*nmaps && (ret_imap->br_startblock == HOLESTARTBLOCK)) | 282 | if (*nmaps && (imap->br_startblock == HOLESTARTBLOCK)) |
284 | last_fsb = MIN(last_fsb, (xfs_fileoff_t) | 283 | last_fsb = MIN(last_fsb, (xfs_fileoff_t) |
285 | ret_imap->br_blockcount + | 284 | imap->br_blockcount + |
286 | ret_imap->br_startoff); | 285 | imap->br_startoff); |
287 | } | 286 | } |
288 | count_fsb = last_fsb - offset_fsb; | 287 | count_fsb = last_fsb - offset_fsb; |
289 | ASSERT(count_fsb > 0); | 288 | ASSERT(count_fsb > 0); |
@@ -336,12 +335,15 @@ xfs_iomap_write_direct( | |||
336 | bmapi_flag |= XFS_BMAPI_PREALLOC; | 335 | bmapi_flag |= XFS_BMAPI_PREALLOC; |
337 | 336 | ||
338 | /* | 337 | /* |
339 | * Issue the xfs_bmapi() call to allocate the blocks | 338 | * Issue the xfs_bmapi() call to allocate the blocks. |
339 | * | ||
340 | * From this point onwards we overwrite the imap pointer that the | ||
341 | * caller gave to us. | ||
340 | */ | 342 | */ |
341 | xfs_bmap_init(&free_list, &firstfsb); | 343 | xfs_bmap_init(&free_list, &firstfsb); |
342 | nimaps = 1; | 344 | nimaps = 1; |
343 | error = xfs_bmapi(tp, ip, offset_fsb, count_fsb, bmapi_flag, | 345 | error = xfs_bmapi(tp, ip, offset_fsb, count_fsb, bmapi_flag, |
344 | &firstfsb, 0, &imap, &nimaps, &free_list); | 346 | &firstfsb, 0, imap, &nimaps, &free_list); |
345 | if (error) | 347 | if (error) |
346 | goto error0; | 348 | goto error0; |
347 | 349 | ||
@@ -363,12 +365,11 @@ xfs_iomap_write_direct( | |||
363 | goto error_out; | 365 | goto error_out; |
364 | } | 366 | } |
365 | 367 | ||
366 | if (!(imap.br_startblock || XFS_IS_REALTIME_INODE(ip))) { | 368 | if (!(imap->br_startblock || XFS_IS_REALTIME_INODE(ip))) { |
367 | error = xfs_cmn_err_fsblock_zero(ip, &imap); | 369 | error = xfs_cmn_err_fsblock_zero(ip, imap); |
368 | goto error_out; | 370 | goto error_out; |
369 | } | 371 | } |
370 | 372 | ||
371 | *ret_imap = imap; | ||
372 | *nmaps = 1; | 373 | *nmaps = 1; |
373 | return 0; | 374 | return 0; |
374 | 375 | ||
@@ -542,7 +543,7 @@ xfs_iomap_write_allocate( | |||
542 | xfs_inode_t *ip, | 543 | xfs_inode_t *ip, |
543 | xfs_off_t offset, | 544 | xfs_off_t offset, |
544 | size_t count, | 545 | size_t count, |
545 | xfs_bmbt_irec_t *map, | 546 | xfs_bmbt_irec_t *imap, |
546 | int *retmap) | 547 | int *retmap) |
547 | { | 548 | { |
548 | xfs_mount_t *mp = ip->i_mount; | 549 | xfs_mount_t *mp = ip->i_mount; |
@@ -551,7 +552,6 @@ xfs_iomap_write_allocate( | |||
551 | xfs_fsblock_t first_block; | 552 | xfs_fsblock_t first_block; |
552 | xfs_bmap_free_t free_list; | 553 | xfs_bmap_free_t free_list; |
553 | xfs_filblks_t count_fsb; | 554 | xfs_filblks_t count_fsb; |
554 | xfs_bmbt_irec_t imap; | ||
555 | xfs_trans_t *tp; | 555 | xfs_trans_t *tp; |
556 | int nimaps, committed; | 556 | int nimaps, committed; |
557 | int error = 0; | 557 | int error = 0; |
@@ -567,8 +567,8 @@ xfs_iomap_write_allocate( | |||
567 | return XFS_ERROR(error); | 567 | return XFS_ERROR(error); |
568 | 568 | ||
569 | offset_fsb = XFS_B_TO_FSBT(mp, offset); | 569 | offset_fsb = XFS_B_TO_FSBT(mp, offset); |
570 | count_fsb = map->br_blockcount; | 570 | count_fsb = imap->br_blockcount; |
571 | map_start_fsb = map->br_startoff; | 571 | map_start_fsb = imap->br_startoff; |
572 | 572 | ||
573 | XFS_STATS_ADD(xs_xstrat_bytes, XFS_FSB_TO_B(mp, count_fsb)); | 573 | XFS_STATS_ADD(xs_xstrat_bytes, XFS_FSB_TO_B(mp, count_fsb)); |
574 | 574 | ||
@@ -647,10 +647,15 @@ xfs_iomap_write_allocate( | |||
647 | } | 647 | } |
648 | } | 648 | } |
649 | 649 | ||
650 | /* Go get the actual blocks */ | 650 | /* |
651 | * Go get the actual blocks. | ||
652 | * | ||
653 | * From this point onwards we overwrite the imap | ||
654 | * pointer that the caller gave to us. | ||
655 | */ | ||
651 | error = xfs_bmapi(tp, ip, map_start_fsb, count_fsb, | 656 | error = xfs_bmapi(tp, ip, map_start_fsb, count_fsb, |
652 | XFS_BMAPI_WRITE, &first_block, 1, | 657 | XFS_BMAPI_WRITE, &first_block, 1, |
653 | &imap, &nimaps, &free_list); | 658 | imap, &nimaps, &free_list); |
654 | if (error) | 659 | if (error) |
655 | goto trans_cancel; | 660 | goto trans_cancel; |
656 | 661 | ||
@@ -669,13 +674,12 @@ xfs_iomap_write_allocate( | |||
669 | * See if we were able to allocate an extent that | 674 | * See if we were able to allocate an extent that |
670 | * covers at least part of the callers request | 675 | * covers at least part of the callers request |
671 | */ | 676 | */ |
672 | if (!(imap.br_startblock || XFS_IS_REALTIME_INODE(ip))) | 677 | if (!(imap->br_startblock || XFS_IS_REALTIME_INODE(ip))) |
673 | return xfs_cmn_err_fsblock_zero(ip, &imap); | 678 | return xfs_cmn_err_fsblock_zero(ip, imap); |
674 | 679 | ||
675 | if ((offset_fsb >= imap.br_startoff) && | 680 | if ((offset_fsb >= imap->br_startoff) && |
676 | (offset_fsb < (imap.br_startoff + | 681 | (offset_fsb < (imap->br_startoff + |
677 | imap.br_blockcount))) { | 682 | imap->br_blockcount))) { |
678 | *map = imap; | ||
679 | *retmap = 1; | 683 | *retmap = 1; |
680 | XFS_STATS_INC(xs_xstrat_quick); | 684 | XFS_STATS_INC(xs_xstrat_quick); |
681 | return 0; | 685 | return 0; |
@@ -685,8 +689,8 @@ xfs_iomap_write_allocate( | |||
685 | * So far we have not mapped the requested part of the | 689 | * So far we have not mapped the requested part of the |
686 | * file, just surrounding data, try again. | 690 | * file, just surrounding data, try again. |
687 | */ | 691 | */ |
688 | count_fsb -= imap.br_blockcount; | 692 | count_fsb -= imap->br_blockcount; |
689 | map_start_fsb = imap.br_startoff + imap.br_blockcount; | 693 | map_start_fsb = imap->br_startoff + imap->br_blockcount; |
690 | } | 694 | } |
691 | 695 | ||
692 | trans_cancel: | 696 | trans_cancel: |