From: Greg Kroah-Hartman <gregkh@suse.de>
To: linux-kernel@vger.kernel.org
Cc: Tejun Heo <htejun@gmail.com>, Greg Kroah-Hartman <gregkh@suse.de>
Subject: [PATCH 30/61] sysfs: add sysfs_dirent->s_name
Date: Wed, 11 Jul 2007 16:31:49 -0700 [thread overview]
Message-ID: <11841968773426-git-send-email-gregkh@suse.de> (raw)
In-Reply-To: <11841968731843-git-send-email-gregkh@suse.de>
From: Tejun Heo <htejun@gmail.com>
Add s_name to sysfs_dirent. This is to further reduce dependency to
the associated dentry. Name is copied for directories and symlinks
but not for attributes.
Where possible, name dereferences are converted to use sd->s_name.
sysfs_symlink->link_name and sysfs_get_name() are unused now and
removed.
This change allows symlink to be implemented using sysfs_dirent tree
proper, which is the last remaining dentry-dependent sysfs walk.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
fs/sysfs/dir.c | 67 ++++++++++++++++++++++++++++++++-----------------
fs/sysfs/file.c | 2 +-
fs/sysfs/inode.c | 33 +-----------------------
fs/sysfs/symlink.c | 8 +-----
fs/sysfs/sysfs.h | 7 ++---
include/linux/sysfs.h | 1 +
6 files changed, 51 insertions(+), 67 deletions(-)
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index 5d50e1d..6e8d6f5 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -54,10 +54,11 @@ void release_sysfs_dirent(struct sysfs_dirent * sd)
if (sd->s_type & SYSFS_KOBJ_LINK) {
struct sysfs_symlink * sl = sd->s_element;
- kfree(sl->link_name);
kobject_put(sl->target_kobj);
kfree(sl);
}
+ if (sd->s_type & SYSFS_COPY_NAME)
+ kfree(sd->s_name);
kfree(sd->s_iattr);
sysfs_free_ino(sd->s_ino);
kmem_cache_free(sysfs_dir_cachep, sd);
@@ -94,29 +95,41 @@ static struct dentry_operations sysfs_dentry_ops = {
.d_iput = sysfs_d_iput,
};
-struct sysfs_dirent *sysfs_new_dirent(void *element, umode_t mode, int type)
+struct sysfs_dirent *sysfs_new_dirent(const char *name, void *element,
+ umode_t mode, int type)
{
- struct sysfs_dirent * sd;
+ char *dup_name = NULL;
+ struct sysfs_dirent *sd = NULL;
+
+ if (type & SYSFS_COPY_NAME) {
+ name = dup_name = kstrdup(name, GFP_KERNEL);
+ if (!name)
+ goto err_out;
+ }
sd = kmem_cache_zalloc(sysfs_dir_cachep, GFP_KERNEL);
if (!sd)
- return NULL;
+ goto err_out;
- if (sysfs_alloc_ino(&sd->s_ino)) {
- kmem_cache_free(sysfs_dir_cachep, sd);
- return NULL;
- }
+ if (sysfs_alloc_ino(&sd->s_ino))
+ goto err_out;
atomic_set(&sd->s_count, 1);
atomic_set(&sd->s_event, 1);
INIT_LIST_HEAD(&sd->s_children);
INIT_LIST_HEAD(&sd->s_sibling);
+ sd->s_name = name;
sd->s_element = element;
sd->s_mode = mode;
sd->s_type = type;
return sd;
+
+ err_out:
+ kfree(dup_name);
+ kmem_cache_free(sysfs_dir_cachep, sd);
+ return NULL;
}
void sysfs_attach_dirent(struct sysfs_dirent *sd,
@@ -148,8 +161,7 @@ int sysfs_dirent_exist(struct sysfs_dirent *parent_sd,
list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
if (sd->s_element) {
- const unsigned char *existing = sysfs_get_name(sd);
- if (strcmp(existing, new))
+ if (strcmp(sd->s_name, new))
continue;
else
return -EEXIST;
@@ -203,7 +215,7 @@ static int create_dir(struct kobject *kobj, struct dentry *parent,
goto out_dput;
error = -ENOMEM;
- sd = sysfs_new_dirent(kobj, mode, SYSFS_DIR);
+ sd = sysfs_new_dirent(name, kobj, mode, SYSFS_DIR);
if (!sd)
goto out_drop;
sysfs_attach_dirent(sd, parent->d_fsdata, dentry);
@@ -334,9 +346,7 @@ static struct dentry * sysfs_lookup(struct inode *dir, struct dentry *dentry,
list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
if (sd->s_type & SYSFS_NOT_PINNED) {
- const unsigned char * name = sysfs_get_name(sd);
-
- if (strcmp(name, dentry->d_name.name))
+ if (strcmp(sd->s_name, dentry->d_name.name))
continue;
if (sd->s_type & SYSFS_KOBJ_LINK)
@@ -427,9 +437,11 @@ void sysfs_remove_dir(struct kobject * kobj)
int sysfs_rename_dir(struct kobject * kobj, struct dentry *new_parent,
const char *new_name)
{
+ struct sysfs_dirent *sd = kobj->dentry->d_fsdata;
+ struct sysfs_dirent *parent_sd = new_parent->d_fsdata;
+ struct dentry *new_dentry;
+ char *dup_name;
int error;
- struct dentry * new_dentry;
- struct sysfs_dirent *sd, *parent_sd;
if (!new_parent)
return -EFAULT;
@@ -457,22 +469,31 @@ int sysfs_rename_dir(struct kobject * kobj, struct dentry *new_parent,
if (new_dentry->d_inode)
goto out_dput;
+ /* rename kobject and sysfs_dirent */
+ error = -ENOMEM;
+ new_name = dup_name = kstrdup(new_name, GFP_KERNEL);
+ if (!new_name)
+ goto out_drop;
+
error = kobject_set_name(kobj, "%s", new_name);
if (error)
- goto out_drop;
+ goto out_free;
+ kfree(sd->s_name);
+ sd->s_name = new_name;
+
+ /* move under the new parent */
d_add(new_dentry, NULL);
d_move(kobj->dentry, new_dentry);
- sd = kobj->dentry->d_fsdata;
- parent_sd = new_parent->d_fsdata;
-
list_del_init(&sd->s_sibling);
list_add(&sd->s_sibling, &parent_sd->s_children);
error = 0;
goto out_unlock;
+ out_free:
+ kfree(dup_name);
out_drop:
d_drop(new_dentry);
out_dput:
@@ -535,7 +556,7 @@ static int sysfs_dir_open(struct inode *inode, struct file *file)
struct sysfs_dirent * sd;
mutex_lock(&dentry->d_inode->i_mutex);
- sd = sysfs_new_dirent(NULL, 0, 0);
+ sd = sysfs_new_dirent("_DIR_", NULL, 0, 0);
if (sd)
sysfs_attach_dirent(sd, parent_sd, NULL);
mutex_unlock(&dentry->d_inode->i_mutex);
@@ -605,7 +626,7 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir)
if (!next->s_element)
continue;
- name = sysfs_get_name(next);
+ name = next->s_name;
len = strlen(name);
ino = next->s_ino;
@@ -717,7 +738,7 @@ struct dentry *sysfs_create_shadow_dir(struct kobject *kobj)
if (!shadow)
goto nomem;
- sd = sysfs_new_dirent(kobj, inode->i_mode, SYSFS_DIR);
+ sd = sysfs_new_dirent("_SHADOW_", kobj, inode->i_mode, SYSFS_DIR);
if (!sd)
goto nomem;
/* point to parent_sd but don't attach to it */
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index fd4b6dc..8240b16 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -454,7 +454,7 @@ int sysfs_add_file(struct dentry * dir, const struct attribute * attr, int type)
goto out_unlock;
}
- sd = sysfs_new_dirent((void *)attr, mode, type);
+ sd = sysfs_new_dirent(attr->name, (void *)attr, mode, type);
if (!sd) {
error = -ENOMEM;
goto out_unlock;
diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c
index 5266eec..5c605b0 100644
--- a/fs/sysfs/inode.c
+++ b/fs/sysfs/inode.c
@@ -191,37 +191,6 @@ int sysfs_create(struct dentry * dentry, int mode, int (*init)(struct inode *))
return error;
}
-/*
- * Get the name for corresponding element represented by the given sysfs_dirent
- */
-const unsigned char * sysfs_get_name(struct sysfs_dirent *sd)
-{
- struct attribute * attr;
- struct bin_attribute * bin_attr;
- struct sysfs_symlink * sl;
-
- BUG_ON(!sd || !sd->s_element);
-
- switch (sd->s_type) {
- case SYSFS_DIR:
- /* Always have a dentry so use that */
- return sd->s_dentry->d_name.name;
-
- case SYSFS_KOBJ_ATTR:
- attr = sd->s_element;
- return attr->name;
-
- case SYSFS_KOBJ_BIN_ATTR:
- bin_attr = sd->s_element;
- return bin_attr->attr.name;
-
- case SYSFS_KOBJ_LINK:
- sl = sd->s_element;
- return sl->link_name;
- }
- return NULL;
-}
-
static inline void orphan_all_buffers(struct inode *node)
{
struct sysfs_buffer_collection *set;
@@ -305,7 +274,7 @@ int sysfs_hash_and_remove(struct dentry * dir, const char * name)
list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
if (!sd->s_element)
continue;
- if (!strcmp(sysfs_get_name(sd), name)) {
+ if (!strcmp(sd->s_name, name)) {
list_del_init(&sd->s_sibling);
sysfs_drop_dentry(sd, dir);
sysfs_put(sd);
diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c
index d96bb9c..c728204 100644
--- a/fs/sysfs/symlink.c
+++ b/fs/sysfs/symlink.c
@@ -57,14 +57,9 @@ static int sysfs_add_link(struct dentry * parent, const char * name, struct kobj
if (!sl)
goto err_out;
- sl->link_name = kmalloc(strlen(name) + 1, GFP_KERNEL);
- if (!sl->link_name)
- goto err_out;
-
- strcpy(sl->link_name, name);
sl->target_kobj = kobject_get(target);
- sd = sysfs_new_dirent(sl, S_IFLNK|S_IRWXUGO, SYSFS_KOBJ_LINK);
+ sd = sysfs_new_dirent(name, sl, S_IFLNK|S_IRWXUGO, SYSFS_KOBJ_LINK);
if (!sd)
goto err_out;
sysfs_attach_dirent(sd, parent_sd, NULL);
@@ -74,7 +69,6 @@ static int sysfs_add_link(struct dentry * parent, const char * name, struct kobj
err_out:
if (sl) {
kobject_put(sl->target_kobj);
- kfree(sl->link_name);
kfree(sl);
}
return error;
diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h
index ce05d6f..d34b008 100644
--- a/fs/sysfs/sysfs.h
+++ b/fs/sysfs/sysfs.h
@@ -3,6 +3,7 @@ struct sysfs_dirent {
struct sysfs_dirent * s_parent;
struct list_head s_sibling;
struct list_head s_children;
+ const char * s_name;
void * s_element;
int s_type;
umode_t s_mode;
@@ -21,8 +22,8 @@ extern int sysfs_create(struct dentry *, int mode, int (*init)(struct inode *));
extern void release_sysfs_dirent(struct sysfs_dirent * sd);
extern int sysfs_dirent_exist(struct sysfs_dirent *, const unsigned char *);
-extern struct sysfs_dirent *sysfs_new_dirent(void *element, umode_t mode,
- int type);
+extern struct sysfs_dirent *sysfs_new_dirent(const char *name, void *element,
+ umode_t mode, int type);
extern void sysfs_attach_dirent(struct sysfs_dirent *sd,
struct sysfs_dirent *parent_sd,
struct dentry *dentry);
@@ -34,7 +35,6 @@ extern struct sysfs_dirent *sysfs_find(struct sysfs_dirent *dir, const char * na
extern int sysfs_create_subdir(struct kobject *, const char *, struct dentry **);
extern void sysfs_remove_subdir(struct dentry *);
-extern const unsigned char * sysfs_get_name(struct sysfs_dirent *sd);
extern void sysfs_drop_dentry(struct sysfs_dirent *sd, struct dentry *parent);
extern int sysfs_setattr(struct dentry *dentry, struct iattr *iattr);
@@ -48,7 +48,6 @@ extern const struct inode_operations sysfs_dir_inode_operations;
extern const struct inode_operations sysfs_symlink_inode_operations;
struct sysfs_symlink {
- char * link_name;
struct kobject * target_kobj;
};
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h
index 7d5d1ec..2f86b08 100644
--- a/include/linux/sysfs.h
+++ b/include/linux/sysfs.h
@@ -76,6 +76,7 @@ struct sysfs_ops {
#define SYSFS_KOBJ_BIN_ATTR 0x0008
#define SYSFS_KOBJ_LINK 0x0020
#define SYSFS_NOT_PINNED (SYSFS_KOBJ_ATTR | SYSFS_KOBJ_BIN_ATTR | SYSFS_KOBJ_LINK)
+#define SYSFS_COPY_NAME (SYSFS_DIR | SYSFS_KOBJ_LINK)
#ifdef CONFIG_SYSFS
--
1.5.2.2
next prev parent reply other threads:[~2007-07-11 23:46 UTC|newest]
Thread overview: 81+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-07-11 23:30 [GIT PATCH] sysfs and driver core patches for 2.6.22 Greg KH
2007-07-11 23:31 ` [PATCH 01/61] Rules on how to use sysfs in userspace programs Greg Kroah-Hartman
2007-07-11 23:31 ` [PATCH 02/61] debugfs: add rename for debugfs files Greg Kroah-Hartman
2007-07-11 23:31 ` [PATCH 03/61] DMI-based module autoloading Greg Kroah-Hartman
2007-07-11 23:31 ` [PATCH 04/61] Driver core: add missing kset uevent Greg Kroah-Hartman
2007-07-11 23:31 ` [PATCH 05/61] sysdev: use mutex instead of semaphore Greg Kroah-Hartman
2007-07-11 23:31 ` [PATCH 06/61] Power Management: use mutexes instead of semaphores Greg Kroah-Hartman
2007-07-11 23:31 ` [PATCH 07/61] PM: Remove pm_parent from struct dev_pm_info Greg Kroah-Hartman
2007-07-11 23:31 ` [PATCH 08/61] PM: Remove saved_state " Greg Kroah-Hartman
2007-07-11 23:31 ` [PATCH 09/61] PM: Simplify suspend_device Greg Kroah-Hartman
2007-07-11 23:31 ` [PATCH 10/61] Driver core: include linux/mutex.h from attribute_container.c Greg Kroah-Hartman
2007-07-11 23:31 ` [PATCH 11/61] driver core: properly get driver in device_release_driver Greg Kroah-Hartman
2007-07-11 23:31 ` [PATCH 12/61] driver core: fix kernel doc of device_release_driver Greg Kroah-Hartman
2007-07-11 23:31 ` [PATCH 13/61] Driver core: fix devres_release_all() return value Greg Kroah-Hartman
2007-07-11 23:31 ` [PATCH 14/61] PM: Remove prev_state from struct dev_pm_info Greg Kroah-Hartman
2007-07-11 23:31 ` [PATCH 15/61] PM: Remove power_state.event checks from suspend core code Greg Kroah-Hartman
2007-07-11 23:31 ` [PATCH 16/61] PM: Do not check parent state in suspend and resume " Greg Kroah-Hartman
2007-07-11 23:31 ` [PATCH 17/61] PM: do not use saved_state from struct dev_pm_info on ARM Greg Kroah-Hartman
2007-07-11 23:31 ` [PATCH 18/61] Driver core: coding style cleanup Greg Kroah-Hartman
2007-07-11 23:31 ` [PATCH 19/61] idr: fix obscure bug in allocation path Greg Kroah-Hartman
2007-07-11 23:31 ` [PATCH 20/61] idr: separate out idr_mark_full() Greg Kroah-Hartman
2007-07-11 23:31 ` [PATCH 21/61] ida: implement idr based id allocator Greg Kroah-Hartman
2007-07-11 23:31 ` [PATCH 22/61] sysfs: move release_sysfs_dirent() to dir.c Greg Kroah-Hartman
2007-07-11 23:31 ` [PATCH 23/61] sysfs: allocate inode number using ida Greg Kroah-Hartman
2007-07-11 23:31 ` [PATCH 24/61] sysfs: make sysfs_put() ignore NULL sd Greg Kroah-Hartman
2007-07-11 23:31 ` [PATCH 25/61] sysfs: fix error handling in binattr write() Greg Kroah-Hartman
2007-07-11 23:31 ` [PATCH 26/61] sysfs: flatten cleanup paths in sysfs_add_link() and create_dir() Greg Kroah-Hartman
2007-07-11 23:31 ` [PATCH 27/61] sysfs: flatten and fix sysfs_rename_dir() error handling Greg Kroah-Hartman
2007-07-11 23:31 ` [PATCH 28/61] sysfs: consolidate sysfs_dirent creation functions Greg Kroah-Hartman
2007-07-11 23:31 ` [PATCH 29/61] sysfs: add sysfs_dirent->s_parent Greg Kroah-Hartman
2007-07-11 23:31 ` Greg Kroah-Hartman [this message]
2007-07-11 23:31 ` [PATCH 31/61] sysfs: make sysfs_dirent->s_element a union Greg Kroah-Hartman
2007-07-11 23:31 ` [PATCH 32/61] sysfs: implement kobj_sysfs_assoc_lock Greg Kroah-Hartman
2007-07-11 23:31 ` [PATCH 33/61] sysfs: reimplement symlink using sysfs_dirent tree Greg Kroah-Hartman
2007-07-11 23:31 ` [PATCH 34/61] sysfs: implement bin_buffer Greg Kroah-Hartman
2007-07-11 23:31 ` [PATCH 35/61] sysfs: implement sysfs_dirent active reference and immediate disconnect Greg Kroah-Hartman
2007-07-11 23:31 ` [PATCH 36/61] sysfs: kill attribute file orphaning Greg Kroah-Hartman
2007-07-11 23:31 ` [PATCH 37/61] sysfs: separate out sysfs_attach_dentry() Greg Kroah-Hartman
2007-07-11 23:31 ` [PATCH 38/61] sysfs: reimplement sysfs_drop_dentry() Greg Kroah-Hartman
2007-07-11 23:31 ` [PATCH 39/61] sysfs: kill unnecessary attribute->owner Greg Kroah-Hartman
2007-07-11 23:31 ` [PATCH 40/61] driver-core: make devt_attr and uevent_attr static Greg Kroah-Hartman
2007-07-11 23:32 ` [PATCH 41/61] sysfs: make sysfs_alloc_ino() static Greg Kroah-Hartman
2007-07-11 23:32 ` [PATCH 42/61] sysfs: fix parent refcounting during rename and move Greg Kroah-Hartman
2007-07-11 23:32 ` [PATCH 43/61] sysfs: reorganize sysfs_new_indoe() and sysfs_create() Greg Kroah-Hartman
2007-07-11 23:32 ` [PATCH 44/61] sysfs: use iget_locked() instead of new_inode() Greg Kroah-Hartman
2007-07-11 23:32 ` [PATCH 45/61] sysfs: fix root sysfs_dirent -> root dentry association Greg Kroah-Hartman
2007-07-11 23:32 ` [PATCH 46/61] sysfs: move s_active functions to fs/sysfs/dir.c Greg Kroah-Hartman
2007-07-11 23:32 ` [PATCH 47/61] sysfs: slim down sysfs_dirent->s_active Greg Kroah-Hartman
2007-07-11 23:32 ` [PATCH 48/61] sysfs: use singly-linked list for sysfs_dirent tree Greg Kroah-Hartman
2007-07-11 23:32 ` [PATCH 49/61] sysfs: Fix oops in sysfs_drop_dentry on x86_64 Greg Kroah-Hartman
2007-07-11 23:32 ` [PATCH 50/61] sysfs: make sysfs_drop_dentry() access inodes using ilookup() Greg Kroah-Hartman
2007-07-11 23:32 ` [PATCH 51/61] sysfs: rename sysfs_dirent->s_type to s_flags and make room for flags Greg Kroah-Hartman
2007-07-11 23:32 ` [PATCH 52/61] sysfs: implement SYSFS_FLAG_REMOVED flag Greg Kroah-Hartman
2007-07-11 23:32 ` [PATCH 53/61] sysfs: implement sysfs_find_dirent() and sysfs_get_dirent() Greg Kroah-Hartman
2007-07-11 23:32 ` [PATCH 54/61] sysfs: make kobj point to sysfs_dirent instead of dentry Greg Kroah-Hartman
2007-07-11 23:32 ` [PATCH 55/61] sysfs: consolidate sysfs spinlocks Greg Kroah-Hartman
2007-07-11 23:32 ` [PATCH 56/61] sysfs: use sysfs_mutex to protect the sysfs_dirent tree Greg Kroah-Hartman
2007-07-11 23:32 ` [PATCH 57/61] sysfs: restructure add/remove paths and fix inode update Greg Kroah-Hartman
2007-07-11 23:32 ` [PATCH 58/61] sysfs: move sysfs_drop_dentry() to dir.c and make it static Greg Kroah-Hartman
2007-07-11 23:32 ` [PATCH 59/61] sysfs: implement sysfs_get_dentry() Greg Kroah-Hartman
2007-07-11 23:32 ` [PATCH 60/61] sysfs: make directory dentries and inodes reclaimable Greg Kroah-Hartman
2007-07-11 23:32 ` [PATCH 61/61] sysfs: add parameter "struct bin_attribute *" in .read/.write methods for sysfs binary attributes Greg Kroah-Hartman
2007-07-11 23:50 ` [PATCH 24/61] sysfs: make sysfs_put() ignore NULL sd YOSHIFUJI Hideaki / 吉藤英明
2007-07-11 23:55 ` Greg KH
2007-07-12 1:06 ` YOSHIFUJI Hideaki / 吉藤英明
2007-07-12 3:00 ` Tejun Heo
2007-07-12 19:46 ` Satyam Sharma
2007-07-13 4:21 ` Tejun Heo
2007-07-13 5:03 ` Tejun Heo
2007-07-13 17:28 ` Satyam Sharma
2007-07-14 3:01 ` Tejun Heo
2007-07-14 4:27 ` Satyam Sharma
2007-07-14 4:52 ` Tejun Heo
2007-07-11 23:38 ` [PATCH 01/61] Rules on how to use sysfs in userspace programs Robert P. J. Day
2007-07-11 23:43 ` Greg KH
2007-07-12 10:39 ` Rene Herman
2007-07-12 8:48 ` Pavel Machek
2007-07-12 21:59 ` Kay Sievers
2007-07-12 22:14 ` Greg KH
2007-07-12 22:41 ` Pavel Machek
2007-07-13 2:14 ` 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=11841968773426-git-send-email-gregkh@suse.de \
--to=gregkh@suse.de \
--cc=htejun@gmail.com \
--cc=linux-kernel@vger.kernel.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox