lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1205001459-5291-7-git-send-email-duaneg@dghda.com>
Date:	Sat,  8 Mar 2008 18:37:39 +0000
From:	"Duane Griffin" <duaneg@...da.com>
To:	linux-ext4@...r.kernel.org
Cc:	linux-kernel@...r.kernel.org,
	Christoph Hellwig <hch@...radead.org>,
	Theodore Tso <tytso@....edu>, sct@...hat.com,
	akpm@...ux-foundation.org, adilger@...sterfs.com,
	Duane Griffin <duaneg@...da.com>
Subject: [PATCH] jbd2: handle cache initialisation failure gracefully when statically compiled in

When jbd2 is statically compiled into the kernel we need to check whether the
caches are properly initialised before using them. If they are not then have
another go before failing gracefully.

Signed-off-by: Duane Griffin <duaneg@...da.com>
---
 fs/jbd2/journal.c |  154 ++++++++++++++++++++++++++---------------------------
 fs/jbd2/revoke.c  |    2 +-
 2 files changed, 76 insertions(+), 80 deletions(-)

diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
index 96ba846..d4cc95a 100644
--- a/fs/jbd2/journal.c
+++ b/fs/jbd2/journal.c
@@ -641,6 +641,67 @@ struct journal_head *jbd2_journal_get_descriptor_buffer(journal_t *journal)
 	return jbd2_journal_add_journal_head(bh);
 }
 
