mirror of
https://github.com/adulau/aha.git
synced 2024-12-28 03:36:19 +00:00
ext4: partial revert to fix double brelse WARNING()
This is a partial revert of commit6487a9d
(only the changes made to fs/ext4/namei.c), since it is causing the following brelse() double-free warning when running fsstress on a file system with 1k blocksize and we run into a block allocation failure while converting a single-block directory to a multi-block hash-tree indexed directory. WARNING: at fs/buffer.c:1197 __brelse+0x2e/0x33() Hardware name: VFS: brelse: Trying to free free buffer Modules linked in: Pid: 2226, comm: jbd2/sdd-8 Not tainted 2.6.32-rc6-00577-g0003f55 #101 Call Trace: [<c01587fb>] warn_slowpath_common+0x65/0x95 [<c0158869>] warn_slowpath_fmt+0x29/0x2c [<c021168e>] __brelse+0x2e/0x33 [<c0288a9f>] jbd2_journal_refile_buffer+0x67/0x6c [<c028a9ed>] jbd2_journal_commit_transaction+0x319/0x14d8 [<c0164d73>] ? try_to_del_timer_sync+0x58/0x60 [<c0175bcc>] ? sched_clock_cpu+0x12a/0x13e [<c017f6b4>] ? trace_hardirqs_off+0xb/0xd [<c0175c1f>] ? cpu_clock+0x3f/0x5b [<c017f6ec>] ? lock_release_holdtime+0x36/0x137 [<c0664ad0>] ? _spin_unlock_irqrestore+0x44/0x51 [<c0180af3>] ? trace_hardirqs_on_caller+0x103/0x124 [<c0180b1f>] ? trace_hardirqs_on+0xb/0xd [<c0164d73>] ? try_to_del_timer_sync+0x58/0x60 [<c0290d1c>] kjournald2+0x11a/0x310 [<c017118e>] ? autoremove_wake_function+0x0/0x38 [<c0290c02>] ? kjournald2+0x0/0x310 [<c0170ee6>] kthread+0x66/0x6b [<c0170e80>] ? kthread+0x0/0x6b [<c01251b3>] kernel_thread_helper+0x7/0x10 ---[ end trace 5579351b86af61e3 ]--- Commit6487a9d
was an attempt some buffer head leaks in an ENOSPC error path, but in some cases it actually results in an excess ENOSPC, as shown above. Fixing this means cleaning up who is responsible for releasing the buffer heads from the callee to the caller of add_dirent_to_buf(). Since that's a relatively complex change, and we're late in the rcX development cycle, I'm reverting this now, and holding back a more complete fix until after 2.6.32 ships. We've lived with this buffer_head leak on ENOSPC in ext3 and ext4 for a very long time; a few more months won't kill us. Signed-off-by: "Theodore Ts'o" <tytso@mit.edu> Cc: Curt Wohlgemuth <curtw@google.com>
This commit is contained in:
parent
ba230c3f6d
commit
1e424a3483
1 changed files with 4 additions and 12 deletions
|
@ -1518,12 +1518,8 @@ static int ext4_add_entry(handle_t *handle, struct dentry *dentry,
|
|||
return retval;
|
||||
|
||||
if (blocks == 1 && !dx_fallback &&
|
||||
EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_DIR_INDEX)) {
|
||||
retval = make_indexed_dir(handle, dentry, inode, bh);
|
||||
if (retval == -ENOSPC)
|
||||
brelse(bh);
|
||||
return retval;
|
||||
}
|
||||
EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_DIR_INDEX))
|
||||
return make_indexed_dir(handle, dentry, inode, bh);
|
||||
brelse(bh);
|
||||
}
|
||||
bh = ext4_append(handle, dir, &block, &retval);
|
||||
|
@ -1532,10 +1528,7 @@ static int ext4_add_entry(handle_t *handle, struct dentry *dentry,
|
|||
de = (struct ext4_dir_entry_2 *) bh->b_data;
|
||||
de->inode = 0;
|
||||
de->rec_len = ext4_rec_len_to_disk(blocksize, blocksize);
|
||||
retval = add_dirent_to_buf(handle, dentry, inode, de, bh);
|
||||
if (retval == -ENOSPC)
|
||||
brelse(bh);
|
||||
return retval;
|
||||
return add_dirent_to_buf(handle, dentry, inode, de, bh);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1664,8 +1657,7 @@ static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry,
|
|||
if (!de)
|
||||
goto cleanup;
|
||||
err = add_dirent_to_buf(handle, dentry, inode, de, bh);
|
||||
if (err != -ENOSPC)
|
||||
bh = NULL;
|
||||
bh = NULL;
|
||||
goto cleanup;
|
||||
|
||||
journal_error:
|
||||
|
|
Loading…
Reference in a new issue