Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f34d3606 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull cgroup updates from Tejun Heo:

 - tracepoints for basic cgroup management operations added

 - kernfs and cgroup path formatting functions updated to behave in the
   style of strlcpy()

 - non-critical bug fixes

* 'for-4.9' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup:
  blkcg: Unlock blkcg_pol_mutex only once when cpd == NULL
  cgroup: fix error handling regressions in proc_cgroup_show() and cgroup_release_agent()
  cpuset: fix error handling regression in proc_cpuset_show()
  cgroup: add tracepoints for basic operations
  cgroup: make cgroup_path() and friends behave in the style of strlcpy()
  kernfs: remove kernfs_path_len()
  kernfs: make kernfs_path*() behave in the style of strlcpy()
  kernfs: add dummy implementation of kernfs_path_from_node()
parents b6daa51b bbb427e3
Loading
Loading
Loading
Loading
+1 −3
Original line number Diff line number Diff line
@@ -1340,10 +1340,8 @@ int blkcg_policy_register(struct blkcg_policy *pol)
			struct blkcg_policy_data *cpd;

			cpd = pol->cpd_alloc_fn(GFP_KERNEL);
			if (!cpd) {
				mutex_unlock(&blkcg_pol_mutex);
			if (!cpd)
				goto err_free_cpds;
			}

			blkcg->cpd[pol->plid] = cpd;
			cpd->blkcg = blkcg;
