diff options
| -rw-r--r-- | fs/jbd/commit.c | 6 | ||||
| -rw-r--r-- | fs/jbd/journal.c | 88 | ||||
| -rw-r--r-- | fs/jbd/transaction.c | 8 | ||||
| -rw-r--r-- | include/linux/jbd.h | 13 |
4 files changed, 21 insertions, 94 deletions
diff --git a/fs/jbd/commit.c b/fs/jbd/commit.c index a003d50edcdb..a263d82761df 100644 --- a/fs/jbd/commit.c +++ b/fs/jbd/commit.c | |||
| @@ -375,7 +375,7 @@ void journal_commit_transaction(journal_t *journal) | |||
| 375 | struct buffer_head *bh = jh2bh(jh); | 375 | struct buffer_head *bh = jh2bh(jh); |
| 376 | 376 | ||
| 377 | jbd_lock_bh_state(bh); | 377 | jbd_lock_bh_state(bh); |
| 378 | jbd_slab_free(jh->b_committed_data, bh->b_size); | 378 | jbd_free(jh->b_committed_data, bh->b_size); |
| 379 | jh->b_committed_data = NULL; | 379 | jh->b_committed_data = NULL; |
| 380 | jbd_unlock_bh_state(bh); | 380 | jbd_unlock_bh_state(bh); |
| 381 | } | 381 | } |
| @@ -792,14 +792,14 @@ restart_loop: | |||
| 792 | * Otherwise, we can just throw away the frozen data now. | 792 | * Otherwise, we can just throw away the frozen data now. |
| 793 | */ | 793 | */ |
| 794 | if (jh->b_committed_data) { | 794 | if (jh->b_committed_data) { |
| 795 | jbd_slab_free(jh->b_committed_data, bh->b_size); | 795 | jbd_free(jh->b_committed_data, bh->b_size); |
| 796 | jh->b_committed_data = NULL; | 796 | jh->b_committed_data = NULL; |
| 797 | if (jh->b_frozen_data) { | 797 | if (jh->b_frozen_data) { |
| 798 | jh->b_committed_data = jh->b_frozen_data; | 798 | jh->b_committed_data = jh->b_frozen_data; |
| 799 | jh->b_frozen_data = NULL; | 799 | jh->b_frozen_data = NULL; |
| 800 | } | 800 | } |
| 801 | } else if (jh->b_frozen_data) { | 801 | } else if (jh->b_frozen_data) { |
| 802 | jbd_slab_free(jh->b_frozen_data, bh->b_size); | 802 | jbd_free(jh->b_frozen_data, bh->b_size); |
| 803 | jh->b_frozen_data = NULL; | 803 | jh->b_frozen_data = NULL; |
| 804 | } | 804 | } |
| 805 | 805 | ||
diff --git a/fs/jbd/journal.c b/fs/jbd/journal.c index a6be78c05dce..7edf3fdfdadd 100644 --- a/fs/jbd/journal.c +++ b/fs/jbd/journal.c | |||
| @@ -83,7 +83,6 @@ EXPORT_SYMBOL(journal_force_commit); | |||
| 83 | 83 | ||
| 84 | static int journal_convert_superblock_v1(journal_t *, journal_superblock_t *); | 84 | static int journal_convert_superblock_v1(journal_t *, journal_superblock_t *); |
| 85 | static void __journal_abort_soft (journal_t *journal, int errno); | 85 | static void __journal_abort_soft (journal_t *journal, int errno); |
| 86 | static int journal_create_jbd_slab(size_t slab_size); | ||
| 87 | 86 | ||
| 88 | /* | 87 | /* |
| 89 | * Helper function used to manage commit timeouts | 88 | * Helper function used to manage commit timeouts |
| @@ -334,10 +333,10 @@ repeat: | |||
| 334 | char *tmp; | 333 | char *tmp; |
| 335 | 334 | ||
| 336 | jbd_unlock_bh_state(bh_in); | 335 | jbd_unlock_bh_state(bh_in); |
| 337 | tmp = jbd_slab_alloc(bh_in->b_size, GFP_NOFS); | 336 | tmp = jbd_alloc(bh_in->b_size, GFP_NOFS); |
| 338 | jbd_lock_bh_state(bh_in); | 337 | jbd_lock_bh_state(bh_in); |
| 339 | if (jh_in->b_frozen_data) { | 338 | if (jh_in->b_frozen_data) { |
| 340 | jbd_slab_free(tmp, bh_in->b_size); | 339 | jbd_free(tmp, bh_in->b_size); |
| 341 | goto repeat; | 340 | goto repeat; |
| 342 | } | 341 | } |
| 343 | 342 | ||
| @@ -1095,13 +1094,6 @@ int journal_load(journal_t *journal) | |||
| 1095 | } | 1094 | } |
| 1096 | } | 1095 | } |
| 1097 | 1096 | ||
| 1098 | /* | ||
| 1099 | * Create a slab for this blocksize | ||
| 1100 | */ | ||
| 1101 | err = journal_create_jbd_slab(be32_to_cpu(sb->s_blocksize)); | ||
| 1102 | if (err) | ||
| 1103 | return err; | ||
| 1104 | |||
| 1105 | /* Let the recovery code check whether it needs to recover any | 1097 | /* Let the recovery code check whether it needs to recover any |
| 1106 | * data from the journal. */ | 1098 | * data from the journal. */ |
| 1107 | if (journal_recover(journal)) | 1099 | if (journal_recover(journal)) |
| @@ -1624,77 +1616,6 @@ void * __jbd_kmalloc (const char *where, size_t size, gfp_t flags, int retry) | |||
| 1624 | } | 1616 | } |
| 1625 | 1617 | ||
| 1626 | /* | 1618 | /* |
| 1627 | * jbd slab management: create 1k, 2k, 4k, 8k slabs as needed | ||
| 1628 | * and allocate frozen and commit buffers from these slabs. | ||
| 1629 | * | ||
| 1630 | * Reason for doing this is to avoid, SLAB_DEBUG - since it could | ||
| 1631 | * cause bh to cross page boundary. | ||
| 1632 | */ | ||
| 1633 | |||
| 1634 | #define JBD_MAX_SLABS 5 | ||
| 1635 | #define JBD_SLAB_INDEX(size) (size >> 11) | ||
| 1636 | |||
| 1637 | static struct kmem_cache *jbd_slab[JBD_MAX_SLABS]; | ||
| 1638 | static const char *jbd_slab_names[JBD_MAX_SLABS] = { | ||
| 1639 | "jbd_1k", "jbd_2k", "jbd_4k", NULL, "jbd_8k" | ||
| 1640 | }; | ||
| 1641 | |||
| 1642 | static void journal_destroy_jbd_slabs(void) | ||
| 1643 | { | ||
| 1644 | int i; | ||
| 1645 | |||
| 1646 | for (i = 0; i < JBD_MAX_SLABS; i++) { | ||
| 1647 | if (jbd_slab[i]) | ||
| 1648 | kmem_cache_destroy(jbd_slab[i]); | ||
| 1649 | jbd_slab[i] = NULL; | ||
| 1650 | } | ||
| 1651 | } | ||
| 1652 | |||
| 1653 | static int journal_create_jbd_slab(size_t slab_size) | ||
| 1654 | { | ||
| 1655 | int i = JBD_SLAB_INDEX(slab_size); | ||
| 1656 | |||
| 1657 | BUG_ON(i >= JBD_MAX_SLABS); | ||
| 1658 | |||
| 1659 | /* | ||
| 1660 | * Check if we already have a slab created for this size | ||
| 1661 | */ | ||
| 1662 | if (jbd_slab[i]) | ||
| 1663 | return 0; | ||
| 1664 | |||
| 1665 | /* | ||
| 1666 | * Create a slab and force alignment to be same as slabsize - | ||
| 1667 | * this will make sure that allocations won't cross the page | ||
| 1668 | * boundary. | ||
| 1669 | */ | ||
| 1670 | jbd_slab[i] = kmem_cache_create(jbd_slab_names[i], | ||
| 1671 | slab_size, slab_size, 0, NULL); | ||
| 1672 | if (!jbd_slab[i]) { | ||
| 1673 | printk(KERN_EMERG "JBD: no memory for jbd_slab cache\n"); | ||
| 1674 | return -ENOMEM; | ||
| 1675 | } | ||
| 1676 | return 0; | ||
| 1677 | } | ||
| 1678 | |||
| 1679 | void * jbd_slab_alloc(size_t size, gfp_t flags) | ||
| 1680 | { | ||
| 1681 | int idx; | ||
| 1682 | |||
| 1683 | idx = JBD_SLAB_INDEX(size); | ||
| 1684 | BUG_ON(jbd_slab[idx] == NULL); | ||
| 1685 | return kmem_cache_alloc(jbd_slab[idx], flags | __GFP_NOFAIL); | ||
| 1686 | } | ||
| 1687 | |||
| 1688 | void jbd_slab_free(void *ptr, size_t size) | ||
| 1689 | { | ||
| 1690 | int idx; | ||
| 1691 | |||
| 1692 | idx = JBD_SLAB_INDEX(size); | ||
| 1693 | BUG_ON(jbd_slab[idx] == NULL); | ||
| 1694 | kmem_cache_free(jbd_slab[idx], ptr); | ||
| 1695 | } | ||
| 1696 | |||
| 1697 | /* | ||
| 1698 | * Journal_head storage management | 1619 | * Journal_head storage management |
| 1699 | */ | 1620 | */ |
| 1700 | static struct kmem_cache *journal_head_cache; | 1621 | static struct kmem_cache *journal_head_cache; |
| @@ -1881,13 +1802,13 @@ static void __journal_remove_journal_head(struct buffer_head *bh) | |||
| 1881 | printk(KERN_WARNING "%s: freeing " | 1802 | printk(KERN_WARNING "%s: freeing " |
| 1882 | "b_frozen_data\n", | 1803 | "b_frozen_data\n", |
| 1883 | __FUNCTION__); | 1804 | __FUNCTION__); |
| 1884 | jbd_slab_free(jh->b_frozen_data, bh->b_size); | 1805 | jbd_free(jh->b_frozen_data, bh->b_size); |
| 1885 | } | 1806 | } |
| 1886 | if (jh->b_committed_data) { | 1807 | if (jh->b_committed_data) { |
| 1887 | printk(KERN_WARNING "%s: freeing " | 1808 | printk(KERN_WARNING "%s: freeing " |
| 1888 | "b_committed_data\n", | 1809 | "b_committed_data\n", |
| 1889 | __FUNCTION__); | 1810 | __FUNCTION__); |
| 1890 | jbd_slab_free(jh->b_committed_data, bh->b_size); | 1811 | jbd_free(jh->b_committed_data, bh->b_size); |
| 1891 | } | 1812 | } |
| 1892 | bh->b_private = NULL; | 1813 | bh->b_private = NULL; |
| 1893 | jh->b_bh = NULL; /* debug, really */ | 1814 | jh->b_bh = NULL; /* debug, really */ |
| @@ -2042,7 +1963,6 @@ static void journal_destroy_caches(void) | |||
| 2042 | journal_destroy_revoke_caches(); | 1963 | journal_destroy_revoke_caches(); |
| 2043 | journal_destroy_journal_head_cache(); | 1964 | journal_destroy_journal_head_cache(); |
| 2044 | journal_destroy_handle_cache(); | 1965 | journal_destroy_handle_cache(); |
| 2045 | journal_destroy_jbd_slabs(); | ||
| 2046 | } | 1966 | } |
| 2047 | 1967 | ||
| 2048 | static int __init journal_init(void) | 1968 | static int __init journal_init(void) |
diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c index 8df5bac0b7a5..db8404514c92 100644 --- a/fs/jbd/transaction.c +++ b/fs/jbd/transaction.c | |||
| @@ -675,7 +675,7 @@ repeat: | |||
| 675 | JBUFFER_TRACE(jh, "allocate memory for buffer"); | 675 | JBUFFER_TRACE(jh, "allocate memory for buffer"); |
| 676 | jbd_unlock_bh_state(bh); | 676 | jbd_unlock_bh_state(bh); |
| 677 | frozen_buffer = | 677 | frozen_buffer = |
| 678 | jbd_slab_alloc(jh2bh(jh)->b_size, | 678 | jbd_alloc(jh2bh(jh)->b_size, |
| 679 | GFP_NOFS); | 679 | GFP_NOFS); |
| 680 | if (!frozen_buffer) { | 680 | if (!frozen_buffer) { |
| 681 | printk(KERN_EMERG | 681 | printk(KERN_EMERG |
| @@ -735,7 +735,7 @@ done: | |||
| 735 | 735 | ||
| 736 | out: | 736 | out: |
| 737 | if (unlikely(frozen_buffer)) /* It's usually NULL */ | 737 | if (unlikely(frozen_buffer)) /* It's usually NULL */ |
| 738 | jbd_slab_free(frozen_buffer, bh->b_size); | 738 | jbd_free(frozen_buffer, bh->b_size); |
| 739 | 739 | ||
| 740 | JBUFFER_TRACE(jh, "exit"); | 740 | JBUFFER_TRACE(jh, "exit"); |
| 741 | return error; | 741 | return error; |
| @@ -888,7 +888,7 @@ int journal_get_undo_access(handle_t *handle, struct buffer_head *bh) | |||
| 888 | 888 | ||
| 889 | repeat: | 889 | repeat: |
| 890 | if (!jh->b_committed_data) { | 890 | if (!jh->b_committed_data) { |
| 891 | committed_data = jbd_slab_alloc(jh2bh(jh)->b_size, GFP_NOFS); | 891 | committed_data = jbd_alloc(jh2bh(jh)->b_size, GFP_NOFS); |
| 892 | if (!committed_data) { | 892 | if (!committed_data) { |
| 893 | printk(KERN_EMERG "%s: No memory for committed data\n", | 893 | printk(KERN_EMERG "%s: No memory for committed data\n", |
| 894 | __FUNCTION__); | 894 | __FUNCTION__); |
| @@ -915,7 +915,7 @@ repeat: | |||
| 915 | out: | 915 | out: |
| 916 | journal_put_journal_head(jh); | 916 | journal_put_journal_head(jh); |
| 917 | if (unlikely(committed_data)) | 917 | if (unlikely(committed_data)) |
| 918 | jbd_slab_free(committed_data, bh->b_size); | 918 | jbd_free(committed_data, bh->b_size); |
| 919 | return err; | 919 | return err; |
| 920 | } | 920 | } |
| 921 | 921 | ||
diff --git a/include/linux/jbd.h b/include/linux/jbd.h index 72f522372924..1db3b684f557 100644 --- a/include/linux/jbd.h +++ b/include/linux/jbd.h | |||
| @@ -73,14 +73,21 @@ extern int journal_enable_debug; | |||
| 73 | #endif | 73 | #endif |
| 74 | 74 | ||
| 75 | extern void * __jbd_kmalloc (const char *where, size_t size, gfp_t flags, int retry); | 75 | extern void * __jbd_kmalloc (const char *where, size_t size, gfp_t flags, int retry); |
| 76 | extern void * jbd_slab_alloc(size_t size, gfp_t flags); | ||
| 77 | extern void jbd_slab_free(void *ptr, size_t size); | ||
| 78 | |||
| 79 | #define jbd_kmalloc(size, flags) \ | 76 | #define jbd_kmalloc(size, flags) \ |
| 80 | __jbd_kmalloc(__FUNCTION__, (size), (flags), journal_oom_retry) | 77 | __jbd_kmalloc(__FUNCTION__, (size), (flags), journal_oom_retry) |
| 81 | #define jbd_rep_kmalloc(size, flags) \ | 78 | #define jbd_rep_kmalloc(size, flags) \ |
| 82 | __jbd_kmalloc(__FUNCTION__, (size), (flags), 1) | 79 | __jbd_kmalloc(__FUNCTION__, (size), (flags), 1) |
| 83 | 80 | ||
| 81 | static inline void *jbd_alloc(size_t size, gfp_t flags) | ||
| 82 | { | ||
| 83 | return (void *)__get_free_pages(flags, get_order(size)); | ||
| 84 | } | ||
| 85 | |||
| 86 | static inline void jbd_free(void *ptr, size_t size) | ||
| 87 | { | ||
| 88 | free_pages((unsigned long)ptr, get_order(size)); | ||
| 89 | }; | ||
| 90 | |||
| 84 | #define JFS_MIN_JOURNAL_BLOCKS 1024 | 91 | #define JFS_MIN_JOURNAL_BLOCKS 1024 |
| 85 | 92 | ||
| 86 | #ifdef __KERNEL__ | 93 | #ifdef __KERNEL__ |
