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

Commit e9d67a78 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6:
  sysfs: allow creating symlinks from untagged to tagged directories
  sysfs: sysfs_delete_link handle symlinks from untagged to tagged directories.
  sysfs: Don't allow the creation of symlinks we can't remove
parents 592d32cc d3300212
Loading
Loading
Loading
Loading
+20 −6
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ static int sysfs_do_create_link(struct kobject *kobj, struct kobject *target,
	struct sysfs_dirent *target_sd = NULL;
	struct sysfs_dirent *sd = NULL;
	struct sysfs_addrm_cxt acxt;
	enum kobj_ns_type ns_type;
	int error;

	BUG_ON(!name);
@@ -58,16 +59,29 @@ static int sysfs_do_create_link(struct kobject *kobj, struct kobject *target,
	if (!sd)
		goto out_put;

	if (sysfs_ns_type(parent_sd))
	ns_type = sysfs_ns_type(parent_sd);
	if (ns_type)
		sd->s_ns = target->ktype->namespace(target);
	sd->s_symlink.target_sd = target_sd;
	target_sd = NULL;	/* reference is now owned by the symlink */

	sysfs_addrm_start(&acxt, parent_sd);
	/* Symlinks must be between directories with the same ns_type */
	if (!ns_type ||
	    (ns_type == sysfs_ns_type(sd->s_symlink.target_sd->s_parent))) {
		if (warn)
			error = sysfs_add_one(&acxt, sd);
		else
			error = __sysfs_add_one(&acxt, sd);
	} else {
		error = -EINVAL;
		WARN(1, KERN_WARNING
			"sysfs: symlink across ns_types %s/%s -> %s/%s\n",
			parent_sd->s_name,
			sd->s_name,
			sd->s_symlink.target_sd->s_parent->s_name,
			sd->s_symlink.target_sd->s_name);
	}
	sysfs_addrm_finish(&acxt);

	if (error)
@@ -122,7 +136,7 @@ void sysfs_delete_link(struct kobject *kobj, struct kobject *targ,
{
	const void *ns = NULL;
	spin_lock(&sysfs_assoc_lock);
	if (targ->sd)
	if (targ->sd && sysfs_ns_type(kobj->sd))
		ns = targ->sd->s_ns;
	spin_unlock(&sysfs_assoc_lock);
	sysfs_hash_and_remove(kobj->sd, ns, name);