Skip to content

Commit

Permalink
xfs: reduce stack usage of _reflink_clear_inode_flag
Browse files Browse the repository at this point in the history
The loop in _reflink_clear_inode_flag isn't necessary since we
jump out if any part of any extent is shared.  Remove the loop
and we no longer need two maps, so we can save some stack use.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reported-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
  • Loading branch information
Darrick J. Wong authored and Dave Chinner committed Oct 10, 2016
1 parent 63646fc commit 024adf4
Showing 1 changed file with 16 additions and 24 deletions.
40 changes: 16 additions & 24 deletions fs/xfs/xfs_reflink.c
Original file line number Diff line number Diff line change
Expand Up @@ -1507,7 +1507,7 @@ xfs_reflink_clear_inode_flag(
xfs_extlen_t aglen;
xfs_agblock_t rbno;
xfs_extlen_t rlen;
struct xfs_bmbt_irec map[2];
struct xfs_bmbt_irec map;
int nmaps;
int error = 0;

Expand All @@ -1521,37 +1521,29 @@ xfs_reflink_clear_inode_flag(
* Look for extents in the file. Skip holes, delalloc, or
* unwritten extents; they can't be reflinked.
*/
error = xfs_bmapi_read(ip, fbno, end - fbno, map, &nmaps, 0);
error = xfs_bmapi_read(ip, fbno, end - fbno, &map, &nmaps, 0);
if (error)
return error;
if (nmaps == 0)
break;
if (map[0].br_startblock == HOLESTARTBLOCK ||
map[0].br_startblock == DELAYSTARTBLOCK ||
ISUNWRITTEN(&map[0]))
if (map.br_startblock == HOLESTARTBLOCK ||
map.br_startblock == DELAYSTARTBLOCK ||
ISUNWRITTEN(&map))
goto next;

map[1] = map[0];
while (map[1].br_blockcount) {
agno = XFS_FSB_TO_AGNO(mp, map[1].br_startblock);
agbno = XFS_FSB_TO_AGBNO(mp, map[1].br_startblock);
aglen = map[1].br_blockcount;

error = xfs_reflink_find_shared(mp, agno, agbno, aglen,
&rbno, &rlen, false);
if (error)
return error;
/* Is there still a shared block here? */
if (rbno != NULLAGBLOCK)
return 0;

map[1].br_blockcount -= aglen;
map[1].br_startoff += aglen;
map[1].br_startblock += aglen;
}
agno = XFS_FSB_TO_AGNO(mp, map.br_startblock);
agbno = XFS_FSB_TO_AGBNO(mp, map.br_startblock);
aglen = map.br_blockcount;

error = xfs_reflink_find_shared(mp, agno, agbno, aglen,
&rbno, &rlen, false);
if (error)
return error;
/* Is there still a shared block here? */
if (rbno != NULLAGBLOCK)
return 0;
next:
fbno = map[0].br_startoff + map[0].br_blockcount;
fbno = map.br_startoff + map.br_blockcount;
}

/*
Expand Down

0 comments on commit 024adf4

Please sign in to comment.