Commit 4195f73d1329e49727bcceb028e58cb38376c2b0
Committed by
Al Viro
1 parent
545b9fd3d7
Exists in
master
and in
7 other branches
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>
Showing 1 changed file with 24 additions and 17 deletions Side-by-side Diff
fs/fs-writeback.c
... | ... | @@ -64,6 +64,28 @@ |
64 | 64 | clear_bit(BDI_pdflush, &bdi->state); |
65 | 65 | } |
66 | 66 | |
67 | +static noinline void block_dump___mark_inode_dirty(struct inode *inode) | |
68 | +{ | |
69 | + if (inode->i_ino || strcmp(inode->i_sb->s_id, "bdev")) { | |
70 | + struct dentry *dentry; | |
71 | + const char *name = "?"; | |
72 | + | |
73 | + dentry = d_find_alias(inode); | |
74 | + if (dentry) { | |
75 | + spin_lock(&dentry->d_lock); | |
76 | + name = (const char *) dentry->d_name.name; | |
77 | + } | |
78 | + printk(KERN_DEBUG | |
79 | + "%s(%d): dirtied inode %lu (%s) on %s\n", | |
80 | + current->comm, task_pid_nr(current), inode->i_ino, | |
81 | + name, inode->i_sb->s_id); | |
82 | + if (dentry) { | |
83 | + spin_unlock(&dentry->d_lock); | |
84 | + dput(dentry); | |
85 | + } | |
86 | + } | |
87 | +} | |
88 | + | |
67 | 89 | /** |
68 | 90 | * __mark_inode_dirty - internal function |
69 | 91 | * @inode: inode to mark |
... | ... | @@ -114,23 +136,8 @@ |
114 | 136 | if ((inode->i_state & flags) == flags) |
115 | 137 | return; |
116 | 138 | |
117 | - if (unlikely(block_dump)) { | |
118 | - struct dentry *dentry = NULL; | |
119 | - const char *name = "?"; | |
120 | - | |
121 | - if (!list_empty(&inode->i_dentry)) { | |
122 | - dentry = list_entry(inode->i_dentry.next, | |
123 | - struct dentry, d_alias); | |
124 | - if (dentry && dentry->d_name.name) | |
125 | - name = (const char *) dentry->d_name.name; | |
126 | - } | |
127 | - | |
128 | - if (inode->i_ino || strcmp(inode->i_sb->s_id, "bdev")) | |
129 | - printk(KERN_DEBUG | |
130 | - "%s(%d): dirtied inode %lu (%s) on %s\n", | |
131 | - current->comm, task_pid_nr(current), inode->i_ino, | |
132 | - name, inode->i_sb->s_id); | |
133 | - } | |
139 | + if (unlikely(block_dump)) | |
140 | + block_dump___mark_inode_dirty(inode); | |
134 | 141 | |
135 | 142 | spin_lock(&inode_lock); |
136 | 143 | if ((inode->i_state & flags) != flags) { |