+/*
+ * Journal_head storage management
+ */
+static struct kmem_cache *jbd2_journal_head_cache;
+#ifdef CONFIG_JBD2_DEBUG
+static atomic_t nr_journal_heads = ATOMIC_INIT(0);
+#endif
+
+struct kmem_cache *jbd2_handle_cache;
+
+static void jbd2_journal_destroy_caches(void)
+{
+	jbd2_journal_destroy_revoke_caches();
+
+	if (jbd2_journal_head_cache) {
+		kmem_cache_destroy(jbd2_journal_head_cache);
+		jbd2_journal_head_cache = NULL;
+	}
+
+	if (jbd2_handle_cache) {
+		kmem_cache_destroy(jbd2_handle_cache);
+		jbd2_handle_cache = NULL;
+	}
+}
+
+static int jbd2_journal_init_caches(void)
+{
+	int ret;
+
+	J_ASSERT(!jbd2_journal_head_cache);
+	J_ASSERT(!jbd2_handle_cache);
+
+	ret = jbd2_journal_init_revoke_caches();
+	if (ret)
+		goto fail;
+
+	ret = -ENOMEM;
+	jbd2_journal_head_cache = kmem_cache_create("jbd2_journal_head",
+				sizeof(struct journal_head),
+				0,		/* offset */
+				SLAB_TEMPORARY,	/* flags */
+				NULL);		/* ctor */
+	if (!jbd2_journal_head_cache)
+		goto fail;
+
+	jbd2_handle_cache = kmem_cache_create("jbd2_journal_handle",
+				sizeof(handle_t),
+				0,		/* offset */
+				SLAB_TEMPORARY,	/* flags */
+				NULL);		/* ctor */
+	if (!jbd2_handle_cache)
+		goto fail;
+
+	return 0;
+
+fail:
+	jbd2_journal_destroy_caches();
+	printk(KERN_EMERG "JBD2: no memory to initialise cache\n");
+	return ret;
+}
+
 struct jbd2_stats_proc_session {
 	journal_t *journal;
 	struct transaction_stats_s *stats;
@@ -959,7 +1020,14 @@ static void journal_init_stats(journal_t *journal)
 static journal_t * journal_init_common (void)
 {
 	journal_t *journal;
-	int err;
+	int err = 0;
+
+	if (!jbd2_journal_head_cache)
+		err = jbd2_journal_init_caches();
+	if (err) {
+		jbd2_journal_destroy_caches();
+		return NULL;
+	}
 
 	journal = kzalloc(sizeof(*journal), GFP_KERNEL|__GFP_NOFAIL);
 	if (!journal)
@@ -1958,39 +2026,6 @@ size_t journal_tag_bytes(journal_t *journal)
 }
 
 /*
- * Journal_head storage management
- */
-static struct kmem_cache *jbd2_journal_head_cache;
-#ifdef CONFIG_JBD2_DEBUG
-static atomic_t nr_journal_heads = ATOMIC_INIT(0);
-#endif
-
-static int journal_init_jbd2_journal_head_cache(void)
-{
-	int retval;
-
-	J_ASSERT(jbd2_journal_head_cache == 0);
-	jbd2_journal_head_cache = kmem_cache_create("jbd2_journal_head",
-				sizeof(struct journal_head),
-				0,		/* offset */
-				SLAB_TEMPORARY,	/* flags */
-				NULL);		/* ctor */
-	retval = 0;
-	if (jbd2_journal_head_cache == 0) {
-		retval = -ENOMEM;
-		printk(KERN_EMERG "JBD: no memory for journal_head cache\n");
-	}
-	return retval;
-}
-
-static void jbd2_journal_destroy_jbd2_journal_head_cache(void)
-{
-	J_ASSERT(jbd2_journal_head_cache != NULL);
-	kmem_cache_destroy(jbd2_journal_head_cache);
-	jbd2_journal_head_cache = NULL;
-}
-
-/*
  * journal_head splicing and dicing
  */
 static struct journal_head *journal_alloc_journal_head(void)
@@ -2262,62 +2297,23 @@ static void __exit jbd2_remove_jbd_stats_proc_entry(void)
 
 #endif
 
-struct kmem_cache *jbd2_handle_cache;
-
-static int __init journal_init_handle_cache(void)
-{
-	jbd2_handle_cache = kmem_cache_create("jbd2_journal_handle",
-				sizeof(handle_t),
-				0,		/* offset */
-				SLAB_TEMPORARY,	/* flags */
-				NULL);		/* ctor */
-	if (jbd2_handle_cache == NULL) {
-		printk(KERN_EMERG "JBD: failed to create handle cache\n");
-		return -ENOMEM;
-	}
-	return 0;
-}
-
-static void jbd2_journal_destroy_handle_cache(void)
-{
-	if (jbd2_handle_cache)
-		kmem_cache_destroy(jbd2_handle_cache);
-}
-
 /*
  * Module startup and shutdown
  */
 
-static int __init journal_init_caches(void)
-{
-	int ret;
-
-	ret = jbd2_journal_init_revoke_caches();
-	if (ret == 0)
-		ret = journal_init_jbd2_journal_head_cache();
-	if (ret == 0)
-		ret = journal_init_handle_cache();
-	return ret;
-}
-
-static void jbd2_journal_destroy_caches(void)
-{
-	jbd2_journal_destroy_revoke_caches();
-	jbd2_journal_destroy_jbd2_journal_head_cache();
-	jbd2_journal_destroy_handle_cache();
-}
-
 static int __init journal_init(void)
 {
 	int ret;
 
 	BUILD_BUG_ON(sizeof(struct journal_superblock_s) != 1024);
 
-	ret = journal_init_caches();
-	if (ret != 0)
+	ret = jbd2_journal_init_caches();
+	if (ret == 0) {
+		jbd2_create_debugfs_entry();
+		jbd2_create_jbd_stats_proc_entry();
+	} else {
 		jbd2_journal_destroy_caches();
-	jbd2_create_debugfs_entry();
-	jbd2_create_jbd_stats_proc_entry();
+	}
 	return ret;
 }
 
diff --git a/fs/jbd2/revoke.c b/fs/jbd2/revoke.c
index 5a020f1..da4551e 100644
--- a/fs/jbd2/revoke.c
+++ b/fs/jbd2/revoke.c
@@ -179,7 +179,7 @@ void jbd2_journal_destroy_revoke_caches(void)
 	}
 }
 
-int __init jbd2_journal_init_revoke_caches(void)
+int jbd2_journal_init_revoke_caches(void)
 {
 	J_ASSERT(!jbd2_revoke_record_cache);
 	J_ASSERT(!jbd2_revoke_table_cache);
-- 
1.5.3.7

--
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