aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/selinuxfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux/selinuxfs.c')
-rw-r--r--security/selinux/selinuxfs.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index 073fd5b0a53a..017ec096446e 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -1146,22 +1146,30 @@ static void sel_remove_entries(struct dentry *de)
1146 struct list_head *node; 1146 struct list_head *node;
1147 1147
1148 spin_lock(&dcache_lock); 1148 spin_lock(&dcache_lock);
1149 spin_lock(&de->d_lock);
1149 node = de->d_subdirs.next; 1150 node = de->d_subdirs.next;
1150 while (node != &de->d_subdirs) { 1151 while (node != &de->d_subdirs) {
1151 struct dentry *d = list_entry(node, struct dentry, d_u.d_child); 1152 struct dentry *d = list_entry(node, struct dentry, d_u.d_child);
1153
1154 spin_lock_nested(&d->d_lock, DENTRY_D_LOCK_NESTED);
1152 list_del_init(node); 1155 list_del_init(node);
1153 1156
1154 if (d->d_inode) { 1157 if (d->d_inode) {
1155 d = dget_locked(d); 1158 dget_locked_dlock(d);
1159 spin_unlock(&de->d_lock);
1160 spin_unlock(&d->d_lock);
1156 spin_unlock(&dcache_lock); 1161 spin_unlock(&dcache_lock);
1157 d_delete(d); 1162 d_delete(d);
1158 simple_unlink(de->d_inode, d); 1163 simple_unlink(de->d_inode, d);
1159 dput(d); 1164 dput(d);
1160 spin_lock(&dcache_lock); 1165 spin_lock(&dcache_lock);
1161 } 1166 spin_lock(&de->d_lock);
1167 } else
1168 spin_unlock(&d->d_lock);
1162 node = de->d_subdirs.next; 1169 node = de->d_subdirs.next;
1163 } 1170 }
1164 1171
1172 spin_unlock(&de->d_lock);
1165 spin_unlock(&dcache_lock); 1173 spin_unlock(&dcache_lock);
1166} 1174}
1167 1175