| @@ -84,6 +84,7 @@ EXPORT_SYMBOL(journal_force_commit); · 83 unmodified lines |
| 84 | | 84 | |
| 85 | static int journal_convert_superblock_v1(journal_t *, journal_superblock_t *); | 85 | static int journal_convert_superblock_v1(journal_t *, journal_superblock_t *); |
| 86 | static void __journal_abort_soft (journal_t *journal, int errno); | 86 | static void __journal_abort_soft (journal_t *journal, int errno); |
| | 87 | static int journal_create_jbd_slab(size_t slab_size); |
| 87 | | 88 | |
| 88 | /* | 89 | /* |
| 89 | * Helper function used to manage commit timeouts | 90 | * Helper function used to manage commit timeouts |
| @@ -328,10 +329,10 @@ repeat: · 238 unmodified lines |
| 328 | char *tmp; | 329 | char *tmp; |
| 329 | | 330 | |
| 330 | jbd_unlock_bh_state(bh_in); | 331 | jbd_unlock_bh_state(bh_in); |
| 331 | tmp = jbd_rep_kmalloc(bh_in->b_size, GFP_NOFS); | 332 | tmp = jbd_slab_alloc(bh_in->b_size, GFP_NOFS); |
| 332 | jbd_lock_bh_state(bh_in); | 333 | jbd_lock_bh_state(bh_in); |
| 333 | if (jh_in->b_frozen_data) { | 334 | if (jh_in->b_frozen_data) { |
| 334 | kfree(tmp); | 335 | jbd_slab_free(tmp, bh_in->b_size); |
| 335 | goto repeat; | 336 | goto repeat; |
| 336 | } | 337 | } |
| 337 | | 338 | |
| @@ -1069,17 +1070,17 @@ static int load_superblock(journal_t *journal) · 731 unmodified lines |
| 1069 | int journal_load(journal_t *journal) | 1070 | int journal_load(journal_t *journal) |
| 1070 | { | 1071 | { |
| 1071 | int err; | 1072 | int err; |
| | 1073 | journal_superblock_t *sb; |
| 1072 | | 1074 | |
| 1073 | err = load_superblock(journal); | 1075 | err = load_superblock(journal); |
| 1074 | if (err) | 1076 | if (err) |
| 1075 | return err; | 1077 | return err; |
| 1076 | | 1078 | |
| | 1079 | sb = journal->j_superblock; |
| 1077 | /* If this is a V2 superblock, then we have to check the | 1080 | /* If this is a V2 superblock, then we have to check the |
| 1078 | * features flags on it. */ | 1081 | * features flags on it. */ |
| 1079 | | 1082 | |
| 1080 | if (journal->j_format_version >= 2) { | 1083 | if (journal->j_format_version >= 2) { |
| 1081 | journal_superblock_t *sb = journal->j_superblock; | | |
| 1082 | | | |
| 1083 | if ((sb->s_feature_ro_compat & | 1084 | if ((sb->s_feature_ro_compat & |
| 1084 | ~cpu_to_be32(JFS_KNOWN_ROCOMPAT_FEATURES)) || | 1085 | ~cpu_to_be32(JFS_KNOWN_ROCOMPAT_FEATURES)) || |
| 1085 | (sb->s_feature_incompat & | 1086 | (sb->s_feature_incompat & |
| @@ -1090,6 +1091,13 @@ int journal_load(journal_t *journal) · 4 unmodified lines |
| 1090 | } | 1091 | } |
| 1091 | } | 1092 | } |
| 1092 | | 1093 | |
| | 1094 | /* |
| | 1095 | * Create a slab for this blocksize |
| | 1096 | */ |
| | 1097 | err = journal_create_jbd_slab(cpu_to_be32(sb->s_blocksize)); |
| | 1098 | if (err) |
| | 1099 | return err; |
| | 1100 | |
| 1093 | /* Let the recovery code check whether it needs to recover any | 1101 | /* Let the recovery code check whether it needs to recover any |
| 1094 | * data from the journal. */ | 1102 | * data from the journal. */ |
| 1095 | if (journal_recover(journal)) | 1103 | if (journal_recover(journal)) |
| @@ -1611,6 +1619,77 @@ void * __jbd_kmalloc (const char *where, size_t size, gfp_t flags, int retry) · 515 unmodified lines |
| 1611 | return kmalloc(size, flags | (retry ? __GFP_NOFAIL : 0)); | 1619 | return kmalloc(size, flags | (retry ? __GFP_NOFAIL : 0)); |
| 1612 | } | 1620 | } |
| 1613 | | 1621 | |
| | 1622 | /* |
| | 1623 | * jbd slab management: create 1k, 2k, 4k, 8k slabs as needed |
| | 1624 | * and allocate frozen and commit buffers from these slabs. |
| | 1625 | * |
| | 1626 | * Reason for doing this is to avoid, SLAB_DEBUG - since it could |
| | 1627 | * cause bh to cross page boundary. |
| | 1628 | */ |
| | 1629 | |
| | 1630 | #define JBD_MAX_SLABS 5 |
| | 1631 | #define JBD_SLAB_INDEX(size) (size >> 11) |
| | 1632 | |
| | 1633 | static kmem_cache_t *jbd_slab[JBD_MAX_SLABS]; |
| | 1634 | static const char *jbd_slab_names[JBD_MAX_SLABS] = { |
| | 1635 | "jbd_1k", "jbd_2k", "jbd_4k", NULL, "jbd_8k" |
| | 1636 | }; |
| | 1637 | |
| | 1638 | static void journal_destroy_jbd_slabs(void) |
| | 1639 | { |
| | 1640 | int i; |
| | 1641 | |
| | 1642 | for (i = 0; i < JBD_MAX_SLABS; i++) { |
| | 1643 | if (jbd_slab[i]) |
| | 1644 | kmem_cache_destroy(jbd_slab[i]); |
| | 1645 | jbd_slab[i] = NULL; |
| | 1646 | } |
| | 1647 | } |
| | 1648 | |
| | 1649 | static int journal_create_jbd_slab(size_t slab_size) |
| | 1650 | { |
| | 1651 | int i = JBD_SLAB_INDEX(slab_size); |
| | 1652 | |
| | 1653 | BUG_ON(i >= JBD_MAX_SLABS); |
| | 1654 | |
| | 1655 | /* |
| | 1656 | * Check if we already have a slab created for this size |
| | 1657 | */ |
| | 1658 | if (jbd_slab[i]) |
| | 1659 | return 0; |
| | 1660 | |
| | 1661 | /* |
| | 1662 | * Create a slab and force alignment to be same as slabsize - |
| | 1663 | * this will make sure that allocations won't cross the page |
| | 1664 | * boundary. |
| | 1665 | */ |
| | 1666 | jbd_slab[i] = kmem_cache_create(jbd_slab_names[i], |
| | 1667 | slab_size, slab_size, 0, NULL, NULL); |
| | 1668 | if (!jbd_slab[i]) { |
| | 1669 | printk(KERN_EMERG "JBD: no memory for jbd_slab cache\n"); |
| | 1670 | return -ENOMEM; |
| | 1671 | } |
| | 1672 | return 0; |
| | 1673 | } |
| | 1674 | |
| | 1675 | void * jbd_slab_alloc(size_t size, gfp_t flags) |
| | 1676 | { |
| | 1677 | int idx; |
| | 1678 | |
| | 1679 | idx = JBD_SLAB_INDEX(size); |
| | 1680 | BUG_ON(jbd_slab[idx] == NULL); |
| | 1681 | return kmem_cache_alloc(jbd_slab[idx], flags | __GFP_NOFAIL); |
| | 1682 | } |
| | 1683 | |
| | 1684 | void jbd_slab_free(void *ptr, size_t size) |
| | 1685 | { |
| | 1686 | int idx; |
| | 1687 | |
| | 1688 | idx = JBD_SLAB_INDEX(size); |
| | 1689 | BUG_ON(jbd_slab[idx] == NULL); |
| | 1690 | kmem_cache_free(jbd_slab[idx], ptr); |
| | 1691 | } |
| | 1692 | |
| 1614 | /* | 1693 | /* |
| 1615 | * Journal_head storage management | 1694 | * Journal_head storage management |
| 1616 | */ | 1695 | */ |
| @@ -1799,13 +1878,13 @@ static void __journal_remove_journal_head(struct buffer_head *bh) · 182 unmodified lines |
| 1799 | printk(KERN_WARNING "%s: freeing " | 1878 | printk(KERN_WARNING "%s: freeing " |
| 1800 | "b_frozen_data\n", | 1879 | "b_frozen_data\n", |
| 1801 | __FUNCTION__); | 1880 | __FUNCTION__); |
| 1802 | kfree(jh->b_frozen_data); | 1881 | jbd_slab_free(jh->b_frozen_data, bh->b_size); |
| 1803 | } | 1882 | } |
| 1804 | if (jh->b_committed_data) { | 1883 | if (jh->b_committed_data) { |
| 1805 | printk(KERN_WARNING "%s: freeing " | 1884 | printk(KERN_WARNING "%s: freeing " |
| 1806 | "b_committed_data\n", | 1885 | "b_committed_data\n", |
| 1807 | __FUNCTION__); | 1886 | __FUNCTION__); |
| 1808 | kfree(jh->b_committed_data); | 1887 | jbd_slab_free(jh->b_committed_data, bh->b_size); |
| 1809 | } | 1888 | } |
| 1810 | bh->b_private = NULL; | 1889 | bh->b_private = NULL; |
| 1811 | jh->b_bh = NULL; /* debug, really */ | 1890 | jh->b_bh = NULL; /* debug, really */ |
| @@ -1961,6 +2040,7 @@ static void journal_destroy_caches(void) · 149 unmodified lines |
| 1961 | journal_destroy_revoke_caches(); | 2040 | journal_destroy_revoke_caches(); |
| 1962 | journal_destroy_journal_head_cache(); | 2041 | journal_destroy_journal_head_cache(); |
| 1963 | journal_destroy_handle_cache(); | 2042 | journal_destroy_handle_cache(); |
| | 2043 | journal_destroy_jbd_slabs(); |
| 1964 | } | 2044 | } |
| 1965 | | 2045 | |
| 1966 | static int __init journal_init(void) | 2046 | static int __init journal_init(void) |