diff options
Diffstat (limited to 'kernel/cgroup.c')
-rw-r--r-- | kernel/cgroup.c | 36 |
1 files changed, 18 insertions, 18 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 72fcd3069a90..b303dfc7dce0 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
@@ -255,12 +255,17 @@ int cgroup_lock_is_held(void) | |||
255 | 255 | ||
256 | EXPORT_SYMBOL_GPL(cgroup_lock_is_held); | 256 | EXPORT_SYMBOL_GPL(cgroup_lock_is_held); |
257 | 257 | ||
258 | static int css_unbias_refcnt(int refcnt) | ||
259 | { | ||
260 | return refcnt >= 0 ? refcnt : refcnt - CSS_DEACT_BIAS; | ||
261 | } | ||
262 | |||
258 | /* the current nr of refs, always >= 0 whether @css is deactivated or not */ | 263 | /* the current nr of refs, always >= 0 whether @css is deactivated or not */ |
259 | static int css_refcnt(struct cgroup_subsys_state *css) | 264 | static int css_refcnt(struct cgroup_subsys_state *css) |
260 | { | 265 | { |
261 | int v = atomic_read(&css->refcnt); | 266 | int v = atomic_read(&css->refcnt); |
262 | 267 | ||
263 | return v >= 0 ? v : v - CSS_DEACT_BIAS; | 268 | return css_unbias_refcnt(v); |
264 | } | 269 | } |
265 | 270 | ||
266 | /* convenient tests for these bits */ | 271 | /* convenient tests for these bits */ |
@@ -896,13 +901,10 @@ static void cgroup_diput(struct dentry *dentry, struct inode *inode) | |||
896 | mutex_unlock(&cgroup_mutex); | 901 | mutex_unlock(&cgroup_mutex); |
897 | 902 | ||
898 | /* | 903 | /* |
899 | * We want to drop the active superblock reference from the | 904 | * Drop the active superblock reference that we took when we |
900 | * cgroup creation after all the dentry refs are gone - | 905 | * created the cgroup |
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(). | ||
904 | */ | 906 | */ |
905 | dentry->d_fsdata = cgroup_diput; | 907 | deactivate_super(cgrp->root->sb); |
906 | 908 | ||
907 | /* | 909 | /* |
908 | * if we're getting rid of the cgroup, refcount should ensure | 910 | * if we're getting rid of the cgroup, refcount should ensure |
@@ -928,13 +930,6 @@ static int cgroup_delete(const struct dentry *d) | |||
928 | return 1; | 930 | return 1; |
929 | } | 931 | } |
930 | 932 | ||
931 | static 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 | |||
938 | static void remove_dir(struct dentry *d) | 933 | static void remove_dir(struct dentry *d) |
939 | { | 934 | { |
940 | struct dentry *parent = dget(d->d_parent); | 935 | struct dentry *parent = dget(d->d_parent); |
@@ -1542,7 +1537,6 @@ static int cgroup_get_rootdir(struct super_block *sb) | |||
1542 | static const struct dentry_operations cgroup_dops = { | 1537 | static const struct dentry_operations cgroup_dops = { |
1543 | .d_iput = cgroup_diput, | 1538 | .d_iput = cgroup_diput, |
1544 | .d_delete = cgroup_delete, | 1539 | .d_delete = cgroup_delete, |
1545 | .d_release = cgroup_d_release, | ||
1546 | }; | 1540 | }; |
1547 | 1541 | ||
1548 | struct inode *inode = | 1542 | struct inode *inode = |
@@ -3889,8 +3883,12 @@ static void css_dput_fn(struct work_struct *work) | |||
3889 | { | 3883 | { |
3890 | struct cgroup_subsys_state *css = | 3884 | struct cgroup_subsys_state *css = |
3891 | container_of(work, struct cgroup_subsys_state, dput_work); | 3885 | container_of(work, struct cgroup_subsys_state, dput_work); |
3886 | struct dentry *dentry = css->cgroup->dentry; | ||
3887 | struct super_block *sb = dentry->d_sb; | ||
3892 | 3888 | ||
3893 | dput(css->cgroup->dentry); | 3889 | atomic_inc(&sb->s_active); |
3890 | dput(dentry); | ||
3891 | deactivate_super(sb); | ||
3894 | } | 3892 | } |
3895 | 3893 | ||
3896 | static void init_cgroup_css(struct cgroup_subsys_state *css, | 3894 | static void init_cgroup_css(struct cgroup_subsys_state *css, |
@@ -4982,10 +4980,12 @@ EXPORT_SYMBOL_GPL(__css_tryget); | |||
4982 | void __css_put(struct cgroup_subsys_state *css) | 4980 | void __css_put(struct cgroup_subsys_state *css) |
4983 | { | 4981 | { |
4984 | struct cgroup *cgrp = css->cgroup; | 4982 | struct cgroup *cgrp = css->cgroup; |
4983 | int v; | ||
4985 | 4984 | ||
4986 | rcu_read_lock(); | 4985 | rcu_read_lock(); |
4987 | atomic_dec(&css->refcnt); | 4986 | v = css_unbias_refcnt(atomic_dec_return(&css->refcnt)); |
4988 | switch (css_refcnt(css)) { | 4987 | |
4988 | switch (v) { | ||
4989 | case 1: | 4989 | case 1: |
4990 | if (notify_on_release(cgrp)) { | 4990 | if (notify_on_release(cgrp)) { |
4991 | set_bit(CGRP_RELEASABLE, &cgrp->flags); | 4991 | set_bit(CGRP_RELEASABLE, &cgrp->flags); |