Commit 0b6af0f0 authored by Oleg Drokin's avatar Oleg Drokin

reiserfs: Correctly free all the allocated memory if open of the journal failed.

  Also added \n to some error messages.
parent bc7ae54e
...@@ -1310,6 +1310,10 @@ static void free_journal_ram(struct super_block *p_s_sb) { ...@@ -1310,6 +1310,10 @@ static void free_journal_ram(struct super_block *p_s_sb) {
if (SB_JOURNAL(p_s_sb)->j_header_bh) { if (SB_JOURNAL(p_s_sb)->j_header_bh) {
brelse(SB_JOURNAL(p_s_sb)->j_header_bh) ; brelse(SB_JOURNAL(p_s_sb)->j_header_bh) ;
} }
/* j_header_bh is on the journal dev, make sure not to release the journal
* dev until we brelse j_header_bh
*/
release_journal_dev(p_s_sb, SB_JOURNAL(p_s_sb));
vfree(SB_JOURNAL(p_s_sb)) ; vfree(SB_JOURNAL(p_s_sb)) ;
} }
...@@ -1341,7 +1345,6 @@ static int do_journal_release(struct reiserfs_transaction_handle *th, struct sup ...@@ -1341,7 +1345,6 @@ static int do_journal_release(struct reiserfs_transaction_handle *th, struct sup
commit_wq = NULL; commit_wq = NULL;
} }
release_journal_dev( p_s_sb, SB_JOURNAL( p_s_sb ) );
free_journal_ram(p_s_sb) ; free_journal_ram(p_s_sb) ;
return 0 ; return 0 ;
...@@ -1867,24 +1870,18 @@ static int release_journal_dev( struct super_block *super, ...@@ -1867,24 +1870,18 @@ static int release_journal_dev( struct super_block *super,
int result; int result;
result = 0; result = 0;
if( journal -> j_dev_file != NULL ) { if( journal -> j_dev_file != NULL ) {
/*
* journal block device was taken via filp_open
*/
result = filp_close( journal -> j_dev_file, NULL ); result = filp_close( journal -> j_dev_file, NULL );
journal -> j_dev_file = NULL; journal -> j_dev_file = NULL;
journal -> j_dev_bd = NULL; journal -> j_dev_bd = NULL;
} else if( journal -> j_dev_bd != NULL ) { } else if( journal -> j_dev_bd != NULL ) {
/*
* journal block device was taken via bdget and blkdev_get
*/
result = blkdev_put( journal -> j_dev_bd, BDEV_FS ); result = blkdev_put( journal -> j_dev_bd, BDEV_FS );
journal -> j_dev_bd = NULL; journal -> j_dev_bd = NULL;
} }
if( result != 0 ) { if( result != 0 ) {
reiserfs_warning("sh-457: release_journal_dev: Cannot release journal device: %i", result ); reiserfs_warning("sh-457: release_journal_dev: Cannot release journal device: %i\n", result );
} }
return result; return result;
} }
...@@ -1895,6 +1892,7 @@ static int journal_init_dev( struct super_block *super, ...@@ -1895,6 +1892,7 @@ static int journal_init_dev( struct super_block *super,
{ {
int result; int result;
dev_t jdev; dev_t jdev;
int blkdev_mode = FMODE_READ | FMODE_WRITE;
result = 0; result = 0;
...@@ -1902,12 +1900,16 @@ static int journal_init_dev( struct super_block *super, ...@@ -1902,12 +1900,16 @@ static int journal_init_dev( struct super_block *super,
journal -> j_dev_file = NULL; journal -> j_dev_file = NULL;
jdev = SB_ONDISK_JOURNAL_DEVICE( super ) ? jdev = SB_ONDISK_JOURNAL_DEVICE( super ) ?
SB_ONDISK_JOURNAL_DEVICE( super ) : super->s_dev; SB_ONDISK_JOURNAL_DEVICE( super ) : super->s_dev;
if (bdev_read_only(super->s_bdev))
blkdev_mode = FMODE_READ;
/* there is no "jdev" option and journal is on separate device */ /* there is no "jdev" option and journal is on separate device */
if( ( !jdev_name || !jdev_name[ 0 ] ) ) { if( ( !jdev_name || !jdev_name[ 0 ] ) ) {
journal -> j_dev_bd = bdget(jdev); journal -> j_dev_bd = bdget(jdev);
if( journal -> j_dev_bd ) if( journal -> j_dev_bd )
result = blkdev_get( journal -> j_dev_bd, result = blkdev_get( journal -> j_dev_bd,
FMODE_READ | FMODE_WRITE, 0, blkdev_mode, 0,
BDEV_FS ); BDEV_FS );
else else
result = -ENOMEM; result = -ENOMEM;
...@@ -1928,10 +1930,10 @@ static int journal_init_dev( struct super_block *super, ...@@ -1928,10 +1930,10 @@ static int journal_init_dev( struct super_block *super,
jdev_inode = journal -> j_dev_file -> f_dentry -> d_inode; jdev_inode = journal -> j_dev_file -> f_dentry -> d_inode;
journal -> j_dev_bd = jdev_inode -> i_bdev; journal -> j_dev_bd = jdev_inode -> i_bdev;
if( !S_ISBLK( jdev_inode -> i_mode ) ) { if( !S_ISBLK( jdev_inode -> i_mode ) ) {
printk( "journal_init_dev: '%s' is not a block device", jdev_name ); printk( "journal_init_dev: '%s' is not a block device\n", jdev_name );
result = -ENOTBLK; result = -ENOTBLK;
} else if( jdev_inode -> i_bdev == NULL ) { } else if( jdev_inode -> i_bdev == NULL ) {
printk( "journal_init_dev: bdev uninitialized for '%s'", jdev_name ); printk( "journal_init_dev: bdev uninitialized for '%s'\n", jdev_name );
result = -ENOMEM; result = -ENOMEM;
} else { } else {
/* ok */ /* ok */
...@@ -1941,12 +1943,12 @@ static int journal_init_dev( struct super_block *super, ...@@ -1941,12 +1943,12 @@ static int journal_init_dev( struct super_block *super,
} else { } else {
result = PTR_ERR( journal -> j_dev_file ); result = PTR_ERR( journal -> j_dev_file );
journal -> j_dev_file = NULL; journal -> j_dev_file = NULL;
printk( "journal_init_dev: Cannot open '%s': %i", jdev_name, result ); printk( "journal_init_dev: Cannot open '%s': %i\n", jdev_name, result );
} }
if( result != 0 ) { if( result != 0 ) {
release_journal_dev( super, journal ); release_journal_dev( super, journal );
} }
printk( "journal_init_dev: journal device: %s", bdevname(journal->j_dev_bd)); printk( "journal_init_dev: journal device: %s\n", bdevname(journal->j_dev_bd));
return result; return result;
} }
...@@ -1960,20 +1962,24 @@ int journal_init(struct super_block *p_s_sb, const char * j_dev_name, int old_fo ...@@ -1960,20 +1962,24 @@ int journal_init(struct super_block *p_s_sb, const char * j_dev_name, int old_fo
struct reiserfs_journal_header *jh; struct reiserfs_journal_header *jh;
struct reiserfs_journal *journal; struct reiserfs_journal *journal;
if (sizeof(struct reiserfs_journal_commit) != 4096 || if (sizeof(struct reiserfs_journal_commit) != 4096 ||
sizeof(struct reiserfs_journal_desc) != 4096 sizeof(struct reiserfs_journal_desc) != 4096) {
) { printk("journal-1249: commit or desc struct not 4096 %Zd %Zd\n", sizeof(struct reiserfs_journal_commit),
printk("journal-1249: commit or desc struct not 4096 %Zd %Zd\n", sizeof(struct reiserfs_journal_commit),
sizeof(struct reiserfs_journal_desc)) ; sizeof(struct reiserfs_journal_desc)) ;
return 1 ; return 1 ;
} }
journal = SB_JOURNAL(p_s_sb) = vmalloc(sizeof (struct reiserfs_journal)) ; journal = SB_JOURNAL(p_s_sb) = vmalloc(sizeof (struct reiserfs_journal)) ;
if (!journal) { if (!journal) {
printk("journal-1256: unable to get memory for journal structure\n") ; printk("journal-1256: unable to get memory for journal structure\n") ;
return 1 ; return 1 ;
} }
memset(journal, 0, sizeof(struct reiserfs_journal)) ; memset(journal, 0, sizeof(struct reiserfs_journal)) ;
INIT_LIST_HEAD(&SB_JOURNAL(p_s_sb)->j_bitmap_nodes) ;
INIT_LIST_HEAD (&SB_JOURNAL(p_s_sb)->j_prealloc_list);
reiserfs_allocate_list_bitmaps(p_s_sb, SB_JOURNAL(p_s_sb)->j_list_bitmap,
SB_BMAP_NR(p_s_sb)) ;
allocate_bitmap_nodes(p_s_sb) ;
/* reserved for journal area support */ /* reserved for journal area support */
SB_JOURNAL_1st_RESERVED_BLOCK(p_s_sb) = (old_format ? SB_JOURNAL_1st_RESERVED_BLOCK(p_s_sb) = (old_format ?
...@@ -1983,7 +1989,7 @@ int journal_init(struct super_block *p_s_sb, const char * j_dev_name, int old_fo ...@@ -1983,7 +1989,7 @@ int journal_init(struct super_block *p_s_sb, const char * j_dev_name, int old_fo
if( journal_init_dev( p_s_sb, journal, j_dev_name ) != 0 ) { if( journal_init_dev( p_s_sb, journal, j_dev_name ) != 0 ) {
printk( "sh-462: unable to initialize jornal device\n"); printk( "sh-462: unable to initialize jornal device\n");
return 1; goto free_and_return;
} }
rs = SB_DISK_SUPER_BLOCK(p_s_sb); rs = SB_DISK_SUPER_BLOCK(p_s_sb);
...@@ -1993,8 +1999,7 @@ int journal_init(struct super_block *p_s_sb, const char * j_dev_name, int old_fo ...@@ -1993,8 +1999,7 @@ int journal_init(struct super_block *p_s_sb, const char * j_dev_name, int old_fo
SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + SB_ONDISK_JOURNAL_SIZE(p_s_sb)); SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + SB_ONDISK_JOURNAL_SIZE(p_s_sb));
if (!bhjh) { if (!bhjh) {
printk("sh-459: unable to read journal header\n") ; printk("sh-459: unable to read journal header\n") ;
release_journal_dev(p_s_sb, journal); goto free_and_return;
return 1 ;
} }
jh = (struct reiserfs_journal_header *)(bhjh->b_data); jh = (struct reiserfs_journal_header *)(bhjh->b_data);
...@@ -2005,8 +2010,7 @@ int journal_init(struct super_block *p_s_sb, const char * j_dev_name, int old_fo ...@@ -2005,8 +2010,7 @@ int journal_init(struct super_block *p_s_sb, const char * j_dev_name, int old_fo
jh->jh_journal.jp_journal_magic, bdevname( SB_JOURNAL(p_s_sb)->j_dev_bd ), jh->jh_journal.jp_journal_magic, bdevname( SB_JOURNAL(p_s_sb)->j_dev_bd ),
sb_jp_journal_magic(rs), reiserfs_bdevname (p_s_sb)); sb_jp_journal_magic(rs), reiserfs_bdevname (p_s_sb));
brelse (bhjh); brelse (bhjh);
release_journal_dev(p_s_sb, journal); goto free_and_return;
return 1 ;
} }
SB_JOURNAL_TRANS_MAX(p_s_sb) = le32_to_cpu (jh->jh_journal.jp_journal_trans_max); SB_JOURNAL_TRANS_MAX(p_s_sb) = le32_to_cpu (jh->jh_journal.jp_journal_trans_max);
...@@ -2064,7 +2068,6 @@ int journal_init(struct super_block *p_s_sb, const char * j_dev_name, int old_fo ...@@ -2064,7 +2068,6 @@ int journal_init(struct super_block *p_s_sb, const char * j_dev_name, int old_fo
brelse (bhjh); brelse (bhjh);
SB_JOURNAL(p_s_sb)->j_list_bitmap_index = 0 ; SB_JOURNAL(p_s_sb)->j_list_bitmap_index = 0 ;
SB_JOURNAL_LIST_INDEX(p_s_sb) = -10000 ; /* make sure flush_old_commits does not try to flush a list while replay is on */ SB_JOURNAL_LIST_INDEX(p_s_sb) = -10000 ; /* make sure flush_old_commits does not try to flush a list while replay is on */
...@@ -2075,12 +2078,8 @@ int journal_init(struct super_block *p_s_sb, const char * j_dev_name, int old_fo ...@@ -2075,12 +2078,8 @@ int journal_init(struct super_block *p_s_sb, const char * j_dev_name, int old_fo
memset(SB_JOURNAL(p_s_sb)->j_list_hash_table, 0, JOURNAL_HASH_SIZE * sizeof(struct reiserfs_journal_cnode *)) ; memset(SB_JOURNAL(p_s_sb)->j_list_hash_table, 0, JOURNAL_HASH_SIZE * sizeof(struct reiserfs_journal_cnode *)) ;
memset(journal_writers, 0, sizeof(char *) * 512) ; /* debug code */ memset(journal_writers, 0, sizeof(char *) * 512) ; /* debug code */
INIT_LIST_HEAD(&SB_JOURNAL(p_s_sb)->j_bitmap_nodes) ;
INIT_LIST_HEAD(&SB_JOURNAL(p_s_sb)->j_dirty_buffers) ; INIT_LIST_HEAD(&SB_JOURNAL(p_s_sb)->j_dirty_buffers) ;
spin_lock_init(&SB_JOURNAL(p_s_sb)->j_dirty_buffers_lock) ; spin_lock_init(&SB_JOURNAL(p_s_sb)->j_dirty_buffers_lock) ;
reiserfs_allocate_list_bitmaps(p_s_sb, SB_JOURNAL(p_s_sb)->j_list_bitmap,
SB_BMAP_NR(p_s_sb)) ;
allocate_bitmap_nodes(p_s_sb) ;
SB_JOURNAL(p_s_sb)->j_start = 0 ; SB_JOURNAL(p_s_sb)->j_start = 0 ;
SB_JOURNAL(p_s_sb)->j_len = 0 ; SB_JOURNAL(p_s_sb)->j_len = 0 ;
...@@ -2107,20 +2106,15 @@ int journal_init(struct super_block *p_s_sb, const char * j_dev_name, int old_fo ...@@ -2107,20 +2106,15 @@ int journal_init(struct super_block *p_s_sb, const char * j_dev_name, int old_fo
SB_JOURNAL_LIST(p_s_sb)[0].j_list_bitmap = get_list_bitmap(p_s_sb, SB_JOURNAL_LIST(p_s_sb)) ; SB_JOURNAL_LIST(p_s_sb)[0].j_list_bitmap = get_list_bitmap(p_s_sb, SB_JOURNAL_LIST(p_s_sb)) ;
if (!(SB_JOURNAL_LIST(p_s_sb)[0].j_list_bitmap)) { if (!(SB_JOURNAL_LIST(p_s_sb)[0].j_list_bitmap)) {
reiserfs_warning("journal-2005, get_list_bitmap failed for journal list 0\n") ; reiserfs_warning("journal-2005, get_list_bitmap failed for journal list 0\n") ;
release_journal_dev(p_s_sb, journal); goto free_and_return;
return 1 ;
} }
if (journal_read(p_s_sb) < 0) { if (journal_read(p_s_sb) < 0) {
reiserfs_warning("Replay Failure, unable to mount\n") ; reiserfs_warning("Replay Failure, unable to mount\n") ;
free_journal_ram(p_s_sb) ; goto free_and_return;
release_journal_dev(p_s_sb, journal);
return 1 ;
} }
SB_JOURNAL_LIST_INDEX(p_s_sb) = 0 ; /* once the read is done, we can set this SB_JOURNAL_LIST_INDEX(p_s_sb) = 0 ; /* once the read is done, we can set this
where it belongs */ where it belongs */
INIT_LIST_HEAD (&SB_JOURNAL(p_s_sb)->j_prealloc_list);
if (reiserfs_dont_log (p_s_sb)) if (reiserfs_dont_log (p_s_sb))
return 0; return 0;
...@@ -2129,7 +2123,9 @@ int journal_init(struct super_block *p_s_sb, const char * j_dev_name, int old_fo ...@@ -2129,7 +2123,9 @@ int journal_init(struct super_block *p_s_sb, const char * j_dev_name, int old_fo
commit_wq = create_workqueue("reiserfs"); commit_wq = create_workqueue("reiserfs");
return 0 ; return 0 ;
free_and_return:
free_journal_ram(p_s_sb);
return 1;
} }
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment