diff options
-rw-r--r-- | fs/gfs2/incore.h | 7 | ||||
-rw-r--r-- | fs/gfs2/rgrp.c | 460 |
2 files changed, 257 insertions, 210 deletions
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index d5e254604c7..99d7c64b509 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h | |||
@@ -113,6 +113,13 @@ static inline u64 gfs2_rbm_to_block(const struct gfs2_rbm *rbm) | |||
113 | return rbm->rgd->rd_data0 + (rbm->bi->bi_start * GFS2_NBBY) + rbm->offset; | 113 | return rbm->rgd->rd_data0 + (rbm->bi->bi_start * GFS2_NBBY) + rbm->offset; |
114 | } | 114 | } |
115 | 115 | ||
116 | static inline bool gfs2_rbm_eq(const struct gfs2_rbm *rbm1, | ||
117 | const struct gfs2_rbm *rbm2) | ||
118 | { | ||
119 | return (rbm1->rgd == rbm2->rgd) && (rbm1->bi == rbm2->bi) && | ||
120 | (rbm1->offset == rbm2->offset); | ||
121 | } | ||
122 | |||
116 | enum gfs2_state_bits { | 123 | enum gfs2_state_bits { |
117 | BH_Pinned = BH_PrivateStart, | 124 | BH_Pinned = BH_PrivateStart, |
118 | BH_Escaped = BH_PrivateStart + 1, | 125 | BH_Escaped = BH_PrivateStart + 1, |
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index eaa41885a00..bd3b926949d 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c | |||
@@ -67,10 +67,6 @@ static const char valid_change[16] = { | |||
67 | 1, 0, 0, 0 | 67 | 1, 0, 0, 0 |
68 | }; | 68 | }; |
69 | 69 | ||
70 | static u32 rgblk_search(struct gfs2_rgrpd *rgd, u32 goal, | ||
71 | unsigned char old_state, | ||
72 | struct gfs2_bitmap **rbi); | ||
73 | |||
74 | /** | 70 | /** |
75 | * gfs2_setbit - Set a bit in the bitmaps | 71 | * gfs2_setbit - Set a bit in the bitmaps |
76 | * @rgd: the resource group descriptor | 72 | * @rgd: the resource group descriptor |
@@ -202,36 +198,6 @@ static inline int rs_cmp(u64 blk, u32 len, struct gfs2_blkreserv *rs) | |||
202 | } | 198 | } |
203 | 199 | ||
204 | /** | 200 | /** |
205 | * rs_find - Find a rgrp multi-block reservation that contains a given block | ||
206 | * @rgd: The rgrp | ||
207 | * @rgblk: The block we're looking for, relative to the rgrp | ||
208 | */ | ||
209 | static struct gfs2_blkreserv *rs_find(struct gfs2_rgrpd *rgd, u32 rgblk) | ||
210 | { | ||
211 | struct rb_node **newn; | ||
212 | int rc; | ||
213 | u64 fsblk = rgblk + rgd->rd_data0; | ||
214 | |||
215 | spin_lock(&rgd->rd_rsspin); | ||
216 | newn = &rgd->rd_rstree.rb_node; | ||
217 | while (*newn) { | ||
218 | struct gfs2_blkreserv *cur = | ||
219 | rb_entry(*newn, struct gfs2_blkreserv, rs_node); | ||
220 | rc = rs_cmp(fsblk, 1, cur); | ||
221 | if (rc < 0) | ||
222 | newn = &((*newn)->rb_left); | ||
223 | else if (rc > 0) | ||
224 | newn = &((*newn)->rb_right); | ||
225 | else { | ||
226 | spin_unlock(&rgd->rd_rsspin); | ||
227 | return cur; | ||
228 | } | ||
229 | } | ||
230 | spin_unlock(&rgd->rd_rsspin); | ||
231 | return NULL; | ||
232 | } | ||
233 | |||
234 | /** | ||
235 | * gfs2_bitfit - Search an rgrp's bitmap buffer to find a bit-pair representing | 201 | * gfs2_bitfit - Search an rgrp's bitmap buffer to find a bit-pair representing |
236 | * a block in a given allocation state. | 202 | * a block in a given allocation state. |
237 | * @buf: the buffer that holds the bitmaps | 203 | * @buf: the buffer that holds the bitmaps |
@@ -1306,9 +1272,6 @@ static struct gfs2_blkreserv *rs_insert(struct gfs2_bitmap *bi, | |||
1306 | rb_link_node(&rs->rs_node, parent, newn); | 1272 | rb_link_node(&rs->rs_node, parent, newn); |
1307 | rb_insert_color(&rs->rs_node, &rgd->rd_rstree); | 1273 | rb_insert_color(&rs->rs_node, &rgd->rd_rstree); |
1308 | 1274 | ||
1309 | /* Do our inode accounting for the reservation */ | ||
1310 | /*BUG_ON(!gfs2_glock_is_locked_by_me(ip->i_gl));*/ | ||
1311 | |||
1312 | /* Do our rgrp accounting for the reservation */ | 1275 | /* Do our rgrp accounting for the reservation */ |
1313 | rgd->rd_reserved += amount; /* blocks reserved */ | 1276 | rgd->rd_reserved += amount; /* blocks reserved */ |
1314 | rgd->rd_rs_cnt++; /* number of in-tree reservations */ | 1277 | rgd->rd_rs_cnt++; /* number of in-tree reservations */ |
@@ -1464,6 +1427,199 @@ static int try_rgrp_fit(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip, | |||
1464 | } | 1427 | } |
1465 | 1428 | ||
1466 | /** | 1429 | /** |
1430 | * gfs2_next_unreserved_block - Return next block that is not reserved | ||
1431 | * @rgd: The resource group | ||
1432 | * @block: The starting block | ||
1433 | * @ip: Ignore any reservations for this inode | ||
1434 | * | ||
1435 | * If the block does not appear in any reservation, then return the | ||
1436 | * block number unchanged. If it does appear in the reservation, then | ||
1437 | * keep looking through the tree of reservations in order to find the | ||
1438 | * first block number which is not reserved. | ||
1439 | */ | ||
1440 | |||
1441 | static u64 gfs2_next_unreserved_block(struct gfs2_rgrpd *rgd, u64 block, | ||
1442 | const struct gfs2_inode *ip) | ||
1443 | { | ||
1444 | struct gfs2_blkreserv *rs; | ||
1445 | struct rb_node *n; | ||
1446 | int rc; | ||
1447 | |||
1448 | spin_lock(&rgd->rd_rsspin); | ||
1449 | n = rb_first(&rgd->rd_rstree); | ||
1450 | while (n) { | ||
1451 | rs = rb_entry(n, struct gfs2_blkreserv, rs_node); | ||
1452 | rc = rs_cmp(block, 1, rs); | ||
1453 | if (rc < 0) | ||
1454 | n = n->rb_left; | ||
1455 | else if (rc > 0) | ||
1456 | n = n->rb_right; | ||
1457 | else | ||
1458 | break; | ||
1459 | } | ||
1460 | |||
1461 | if (n) { | ||
1462 | while ((rs_cmp(block, 1, rs) == 0) && (ip->i_res != rs)) { | ||
1463 | block = gfs2_rbm_to_block(&rs->rs_rbm) + rs->rs_free; | ||
1464 | n = rb_next(&rs->rs_node); | ||
1465 | if (n == NULL) | ||
1466 | break; | ||
1467 | rs = rb_entry(n, struct gfs2_blkreserv, rs_node); | ||
1468 | } | ||
1469 | } | ||
1470 | |||
1471 | spin_unlock(&rgd->rd_rsspin); | ||
1472 | return block; | ||
1473 | } | ||
1474 | |||
1475 | /** | ||
1476 | * gfs2_rbm_from_block - Set the rbm based upon rgd and block number | ||
1477 | * @rbm: The rbm with rgd already set correctly | ||
1478 | * @block: The block number (filesystem relative) | ||
1479 | * | ||
1480 | * This sets the bi and offset members of an rbm based on a | ||
1481 | * resource group and a filesystem relative block number. The | ||
1482 | * resource group must be set in the rbm on entry, the bi and | ||
1483 | * offset members will be set by this function. | ||
1484 | * | ||
1485 | * Returns: 0 on success, or an error code | ||
1486 | */ | ||
1487 | |||
1488 | static int gfs2_rbm_from_block(struct gfs2_rbm *rbm, u64 block) | ||
1489 | { | ||
1490 | u64 rblock = block - rbm->rgd->rd_data0; | ||
1491 | u32 goal = (u32)rblock; | ||
1492 | int x; | ||
1493 | |||
1494 | if (WARN_ON_ONCE(rblock > UINT_MAX)) | ||
1495 | return -EINVAL; | ||
1496 | |||
1497 | for (x = 0; x < rbm->rgd->rd_length; x++) { | ||
1498 | rbm->bi = rbm->rgd->rd_bits + x; | ||
1499 | if (goal < (rbm->bi->bi_start + rbm->bi->bi_len) * GFS2_NBBY) { | ||
1500 | rbm->offset = goal - (rbm->bi->bi_start * GFS2_NBBY); | ||
1501 | return 0; | ||
1502 | } | ||
1503 | } | ||
1504 | |||
1505 | return -E2BIG; | ||
1506 | } | ||
1507 | |||
1508 | /** | ||
1509 | * gfs2_reservation_check_and_update - Check for reservations during block alloc | ||
1510 | * @rbm: The current position in the resource group | ||
1511 | * | ||
1512 | * This checks the current position in the rgrp to see whether there is | ||
1513 | * a reservation covering this block. If not then this function is a | ||
1514 | * no-op. If there is, then the position is moved to the end of the | ||
1515 | * contiguous reservation(s) so that we are pointing at the first | ||
1516 | * non-reserved block. | ||
1517 | * | ||
1518 | * Returns: 0 if no reservation, 1 if @rbm has changed, otherwise an error | ||
1519 | */ | ||
1520 | |||
1521 | static int gfs2_reservation_check_and_update(struct gfs2_rbm *rbm, | ||
1522 | const struct gfs2_inode *ip) | ||
1523 | { | ||
1524 | u64 block = gfs2_rbm_to_block(rbm); | ||
1525 | u64 nblock; | ||
1526 | int ret; | ||
1527 | |||
1528 | nblock = gfs2_next_unreserved_block(rbm->rgd, block, ip); | ||
1529 | if (nblock == block) | ||
1530 | return 0; | ||
1531 | ret = gfs2_rbm_from_block(rbm, nblock); | ||
1532 | if (ret < 0) | ||
1533 | return ret; | ||
1534 | return 1; | ||
1535 | } | ||
1536 | |||
1537 | /** | ||
1538 | * gfs2_rbm_find - Look for blocks of a particular state | ||
1539 | * @rbm: Value/result starting position and final position | ||
1540 | * @state: The state which we want to find | ||
1541 | * @ip: If set, check for reservations | ||
1542 | * @nowrap: Stop looking at the end of the rgrp, rather than wrapping | ||
1543 | * around until we've reached the starting point. | ||
1544 | * | ||
1545 | * Side effects: | ||
1546 | * - If looking for free blocks, we set GBF_FULL on each bitmap which | ||
1547 | * has no free blocks in it. | ||
1548 | * | ||
1549 | * Returns: 0 on success, -ENOSPC if there is no block of the requested state | ||
1550 | */ | ||
1551 | |||
1552 | static int gfs2_rbm_find(struct gfs2_rbm *rbm, u8 state, | ||
1553 | const struct gfs2_inode *ip, bool nowrap) | ||
1554 | { | ||
1555 | struct buffer_head *bh; | ||
1556 | struct gfs2_bitmap *initial_bi; | ||
1557 | u32 initial_offset; | ||
1558 | u32 offset; | ||
1559 | u8 *buffer; | ||
1560 | int index; | ||
1561 | int n = 0; | ||
1562 | int iters = rbm->rgd->rd_length; | ||
1563 | int ret; | ||
1564 | |||
1565 | /* If we are not starting at the beginning of a bitmap, then we | ||
1566 | * need to add one to the bitmap count to ensure that we search | ||
1567 | * the starting bitmap twice. | ||
1568 | */ | ||
1569 | if (rbm->offset != 0) | ||
1570 | iters++; | ||
1571 | |||
1572 | while(1) { | ||
1573 | if (test_bit(GBF_FULL, &rbm->bi->bi_flags) && | ||
1574 | (state == GFS2_BLKST_FREE)) | ||
1575 | goto next_bitmap; | ||
1576 | |||
1577 | bh = rbm->bi->bi_bh; | ||
1578 | buffer = bh->b_data + rbm->bi->bi_offset; | ||
1579 | WARN_ON(!buffer_uptodate(bh)); | ||
1580 | if (state != GFS2_BLKST_UNLINKED && rbm->bi->bi_clone) | ||
1581 | buffer = rbm->bi->bi_clone + rbm->bi->bi_offset; | ||
1582 | find_next: | ||
1583 | initial_offset = rbm->offset; | ||
1584 | offset = gfs2_bitfit(buffer, rbm->bi->bi_len, rbm->offset, state); | ||
1585 | if (offset == BFITNOENT) | ||
1586 | goto bitmap_full; | ||
1587 | rbm->offset = offset; | ||
1588 | if (ip == NULL) | ||
1589 | return 0; | ||
1590 | |||
1591 | initial_bi = rbm->bi; | ||
1592 | ret = gfs2_reservation_check_and_update(rbm, ip); | ||
1593 | if (ret == 0) | ||
1594 | return 0; | ||
1595 | if (ret > 0) { | ||
1596 | n += (rbm->bi - initial_bi); | ||
1597 | goto find_next; | ||
1598 | } | ||
1599 | return ret; | ||
1600 | |||
1601 | bitmap_full: /* Mark bitmap as full and fall through */ | ||
1602 | if ((state == GFS2_BLKST_FREE) && initial_offset == 0) | ||
1603 | set_bit(GBF_FULL, &rbm->bi->bi_flags); | ||
1604 | |||
1605 | next_bitmap: /* Find next bitmap in the rgrp */ | ||
1606 | rbm->offset = 0; | ||
1607 | index = rbm->bi - rbm->rgd->rd_bits; | ||
1608 | index++; | ||
1609 | if (index == rbm->rgd->rd_length) | ||
1610 | index = 0; | ||
1611 | rbm->bi = &rbm->rgd->rd_bits[index]; | ||
1612 | if ((index == 0) && nowrap) | ||
1613 | break; | ||
1614 | n++; | ||
1615 | if (n >= iters) | ||
1616 | break; | ||
1617 | } | ||
1618 | |||
1619 | return -ENOSPC; | ||
1620 | } | ||
1621 | |||
1622 | /** | ||
1467 | * try_rgrp_unlink - Look for any unlinked, allocated, but unused inodes | 1623 | * try_rgrp_unlink - Look for any unlinked, allocated, but unused inodes |
1468 | * @rgd: The rgrp | 1624 | * @rgd: The rgrp |
1469 | * @last_unlinked: block address of the last dinode we unlinked | 1625 | * @last_unlinked: block address of the last dinode we unlinked |
@@ -1475,34 +1631,33 @@ static int try_rgrp_fit(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip, | |||
1475 | 1631 | ||
1476 | static void try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked, u64 skip) | 1632 | static void try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked, u64 skip) |
1477 | { | 1633 | { |
1478 | u32 goal = 0, block; | 1634 | u64 block; |
1479 | u64 no_addr; | ||
1480 | struct gfs2_sbd *sdp = rgd->rd_sbd; | 1635 | struct gfs2_sbd *sdp = rgd->rd_sbd; |
1481 | struct gfs2_glock *gl; | 1636 | struct gfs2_glock *gl; |
1482 | struct gfs2_inode *ip; | 1637 | struct gfs2_inode *ip; |
1483 | int error; | 1638 | int error; |
1484 | int found = 0; | 1639 | int found = 0; |
1485 | struct gfs2_bitmap *bi; | 1640 | struct gfs2_rbm rbm = { .rgd = rgd, .bi = rgd->rd_bits, .offset = 0 }; |
1486 | 1641 | ||
1487 | while (goal < rgd->rd_data) { | 1642 | while (1) { |
1488 | down_write(&sdp->sd_log_flush_lock); | 1643 | down_write(&sdp->sd_log_flush_lock); |
1489 | block = rgblk_search(rgd, goal, GFS2_BLKST_UNLINKED, &bi); | 1644 | error = gfs2_rbm_find(&rbm, GFS2_BLKST_UNLINKED, NULL, true); |
1490 | up_write(&sdp->sd_log_flush_lock); | 1645 | up_write(&sdp->sd_log_flush_lock); |
1491 | if (block == BFITNOENT) | 1646 | if (error == -ENOSPC) |
1647 | break; | ||
1648 | if (WARN_ON_ONCE(error)) | ||
1492 | break; | 1649 | break; |
1493 | 1650 | ||
1494 | block = gfs2_bi2rgd_blk(bi, block); | 1651 | block = gfs2_rbm_to_block(&rbm); |
1495 | /* rgblk_search can return a block < goal, so we need to | 1652 | if (gfs2_rbm_from_block(&rbm, block + 1)) |
1496 | keep it marching forward. */ | 1653 | break; |
1497 | no_addr = block + rgd->rd_data0; | 1654 | if (*last_unlinked != NO_BLOCK && block <= *last_unlinked) |
1498 | goal = max(block + 1, goal + 1); | ||
1499 | if (*last_unlinked != NO_BLOCK && no_addr <= *last_unlinked) | ||
1500 | continue; | 1655 | continue; |
1501 | if (no_addr == skip) | 1656 | if (block == skip) |
1502 | continue; | 1657 | continue; |
1503 | *last_unlinked = no_addr; | 1658 | *last_unlinked = block; |
1504 | 1659 | ||
1505 | error = gfs2_glock_get(sdp, no_addr, &gfs2_inode_glops, CREATE, &gl); | 1660 | error = gfs2_glock_get(sdp, block, &gfs2_inode_glops, CREATE, &gl); |
1506 | if (error) | 1661 | if (error) |
1507 | continue; | 1662 | continue; |
1508 | 1663 | ||
@@ -1692,105 +1847,6 @@ static unsigned char gfs2_get_block_type(struct gfs2_rgrpd *rgd, u64 block) | |||
1692 | return type; | 1847 | return type; |
1693 | } | 1848 | } |
1694 | 1849 | ||
1695 | /** | ||
1696 | * rgblk_search - find a block in @state | ||
1697 | * @rgd: the resource group descriptor | ||
1698 | * @goal: the goal block within the RG (start here to search for avail block) | ||
1699 | * @state: GFS2_BLKST_XXX the before-allocation state to find | ||
1700 | * @rbi: address of the pointer to the bitmap containing the block found | ||
1701 | * | ||
1702 | * Walk rgrp's bitmap to find bits that represent a block in @state. | ||
1703 | * | ||
1704 | * This function never fails, because we wouldn't call it unless we | ||
1705 | * know (from reservation results, etc.) that a block is available. | ||
1706 | * | ||
1707 | * Scope of @goal is just within rgrp, not the whole filesystem. | ||
1708 | * Scope of @returned block is just within bitmap, not the whole filesystem. | ||
1709 | * | ||
1710 | * Returns: the block number found relative to the bitmap rbi | ||
1711 | */ | ||
1712 | |||
1713 | static u32 rgblk_search(struct gfs2_rgrpd *rgd, u32 goal, unsigned char state, | ||
1714 | struct gfs2_bitmap **rbi) | ||
1715 | { | ||
1716 | struct gfs2_bitmap *bi = NULL; | ||
1717 | const u32 length = rgd->rd_length; | ||
1718 | u32 biblk = BFITNOENT; | ||
1719 | unsigned int buf, x; | ||
1720 | const u8 *buffer = NULL; | ||
1721 | |||
1722 | *rbi = NULL; | ||
1723 | /* Find bitmap block that contains bits for goal block */ | ||
1724 | for (buf = 0; buf < length; buf++) { | ||
1725 | bi = rgd->rd_bits + buf; | ||
1726 | /* Convert scope of "goal" from rgrp-wide to within found bit block */ | ||
1727 | if (goal < (bi->bi_start + bi->bi_len) * GFS2_NBBY) { | ||
1728 | goal -= bi->bi_start * GFS2_NBBY; | ||
1729 | goto do_search; | ||
1730 | } | ||
1731 | } | ||
1732 | buf = 0; | ||
1733 | goal = 0; | ||
1734 | |||
1735 | do_search: | ||
1736 | /* Search (up to entire) bitmap in this rgrp for allocatable block. | ||
1737 | "x <= length", instead of "x < length", because we typically start | ||
1738 | the search in the middle of a bit block, but if we can't find an | ||
1739 | allocatable block anywhere else, we want to be able wrap around and | ||
1740 | search in the first part of our first-searched bit block. */ | ||
1741 | for (x = 0; x <= length; x++) { | ||
1742 | bi = rgd->rd_bits + buf; | ||
1743 | |||
1744 | if (test_bit(GBF_FULL, &bi->bi_flags) && | ||
1745 | (state == GFS2_BLKST_FREE)) | ||
1746 | goto skip; | ||
1747 | |||
1748 | /* The GFS2_BLKST_UNLINKED state doesn't apply to the clone | ||
1749 | bitmaps, so we must search the originals for that. */ | ||
1750 | buffer = bi->bi_bh->b_data + bi->bi_offset; | ||
1751 | WARN_ON(!buffer_uptodate(bi->bi_bh)); | ||
1752 | if (state != GFS2_BLKST_UNLINKED && bi->bi_clone) | ||
1753 | buffer = bi->bi_clone + bi->bi_offset; | ||
1754 | |||
1755 | while (1) { | ||
1756 | struct gfs2_blkreserv *rs; | ||
1757 | u32 rgblk; | ||
1758 | |||
1759 | biblk = gfs2_bitfit(buffer, bi->bi_len, goal, state); | ||
1760 | if (biblk == BFITNOENT) | ||
1761 | break; | ||
1762 | /* Check if this block is reserved() */ | ||
1763 | rgblk = gfs2_bi2rgd_blk(bi, biblk); | ||
1764 | rs = rs_find(rgd, rgblk); | ||
1765 | if (rs == NULL) | ||
1766 | break; | ||
1767 | |||
1768 | BUG_ON(rs->rs_rbm.bi != bi); | ||
1769 | biblk = BFITNOENT; | ||
1770 | /* This should jump to the first block after the | ||
1771 | reservation. */ | ||
1772 | goal = rs->rs_rbm.offset + rs->rs_free; | ||
1773 | if (goal >= bi->bi_len * GFS2_NBBY) | ||
1774 | break; | ||
1775 | } | ||
1776 | if (biblk != BFITNOENT) | ||
1777 | break; | ||
1778 | |||
1779 | if ((goal == 0) && (state == GFS2_BLKST_FREE)) | ||
1780 | set_bit(GBF_FULL, &bi->bi_flags); | ||
1781 | |||
1782 | /* Try next bitmap block (wrap back to rgrp header if at end) */ | ||
1783 | skip: | ||
1784 | buf++; | ||
1785 | buf %= length; | ||
1786 | goal = 0; | ||
1787 | } | ||
1788 | |||
1789 | if (biblk != BFITNOENT) | ||
1790 | *rbi = bi; | ||
1791 | |||
1792 | return biblk; | ||
1793 | } | ||
1794 | 1850 | ||
1795 | /** | 1851 | /** |
1796 | * gfs2_alloc_extent - allocate an extent from a given bitmap | 1852 | * gfs2_alloc_extent - allocate an extent from a given bitmap |
@@ -1809,9 +1865,8 @@ static u64 gfs2_alloc_extent(const struct gfs2_rbm *rbm, bool dinode, | |||
1809 | struct gfs2_bitmap *bi = rbm->bi; | 1865 | struct gfs2_bitmap *bi = rbm->bi; |
1810 | u32 blk = rbm->offset; | 1866 | u32 blk = rbm->offset; |
1811 | const unsigned int elen = *n; | 1867 | const unsigned int elen = *n; |
1812 | u32 goal, rgblk; | 1868 | u32 goal; |
1813 | const u8 *buffer = NULL; | 1869 | const u8 *buffer = NULL; |
1814 | struct gfs2_blkreserv *rs; | ||
1815 | 1870 | ||
1816 | *n = 0; | 1871 | *n = 0; |
1817 | buffer = bi->bi_bh->b_data + bi->bi_offset; | 1872 | buffer = bi->bi_bh->b_data + bi->bi_offset; |
@@ -1824,10 +1879,6 @@ static u64 gfs2_alloc_extent(const struct gfs2_rbm *rbm, bool dinode, | |||
1824 | goal++; | 1879 | goal++; |
1825 | if (goal >= (bi->bi_len * GFS2_NBBY)) | 1880 | if (goal >= (bi->bi_len * GFS2_NBBY)) |
1826 | break; | 1881 | break; |
1827 | rgblk = gfs2_bi2rgd_blk(bi, goal); | ||
1828 | rs = rs_find(rgd, rgblk); | ||
1829 | if (rs) /* Oops, we bumped into someone's reservation */ | ||
1830 | break; | ||
1831 | if (gfs2_testbit(rgd, buffer, bi->bi_len, goal) != | 1882 | if (gfs2_testbit(rgd, buffer, bi->bi_len, goal) != |
1832 | GFS2_BLKST_FREE) | 1883 | GFS2_BLKST_FREE) |
1833 | break; | 1884 | break; |
@@ -1933,46 +1984,41 @@ static void gfs2_rgrp_error(struct gfs2_rgrpd *rgd) | |||
1933 | } | 1984 | } |
1934 | 1985 | ||
1935 | /** | 1986 | /** |
1936 | * claim_reserved_blks - Claim previously reserved blocks | 1987 | * gfs2_adjust_reservation - Adjust (or remove) a reservation after allocation |
1937 | * @ip: the inode that's claiming the reservation | 1988 | * @ip: The inode we have just allocated blocks for |
1938 | * @dinode: 1 if this block is a dinode block, otherwise data block | 1989 | * @rbm: The start of the allocated blocks |
1939 | * @nblocks: desired extent length | 1990 | * @len: The extent length |
1940 | * | 1991 | * |
1941 | * Lay claim to previously reserved blocks. | 1992 | * Adjusts a reservation after an allocation has taken place. If the |
1942 | * Returns: Starting block number of the blocks claimed. | 1993 | * reservation does not match the allocation, or if it is now empty |
1943 | * Sets *nblocks to the actual extent length allocated. | 1994 | * then it is removed. |
1944 | */ | 1995 | */ |
1945 | static u64 claim_reserved_blks(struct gfs2_inode *ip, bool dinode, | 1996 | |
1946 | unsigned int *nblocks) | 1997 | static void gfs2_adjust_reservation(struct gfs2_inode *ip, |
1998 | const struct gfs2_rbm *rbm, unsigned len) | ||
1947 | { | 1999 | { |
1948 | struct gfs2_blkreserv *rs = ip->i_res; | 2000 | struct gfs2_blkreserv *rs = ip->i_res; |
1949 | struct gfs2_rgrpd *rgd = rs->rs_rbm.rgd; | 2001 | struct gfs2_rgrpd *rgd = rbm->rgd; |
1950 | struct gfs2_bitmap *bi; | 2002 | unsigned rlen; |
1951 | u64 start_block = gfs2_rbm_to_block(&rs->rs_rbm); | 2003 | u64 block; |
1952 | const unsigned int elen = *nblocks; | 2004 | int ret; |
1953 | |||
1954 | bi = rs->rs_rbm.bi; | ||
1955 | gfs2_trans_add_bh(rgd->rd_gl, bi->bi_bh, 1); | ||
1956 | 2005 | ||
1957 | for (*nblocks = 0; *nblocks < elen && rs->rs_free; (*nblocks)++) { | 2006 | spin_lock(&rgd->rd_rsspin); |
1958 | if (gfs2_testbit(rgd, bi->bi_bh->b_data + bi->bi_offset, | 2007 | if (gfs2_rs_active(rs)) { |
1959 | bi->bi_len, rs->rs_rbm.offset) != GFS2_BLKST_FREE) | 2008 | if (gfs2_rbm_eq(&rs->rs_rbm, rbm)) { |
1960 | break; | 2009 | block = gfs2_rbm_to_block(rbm); |
1961 | gfs2_setbit(rgd, bi->bi_clone, bi, rs->rs_rbm.offset, | 2010 | ret = gfs2_rbm_from_block(&rs->rs_rbm, block + len); |
1962 | dinode ? GFS2_BLKST_DINODE : GFS2_BLKST_USED); | 2011 | rlen = min(rs->rs_free, len); |
1963 | rs->rs_rbm.offset++; | 2012 | rs->rs_free -= rlen; |
1964 | rs->rs_free--; | 2013 | rgd->rd_reserved -= rlen; |
1965 | 2014 | trace_gfs2_rs(ip, rs, TRACE_RS_CLAIM); | |
1966 | BUG_ON(!rgd->rd_reserved); | 2015 | if (rs->rs_free && !ret) |
1967 | rgd->rd_reserved--; | 2016 | goto out; |
1968 | dinode = false; | 2017 | } |
2018 | __rs_deltree(ip, rs); | ||
1969 | } | 2019 | } |
1970 | 2020 | out: | |
1971 | trace_gfs2_rs(ip, rs, TRACE_RS_CLAIM); | 2021 | spin_unlock(&rgd->rd_rsspin); |
1972 | if (!rs->rs_free || *nblocks != elen) | ||
1973 | gfs2_rs_deltree(ip, rs); | ||
1974 | |||
1975 | return start_block; | ||
1976 | } | 2022 | } |
1977 | 2023 | ||
1978 | /** | 2024 | /** |
@@ -1993,36 +2039,30 @@ int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *nblocks, | |||
1993 | struct buffer_head *dibh; | 2039 | struct buffer_head *dibh; |
1994 | struct gfs2_rbm rbm = { .rgd = ip->i_rgd, }; | 2040 | struct gfs2_rbm rbm = { .rgd = ip->i_rgd, }; |
1995 | unsigned int ndata; | 2041 | unsigned int ndata; |
1996 | u32 goal; /* block, within the rgrp scope */ | 2042 | u64 goal; |
1997 | u64 block; /* block, within the file system scope */ | 2043 | u64 block; /* block, within the file system scope */ |
1998 | int error; | 2044 | int error; |
1999 | 2045 | ||
2000 | /* If we have a reservation, claim blocks from it. */ | 2046 | if (gfs2_rs_active(ip->i_res)) |
2001 | if (gfs2_rs_active(ip->i_res)) { | 2047 | goal = gfs2_rbm_to_block(&ip->i_res->rs_rbm); |
2002 | BUG_ON(!ip->i_res->rs_free); | 2048 | else if (!dinode && rgrp_contains_block(rbm.rgd, ip->i_goal)) |
2003 | rbm.rgd = ip->i_res->rs_rbm.rgd; | 2049 | goal = ip->i_goal; |
2004 | block = claim_reserved_blks(ip, dinode, nblocks); | ||
2005 | if (*nblocks) | ||
2006 | goto found_blocks; | ||
2007 | } | ||
2008 | |||
2009 | if (!dinode && rgrp_contains_block(rbm.rgd, ip->i_goal)) | ||
2010 | goal = ip->i_goal - rbm.rgd->rd_data0; | ||
2011 | else | 2050 | else |
2012 | goal = rbm.rgd->rd_last_alloc; | 2051 | goal = rbm.rgd->rd_last_alloc + rbm.rgd->rd_data0; |
2013 | 2052 | ||
2014 | rbm.offset = rgblk_search(rbm.rgd, goal, GFS2_BLKST_FREE, &rbm.bi); | 2053 | gfs2_rbm_from_block(&rbm, goal); |
2054 | error = gfs2_rbm_find(&rbm, GFS2_BLKST_FREE, ip, false); | ||
2015 | 2055 | ||
2016 | /* Since all blocks are reserved in advance, this shouldn't happen */ | 2056 | /* Since all blocks are reserved in advance, this shouldn't happen */ |
2017 | if (rbm.offset == BFITNOENT) { | 2057 | if (error) { |
2018 | printk(KERN_WARNING "BFITNOENT, nblocks=%u\n", *nblocks); | 2058 | fs_warn(sdp, "error=%d, nblocks=%u, full=%d\n", error, *nblocks, |
2019 | printk(KERN_WARNING "FULL=%d\n", | 2059 | test_bit(GBF_FULL, &rbm.rgd->rd_bits->bi_flags)); |
2020 | test_bit(GBF_FULL, &rbm.rgd->rd_bits->bi_flags)); | ||
2021 | goto rgrp_error; | 2060 | goto rgrp_error; |
2022 | } | 2061 | } |
2023 | 2062 | ||
2024 | block = gfs2_alloc_extent(&rbm, dinode, nblocks); | 2063 | block = gfs2_alloc_extent(&rbm, dinode, nblocks); |
2025 | found_blocks: | 2064 | if (gfs2_rs_active(ip->i_res)) |
2065 | gfs2_adjust_reservation(ip, &rbm, *nblocks); | ||
2026 | ndata = *nblocks; | 2066 | ndata = *nblocks; |
2027 | if (dinode) | 2067 | if (dinode) |
2028 | ndata--; | 2068 | ndata--; |