aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/cgroup.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/cgroup.c')
-rw-r--r--kernel/cgroup.c54
1 files changed, 39 insertions, 15 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 66a416b42c18..51cddc11cd85 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -763,6 +763,8 @@ EXPORT_SYMBOL_GPL(cgroup_unlock);
763 * -> cgroup_mkdir. 763 * -> cgroup_mkdir.
764 */ 764 */
765 765
766static struct dentry *cgroup_lookup(struct inode *dir,
767 struct dentry *dentry, struct nameidata *nd);
766static int cgroup_mkdir(struct inode *dir, struct dentry *dentry, int mode); 768static int cgroup_mkdir(struct inode *dir, struct dentry *dentry, int mode);
767static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry); 769static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry);
768static int cgroup_populate_dir(struct cgroup *cgrp); 770static int cgroup_populate_dir(struct cgroup *cgrp);
@@ -874,25 +876,29 @@ static void cgroup_clear_directory(struct dentry *dentry)
874 struct list_head *node; 876 struct list_head *node;
875 877
876 BUG_ON(!mutex_is_locked(&dentry->d_inode->i_mutex)); 878 BUG_ON(!mutex_is_locked(&dentry->d_inode->i_mutex));
877 spin_lock(&dcache_lock); 879 spin_lock(&dentry->d_lock);
878 node = dentry->d_subdirs.next; 880 node = dentry->d_subdirs.next;
879 while (node != &dentry->d_subdirs) { 881 while (node != &dentry->d_subdirs) {
880 struct dentry *d = list_entry(node, struct dentry, d_u.d_child); 882 struct dentry *d = list_entry(node, struct dentry, d_u.d_child);
883
884 spin_lock_nested(&d->d_lock, DENTRY_D_LOCK_NESTED);
881 list_del_init(node); 885 list_del_init(node);
882 if (d->d_inode) { 886 if (d->d_inode) {
883 /* This should never be called on a cgroup 887 /* This should never be called on a cgroup
884 * directory with child cgroups */ 888 * directory with child cgroups */
885 BUG_ON(d->d_inode->i_mode & S_IFDIR); 889 BUG_ON(d->d_inode->i_mode & S_IFDIR);
886 d = dget_locked(d); 890 dget_dlock(d);
887 spin_unlock(&dcache_lock); 891 spin_unlock(&d->d_lock);
892 spin_unlock(&dentry->d_lock);
888 d_delete(d); 893 d_delete(d);
889 simple_unlink(dentry->d_inode, d); 894 simple_unlink(dentry->d_inode, d);
890 dput(d); 895 dput(d);
891 spin_lock(&dcache_lock); 896 spin_lock(&dentry->d_lock);
892 } 897 } else
898 spin_unlock(&d->d_lock);
893 node = dentry->d_subdirs.next; 899 node = dentry->d_subdirs.next;
894 } 900 }
895 spin_unlock(&dcache_lock); 901 spin_unlock(&dentry->d_lock);
896} 902}
897 903
898/* 904/*
@@ -900,11 +906,16 @@ static void cgroup_clear_directory(struct dentry *dentry)
900 */ 906 */
901static void cgroup_d_remove_dir(struct dentry *dentry) 907static void cgroup_d_remove_dir(struct dentry *dentry)
902{ 908{
909 struct dentry *parent;
910
903 cgroup_clear_directory(dentry); 911 cgroup_clear_directory(dentry);
904 912
905 spin_lock(&dcache_lock); 913 parent = dentry->d_parent;
914 spin_lock(&parent->d_lock);
915 spin_lock(&dentry->d_lock);
906 list_del_init(&dentry->d_u.d_child); 916 list_del_init(&dentry->d_u.d_child);
907 spin_unlock(&dcache_lock); 917 spin_unlock(&dentry->d_lock);
918 spin_unlock(&parent->d_lock);
908 remove_dir(dentry); 919 remove_dir(dentry);
909} 920}
910 921
@@ -2180,7 +2191,7 @@ static const struct file_operations cgroup_file_operations = {
2180}; 2191};
2181 2192
2182static const struct inode_operations cgroup_dir_inode_operations = { 2193static const struct inode_operations cgroup_dir_inode_operations = {
2183 .lookup = simple_lookup, 2194 .lookup = cgroup_lookup,
2184 .mkdir = cgroup_mkdir, 2195 .mkdir = cgroup_mkdir,
2185 .rmdir = cgroup_rmdir, 2196 .rmdir = cgroup_rmdir,
2186 .rename = cgroup_rename, 2197 .rename = cgroup_rename,
@@ -2196,13 +2207,29 @@ static inline struct cftype *__file_cft(struct file *file)
2196 return __d_cft(file->f_dentry); 2207 return __d_cft(file->f_dentry);
2197} 2208}
2198 2209
2199static int cgroup_create_file(struct dentry *dentry, mode_t mode, 2210static int cgroup_delete_dentry(const struct dentry *dentry)
2200 struct super_block *sb) 2211{
2212 return 1;
2213}
2214
2215static struct dentry *cgroup_lookup(struct inode *dir,
2216 struct dentry *dentry, struct nameidata *nd)
2201{ 2217{
2202 static const struct dentry_operations cgroup_dops = { 2218 static const struct dentry_operations cgroup_dentry_operations = {
2219 .d_delete = cgroup_delete_dentry,
2203 .d_iput = cgroup_diput, 2220 .d_iput = cgroup_diput,
2204 }; 2221 };
2205 2222
2223 if (dentry->d_name.len > NAME_MAX)
2224 return ERR_PTR(-ENAMETOOLONG);
2225 d_set_d_op(dentry, &cgroup_dentry_operations);
2226 d_add(dentry, NULL);
2227 return NULL;
2228}
2229
2230static int cgroup_create_file(struct dentry *dentry, mode_t mode,
2231 struct super_block *sb)
2232{
2206 struct inode *inode; 2233 struct inode *inode;
2207 2234
2208 if (!dentry) 2235 if (!dentry)
@@ -2228,7 +2255,6 @@ static int cgroup_create_file(struct dentry *dentry, mode_t mode,
2228 inode->i_size = 0; 2255 inode->i_size = 0;
2229 inode->i_fop = &cgroup_file_operations; 2256 inode->i_fop = &cgroup_file_operations;
2230 } 2257 }
2231 dentry->d_op = &cgroup_dops;
2232 d_instantiate(dentry, inode); 2258 d_instantiate(dentry, inode);
2233 dget(dentry); /* Extra count - pin the dentry in core */ 2259 dget(dentry); /* Extra count - pin the dentry in core */
2234 return 0; 2260 return 0;
@@ -3638,9 +3664,7 @@ again:
3638 list_del(&cgrp->sibling); 3664 list_del(&cgrp->sibling);
3639 cgroup_unlock_hierarchy(cgrp->root); 3665 cgroup_unlock_hierarchy(cgrp->root);
3640 3666
3641 spin_lock(&cgrp->dentry->d_lock);
3642 d = dget(cgrp->dentry); 3667 d = dget(cgrp->dentry);
3643 spin_unlock(&d->d_lock);
3644 3668
3645 cgroup_d_remove_dir(d); 3669 cgroup_d_remove_dir(d);
3646 dput(d); 3670 dput(d);