diff mbox

[3/4] sysfs: Functions for adding/removing symlinks to/from attribute groups

Message ID 3401016.osGyQ9N4xP@vostro.rjw.lan (mailing list archive)
State Superseded, archived
Headers show

Commit Message

Rafael Wysocki Jan. 22, 2013, 2:27 a.m. UTC
From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

The most convenient way to expose ACPI power resources lists of a
device is to put symbolic links to sysfs directories representing
those resources into special attribute groups in the device's sysfs
directory.  For this purpose, it is necessary to be able to add
symbolic links to attribute groups.

For this reason, add sysfs helper functions for adding/removing
symbolic links to/from attribute groups, sysfs_add_link_to_group()
and sysfs_remove_link_from_group(), respectively.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 fs/sysfs/group.c      |   42 ++++++++++++++++++++++++++++++++++++++++++
 fs/sysfs/symlink.c    |   45 ++++++++++++++++++++++++++++++++-------------
 include/linux/sysfs.h |    6 ++++++
 3 files changed, 80 insertions(+), 13 deletions(-)


--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

Greg Kroah-Hartman Jan. 22, 2013, 11:51 p.m. UTC | #1
On Tue, Jan 22, 2013 at 03:27:12AM +0100, Rafael J. Wysocki wrote:
> --- linux-pm.orig/include/linux/sysfs.h
> +++ linux-pm/include/linux/sysfs.h
> @@ -154,6 +154,8 @@ int __must_check sysfs_create_bin_file(s
>  void sysfs_remove_bin_file(struct kobject *kobj,
>  			   const struct bin_attribute *attr);
>  
> +int sysfs_create_link_sd(struct sysfs_dirent *sd, struct kobject *target,
> +			 const char *name);

This should go into fs/sysfs/sysfs.h not include/linux/sysfs.h as it's
an "internal" sysfs function.

thanks,

greg k-h
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Rafael Wysocki Jan. 23, 2013, 12:03 a.m. UTC | #2
On Tuesday, January 22, 2013 03:51:01 PM Greg Kroah-Hartman wrote:
> On Tue, Jan 22, 2013 at 03:27:12AM +0100, Rafael J. Wysocki wrote:
> > --- linux-pm.orig/include/linux/sysfs.h
> > +++ linux-pm/include/linux/sysfs.h
> > @@ -154,6 +154,8 @@ int __must_check sysfs_create_bin_file(s
> >  void sysfs_remove_bin_file(struct kobject *kobj,
> >  			   const struct bin_attribute *attr);
> >  
> > +int sysfs_create_link_sd(struct sysfs_dirent *sd, struct kobject *target,
> > +			 const char *name);
> 
> This should go into fs/sysfs/sysfs.h not include/linux/sysfs.h as it's
> an "internal" sysfs function.

Damn, right.  Will fix.

Thanks,
Rafael
diff mbox

Patch

Index: linux-pm/fs/sysfs/group.c
===================================================================
--- linux-pm.orig/fs/sysfs/group.c
+++ linux-pm/fs/sysfs/group.c
@@ -205,6 +205,48 @@  void sysfs_unmerge_group(struct kobject
 }
 EXPORT_SYMBOL_GPL(sysfs_unmerge_group);
 
+/**
+ * sysfs_add_link_to_group - add a symlink to an attribute group.
+ * @kobj:	The kobject containing the group.
+ * @group_name:	The name of the group.
+ * @target:	The target kobject of the symlink to create.
+ * @link_name:	The name of the symlink to create.
+ */
+int sysfs_add_link_to_group(struct kobject *kobj, const char *group_name,
+			    struct kobject *target, const char *link_name)
+{
+	struct sysfs_dirent *dir_sd;
+	int error = 0;
+
+	dir_sd = sysfs_get_dirent(kobj->sd, NULL, group_name);
+	if (!dir_sd)
+		return -ENOENT;
+
+	error = sysfs_create_link_sd(dir_sd, target, link_name);
+	sysfs_put(dir_sd);
+
+	return error;
+}
+EXPORT_SYMBOL_GPL(sysfs_add_link_to_group);
+
+/**
+ * sysfs_remove_link_from_group - remove a symlink from an attribute group.
+ * @kobj:	The kobject containing the group.
+ * @group_name:	The name of the group.
+ * @link_name:	The name of the symlink to remove.
+ */
+void sysfs_remove_link_from_group(struct kobject *kobj, const char *group_name,
+				  const char *link_name)
+{
+	struct sysfs_dirent *dir_sd;
+
+	dir_sd = sysfs_get_dirent(kobj->sd, NULL, group_name);
+	if (dir_sd) {
+		sysfs_hash_and_remove(dir_sd, NULL, link_name);
+		sysfs_put(dir_sd);
+	}
+}
+EXPORT_SYMBOL_GPL(sysfs_remove_link_from_group);
 
 EXPORT_SYMBOL_GPL(sysfs_create_group);
 EXPORT_SYMBOL_GPL(sysfs_update_group);
Index: linux-pm/fs/sysfs/symlink.c
===================================================================
--- linux-pm.orig/fs/sysfs/symlink.c
+++ linux-pm/fs/sysfs/symlink.c
@@ -21,26 +21,17 @@ 
 
 #include "sysfs.h"
 
-static int sysfs_do_create_link(struct kobject *kobj, struct kobject *target,
-				const char *name, int warn)
+static int sysfs_do_create_link_sd(struct sysfs_dirent *parent_sd,
+				   struct kobject *target,
+				   const char *name, int warn)
 {
-	struct sysfs_dirent *parent_sd = NULL;
 	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);
-
-	if (!kobj)
-		parent_sd = &sysfs_root;
-	else
-		parent_sd = kobj->sd;
-
-	error = -EFAULT;
-	if (!parent_sd)
-		goto out_put;
+	BUG_ON(!name || !parent_sd);
 
 	/* target->sd can go away beneath us but is protected with
 	 * sysfs_assoc_lock.  Fetch target_sd from it.
@@ -96,6 +87,34 @@  static int sysfs_do_create_link(struct k
 }
 
 /**
+ *	sysfs_create_link_sd - create symlink to a given object.
+ *	@sd:		directory we're creating the link in.
+ *	@target:	object we're pointing to.
+ *	@name:		name of the symlink.
+ */
+int sysfs_create_link_sd(struct sysfs_dirent *sd, struct kobject *target,
+			 const char *name)
+{
+	return sysfs_do_create_link_sd(sd, target, name, 1);
+}
+
+static int sysfs_do_create_link(struct kobject *kobj, struct kobject *target,
+				const char *name, int warn)
+{
+	struct sysfs_dirent *parent_sd = NULL;
+
+	if (!kobj)
+		parent_sd = &sysfs_root;
+	else
+		parent_sd = kobj->sd;
+
+	if (!parent_sd)
+		return -EFAULT;
+
+	return sysfs_do_create_link_sd(parent_sd, target, name, warn);
+}
+
+/**
  *	sysfs_create_link - create symlink between two objects.
  *	@kobj:	object whose directory we're creating the link in.
  *	@target:	object we're pointing to.
Index: linux-pm/include/linux/sysfs.h
===================================================================
--- linux-pm.orig/include/linux/sysfs.h
+++ linux-pm/include/linux/sysfs.h
@@ -154,6 +154,8 @@  int __must_check sysfs_create_bin_file(s
 void sysfs_remove_bin_file(struct kobject *kobj,
 			   const struct bin_attribute *attr);
 
+int sysfs_create_link_sd(struct sysfs_dirent *sd, struct kobject *target,
+			 const char *name);
 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,
@@ -181,6 +183,10 @@  int sysfs_merge_group(struct kobject *ko
 		       const struct attribute_group *grp);
 void sysfs_unmerge_group(struct kobject *kobj,
 		       const struct attribute_group *grp);
+int sysfs_add_link_to_group(struct kobject *kobj, const char *group_name,
+			    struct kobject *target, const char *link_name);
+void sysfs_remove_link_from_group(struct kobject *kobj, const char *group_name,
+				  const char *link_name);
 
 void sysfs_notify(struct kobject *kobj, const char *dir, const char *attr);
 void sysfs_notify_dirent(struct sysfs_dirent *sd);