aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/cgroup.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index ad8eae5bb801..e887b55f1f29 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -896,10 +896,13 @@ static void cgroup_diput(struct dentry *dentry, struct inode *inode)
896 mutex_unlock(&cgroup_mutex); 896 mutex_unlock(&cgroup_mutex);
897 897
898 /* 898 /*
899 * Drop the active superblock reference that we took when we 899 * We want to drop the active superblock reference from the
900 * created the cgroup 900 * cgroup creation after all the dentry refs are gone -
901 * kill_sb gets mighty unhappy otherwise. Mark
902 * dentry->d_fsdata with cgroup_diput() to tell
903 * cgroup_d_release() to call deactivate_super().
901 */ 904 */
902 deactivate_super(cgrp->root->sb); 905 dentry->d_fsdata = cgroup_diput;
903 906
904 /* 907 /*
905 * if we're getting rid of the cgroup, refcount should ensure 908 * if we're getting rid of the cgroup, refcount should ensure
@@ -925,6 +928,13 @@ static int cgroup_delete(const struct dentry *d)
925 return 1; 928 return 1;
926} 929}
927 930
931static void cgroup_d_release(struct dentry *dentry)
932{
933 /* did cgroup_diput() tell me to deactivate super? */
934 if (dentry->d_fsdata == cgroup_diput)
935 deactivate_super(dentry->d_sb);
936}
937
928static void remove_dir(struct dentry *d) 938static void remove_dir(struct dentry *d)
929{ 939{
930 struct dentry *parent = dget(d->d_parent); 940 struct dentry *parent = dget(d->d_parent);
@@ -1532,6 +1542,7 @@ static int cgroup_get_rootdir(struct super_block *sb)
1532 static const struct dentry_operations cgroup_dops = { 1542 static const struct dentry_operations cgroup_dops = {
1533 .d_iput = cgroup_diput, 1543 .d_iput = cgroup_diput,
1534 .d_delete = cgroup_delete, 1544 .d_delete = cgroup_delete,
1545 .d_release = cgroup_d_release,
1535 }; 1546 };
1536 1547
1537 struct inode *inode = 1548 struct inode *inode =