diff options
| -rw-r--r-- | drivers/base/core.c | 9 | ||||
| -rw-r--r-- | fs/sysfs/dir.c | 37 | ||||
| -rw-r--r-- | fs/sysfs/symlink.c | 41 | ||||
| -rw-r--r-- | fs/sysfs/sysfs.h | 1 | ||||
| -rw-r--r-- | include/linux/sysfs.h | 10 | 
5 files changed, 84 insertions, 14 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c index c05b1159023..7d5c63c81a5 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -1345,8 +1345,9 @@ int device_rename(struct device *dev, char *new_name)  	if (old_class_name) {  		new_class_name = make_class_name(dev->class->name, &dev->kobj);  		if (new_class_name) { -			error = sysfs_create_link(&dev->parent->kobj, -						  &dev->kobj, new_class_name); +			error = sysfs_create_link_nowarn(&dev->parent->kobj, +							 &dev->kobj, +							 new_class_name);  			if (error)  				goto out;  			sysfs_remove_link(&dev->parent->kobj, old_class_name); @@ -1354,8 +1355,8 @@ int device_rename(struct device *dev, char *new_name)  	}  #else  	if (dev->class) { -		error = sysfs_create_link(&dev->class->p->class_subsys.kobj, -					  &dev->kobj, dev->bus_id); +		error = sysfs_create_link_nowarn(&dev->class->p->class_subsys.kobj, +						 &dev->kobj, dev->bus_id);  		if (error)  			goto out;  		sysfs_remove_link(&dev->class->p->class_subsys.kobj, diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c index 8c0e4b92574..c1a7efb310b 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c @@ -398,7 +398,7 @@ void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt,  }  /** - *	sysfs_add_one - add sysfs_dirent to parent + *	__sysfs_add_one - add sysfs_dirent to parent without warning   *	@acxt: addrm context to use   *	@sd: sysfs_dirent to be added   * @@ -417,7 +417,7 @@ void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt,   *	0 on success, -EEXIST if entry with the given name already   *	exists.   */ -int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd) +int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)  {  	if (sysfs_find_dirent(acxt->parent_sd, sd->s_name))  		return -EEXIST; @@ -435,6 +435,39 @@ int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)  }  /** + *	sysfs_add_one - add sysfs_dirent to parent + *	@acxt: addrm context to use + *	@sd: sysfs_dirent to be added + * + *	Get @acxt->parent_sd and set sd->s_parent to it and increment + *	nlink of parent inode if @sd is a directory and link into the + *	children list of the parent. + * + *	This function should be called between calls to + *	sysfs_addrm_start() and sysfs_addrm_finish() and should be + *	passed the same @acxt as passed to sysfs_addrm_start(). + * + *	LOCKING: + *	Determined by sysfs_addrm_start(). + * + *	RETURNS: + *	0 on success, -EEXIST if entry with the given name already + *	exists. + */ +int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd) +{ +	int ret; + +	ret = __sysfs_add_one(acxt, sd); +	if (ret == -EEXIST) { +		printk(KERN_WARNING "sysfs: duplicate filename '%s' " +		       "can not be created\n", sd->s_name); +		WARN_ON(1); +	} +	return ret; +} + +/**   *	sysfs_remove_one - remove sysfs_dirent from parent   *	@acxt: addrm context to use   *	@sd: sysfs_dirent to be removed diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c index 817f5966edc..a3ba217fbe7 100644 --- a/fs/sysfs/symlink.c +++ b/fs/sysfs/symlink.c @@ -19,13 +19,8 @@  #include "sysfs.h" -/** - *	sysfs_create_link - create symlink between two objects. - *	@kobj:	object whose directory we're creating the link in. - *	@target:	object we're pointing to. - *	@name:		name of the symlink. - */ -int sysfs_create_link(struct kobject * kobj, struct kobject * target, const char * name) +static int sysfs_do_create_link(struct kobject *kobj, struct kobject *target, +				const char *name, int warn)  {  	struct sysfs_dirent *parent_sd = NULL;  	struct sysfs_dirent *target_sd = NULL; @@ -65,7 +60,10 @@ int sysfs_create_link(struct kobject * kobj, struct kobject * target, const char  	target_sd = NULL;	/* reference is now owned by the symlink */  	sysfs_addrm_start(&acxt, parent_sd); -	error = sysfs_add_one(&acxt, sd); +	if (warn) +		error = sysfs_add_one(&acxt, sd); +	else +		error = __sysfs_add_one(&acxt, sd);  	sysfs_addrm_finish(&acxt);  	if (error) @@ -80,6 +78,33 @@ int sysfs_create_link(struct kobject * kobj, struct kobject * target, const char  }  /** + *	sysfs_create_link - create symlink between two objects. + *	@kobj:	object whose directory we're creating the link in. + *	@target:	object we're pointing to. + *	@name:		name of the symlink. + */ +int sysfs_create_link(struct kobject *kobj, struct kobject *target, +		      const char *name) +{ +	return sysfs_do_create_link(kobj, target, name, 1); +} + +/** + *	sysfs_create_link_nowarn - create symlink between two objects. + *	@kobj:	object whose directory we're creating the link in. + *	@target:	object we're pointing to. + *	@name:		name of the symlink. + * + *	This function does the same as sysf_create_link(), but it + *	doesn't warn if the link already exists. + */ +int sysfs_create_link_nowarn(struct kobject *kobj, struct kobject *target, +			     const char *name) +{ +	return sysfs_do_create_link(kobj, target, name, 0); +} + +/**   *	sysfs_remove_link - remove symlink in object's directory.   *	@kobj:	object we're acting for.   *	@name:	name of the symlink to remove. diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h index ce4e15f8aae..a5db496f71c 100644 --- a/fs/sysfs/sysfs.h +++ b/fs/sysfs/sysfs.h @@ -107,6 +107,7 @@ struct sysfs_dirent *sysfs_get_active_two(struct sysfs_dirent *sd);  void sysfs_put_active_two(struct sysfs_dirent *sd);  void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt,  		       struct sysfs_dirent *parent_sd); +int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd);  int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd);  void sysfs_remove_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd);  void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt); diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h index 7858eac40aa..37fa24152bd 100644 --- a/include/linux/sysfs.h +++ b/include/linux/sysfs.h @@ -101,6 +101,9 @@ void sysfs_remove_bin_file(struct kobject *kobj, struct bin_attribute *attr);  int __must_check sysfs_create_link(struct kobject *kobj, struct kobject *target,  				   const char *name); +int __must_check sysfs_create_link_nowarn(struct kobject *kobj, +					  struct kobject *target, +					  const char *name);  void sysfs_remove_link(struct kobject *kobj, const char *name);  int __must_check sysfs_create_group(struct kobject *kobj, @@ -180,6 +183,13 @@ static inline int sysfs_create_link(struct kobject *kobj,  	return 0;  } +static inline int sysfs_create_link_nowarn(struct kobject *kobj, +					   struct kobject *target, +					   const char *name) +{ +	return 0; +} +  static inline void sysfs_remove_link(struct kobject *kobj, const char *name)  {  }  |