diff options
author | Christoph Hellwig <hch@lst.de> | 2011-07-13 07:43:49 -0400 |
---|---|---|
committer | Christoph Hellwig <hch@lst.de> | 2011-07-13 07:43:49 -0400 |
commit | 77936d0280616d84d1eb0eb38a6f857d2827a434 (patch) | |
tree | 3076e827144b7312d84e9ed52c5d2f92b1a10fb6 /fs/xfs/xfs_da_btree.c | |
parent | a230a1df40864ef68ff6fbd09302f16d2a216ea5 (diff) |
xfs: factor out xfs_da_grow_inode_int
xfs_da_grow_inode and xfs_dir2_grow_inode are mostly duplicate code. Factor
the meat of those two functions into a new common helper.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Alex Elder <aelder@sgi.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Diffstat (limited to 'fs/xfs/xfs_da_btree.c')
-rw-r--r-- | fs/xfs/xfs_da_btree.c | 126 |
1 files changed, 69 insertions, 57 deletions
diff --git a/fs/xfs/xfs_da_btree.c b/fs/xfs/xfs_da_btree.c index a58a6410c58d..73b048f7eb71 100644 --- a/fs/xfs/xfs_da_btree.c +++ b/fs/xfs/xfs_da_btree.c | |||
@@ -1543,79 +1543,62 @@ const struct xfs_nameops xfs_default_nameops = { | |||
1543 | .compname = xfs_da_compname | 1543 | .compname = xfs_da_compname |
1544 | }; | 1544 | }; |
1545 | 1545 | ||
1546 | /* | ||
1547 | * Add a block to the btree ahead of the file. | ||
1548 | * Return the new block number to the caller. | ||
1549 | */ | ||
1550 | int | 1546 | int |
1551 | xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno) | 1547 | xfs_da_grow_inode_int( |
1548 | struct xfs_da_args *args, | ||
1549 | xfs_fileoff_t *bno, | ||
1550 | int count) | ||
1552 | { | 1551 | { |
1553 | xfs_fileoff_t bno, b; | 1552 | struct xfs_trans *tp = args->trans; |
1554 | xfs_bmbt_irec_t map; | 1553 | struct xfs_inode *dp = args->dp; |
1555 | xfs_bmbt_irec_t *mapp; | 1554 | int w = args->whichfork; |
1556 | xfs_inode_t *dp; | 1555 | xfs_drfsbno_t nblks = dp->i_d.di_nblocks; |
1557 | int nmap, error, w, count, c, got, i, mapi; | 1556 | struct xfs_bmbt_irec map, *mapp; |
1558 | xfs_trans_t *tp; | 1557 | int nmap, error, got, i, mapi; |
1559 | xfs_mount_t *mp; | ||
1560 | xfs_drfsbno_t nblks; | ||
1561 | 1558 | ||
1562 | dp = args->dp; | ||
1563 | mp = dp->i_mount; | ||
1564 | w = args->whichfork; | ||
1565 | tp = args->trans; | ||
1566 | nblks = dp->i_d.di_nblocks; | ||
1567 | |||
1568 | /* | ||
1569 | * For new directories adjust the file offset and block count. | ||
1570 | */ | ||
1571 | if (w == XFS_DATA_FORK) { | ||
1572 | bno = mp->m_dirleafblk; | ||
1573 | count = mp->m_dirblkfsbs; | ||
1574 | } else { | ||
1575 | bno = 0; | ||
1576 | count = 1; | ||
1577 | } | ||
1578 | /* | 1559 | /* |
1579 | * Find a spot in the file space to put the new block. | 1560 | * Find a spot in the file space to put the new block. |
1580 | */ | 1561 | */ |
1581 | if ((error = xfs_bmap_first_unused(tp, dp, count, &bno, w))) | 1562 | error = xfs_bmap_first_unused(tp, dp, count, bno, w); |
1563 | if (error) | ||
1582 | return error; | 1564 | return error; |
1583 | if (w == XFS_DATA_FORK) | 1565 | |
1584 | ASSERT(bno >= mp->m_dirleafblk && bno < mp->m_dirfreeblk); | ||
1585 | /* | 1566 | /* |
1586 | * Try mapping it in one filesystem block. | 1567 | * Try mapping it in one filesystem block. |
1587 | */ | 1568 | */ |
1588 | nmap = 1; | 1569 | nmap = 1; |
1589 | ASSERT(args->firstblock != NULL); | 1570 | ASSERT(args->firstblock != NULL); |
1590 | if ((error = xfs_bmapi(tp, dp, bno, count, | 1571 | error = xfs_bmapi(tp, dp, *bno, count, |
1591 | xfs_bmapi_aflag(w)|XFS_BMAPI_WRITE|XFS_BMAPI_METADATA| | 1572 | xfs_bmapi_aflag(w)|XFS_BMAPI_WRITE|XFS_BMAPI_METADATA| |
1592 | XFS_BMAPI_CONTIG, | 1573 | XFS_BMAPI_CONTIG, |
1593 | args->firstblock, args->total, &map, &nmap, | 1574 | args->firstblock, args->total, &map, &nmap, |
1594 | args->flist))) { | 1575 | args->flist); |
1576 | if (error) | ||
1595 | return error; | 1577 | return error; |
1596 | } | 1578 | |
1597 | ASSERT(nmap <= 1); | 1579 | ASSERT(nmap <= 1); |
1598 | if (nmap == 1) { | 1580 | if (nmap == 1) { |
1599 | mapp = ↦ | 1581 | mapp = ↦ |
1600 | mapi = 1; | 1582 | mapi = 1; |
1601 | } | 1583 | } else if (nmap == 0 && count > 1) { |
1602 | /* | 1584 | xfs_fileoff_t b; |
1603 | * If we didn't get it and the block might work if fragmented, | 1585 | int c; |
1604 | * try without the CONTIG flag. Loop until we get it all. | 1586 | |
1605 | */ | 1587 | /* |
1606 | else if (nmap == 0 && count > 1) { | 1588 | * If we didn't get it and the block might work if fragmented, |
1589 | * try without the CONTIG flag. Loop until we get it all. | ||
1590 | */ | ||
1607 | mapp = kmem_alloc(sizeof(*mapp) * count, KM_SLEEP); | 1591 | mapp = kmem_alloc(sizeof(*mapp) * count, KM_SLEEP); |
1608 | for (b = bno, mapi = 0; b < bno + count; ) { | 1592 | for (b = *bno, mapi = 0; b < *bno + count; ) { |
1609 | nmap = MIN(XFS_BMAP_MAX_NMAP, count); | 1593 | nmap = MIN(XFS_BMAP_MAX_NMAP, count); |
1610 | c = (int)(bno + count - b); | 1594 | c = (int)(*bno + count - b); |
1611 | if ((error = xfs_bmapi(tp, dp, b, c, | 1595 | error = xfs_bmapi(tp, dp, b, c, |
1612 | xfs_bmapi_aflag(w)|XFS_BMAPI_WRITE| | 1596 | xfs_bmapi_aflag(w)|XFS_BMAPI_WRITE| |
1613 | XFS_BMAPI_METADATA, | 1597 | XFS_BMAPI_METADATA, |
1614 | args->firstblock, args->total, | 1598 | args->firstblock, args->total, |
1615 | &mapp[mapi], &nmap, args->flist))) { | 1599 | &mapp[mapi], &nmap, args->flist); |
1616 | kmem_free(mapp); | 1600 | if (error) |
1617 | return error; | 1601 | goto out_free_map; |
1618 | } | ||
1619 | if (nmap < 1) | 1602 | if (nmap < 1) |
1620 | break; | 1603 | break; |
1621 | mapi += nmap; | 1604 | mapi += nmap; |
@@ -1626,24 +1609,53 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno) | |||
1626 | mapi = 0; | 1609 | mapi = 0; |
1627 | mapp = NULL; | 1610 | mapp = NULL; |
1628 | } | 1611 | } |
1612 | |||
1629 | /* | 1613 | /* |
1630 | * Count the blocks we got, make sure it matches the total. | 1614 | * Count the blocks we got, make sure it matches the total. |
1631 | */ | 1615 | */ |
1632 | for (i = 0, got = 0; i < mapi; i++) | 1616 | for (i = 0, got = 0; i < mapi; i++) |
1633 | got += mapp[i].br_blockcount; | 1617 | got += mapp[i].br_blockcount; |
1634 | if (got != count || mapp[0].br_startoff != bno || | 1618 | if (got != count || mapp[0].br_startoff != *bno || |
1635 | mapp[mapi - 1].br_startoff + mapp[mapi - 1].br_blockcount != | 1619 | mapp[mapi - 1].br_startoff + mapp[mapi - 1].br_blockcount != |
1636 | bno + count) { | 1620 | *bno + count) { |
1637 | if (mapp != &map) | 1621 | error = XFS_ERROR(ENOSPC); |
1638 | kmem_free(mapp); | 1622 | goto out_free_map; |
1639 | return XFS_ERROR(ENOSPC); | ||
1640 | } | 1623 | } |
1641 | if (mapp != &map) | 1624 | |
1642 | kmem_free(mapp); | ||
1643 | /* account for newly allocated blocks in reserved blocks total */ | 1625 | /* account for newly allocated blocks in reserved blocks total */ |
1644 | args->total -= dp->i_d.di_nblocks - nblks; | 1626 | args->total -= dp->i_d.di_nblocks - nblks; |
1645 | *new_blkno = (xfs_dablk_t)bno; | 1627 | |
1646 | return 0; | 1628 | out_free_map: |
1629 | if (mapp != &map) | ||
1630 | kmem_free(mapp); | ||
1631 | return error; | ||
1632 | } | ||
1633 | |||
1634 | /* | ||
1635 | * Add a block to the btree ahead of the file. | ||
1636 | * Return the new block number to the caller. | ||
1637 | */ | ||
1638 | int | ||
1639 | xfs_da_grow_inode( | ||
1640 | struct xfs_da_args *args, | ||
1641 | xfs_dablk_t *new_blkno) | ||
1642 | { | ||
1643 | xfs_fileoff_t bno; | ||
1644 | int count; | ||
1645 | int error; | ||
1646 | |||
1647 | if (args->whichfork == XFS_DATA_FORK) { | ||
1648 | bno = args->dp->i_mount->m_dirleafblk; | ||
1649 | count = args->dp->i_mount->m_dirblkfsbs; | ||
1650 | } else { | ||
1651 | bno = 0; | ||
1652 | count = 1; | ||
1653 | } | ||
1654 | |||
1655 | error = xfs_da_grow_inode_int(args, &bno, count); | ||
1656 | if (!error) | ||
1657 | *new_blkno = (xfs_dablk_t)bno; | ||
1658 | return error; | ||
1647 | } | 1659 | } |
1648 | 1660 | ||
1649 | /* | 1661 | /* |