+17 −67
Original line number Diff line number Diff line
@@ -110,8 +110,9 @@ static struct kernfs_node *kernfs_common_ancestor(struct kernfs_node *a,
 * kn_to:   /n1/n2/n3         [depth=3]
 * result:  /../..
 *
 * return value: length of the string.  If greater than buflen,
 * then contents of buf are undefined.  On error, -1 is returned.
 * Returns the length of the full path.  If the full length is equal to or
 * greater than @buflen, @buf contains the truncated path with the trailing
 * '\0'.  On error, -errno is returned.
 */
static int kernfs_path_from_node_locked(struct kernfs_node *kn_to,
					struct kernfs_node *kn_from,
@@ -119,9 +120,8 @@ static int kernfs_path_from_node_locked(struct kernfs_node *kn_to,
{
	struct kernfs_node *kn, *common;
	const char parent_str[] = "/..";
	size_t depth_from, depth_to, len = 0, nlen = 0;
	char *p;
	int i;
	size_t depth_from, depth_to, len = 0;
	int i, j;

	if (!kn_from)
		kn_from = kernfs_root(kn_to)->kn;
@@ -131,7 +131,7 @@ static int kernfs_path_from_node_locked(struct kernfs_node *kn_to,

	common = kernfs_common_ancestor(kn_from, kn_to);
	if (WARN_ON(!common))
		return -1;
		return -EINVAL;

	depth_to = kernfs_depth(common, kn_to);
	depth_from = kernfs_depth(common, kn_from);
@@ -144,22 +144,16 @@ static int kernfs_path_from_node_locked(struct kernfs_node *kn_to,
			       len < buflen ? buflen - len : 0);

	/* Calculate how many bytes we need for the rest */
	for (kn = kn_to; kn != common; kn = kn->parent)
		nlen += strlen(kn->name) + 1;

	if (len + nlen >= buflen)
		return len + nlen;

	p = buf + len + nlen;
	*p = '\0';
	for (kn = kn_to; kn != common; kn = kn->parent) {
		size_t tmp = strlen(kn->name);
		p -= tmp;
		memcpy(p, kn->name, tmp);
		*(--p) = '/';
	for (i = depth_to - 1; i >= 0; i--) {
		for (kn = kn_to, j = 0; j < i; j++)
			kn = kn->parent;
		len += strlcpy(buf + len, "/",
			       len < buflen ? buflen - len : 0);
		len += strlcpy(buf + len, kn->name,
			       len < buflen ? buflen - len : 0);
	}

	return len + nlen;
	return len;
}

/**
@@ -185,29 +179,6 @@ int kernfs_name(struct kernfs_node *kn, char *buf, size_t buflen)
	return ret;
}

/**
 * kernfs_path_len - determine the length of the full path of a given node
 * @kn: kernfs_node of interest
 *
 * The returned length doesn't include the space for the terminating '\0'.
 */
size_t kernfs_path_len(struct kernfs_node *kn)
{
	size_t len = 0;
	unsigned long flags;

	spin_lock_irqsave(&kernfs_rename_lock, flags);

	do {
		len += strlen(kn->name) + 1;
		kn = kn->parent;
	} while (kn && kn->parent);

	spin_unlock_irqrestore(&kernfs_rename_lock, flags);

	return len;
}

/**
 * kernfs_path_from_node - build path of node @to relative to @from.
 * @from: parent kernfs_node relative to which we need to build the path
@@ -220,8 +191,9 @@ size_t kernfs_path_len(struct kernfs_node *kn)
 * path (which includes '..'s) as needed to reach from @from to @to is
 * returned.
 *
 * If @buf isn't long enough, the return value will be greater than @buflen
 * and @buf contents are undefined.
 * Returns the length of the full path.  If the full length is equal to or
 * greater than @buflen, @buf contains the truncated path with the trailing
 * '\0'.  On error, -errno is returned.
 */
int kernfs_path_from_node(struct kernfs_node *to, struct kernfs_node *from,
			  char *buf, size_t buflen)
@@ -236,28 +208,6 @@ int kernfs_path_from_node(struct kernfs_node *to, struct kernfs_node *from,
}
EXPORT_SYMBOL_GPL(kernfs_path_from_node);

/**
 * kernfs_path - build full path of a given node
 * @kn: kernfs_node of interest
 * @buf: buffer to copy @kn's name into
 * @buflen: size of @buf
 *
 * Builds and returns the full path of @kn in @buf of @buflen bytes.  The
 * path is built from the end of @buf so the returned pointer usually
 * doesn't match @buf.  If @buf isn't long enough, @buf is nul terminated
 * and %NULL is returned.
 */
char *kernfs_path(struct kernfs_node *kn, char *buf, size_t buflen)
{
	int ret;

	ret = kernfs_path_from_node(kn, NULL, buf, buflen);
	if (ret < 0 || ret >= buflen)
		return NULL;
	return buf;
}
EXPORT_SYMBOL_GPL(kernfs_path);

/**
 * pr_cont_kernfs_name - pr_cont name of a kernfs_node
 * @kn: kernfs_node of interest
+3 −3
Original line number Diff line number Diff line
@@ -21,14 +21,14 @@ DEFINE_SPINLOCK(sysfs_symlink_target_lock);

void sysfs_warn_dup(struct kernfs_node *parent, const char *name)
{
	char *buf, *path = NULL;
	char *buf;

	buf = kzalloc(PATH_MAX, GFP_KERNEL);
	if (buf)
		path = kernfs_path(parent, buf, PATH_MAX);
		kernfs_path(parent, buf, PATH_MAX);

	WARN(1, KERN_WARNING "sysfs: cannot create duplicate filename '%s/%s'\n",
	     path, name);
	     buf, name);

	kfree(buf);
}
+1 −10
Original line number Diff line number Diff line
@@ -343,16 +343,7 @@ static inline struct blkcg *cpd_to_blkcg(struct blkcg_policy_data *cpd)
 */
static inline int blkg_path(struct blkcg_gq *blkg, char *buf, int buflen)
{
	char *p;

	p = cgroup_path(blkg->blkcg->css.cgroup, buf, buflen);
	if (!p) {
		strncpy(buf, "<unavailable>", buflen);
		return -ENAMETOOLONG;
	}

	memmove(buf, p, buf + buflen - p);
	return 0;
	return cgroup_path(blkg->blkcg->css.cgroup, buf, buflen);
}

/**
+4 −5
Original line number Diff line number Diff line
@@ -97,7 +97,7 @@ int cgroup_add_legacy_cftypes(struct cgroup_subsys *ss, struct cftype *cfts);
int cgroup_rm_cftypes(struct cftype *cfts);
void cgroup_file_notify(struct cgroup_file *cfile);

char *task_cgroup_path(struct task_struct *task, char *buf, size_t buflen);
int task_cgroup_path(struct task_struct *task, char *buf, size_t buflen);
int cgroupstats_build(struct cgroupstats *stats, struct dentry *dentry);
int proc_cgroup_show(struct seq_file *m, struct pid_namespace *ns,
		     struct pid *pid, struct task_struct *tsk);
@@ -555,8 +555,7 @@ static inline int cgroup_name(struct cgroup *cgrp, char *buf, size_t buflen)
	return kernfs_name(cgrp->kn, buf, buflen);
}

static inline char * __must_check cgroup_path(struct cgroup *cgrp, char *buf,
					      size_t buflen)
static inline int cgroup_path(struct cgroup *cgrp, char *buf, size_t buflen)
{
	return kernfs_path(cgrp->kn, buf, buflen);
}
@@ -658,7 +657,7 @@ struct cgroup_namespace *copy_cgroup_ns(unsigned long flags,
					struct user_namespace *user_ns,
					struct cgroup_namespace *old_ns);

char *cgroup_path_ns(struct cgroup *cgrp, char *buf, size_t buflen,
int cgroup_path_ns(struct cgroup *cgrp, char *buf, size_t buflen,
		   struct cgroup_namespace *ns);

#else /* !CONFIG_CGROUPS */
Loading