jbd2: don't leak memory if setting up journal fails
PATCH 1/1 jbd2: don't leak memory if setting up journal fails
From: Eric Biggers <[email protected]>
In journal_init_common(), if we failed to allocate the j_wbuf array, or if we failed to create the buffer_head for the journal superblock, we leaked the memory allocated for the revocation tables. Fix this.
Signed-off-by Eric Biggers <[email protected]>
--- fs/jbd2/journal.c | 22 +++++++++++----------- fs/jbd2/revoke.c | 1 + 2 files changed, 12 insertions(+), 11 deletions(-)
fs/jbd2/journal.c +11 -11
@@ -1125,10 +1125,8 @@ static journal_t *journal_init_common(struct block_device *bdev,/* Set up a default-sized revoke table for the new mount. */ err =jbd2_journal_init_revoke (journal,JOURNAL_REVOKE_DEFAULT_HASH ); -if (err) { -kfree (journal); -return NULL ; - } +if (err) + goto err_cleanup;spin_lock_init (&journal->j_history_lock);
@@ -1145,23 +1143,25 @@ static journal_t *journal_init_common(struct block_device *bdev, journal->j_wbufsize = n; journal->j_wbuf =kmalloc_array (n,sizeof (struct buffer_head *),GFP_KERNEL ); -if (!journal->j_wbuf) { -kfree (journal); -return NULL ; - } +if (!journal->j_wbuf) + goto err_cleanup; bh =getblk_unmovable (journal->j_dev, start, journal->j_blocksize);if (!bh) {pr_err ("%s: Cannot get buffer for journal superblock\n" , __func__); -kfree (journal->j_wbuf); -kfree (journal); -return NULL ; + goto err_cleanup; } journal->j_sb_buffer = bh; journal->j_superblock = (journal_superblock_t *)bh->b_data;return journal; + +err_cleanup: +kfree (journal->j_wbuf); +jbd2_journal_destroy_revoke (journal); +kfree (journal); +return NULL ; }/* jbd2_journal_init_dev and jbd2_journal_init_inode:
fs/jbd2/revoke.c +1 -0
@@ -280,6 +280,7 @@ int jbd2_journal_init_revoke(journal_t *journal, int hash_size) fail1:jbd2_journal_destroy_revoke_table (journal->j_revoke_table[0 ]); + journal->j_revoke_table[0 ] =NULL ; fail0:return -ENOMEM ; }
Signature · 1 line
2.12.0
Quoted 7 lines · Eric Biggers
From: Eric Biggers <[email protected]>
In
journal_init_common(), if we failed to allocate thej_wbufarray, or if we failed to create thebuffer_headfor the journal superblock, we leaked the memory allocated for the revocation tables. Fix this.Signed-off-by Eric Biggers <[email protected]>
Looks good. You can add:
Reviewed-by Jan Kara <[email protected]>
Honza
Quoted 71 lines
--- fs/jbd2/journal.c | 22 +++++++++++----------- fs/jbd2/revoke.c | 1 + 2 files changed, 12 insertions(+), 11 deletions(-)fs/jbd2/journal.c +11
-11@@ -1125,10 +1125,8 @@ static journal_t *journal_init_common(struct block_device *bdev,/* Set up a default-sized revoke table for the new mount. */ err =jbd2_journal_init_revoke (journal,JOURNAL_REVOKE_DEFAULT_HASH ); -if (err) { -kfree (journal); -return NULL ; - } +if (err) + goto err_cleanup;spin_lock_init (&journal->j_history_lock);@@ -1145,23 +1143,25 @@ static journal_t *journal_init_common(struct block_device *bdev, journal->j_wbufsize = n; journal->j_wbuf =kmalloc_array (n,sizeof (struct buffer_head *),GFP_KERNEL ); -if (!journal->j_wbuf) { -kfree (journal); -return NULL ; - } +if (!journal->j_wbuf) + goto err_cleanup; bh =getblk_unmovable (journal->j_dev, start, journal->j_blocksize);if (!bh) {pr_err ("%s: Cannot get buffer for journal superblock\n" , __func__); -kfree (journal->j_wbuf); -kfree (journal); -return NULL ; + goto err_cleanup; } journal->j_sb_buffer = bh; journal->j_superblock = (journal_superblock_t *)bh->b_data;return journal; + +err_cleanup: +kfree (journal->j_wbuf); +jbd2_journal_destroy_revoke (journal); +kfree (journal); +return NULL ; }/* jbd2_journal_init_dev and jbd2_journal_init_inode: fs/jbd2/revoke.c +1
-0@@ -280,6 +280,7 @@ int jbd2_journal_init_revoke(journal_t *journal, int hash_size) fail1:jbd2_journal_destroy_revoke_table (journal->j_revoke_table[0 ]); + journal->j_revoke_table[0 ] =NULL ; fail0:return -ENOMEM ; }Signature · 1 line
2.12.0
Signature · 2 lines
Jan Kara <[email protected]> SUSE Labs, CR