diff options
Diffstat (limited to 'fs/ocfs2/suballoc.c')
-rw-r--r-- | fs/ocfs2/suballoc.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/fs/ocfs2/suballoc.c b/fs/ocfs2/suballoc.c index a69628603e18..487f00c45f84 100644 --- a/fs/ocfs2/suballoc.c +++ b/fs/ocfs2/suballoc.c | |||
@@ -1618,8 +1618,41 @@ bail: | |||
1618 | return status; | 1618 | return status; |
1619 | } | 1619 | } |
1620 | 1620 | ||
1621 | static void ocfs2_init_inode_ac_group(struct inode *dir, | ||
1622 | struct buffer_head *parent_fe_bh, | ||
1623 | struct ocfs2_alloc_context *ac) | ||
1624 | { | ||
1625 | struct ocfs2_dinode *fe = (struct ocfs2_dinode *)parent_fe_bh->b_data; | ||
1626 | /* | ||
1627 | * Try to allocate inodes from some specific group. | ||
1628 | * | ||
1629 | * If the parent dir has recorded the last group used in allocation, | ||
1630 | * cool, use it. Otherwise if we try to allocate new inode from the | ||
1631 | * same slot the parent dir belongs to, use the same chunk. | ||
1632 | * | ||
1633 | * We are very careful here to avoid the mistake of setting | ||
1634 | * ac_last_group to a group descriptor from a different (unlocked) slot. | ||
1635 | */ | ||
1636 | if (OCFS2_I(dir)->ip_last_used_group && | ||
1637 | OCFS2_I(dir)->ip_last_used_slot == ac->ac_alloc_slot) | ||
1638 | ac->ac_last_group = OCFS2_I(dir)->ip_last_used_group; | ||
1639 | else if (le16_to_cpu(fe->i_suballoc_slot) == ac->ac_alloc_slot) | ||
1640 | ac->ac_last_group = ocfs2_which_suballoc_group( | ||
1641 | le64_to_cpu(fe->i_blkno), | ||
1642 | le16_to_cpu(fe->i_suballoc_bit)); | ||
1643 | } | ||
1644 | |||
1645 | static inline void ocfs2_save_inode_ac_group(struct inode *dir, | ||
1646 | struct ocfs2_alloc_context *ac) | ||
1647 | { | ||
1648 | OCFS2_I(dir)->ip_last_used_group = ac->ac_last_group; | ||
1649 | OCFS2_I(dir)->ip_last_used_slot = ac->ac_alloc_slot; | ||
1650 | } | ||
1651 | |||
1621 | int ocfs2_claim_new_inode(struct ocfs2_super *osb, | 1652 | int ocfs2_claim_new_inode(struct ocfs2_super *osb, |
1622 | handle_t *handle, | 1653 | handle_t *handle, |
1654 | struct inode *dir, | ||
1655 | struct buffer_head *parent_fe_bh, | ||
1623 | struct ocfs2_alloc_context *ac, | 1656 | struct ocfs2_alloc_context *ac, |
1624 | u16 *suballoc_bit, | 1657 | u16 *suballoc_bit, |
1625 | u64 *fe_blkno) | 1658 | u64 *fe_blkno) |
@@ -1635,6 +1668,8 @@ int ocfs2_claim_new_inode(struct ocfs2_super *osb, | |||
1635 | BUG_ON(ac->ac_bits_wanted != 1); | 1668 | BUG_ON(ac->ac_bits_wanted != 1); |
1636 | BUG_ON(ac->ac_which != OCFS2_AC_USE_INODE); | 1669 | BUG_ON(ac->ac_which != OCFS2_AC_USE_INODE); |
1637 | 1670 | ||
1671 | ocfs2_init_inode_ac_group(dir, parent_fe_bh, ac); | ||
1672 | |||
1638 | status = ocfs2_claim_suballoc_bits(osb, | 1673 | status = ocfs2_claim_suballoc_bits(osb, |
1639 | ac, | 1674 | ac, |
1640 | handle, | 1675 | handle, |
@@ -1653,6 +1688,7 @@ int ocfs2_claim_new_inode(struct ocfs2_super *osb, | |||
1653 | 1688 | ||
1654 | *fe_blkno = bg_blkno + (u64) (*suballoc_bit); | 1689 | *fe_blkno = bg_blkno + (u64) (*suballoc_bit); |
1655 | ac->ac_bits_given++; | 1690 | ac->ac_bits_given++; |
1691 | ocfs2_save_inode_ac_group(dir, ac); | ||
1656 | status = 0; | 1692 | status = 0; |
1657 | bail: | 1693 | bail: |
1658 | mlog_exit(status); | 1694 | mlog_exit(status); |