All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tejun Heo <htejun@gmail.com>
To: ebiederm@xmission.com, cornelia.huck@de.ibm.com, greg@kroah.com,
	stern@rowland.harvard.edu, kay.sievers@vrfy.org,
	linux-kernel@vger.kernel.org, htejun@gmail.com
Cc: Tejun Heo <htejun@gmail.com>
Subject: [PATCH 15/22] sysfs: implement sysfs_dirent based link interface
Date: Thu, 20 Sep 2007 17:05:41 +0900	[thread overview]
Message-ID: <11902755414149-git-send-email-htejun@gmail.com> (raw)
In-Reply-To: <11902755392688-git-send-email-htejun@gmail.com>

sysfs_add_link() takes parent sd, name, mode and the target sd and
creates a link accordingly.  Currently, sysfs links can only point to
directories but this limitiation is artificial to avoid inflating the
sysfs_dirent structure by one pointer with future changes and can be
easily removed.

Kobject based sysfs_create_link() is reimplemented using
sysfs_add_link().

This patch doesn't introduce any behavior change to the original API.

Signed-off-by: Tejun Heo <htejun@gmail.com>
---
 fs/sysfs/kobject.c    |   47 +++++++++++++++++++++++++++
 fs/sysfs/symlink.c    |   83 +++++++++++++++++-------------------------------
 include/linux/sysfs.h |   10 ++++++
 3 files changed, 87 insertions(+), 53 deletions(-)

diff --git a/fs/sysfs/kobject.c b/fs/sysfs/kobject.c
index a34c54e..7400575 100644
--- a/fs/sysfs/kobject.c
+++ b/fs/sysfs/kobject.c
@@ -355,6 +355,53 @@ void sysfs_remove_bin_file(struct kobject * kobj, struct bin_attribute * attr)
 }
 EXPORT_SYMBOL_GPL(sysfs_remove_bin_file);
 
+/*
+ * kobject link interface
+ */
+
+/**
+ *	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)
+{
+	struct sysfs_dirent *parent_sd, *target_sd, *sd;
+
+	BUG_ON(!name);
+
+	if (!kobj)
+		parent_sd = sysfs_root;
+	else
+		parent_sd = kobj->sd;
+
+	if (!parent_sd)
+		return -EFAULT;
+
+	/* target->sd can go away beneath us but is protected with
+	 * sysfs_assoc_lock.  Fetch target_sd from it.
+	 */
+	spin_lock(&sysfs_assoc_lock);
+	target_sd = NULL;
+	if (target->sd)
+		target_sd = sysfs_get(target->sd);
+	spin_unlock(&sysfs_assoc_lock);
+
+	if (!target_sd)
+		return -ENOENT;
+
+	sd = sysfs_add_link(parent_sd, name, SYSFS_COPY_NAME, target_sd);
+
+	sysfs_put(target_sd);
+
+	if (IS_ERR(sd))
+		return PTR_ERR(sd);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(sysfs_create_link);
+
 /**
  *	sysfs_remove_link - remove symlink in object's directory.
  *	@kobj:	object we're acting for.
diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c
index 2c3e4f7..42ecb69 100644
--- a/fs/sysfs/symlink.c
+++ b/fs/sysfs/symlink.c
@@ -5,7 +5,6 @@
 #include <linux/fs.h>
 #include <linux/mount.h>
 #include <linux/module.h>
-#include <linux/kobject.h>
 #include <linux/namei.h>
 #include <linux/mutex.h>
 
@@ -45,64 +44,45 @@ static void fill_object_path(struct sysfs_dirent *sd, char *buffer, int length)
 }
 
 /**
- *	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.
+ *	sysfs_add_link - add a new sysfs symlink
+ *	@parent: sysfs_dirent to add symlink under
+ *	@name: name of the symlink
+ *	@mode: SYSFS_* flags for the new symlink
+ *	@target: target of the symlink
+ *
+ *	Add a new symlink which points to @target under @parent with
+ *	the specified parameters.
+ *
+ *	LOCKING:
+ *	Kernel thread context (may sleep).
+ *
+ *	RETURNS:
+ *	Pointer to the new sysfs_dirent on success, ERR_PTR() value on
+ *	error.
  */
-int sysfs_create_link(struct kobject * kobj, struct kobject * target, const char * name)
+struct sysfs_dirent *sysfs_add_link(struct sysfs_dirent *parent,
+				    const char *name, mode_t mode,
+				    struct sysfs_dirent *target)
 {
-	struct sysfs_dirent *parent_sd = NULL;
-	struct sysfs_dirent *target_sd = NULL;
-	struct sysfs_dirent *sd = NULL;
-	struct sysfs_addrm_cxt acxt;
-	int error;
-
-	BUG_ON(!name);
-
-	if (!kobj)
-		parent_sd = sysfs_root;
-	else
-		parent_sd = kobj->sd;
+	struct sysfs_dirent *sd;
 
-	error = -EFAULT;
-	if (!parent_sd)
-		goto out_put;
-
-	/* target->sd can go away beneath us but is protected with
-	 * sysfs_assoc_lock.  Fetch target_sd from it.
+	/* Only symlink to directories are allowed.  This is an
+	 * artificial limitation.  If ever needed, allowing symlinks
+	 * to point to other types of sysfs nodes isn't difficult.
 	 */
-	spin_lock(&sysfs_assoc_lock);
-	if (target->sd)
-		target_sd = sysfs_get(target->sd);
-	spin_unlock(&sysfs_assoc_lock);
-
-	error = -ENOENT;
-	if (!target_sd)
-		goto out_put;
+	if (sysfs_type(target) != SYSFS_DIR)
+		return ERR_PTR(-EINVAL);
 
-	error = -ENOMEM;
-	sd = sysfs_new_dirent(name, S_IRWXUGO | SYSFS_COPY_NAME, SYSFS_LINK);
+	/* allocate & initialize */
+	sd = sysfs_new_dirent(name, mode | S_IRWXUGO, SYSFS_LINK);
 	if (!sd)
-		goto out_put;
-
-	sd->s_link.target = target_sd;
-	target_sd = NULL;	/* reference is now owned by the symlink */
+		return ERR_PTR(-ENOMEM);
 
-	sysfs_addrm_start(&acxt);
-	error = sysfs_add_one(&acxt, parent_sd, sd);
-	sysfs_addrm_finish(&acxt);
+	sd->s_link.target = sysfs_get(target);
 
-	if (error)
-		goto out_put;
-
-	return 0;
-
- out_put:
-	sysfs_put(target_sd);
-	sysfs_put(sd);
-	return error;
+	return sysfs_insert_one(parent, sd);
 }
+EXPORT_SYMBOL_GPL(sysfs_add_link);
 
 static int sysfs_get_target_path(struct sysfs_dirent * parent_sd,
 				 struct sysfs_dirent * target_sd, char *path)
@@ -162,6 +142,3 @@ const struct inode_operations sysfs_link_inode_operations = {
 	.follow_link = sysfs_follow_link,
 	.put_link = sysfs_put_link,
 };
-
-
-EXPORT_SYMBOL_GPL(sysfs_create_link);
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h
index dfb6bd7..08ed1b0 100644
--- a/include/linux/sysfs.h
+++ b/include/linux/sysfs.h
@@ -60,6 +60,9 @@ struct sysfs_dirent *sysfs_add_file(struct sysfs_dirent *parent,
 struct sysfs_dirent *sysfs_add_bin(struct sysfs_dirent *parent,
 			const char *name, mode_t mode, size_t size,
 			const struct sysfs_bin_ops *bops, void *data);
+struct sysfs_dirent *sysfs_add_link(struct sysfs_dirent *parent,
+			const char *name, mode_t mode,
+			struct sysfs_dirent *target);
 
 struct sysfs_dirent *sysfs_find_child(struct sysfs_dirent *parent,
 				      const char *name);
@@ -94,6 +97,13 @@ static inline struct sysfs_dirent *sysfs_add_bin(struct sysfs_dirent *parent,
 	return NULL;
 }
 
+static inline struct sysfs_dirent *sysfs_add_link(struct sysfs_dirent *parent,
+			const char *name, mode_t mode,
+			struct sysfs_dirent *target)
+{
+	return NULL;
+}
+
 static inline struct sysfs_dirent *sysfs_find_child(struct sysfs_dirent *parent,
 						    const char *name)
 {
-- 
1.5.0.3



  parent reply	other threads:[~2007-09-20  8:12 UTC|newest]

Thread overview: 55+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-09-20  8:05 [PATCHSET 3/4] sysfs: divorce sysfs from kobject and driver model Tejun Heo
2007-09-20  8:05 ` [PATCH 05/22] sysfs: implement sysfs_find_child() Tejun Heo
2007-09-20  8:05 ` [PATCH 06/22] sysfs: restructure addrm helpers Tejun Heo
2007-09-20  8:05 ` [PATCH 01/22] sysfs: make sysfs_root a pointer Tejun Heo
2007-09-20  8:05 ` [PATCH 03/22] sysfs: make sysfs_new_dirent() normalize @mode and determine file type Tejun Heo
2007-09-20  8:05 ` [PATCH 04/22] sysfs: make SYSFS_COPY_NAME a flag Tejun Heo
2007-09-20  8:05 ` [PATCH 02/22] sysfs: separate out sysfs-kobject.h and fs/sysfs/kobject.c Tejun Heo
2007-09-20  8:05 ` [PATCH 13/22] sysfs: implement sysfs_dirent based bin interface Tejun Heo
2007-09-20  8:05 ` [PATCH 11/22] sysfs: implement sysfs_dirent based file interface Tejun Heo
2007-09-20  8:05 ` [PATCH 14/22] sysfs: s/symlink/link/g Tejun Heo
2007-09-20  8:05 ` [PATCH 10/22] sysfs: drop kobj and attr from file related symbols Tejun Heo
2007-09-20  8:05 ` [PATCH 09/22] sysfs: rename internal function sysfs_add_file() Tejun Heo
2007-09-20  8:05 ` [PATCH 07/22] sysfs: implement sysfs_dirent based remove interface sysfs_remove() Tejun Heo
2007-09-20  8:05 ` [PATCH 08/22] sysfs: implement sysfs_dirent based directory interface Tejun Heo
2007-09-20  8:05 ` [PATCH 12/22] sysfs: drop kobj and attr from bin related symbols Tejun Heo
2007-09-20  8:05 ` [PATCH 17/22] sysfs: s/sysfs_rename_mutex/sysfs_op_mutex/ and protect all tree modifying ops Tejun Heo
2007-09-20  8:05 ` Tejun Heo [this message]
2007-09-20  8:05 ` [PATCH 16/22] sysfs: convert group implementation to use sd-based interface Tejun Heo
2007-09-20  8:05 ` [PATCH 18/22] kobject: implement __kobject_set_name() Tejun Heo
2007-09-20  8:05 ` [PATCH 22/22] sysfs: move sysfs_assoc_lock into fs/sysfs/kobject.c and make it static Tejun Heo
2007-09-20  8:05 ` [PATCH 19/22] sysfs: implement sysfs_dirent based rename - sysfs_rename() Tejun Heo
2007-09-20  8:05 ` [PATCH 21/22] sysfs: kill sysfs_hash_and_remove() Tejun Heo
2007-09-20  8:05 ` [PATCH 20/22] sysfs: kill now unused __sysfs_add_file() Tejun Heo
2007-09-25 22:17 ` [PATCHSET 3/4] sysfs: divorce sysfs from kobject and driver model Greg KH
2007-09-27 11:35   ` Tejun Heo
2007-09-27 19:25     ` Eric W. Biederman
2007-09-29 22:06       ` Tejun Heo
2007-10-05  6:23       ` Greg KH
2007-10-05 12:12         ` Eric W. Biederman
2007-10-05 13:03           ` [Devel] " Kirill Korotaev
2007-10-05 13:24             ` Eric W. Biederman
2007-10-09 22:51           ` Greg KH
     [not found]             ` <20071009225139.GF21228-U8xfFu+wG4EAvxtiuMwx3w@public.gmane.org>
2007-10-10 13:16               ` Eric W. Biederman
2007-10-10 13:16                 ` Eric W. Biederman
2007-10-10 20:44                 ` Greg KH
2007-10-10 21:16                   ` Eric W. Biederman
2007-10-16 22:18                 ` sukadev
2007-10-16 23:54                   ` Eric W. Biederman
2007-10-05 12:44         ` Eric W. Biederman
2007-10-09 22:53           ` Greg KH
2007-10-05  6:18     ` Greg KH
2007-10-05  8:00       ` Tejun Heo
2007-10-09  9:29         ` Cornelia Huck
2007-10-09 22:26           ` Greg KH
2007-10-09 23:20             ` Roland Dreier
2007-10-09 23:28               ` Greg KH
2007-10-10  9:11                 ` Cornelia Huck
2007-10-10  9:05             ` Cornelia Huck
2007-10-09 22:48         ` Greg KH
2007-10-10 15:38           ` Alan Stern
2007-10-10 16:16             ` Cornelia Huck
2007-10-10 17:24           ` Martin Bligh
2007-10-10 17:30             ` Greg KH
2007-10-10 18:26               ` Martin Bligh
2007-10-10 18:44                 ` Greg KH

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=11902755414149-git-send-email-htejun@gmail.com \
    --to=htejun@gmail.com \
    --cc=cornelia.huck@de.ibm.com \
    --cc=ebiederm@xmission.com \
    --cc=greg@kroah.com \
    --cc=kay.sievers@vrfy.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=stern@rowland.harvard.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.