Merge branch 'for-4.6-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup
Pull cgroup fixes from Tejun Heo: "During v4.6-rc1 cgroup namespace support was merged. There is an issue where it's impossible to tell whether a given cgroup mount point is bind mounted or namespaced. Serge has been working on the issue but it took longer than expected to resolve, so the late pull request. Given that it's a completely new feature and the patches don't touch anything else, the risk seems acceptable. However, if this is too late, an alternative is plugging new cgroup ns creation for v4.6 and retrying for v4.7" * 'for-4.6-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup: cgroup: fix compile warning kernfs: kernfs_sop_show_path: don't return 0 after seq_dentry call cgroup, kernfs: make mountinfo show properly scoped path for cgroup namespaces kernfs_path_from_node_locked: don't overwrite nlen
This commit is contained in:
Коммит
1410b74e40
|
@ -153,9 +153,9 @@ static int kernfs_path_from_node_locked(struct kernfs_node *kn_to,
|
|||
p = buf + len + nlen;
|
||||
*p = '\0';
|
||||
for (kn = kn_to; kn != common; kn = kn->parent) {
|
||||
nlen = strlen(kn->name);
|
||||
p -= nlen;
|
||||
memcpy(p, kn->name, nlen);
|
||||
size_t tmp = strlen(kn->name);
|
||||
p -= tmp;
|
||||
memcpy(p, kn->name, tmp);
|
||||
*(--p) = '/';
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include <linux/slab.h>
|
||||
#include <linux/pagemap.h>
|
||||
#include <linux/namei.h>
|
||||
#include <linux/seq_file.h>
|
||||
|
||||
#include "kernfs-internal.h"
|
||||
|
||||
|
@ -40,6 +41,19 @@ static int kernfs_sop_show_options(struct seq_file *sf, struct dentry *dentry)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int kernfs_sop_show_path(struct seq_file *sf, struct dentry *dentry)
|
||||
{
|
||||
struct kernfs_node *node = dentry->d_fsdata;
|
||||
struct kernfs_root *root = kernfs_root(node);
|
||||
struct kernfs_syscall_ops *scops = root->syscall_ops;
|
||||
|
||||
if (scops && scops->show_path)
|
||||
return scops->show_path(sf, node, root);
|
||||
|
||||
seq_dentry(sf, dentry, " \t\n\\");
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct super_operations kernfs_sops = {
|
||||
.statfs = simple_statfs,
|
||||
.drop_inode = generic_delete_inode,
|
||||
|
@ -47,6 +61,7 @@ const struct super_operations kernfs_sops = {
|
|||
|
||||
.remount_fs = kernfs_sop_remount_fs,
|
||||
.show_options = kernfs_sop_show_options,
|
||||
.show_path = kernfs_sop_show_path,
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -152,6 +152,8 @@ struct kernfs_syscall_ops {
|
|||
int (*rmdir)(struct kernfs_node *kn);
|
||||
int (*rename)(struct kernfs_node *kn, struct kernfs_node *new_parent,
|
||||
const char *new_name);
|
||||
int (*show_path)(struct seq_file *sf, struct kernfs_node *kn,
|
||||
struct kernfs_root *root);
|
||||
};
|
||||
|
||||
struct kernfs_root {
|
||||
|
|
|
@ -1215,6 +1215,41 @@ static void cgroup_destroy_root(struct cgroup_root *root)
|
|||
cgroup_free_root(root);
|
||||
}
|
||||
|
||||
/*
|
||||
* look up cgroup associated with current task's cgroup namespace on the
|
||||
* specified hierarchy
|
||||
*/
|
||||
static struct cgroup *
|
||||
current_cgns_cgroup_from_root(struct cgroup_root *root)
|
||||
{
|
||||
struct cgroup *res = NULL;
|
||||
struct css_set *cset;
|
||||
|
||||
lockdep_assert_held(&css_set_lock);
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
cset = current->nsproxy->cgroup_ns->root_cset;
|
||||
if (cset == &init_css_set) {
|
||||
res = &root->cgrp;
|
||||
} else {
|
||||
struct cgrp_cset_link *link;
|
||||
|
||||
list_for_each_entry(link, &cset->cgrp_links, cgrp_link) {
|
||||
struct cgroup *c = link->cgrp;
|
||||
|
||||
if (c->root == root) {
|
||||
res = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
BUG_ON(!res);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* look up cgroup associated with given css_set on the specified hierarchy */
|
||||
static struct cgroup *cset_cgroup_from_root(struct css_set *cset,
|
||||
struct cgroup_root *root)
|
||||
|
@ -1593,6 +1628,33 @@ static int rebind_subsystems(struct cgroup_root *dst_root, u16 ss_mask)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int cgroup_show_path(struct seq_file *sf, struct kernfs_node *kf_node,
|
||||
struct kernfs_root *kf_root)
|
||||
{
|
||||
int len = 0;
|
||||
char *buf = NULL;
|
||||
struct cgroup_root *kf_cgroot = cgroup_root_from_kf(kf_root);
|
||||
struct cgroup *ns_cgroup;
|
||||
|
||||
buf = kmalloc(PATH_MAX, GFP_KERNEL);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
spin_lock_bh(&css_set_lock);
|
||||
ns_cgroup = current_cgns_cgroup_from_root(kf_cgroot);
|
||||
len = kernfs_path_from_node(kf_node, ns_cgroup->kn, buf, PATH_MAX);
|
||||
spin_unlock_bh(&css_set_lock);
|
||||
|
||||
if (len >= PATH_MAX)
|
||||
len = -ERANGE;
|
||||
else if (len > 0) {
|
||||
seq_escape(sf, buf, " \t\n\\");
|
||||
len = 0;
|
||||
}
|
||||
kfree(buf);
|
||||
return len;
|
||||
}
|
||||
|
||||
static int cgroup_show_options(struct seq_file *seq,
|
||||
struct kernfs_root *kf_root)
|
||||
{
|
||||
|
@ -5433,6 +5495,7 @@ static struct kernfs_syscall_ops cgroup_kf_syscall_ops = {
|
|||
.mkdir = cgroup_mkdir,
|
||||
.rmdir = cgroup_rmdir,
|
||||
.rename = cgroup_rename,
|
||||
.show_path = cgroup_show_path,
|
||||
};
|
||||
|
||||
static void __init cgroup_init_subsys(struct cgroup_subsys *ss, bool early)
|
||||
|
|
Загрузка…
Ссылка в новой задаче