diff options
Diffstat (limited to 'kernel/cgroup.c')
| -rw-r--r-- | kernel/cgroup.c | 17 | 
1 files changed, 14 insertions, 3 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 0f3527d6184a..72fcd3069a90 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -896,10 +896,13 @@ static void cgroup_diput(struct dentry *dentry, struct inode *inode)  		mutex_unlock(&cgroup_mutex);  		/* -		 * Drop the active superblock reference that we took when we -		 * created the cgroup +		 * We want to drop the active superblock reference from the +		 * cgroup creation after all the dentry refs are gone - +		 * kill_sb gets mighty unhappy otherwise.  Mark +		 * dentry->d_fsdata with cgroup_diput() to tell +		 * cgroup_d_release() to call deactivate_super().  		 */ -		deactivate_super(cgrp->root->sb); +		dentry->d_fsdata = cgroup_diput;  		/*  		 * if we're getting rid of the cgroup, refcount should ensure @@ -925,6 +928,13 @@ static int cgroup_delete(const struct dentry *d)  	return 1;  } +static void cgroup_d_release(struct dentry *dentry) +{ +	/* did cgroup_diput() tell me to deactivate super? */ +	if (dentry->d_fsdata == cgroup_diput) +		deactivate_super(dentry->d_sb); +} +  static void remove_dir(struct dentry *d)  {  	struct dentry *parent = dget(d->d_parent); @@ -1532,6 +1542,7 @@ static int cgroup_get_rootdir(struct super_block *sb)  	static const struct dentry_operations cgroup_dops = {  		.d_iput = cgroup_diput,  		.d_delete = cgroup_delete, +		.d_release = cgroup_d_release,  	};  	struct inode *inode =  | 
