]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - fs/jbd2/journal.c
Security: round mmap hint address above mmap_min_addr
[linux-2.6-omap-h63xx.git] / fs / jbd2 / journal.c
index 78d63b818f0b2daac94a2432396577480522ee84..6ddc5531587c7c6598180f105e46645f13d74337 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/kthread.h>
 #include <linux/poison.h>
 #include <linux/proc_fs.h>
+#include <linux/debugfs.h>
 
 #include <asm/uaccess.h>
 #include <asm/page.h>
@@ -83,7 +84,6 @@ EXPORT_SYMBOL(jbd2_journal_force_commit);
 
 static int journal_convert_superblock_v1(journal_t *, journal_superblock_t *);
 static void __journal_abort_soft (journal_t *journal, int errno);
-static int jbd2_journal_create_jbd_slab(size_t slab_size);
 
 /*
  * Helper function used to manage commit timeouts
@@ -334,10 +334,10 @@ repeat:
                char *tmp;
 
                jbd_unlock_bh_state(bh_in);
-               tmp = jbd2_slab_alloc(bh_in->b_size, GFP_NOFS);
+               tmp = jbd2_alloc(bh_in->b_size, GFP_NOFS);
                jbd_lock_bh_state(bh_in);
                if (jh_in->b_frozen_data) {
-                       jbd2_slab_free(tmp, bh_in->b_size);
+                       jbd2_free(tmp, bh_in->b_size);
                        goto repeat;
                }
 
@@ -528,7 +528,7 @@ int jbd2_log_wait_commit(journal_t *journal, tid_t tid)
 {
        int err = 0;
 
-#ifdef CONFIG_JBD_DEBUG
+#ifdef CONFIG_JBD2_DEBUG
        spin_lock(&journal->j_state_lock);
        if (!tid_geq(journal->j_commit_request, tid)) {
                printk(KERN_EMERG
@@ -654,10 +654,9 @@ static journal_t * journal_init_common (void)
        journal_t *journal;
        int err;
 
-       journal = jbd_kmalloc(sizeof(*journal), GFP_KERNEL);
+       journal = kzalloc(sizeof(*journal), GFP_KERNEL|__GFP_NOFAIL);
        if (!journal)
                goto fail;
-       memset(journal, 0, sizeof(*journal));
 
        init_waitqueue_head(&journal->j_wait_transaction_locked);
        init_waitqueue_head(&journal->j_wait_logspace);
@@ -671,7 +670,7 @@ static journal_t * journal_init_common (void)
        spin_lock_init(&journal->j_list_lock);
        spin_lock_init(&journal->j_state_lock);
 
-       journal->j_commit_interval = (HZ * JBD_DEFAULT_MAX_COMMIT_AGE);
+       journal->j_commit_interval = (HZ * JBD2_DEFAULT_MAX_COMMIT_AGE);
 
        /* The journal is marked for error until we succeed with recovery! */
        journal->j_flags = JBD2_ABORT;
@@ -1095,13 +1094,6 @@ int jbd2_journal_load(journal_t *journal)
                }
        }
 
-       /*
-        * Create a slab for this blocksize
-        */
-       err = jbd2_journal_create_jbd_slab(be32_to_cpu(sb->s_blocksize));
-       if (err)
-               return err;
-
        /* Let the recovery code check whether it needs to recover any
         * data from the journal. */
        if (jbd2_journal_recover(journal))
@@ -1620,96 +1612,16 @@ int jbd2_journal_blocks_per_page(struct inode *inode)
 size_t journal_tag_bytes(journal_t *journal)
 {
        if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_64BIT))
-               return JBD_TAG_SIZE64;
+               return JBD2_TAG_SIZE64;
        else
