diff options
-rw-r--r-- | fs/ocfs2/inode.c | 2 | ||||
-rw-r--r-- | fs/ocfs2/inode.h | 4 | ||||
-rw-r--r-- | fs/ocfs2/namei.c | 4 | ||||
-rw-r--r-- | fs/ocfs2/suballoc.c | 36 | ||||
-rw-r--r-- | fs/ocfs2/suballoc.h | 2 |
5 files changed, 46 insertions, 2 deletions
diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c index f1f77b2f5947..4a88bce35079 100644 --- a/fs/ocfs2/inode.c +++ b/fs/ocfs2/inode.c | |||
@@ -352,6 +352,8 @@ void ocfs2_populate_inode(struct inode *inode, struct ocfs2_dinode *fe, | |||
352 | 352 | ||
353 | ocfs2_set_inode_flags(inode); | 353 | ocfs2_set_inode_flags(inode); |
354 | 354 | ||
355 | OCFS2_I(inode)->ip_last_used_slot = 0; | ||
356 | OCFS2_I(inode)->ip_last_used_group = 0; | ||
355 | mlog_exit_void(); | 357 | mlog_exit_void(); |
356 | } | 358 | } |
357 | 359 | ||
diff --git a/fs/ocfs2/inode.h b/fs/ocfs2/inode.h index eb3c302b38d3..e1978acbf65e 100644 --- a/fs/ocfs2/inode.h +++ b/fs/ocfs2/inode.h | |||
@@ -72,6 +72,10 @@ struct ocfs2_inode_info | |||
72 | 72 | ||
73 | struct inode vfs_inode; | 73 | struct inode vfs_inode; |
74 | struct jbd2_inode ip_jinode; | 74 | struct jbd2_inode ip_jinode; |
75 | |||
76 | /* Only valid if the inode is the dir. */ | ||
77 | u32 ip_last_used_slot; | ||
78 | u64 ip_last_used_group; | ||
75 | }; | 79 | }; |
76 | 80 | ||
77 | /* | 81 | /* |
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index 58c318d2f061..2220f93f668b 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c | |||
@@ -485,8 +485,8 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb, | |||
485 | 485 | ||
486 | *new_fe_bh = NULL; | 486 | *new_fe_bh = NULL; |
487 | 487 | ||
488 | status = ocfs2_claim_new_inode(osb, handle, inode_ac, &suballoc_bit, | 488 | status = ocfs2_claim_new_inode(osb, handle, dir, parent_fe_bh, |
489 | &fe_blkno); | 489 | inode_ac, &suballoc_bit, &fe_blkno); |
490 | if (status < 0) { | 490 | if (status < 0) { |
491 | mlog_errno(status); | 491 | mlog_errno(status); |
492 | goto leave; | 492 | goto leave; |
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); |
diff --git a/fs/ocfs2/suballoc.h b/fs/ocfs2/suballoc.h index e3c13c77f9e8..ea85a4c8b4b1 100644 --- a/fs/ocfs2/suballoc.h +++ b/fs/ocfs2/suballoc.h | |||
@@ -88,6 +88,8 @@ int ocfs2_claim_metadata(struct ocfs2_super *osb, | |||
88 | u64 *blkno_start); | 88 | u64 *blkno_start); |
89 | int ocfs2_claim_new_inode(struct ocfs2_super *osb, | 89 | int ocfs2_claim_new_inode(struct ocfs2_super *osb, |
90 | handle_t *handle, | 90 | handle_t *handle, |
91 | struct inode *dir, | ||
92 | struct buffer_head *parent_fe_bh, | ||
91 | struct ocfs2_alloc_context *ac, | 93 | struct ocfs2_alloc_context *ac, |
92 | u16 *suballoc_bit, | 94 | u16 *suballoc_bit, |
93 | u64 *fe_blkno); | 95 | u64 *fe_blkno); |