diff options
author | Li Zefan <lizf@cn.fujitsu.com> | 2009-04-02 19:57:29 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-04-02 22:04:54 -0400 |
commit | 099fca3225b39f7a3ed853036038054172b55581 (patch) | |
tree | c7a8863f9ca8a5c745297e9ee43b63494b6022d1 /kernel | |
parent | b6719ec1ad54e47e40633b19703f2c1254708842 (diff) |
cgroups: show correct file mode
We have some read-only files and write-only files, but currently they are
all set to 0644, which is counter-intuitive and cause trouble for some
cgroup tools like libcgroup.
This patch adds 'mode' to struct cftype to allow cgroup subsys to set it's
own files' file mode, and for the most cases cft->mode can be default to 0
and cgroup will figure out proper mode.
Acked-by: Paul Menage <menage@google.com>
Reviewed-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/cgroup.c | 38 | ||||
-rw-r--r-- | kernel/cpuset.c | 1 |
2 files changed, 35 insertions, 4 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 9a6c2bfa1d9f..fea11c5c990c 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
@@ -1686,7 +1686,7 @@ static struct inode_operations cgroup_dir_inode_operations = { | |||
1686 | .rename = cgroup_rename, | 1686 | .rename = cgroup_rename, |
1687 | }; | 1687 | }; |
1688 | 1688 | ||
1689 | static int cgroup_create_file(struct dentry *dentry, int mode, | 1689 | static int cgroup_create_file(struct dentry *dentry, mode_t mode, |
1690 | struct super_block *sb) | 1690 | struct super_block *sb) |
1691 | { | 1691 | { |
1692 | static const struct dentry_operations cgroup_dops = { | 1692 | static const struct dentry_operations cgroup_dops = { |
@@ -1732,7 +1732,7 @@ static int cgroup_create_file(struct dentry *dentry, int mode, | |||
1732 | * @mode: mode to set on new directory. | 1732 | * @mode: mode to set on new directory. |
1733 | */ | 1733 | */ |
1734 | static int cgroup_create_dir(struct cgroup *cgrp, struct dentry *dentry, | 1734 | static int cgroup_create_dir(struct cgroup *cgrp, struct dentry *dentry, |
1735 | int mode) | 1735 | mode_t mode) |
1736 | { | 1736 | { |
1737 | struct dentry *parent; | 1737 | struct dentry *parent; |
1738 | int error = 0; | 1738 | int error = 0; |
@@ -1750,6 +1750,33 @@ static int cgroup_create_dir(struct cgroup *cgrp, struct dentry *dentry, | |||
1750 | return error; | 1750 | return error; |
1751 | } | 1751 | } |
1752 | 1752 | ||
1753 | /** | ||
1754 | * cgroup_file_mode - deduce file mode of a control file | ||
1755 | * @cft: the control file in question | ||
1756 | * | ||
1757 | * returns cft->mode if ->mode is not 0 | ||
1758 | * returns S_IRUGO|S_IWUSR if it has both a read and a write handler | ||
1759 | * returns S_IRUGO if it has only a read handler | ||
1760 | * returns S_IWUSR if it has only a write hander | ||
1761 | */ | ||
1762 | static mode_t cgroup_file_mode(const struct cftype *cft) | ||
1763 | { | ||
1764 | mode_t mode = 0; | ||
1765 | |||
1766 | if (cft->mode) | ||
1767 | return cft->mode; | ||
1768 | |||
1769 | if (cft->read || cft->read_u64 || cft->read_s64 || | ||
1770 | cft->read_map || cft->read_seq_string) | ||
1771 | mode |= S_IRUGO; | ||
1772 | |||
1773 | if (cft->write || cft->write_u64 || cft->write_s64 || | ||
1774 | cft->write_string || cft->trigger) | ||
1775 | mode |= S_IWUSR; | ||
1776 | |||
1777 | return mode; | ||
1778 | } | ||
1779 | |||
1753 | int cgroup_add_file(struct cgroup *cgrp, | 1780 | int cgroup_add_file(struct cgroup *cgrp, |
1754 | struct cgroup_subsys *subsys, | 1781 | struct cgroup_subsys *subsys, |
1755 | const struct cftype *cft) | 1782 | const struct cftype *cft) |
@@ -1757,6 +1784,7 @@ int cgroup_add_file(struct cgroup *cgrp, | |||
1757 | struct dentry *dir = cgrp->dentry; | 1784 | struct dentry *dir = cgrp->dentry; |
1758 | struct dentry *dentry; | 1785 | struct dentry *dentry; |
1759 | int error; | 1786 | int error; |
1787 | mode_t mode; | ||
1760 | 1788 | ||
1761 | char name[MAX_CGROUP_TYPE_NAMELEN + MAX_CFTYPE_NAME + 2] = { 0 }; | 1789 | char name[MAX_CGROUP_TYPE_NAMELEN + MAX_CFTYPE_NAME + 2] = { 0 }; |
1762 | if (subsys && !test_bit(ROOT_NOPREFIX, &cgrp->root->flags)) { | 1790 | if (subsys && !test_bit(ROOT_NOPREFIX, &cgrp->root->flags)) { |
@@ -1767,7 +1795,8 @@ int cgroup_add_file(struct cgroup *cgrp, | |||
1767 | BUG_ON(!mutex_is_locked(&dir->d_inode->i_mutex)); | 1795 | BUG_ON(!mutex_is_locked(&dir->d_inode->i_mutex)); |
1768 | dentry = lookup_one_len(name, dir, strlen(name)); | 1796 | dentry = lookup_one_len(name, dir, strlen(name)); |
1769 | if (!IS_ERR(dentry)) { | 1797 | if (!IS_ERR(dentry)) { |
1770 | error = cgroup_create_file(dentry, 0644 | S_IFREG, | 1798 | mode = cgroup_file_mode(cft); |
1799 | error = cgroup_create_file(dentry, mode | S_IFREG, | ||
1771 | cgrp->root->sb); | 1800 | cgrp->root->sb); |
1772 | if (!error) | 1801 | if (!error) |
1773 | dentry->d_fsdata = (void *)cft; | 1802 | dentry->d_fsdata = (void *)cft; |
@@ -2349,6 +2378,7 @@ static struct cftype files[] = { | |||
2349 | .write_u64 = cgroup_tasks_write, | 2378 | .write_u64 = cgroup_tasks_write, |
2350 | .release = cgroup_tasks_release, | 2379 | .release = cgroup_tasks_release, |
2351 | .private = FILE_TASKLIST, | 2380 | .private = FILE_TASKLIST, |
2381 | .mode = S_IRUGO | S_IWUSR, | ||
2352 | }, | 2382 | }, |
2353 | 2383 | ||
2354 | { | 2384 | { |
@@ -2449,7 +2479,7 @@ static void cgroup_unlock_hierarchy(struct cgroupfs_root *root) | |||
2449 | * Must be called with the mutex on the parent inode held | 2479 | * Must be called with the mutex on the parent inode held |
2450 | */ | 2480 | */ |
2451 | static long cgroup_create(struct cgroup *parent, struct dentry *dentry, | 2481 | static long cgroup_create(struct cgroup *parent, struct dentry *dentry, |
2452 | int mode) | 2482 | mode_t mode) |
2453 | { | 2483 | { |
2454 | struct cgroup *cgrp; | 2484 | struct cgroup *cgrp; |
2455 | struct cgroupfs_root *root = parent->root; | 2485 | struct cgroupfs_root *root = parent->root; |
diff --git a/kernel/cpuset.c b/kernel/cpuset.c index f76db9dcaa05..ee5ec386aa8b 100644 --- a/kernel/cpuset.c +++ b/kernel/cpuset.c | |||
@@ -1706,6 +1706,7 @@ static struct cftype files[] = { | |||
1706 | .read_u64 = cpuset_read_u64, | 1706 | .read_u64 = cpuset_read_u64, |
1707 | .write_u64 = cpuset_write_u64, | 1707 | .write_u64 = cpuset_write_u64, |
1708 | .private = FILE_MEMORY_PRESSURE, | 1708 | .private = FILE_MEMORY_PRESSURE, |
1709 | .mode = S_IRUGO, | ||
1709 | }, | 1710 | }, |
1710 | 1711 | ||
1711 | { | 1712 | { |