-               return JBD_TAG_SIZE32;
-}
-
-/*
- * Simple support for retrying memory allocations.  Introduced to help to
- * debug different VM deadlock avoidance strategies.
- */
-void * __jbd2_kmalloc (const char *where, size_t size, gfp_t flags, int retry)
-{
-       return kmalloc(size, flags | (retry ? __GFP_NOFAIL : 0));
-}
-
-/*
- * jbd slab management: create 1k, 2k, 4k, 8k slabs as needed
- * and allocate frozen and commit buffers from these slabs.
- *
- * Reason for doing this is to avoid, SLAB_DEBUG - since it could
- * cause bh to cross page boundary.
- */
-
-#define JBD_MAX_SLABS 5
-#define JBD_SLAB_INDEX(size)  (size >> 11)
-
-static struct kmem_cache *jbd_slab[JBD_MAX_SLABS];
-static const char *jbd_slab_names[JBD_MAX_SLABS] = {
-       "jbd2_1k", "jbd2_2k", "jbd2_4k", NULL, "jbd2_8k"
-};
-
-static void jbd2_journal_destroy_jbd_slabs(void)
-{
-       int i;
-
-       for (i = 0; i < JBD_MAX_SLABS; i++) {
-               if (jbd_slab[i])
-                       kmem_cache_destroy(jbd_slab[i]);
-               jbd_slab[i] = NULL;
-       }
-}
-
-static int jbd2_journal_create_jbd_slab(size_t slab_size)
-{
-       int i = JBD_SLAB_INDEX(slab_size);
-
-       BUG_ON(i >= JBD_MAX_SLABS);
-
-       /*
-        * Check if we already have a slab created for this size
-        */
-       if (jbd_slab[i])
-               return 0;
-
-       /*
-        * Create a slab and force alignment to be same as slabsize -
-        * this will make sure that allocations won't cross the page
-        * boundary.
-        */
-       jbd_slab[i] = kmem_cache_create(jbd_slab_names[i],
-                               slab_size, slab_size, 0, NULL, NULL);
-       if (!jbd_slab[i]) {
-               printk(KERN_EMERG "JBD: no memory for jbd_slab cache\n");
-               return -ENOMEM;
-       }
-       return 0;
-}
-
-void * jbd2_slab_alloc(size_t size, gfp_t flags)
-{
-       int idx;
-
-       idx = JBD_SLAB_INDEX(size);
-       BUG_ON(jbd_slab[idx] == NULL);
-       return kmem_cache_alloc(jbd_slab[idx], flags | __GFP_NOFAIL);
-}
-
-void jbd2_slab_free(void *ptr,  size_t size)
-{
-       int idx;
-
-       idx = JBD_SLAB_INDEX(size);
-       BUG_ON(jbd_slab[idx] == NULL);
-       kmem_cache_free(jbd_slab[idx], ptr);
+               return JBD2_TAG_SIZE32;
 }
 
 /*
  * Journal_head storage management
  */
 static struct kmem_cache *jbd2_journal_head_cache;
-#ifdef CONFIG_JBD_DEBUG
+#ifdef CONFIG_JBD2_DEBUG
 static atomic_t nr_journal_heads = ATOMIC_INIT(0);
 #endif
 
@@ -1722,8 +1634,7 @@ static int journal_init_jbd2_journal_head_cache(void)
                                sizeof(struct journal_head),
                                0,              /* offset */
                                0,              /* flags */
-                               NULL,           /* ctor */
-                               NULL);          /* dtor */
+                               NULL);          /* ctor */
        retval = 0;
        if (jbd2_journal_head_cache == 0) {
                retval = -ENOMEM;
@@ -1747,7 +1658,7 @@ static struct journal_head *journal_alloc_journal_head(void)
        struct journal_head *ret;
        static unsigned long last_warning;
 
-#ifdef CONFIG_JBD_DEBUG
+#ifdef CONFIG_JBD2_DEBUG
        atomic_inc(&nr_journal_heads);
 #endif
        ret = kmem_cache_alloc(jbd2_journal_head_cache, GFP_NOFS);
@@ -1768,9 +1679,9 @@ static struct journal_head *journal_alloc_journal_head(void)
 
 static void journal_free_journal_head(struct journal_head *jh)
 {
-#ifdef CONFIG_JBD_DEBUG
+#ifdef CONFIG_JBD2_DEBUG
        atomic_dec(&nr_journal_heads);
-       memset(jh, JBD_POISON_FREE, sizeof(*jh));
+       memset(jh, JBD2_POISON_FREE, sizeof(*jh));
 #endif
        kmem_cache_free(jbd2_journal_head_cache, jh);
 }
@@ -1893,13 +1804,13 @@ static void __journal_remove_journal_head(struct buffer_head *bh)
                                printk(KERN_WARNING "%s: freeing "
                                                "b_frozen_data\n",
                                                __FUNCTION__);
-                               jbd2_slab_free(jh->b_frozen_data, bh->b_size);
+                               jbd2_free(jh->b_frozen_data, bh->b_size);
                        }
                        if (jh->b_committed_data) {
                                printk(KERN_WARNING "%s: freeing "
                                                "b_committed_data\n",
                                                __FUNCTION__);
-                               jbd2_slab_free(jh->b_committed_data, bh->b_size);
+                               jbd2_free(jh->b_committed_data, bh->b_size);
                        }
                        bh->b_private = NULL;
                        jh->b_bh = NULL;        /* debug, really */
@@ -1951,64 +1862,42 @@ void jbd2_journal_put_journal_head(struct journal_head *jh)
 }
 
 /*
- * /proc tunables
+ * debugfs tunables
  */
-#if defined(CONFIG_JBD_DEBUG)
-int jbd2_journal_enable_debug;
+#ifdef CONFIG_JBD2_DEBUG
+u8 jbd2_journal_enable_debug __read_mostly;
 EXPORT_SYMBOL(jbd2_journal_enable_debug);
-#endif
 
-#if defined(CONFIG_JBD_DEBUG) && defined(CONFIG_PROC_FS)
+#define JBD2_DEBUG_NAME "jbd2-debug"
 
-static struct proc_dir_entry *proc_jbd_debug;
+static struct dentry *jbd2_debugfs_dir;
+static struct dentry *jbd2_debug;
 
-static int read_jbd_debug(char *page, char **start, off_t off,
-                         int count, int *eof, void *data)
+static void __init jbd2_create_debugfs_entry(void)
 {
-       int ret;
-
-       ret = sprintf(page + off, "%d\n", jbd2_journal_enable_debug);
-       *eof = 1;
-       return ret;
+       jbd2_debugfs_dir = debugfs_create_dir("jbd2", NULL);
+       if (jbd2_debugfs_dir)
+               jbd2_debug = debugfs_create_u8(JBD2_DEBUG_NAME, S_IRUGO,
+                                              jbd2_debugfs_dir,
+                                              &jbd2_journal_enable_debug);
 }
 
-static int write_jbd_debug(struct file *file, const char __user *buffer,
-                          unsigned long count, void *data)
+static void __exit jbd2_remove_debugfs_entry(void)
 {
-       char buf[32];
-
-       if (count > ARRAY_SIZE(buf) - 1)
-               count = ARRAY_SIZE(buf) - 1;
-       if (copy_from_user(buf, buffer, count))
-               return -EFAULT;
-       buf[ARRAY_SIZE(buf) - 1] = '\0';
-       jbd2_journal_enable_debug = simple_strtoul(buf, NULL, 10);
-       return count;
+       debugfs_remove(jbd2_debug);
+       debugfs_remove(jbd2_debugfs_dir);
 }
 
-#define JBD_PROC_NAME "sys/fs/jbd2-debug"
+#else
 
-static void __init create_jbd_proc_entry(void)
+static void __init jbd2_create_debugfs_entry(void)
 {
-       proc_jbd_debug = create_proc_entry(JBD_PROC_NAME, 0644, NULL);
-       if (proc_jbd_debug) {
-               /* Why is this so hard? */
-               proc_jbd_debug->read_proc = read_jbd_debug;
-               proc_jbd_debug->write_proc = write_jbd_debug;
-       }
 }
 
-static void __exit jbd2_remove_jbd_proc_entry(void)
+static void __exit jbd2_remove_debugfs_entry(void)
 {
-       if (proc_jbd_debug)
-               remove_proc_entry(JBD_PROC_NAME, NULL);
 }
 
-#else
-
-#define create_jbd_proc_entry() do {} while (0)
-#define jbd2_remove_jbd_proc_entry() do {} while (0)
-
 #endif
 
 struct kmem_cache *jbd2_handle_cache;
@@ -2019,8 +1908,7 @@ static int __init journal_init_handle_cache(void)
                                sizeof(handle_t),
                                0,              /* offset */
                                0,              /* flags */
-                               NULL,           /* ctor */
-                               NULL);          /* dtor */
+                               NULL);          /* ctor */
        if (jbd2_handle_cache == NULL) {
                printk(KERN_EMERG "JBD: failed to create handle cache\n");
                return -ENOMEM;
@@ -2055,7 +1943,6 @@ static void jbd2_journal_destroy_caches(void)
        jbd2_journal_destroy_revoke_caches();
        jbd2_journal_destroy_jbd2_journal_head_cache();
        jbd2_journal_destroy_handle_cache();
-       jbd2_journal_destroy_jbd_slabs();
 }
 
 static int __init journal_init(void)
@@ -2067,18 +1954,18 @@ static int __init journal_init(void)
        ret = journal_init_caches();
        if (ret != 0)
                jbd2_journal_destroy_caches();
-       create_jbd_proc_entry();
+       jbd2_create_debugfs_entry();
        return ret;
 }
 
 static void __exit journal_exit(void)
 {
-#ifdef CONFIG_JBD_DEBUG
+#ifdef CONFIG_JBD2_DEBUG
        int n = atomic_read(&nr_journal_heads);
        if (n)
                printk(KERN_EMERG "JBD: leaked %d journal_heads!\n", n);
 #endif
-       jbd2_remove_jbd_proc_entry();
+       jbd2_remove_debugfs_entry();
        jbd2_journal_destroy_caches();
 }