diff options
Diffstat (limited to 'fs/sysfs/symlink.c')
| -rw-r--r-- | fs/sysfs/symlink.c | 36 | 
1 files changed, 33 insertions, 3 deletions
| diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c index b93ec51fa7ac..f71246bebfe4 100644 --- a/fs/sysfs/symlink.c +++ b/fs/sysfs/symlink.c @@ -58,6 +58,8 @@ static int sysfs_do_create_link(struct kobject *kobj, struct kobject *target,  	if (!sd)  		goto out_put; +	if (sysfs_ns_type(parent_sd)) +		sd->s_ns = target->ktype->namespace(target);  	sd->s_symlink.target_sd = target_sd;  	target_sd = NULL;	/* reference is now owned by the symlink */ @@ -107,6 +109,26 @@ int sysfs_create_link_nowarn(struct kobject *kobj, struct kobject *target,  }  /** + *	sysfs_delete_link - remove symlink in object's directory. + *	@kobj:	object we're acting for. + *	@targ:	object we're pointing to. + *	@name:	name of the symlink to remove. + * + *	Unlike sysfs_remove_link sysfs_delete_link has enough information + *	to successfully delete symlinks in tagged directories. + */ +void sysfs_delete_link(struct kobject *kobj, struct kobject *targ, +			const char *name) +{ +	const void *ns = NULL; +	spin_lock(&sysfs_assoc_lock); +	if (targ->sd) +		ns = targ->sd->s_ns; +	spin_unlock(&sysfs_assoc_lock); +	sysfs_hash_and_remove(kobj->sd, ns, name); +} + +/**   *	sysfs_remove_link - remove symlink in object's directory.   *	@kobj:	object we're acting for.   *	@name:	name of the symlink to remove. @@ -121,7 +143,7 @@ void sysfs_remove_link(struct kobject * kobj, const char * name)  	else  		parent_sd = kobj->sd; -	sysfs_hash_and_remove(parent_sd, name); +	sysfs_hash_and_remove(parent_sd, NULL, name);  }  /** @@ -137,6 +159,7 @@ int sysfs_rename_link(struct kobject *kobj, struct kobject *targ,  			const char *old, const char *new)  {  	struct sysfs_dirent *parent_sd, *sd = NULL; +	const void *old_ns = NULL, *new_ns = NULL;  	int result;  	if (!kobj) @@ -144,8 +167,11 @@ int sysfs_rename_link(struct kobject *kobj, struct kobject *targ,  	else  		parent_sd = kobj->sd; +	if (targ->sd) +		old_ns = targ->sd->s_ns; +  	result = -ENOENT; -	sd = sysfs_get_dirent(parent_sd, old); +	sd = sysfs_get_dirent(parent_sd, old_ns, old);  	if (!sd)  		goto out; @@ -155,7 +181,10 @@ int sysfs_rename_link(struct kobject *kobj, struct kobject *targ,  	if (sd->s_symlink.target_sd->s_dir.kobj != targ)  		goto out; -	result = sysfs_rename(sd, parent_sd, new); +	if (sysfs_ns_type(parent_sd)) +		new_ns = targ->ktype->namespace(targ); + +	result = sysfs_rename(sd, parent_sd, new_ns, new);  out:  	sysfs_put(sd); @@ -261,3 +290,4 @@ const struct inode_operations sysfs_symlink_inode_operations = {  EXPORT_SYMBOL_GPL(sysfs_create_link);  EXPORT_SYMBOL_GPL(sysfs_remove_link); +EXPORT_SYMBOL_GPL(sysfs_rename_link); | 
