git://ftp.safe.ca
/
safe
/
jmp
/
linux-2.6
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
cgroup: fix strstrip() misuse
[safe/jmp/linux-2.6]
/
kernel
/
cgroup.c
diff --git
a/kernel/cgroup.c
b/kernel/cgroup.c
index
3e356b0
..
0249f4b
100644
(file)
--- a/
kernel/cgroup.c
+++ b/
kernel/cgroup.c
@@
-267,6
+267,12
@@
static struct hlist_head *css_set_hash(struct cgroup_subsys_state *css[])
return &css_set_table[index];
}
return &css_set_table[index];
}
+static void free_css_set_rcu(struct rcu_head *obj)
+{
+ struct css_set *cg = container_of(obj, struct css_set, rcu_head);
+ kfree(cg);
+}
+
/* We don't maintain the lists running through each css_set to its
* task until after the first call to cgroup_iter_start(). This
* reduces the fork()/exit() overhead for people who have cgroups
/* We don't maintain the lists running through each css_set to its
* task until after the first call to cgroup_iter_start(). This
* reduces the fork()/exit() overhead for people who have cgroups
@@
-310,7
+316,7
@@
static void __put_css_set(struct css_set *cg, int taskexit)
}
write_unlock(&css_set_lock);
}
write_unlock(&css_set_lock);
-
kfree(cg
);
+
call_rcu(&cg->rcu_head, free_css_set_rcu
);
}
/*
}
/*
@@
-697,7
+703,7
@@
static int cgroup_mkdir(struct inode *dir, struct dentry *dentry, int mode);
static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry);
static int cgroup_populate_dir(struct cgroup *cgrp);
static const struct inode_operations cgroup_dir_inode_operations;
static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry);
static int cgroup_populate_dir(struct cgroup *cgrp);
static const struct inode_operations cgroup_dir_inode_operations;
-static struct file_operations proc_cgroupstats_operations;
+static
const
struct file_operations proc_cgroupstats_operations;
static struct backing_dev_info cgroup_backing_dev_info = {
.name = "cgroup",
static struct backing_dev_info cgroup_backing_dev_info = {
.name = "cgroup",
@@
-1546,7
+1552,7
@@
int cgroup_attach_task(struct cgroup *cgrp, struct task_struct *tsk)
for_each_subsys(root, ss) {
if (ss->can_attach) {
for_each_subsys(root, ss) {
if (ss->can_attach) {
- retval = ss->can_attach(ss, cgrp, tsk);
+ retval = ss->can_attach(ss, cgrp, tsk
, false
);
if (retval)
return retval;
}
if (retval)
return retval;
}
@@
-1584,7
+1590,7
@@
int cgroup_attach_task(struct cgroup *cgrp, struct task_struct *tsk)
for_each_subsys(root, ss) {
if (ss->attach)
for_each_subsys(root, ss) {
if (ss->attach)
- ss->attach(ss, cgrp, oldcgrp, tsk);
+ ss->attach(ss, cgrp, oldcgrp, tsk
, false
);
}
set_bit(CGRP_RELEASABLE, &oldcgrp->flags);
synchronize_rcu();
}
set_bit(CGRP_RELEASABLE, &oldcgrp->flags);
synchronize_rcu();
@@
-1704,14
+1710,13
@@
static ssize_t cgroup_write_X64(struct cgroup *cgrp, struct cftype *cft,
return -EFAULT;
buffer[nbytes] = 0; /* nul-terminate */
return -EFAULT;
buffer[nbytes] = 0; /* nul-terminate */
- strstrip(buffer);
if (cft->write_u64) {
if (cft->write_u64) {
- u64 val = simple_strtoull(
buffer
, &end, 0);
+ u64 val = simple_strtoull(
strstrip(buffer)
, &end, 0);
if (*end)
return -EINVAL;
retval = cft->write_u64(cgrp, cft, val);
} else {
if (*end)
return -EINVAL;
retval = cft->write_u64(cgrp, cft, val);
} else {
- s64 val = simple_strtoll(
buffer
, &end, 0);
+ s64 val = simple_strtoll(
strstrip(buffer)
, &end, 0);
if (*end)
return -EINVAL;
retval = cft->write_s64(cgrp, cft, val);
if (*end)
return -EINVAL;
retval = cft->write_s64(cgrp, cft, val);
@@
-1747,8
+1752,7
@@
static ssize_t cgroup_write_string(struct cgroup *cgrp, struct cftype *cft,
}
buffer[nbytes] = 0; /* nul-terminate */
}
buffer[nbytes] = 0; /* nul-terminate */
- strstrip(buffer);
- retval = cft->write_string(cgrp, cft, buffer);
+ retval = cft->write_string(cgrp, cft, strstrip(buffer));
if (!retval)
retval = nbytes;
out:
if (!retval)
retval = nbytes;
out:
@@
-1857,7
+1861,7
@@
static int cgroup_seqfile_release(struct inode *inode, struct file *file)
return single_release(inode, file);
}
return single_release(inode, file);
}
-static struct file_operations cgroup_seqfile_operations = {
+static
const
struct file_operations cgroup_seqfile_operations = {
.read = seq_read,
.write = cgroup_file_write,
.llseek = seq_lseek,
.read = seq_read,
.write = cgroup_file_write,
.llseek = seq_lseek,
@@
-1916,7
+1920,7
@@
static int cgroup_rename(struct inode *old_dir, struct dentry *old_dentry,
return simple_rename(old_dir, old_dentry, new_dir, new_dentry);
}
return simple_rename(old_dir, old_dentry, new_dir, new_dentry);
}
-static struct file_operations cgroup_file_operations = {
+static
const
struct file_operations cgroup_file_operations = {
.read = cgroup_file_read,
.write = cgroup_file_write,
.llseek = generic_file_llseek,
.read = cgroup_file_read,
.write = cgroup_file_write,
.llseek = generic_file_llseek,
@@
-3363,7
+3367,7
@@
static int cgroup_open(struct inode *inode, struct file *file)
return single_open(file, proc_cgroup_show, pid);
}
return single_open(file, proc_cgroup_show, pid);
}
-struct file_operations proc_cgroup_operations = {
+
const
struct file_operations proc_cgroup_operations = {
.open = cgroup_open,
.read = seq_read,
.llseek = seq_lseek,
.open = cgroup_open,
.read = seq_read,
.llseek = seq_lseek,
@@
-3392,7
+3396,7
@@
static int cgroupstats_open(struct inode *inode, struct file *file)
return single_open(file, proc_cgroupstats_show, NULL);
}
return single_open(file, proc_cgroupstats_show, NULL);
}
-static struct file_operations proc_cgroupstats_operations = {
+static
const
struct file_operations proc_cgroupstats_operations = {
.open = cgroupstats_open,
.read = seq_read,
.llseek = seq_lseek,
.open = cgroupstats_open,
.read = seq_read,
.llseek = seq_lseek,
@@
-3702,8
+3706,10
@@
static void check_for_release(struct cgroup *cgrp)
void __css_put(struct cgroup_subsys_state *css)
{
struct cgroup *cgrp = css->cgroup;
void __css_put(struct cgroup_subsys_state *css)
{
struct cgroup *cgrp = css->cgroup;
+ int val;
rcu_read_lock();
rcu_read_lock();
- if (atomic_dec_return(&css->refcnt) == 1) {
+ val = atomic_dec_return(&css->refcnt);
+ if (val == 1) {
if (notify_on_release(cgrp)) {
set_bit(CGRP_RELEASABLE, &cgrp->flags);
check_for_release(cgrp);
if (notify_on_release(cgrp)) {
set_bit(CGRP_RELEASABLE, &cgrp->flags);
check_for_release(cgrp);
@@
-3711,6
+3717,7
@@
void __css_put(struct cgroup_subsys_state *css)
cgroup_wakeup_rmdir_waiter(cgrp);
}
rcu_read_unlock();
cgroup_wakeup_rmdir_waiter(cgrp);
}
rcu_read_unlock();
+ WARN_ON_ONCE(val < 1);
}
/*
}
/*