mirror of
https://github.com/adulau/aha.git
synced 2024-12-28 11:46:19 +00:00
fs: block_dump missing dentry locking
I think the block_dump output in __mark_inode_dirty is missing dentry locking. Surely the i_dentry list can change any time, so we may not even *get* a dentry there. If we do get one by chance, then it would appear to be able to go away or get renamed at any time... Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
545b9fd3d7
commit
4195f73d13
1 changed files with 24 additions and 17 deletions
|
@ -64,6 +64,28 @@ static void writeback_release(struct backing_dev_info *bdi)
|
||||||
clear_bit(BDI_pdflush, &bdi->state);
|
clear_bit(BDI_pdflush, &bdi->state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static noinline void block_dump___mark_inode_dirty(struct inode *inode)
|
||||||
|
{
|
||||||
|
if (inode->i_ino || strcmp(inode->i_sb->s_id, "bdev")) {
|
||||||
|
struct dentry *dentry;
|
||||||
|
const char *name = "?";
|
||||||
|
|
||||||
|
dentry = d_find_alias(inode);
|
||||||
|
if (dentry) {
|
||||||
|
spin_lock(&dentry->d_lock);
|
||||||
|
name = (const char *) dentry->d_name.name;
|
||||||
|
}
|
||||||
|
printk(KERN_DEBUG
|
||||||
|
"%s(%d): dirtied inode %lu (%s) on %s\n",
|
||||||
|
current->comm, task_pid_nr(current), inode->i_ino,
|
||||||
|
name, inode->i_sb->s_id);
|
||||||
|
if (dentry) {
|
||||||
|
spin_unlock(&dentry->d_lock);
|
||||||
|
dput(dentry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* __mark_inode_dirty - internal function
|
* __mark_inode_dirty - internal function
|
||||||
* @inode: inode to mark
|
* @inode: inode to mark
|
||||||
|
@ -114,23 +136,8 @@ void __mark_inode_dirty(struct inode *inode, int flags)
|
||||||
if ((inode->i_state & flags) == flags)
|
if ((inode->i_state & flags) == flags)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (unlikely(block_dump)) {
|
if (unlikely(block_dump))
|
||||||
struct dentry *dentry = NULL;
|
block_dump___mark_inode_dirty(inode);
|
||||||
const char *name = "?";
|
|
||||||
|
|
||||||
if (!list_empty(&inode->i_dentry)) {
|
|
||||||
dentry = list_entry(inode->i_dentry.next,
|
|
||||||
struct dentry, d_alias);
|
|
||||||
if (dentry && dentry->d_name.name)
|
|
||||||
name = (const char *) dentry->d_name.name;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (inode->i_ino || strcmp(inode->i_sb->s_id, "bdev"))
|
|
||||||
printk(KERN_DEBUG
|
|
||||||
"%s(%d): dirtied inode %lu (%s) on %s\n",
|
|
||||||
current->comm, task_pid_nr(current), inode->i_ino,
|
|
||||||
name, inode->i_sb->s_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
spin_lock(&inode_lock);
|
spin_lock(&inode_lock);
|
||||||
if ((inode->i_state & flags) != flags) {
|
if ((inode->i_state & flags) != flags) {
|
||||||
|
|
Loading…
Reference in a new issue