public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Maneesh Soni <maneesh@in.ibm.com>
To: Al Viro <viro@parcelfarce.linux.theplanet.co.uk>,
	Greg KH <greg@kroah.com>, Patrick Mochel <mochel@osdl.org>,
	Christian Borntraeger <CBORNTRA@de.ibm.com>
Cc: LKML <linux-kernel@vger.kernel.org>,
	Dipankar Sarma <dipankar@in.ibm.com>
Subject: [RFC 1/5] sysfs-backing-store.patch
Date: Wed, 12 Nov 2003 17:55:03 +0530	[thread overview]
Message-ID: <20031112122503.GE14580@in.ibm.com> (raw)
In-Reply-To: <20031112122344.GD14580@in.ibm.com>



o This patch describes the necessary data structures needed for sysfs backing
  store and the changes related to initialing sysfs filesystem. sysfs_dirent
  represents any element from kobject infrastructure. The element could be
  kobject, attribute, binary attribute, attribute group or symlink. kobject
  hierarchy is represented by using sysfs_dirent's s_children & s_sibling
  links. 

o Root of sysfs filesystem is represented by statically allocated sysfs_dirent
  structure. Initialisation now does not mount sysfs filesystem and just
  does registration.

o The patch also has some support routines internal to sysfs code.


 fs/sysfs/mount.c        |   41 ++++++++++---------
 fs/sysfs/sysfs.h        |  103 ++++++++++++++++++++++++++++++++++++++++++++++--
 include/linux/kobject.h |    2 
 include/linux/sysfs.h   |   19 ++++++++
 4 files changed, 142 insertions(+), 23 deletions(-)

diff -puN include/linux/kobject.h~sysfs-backing-store include/linux/kobject.h
--- linux-2.6.0-test9/include/linux/kobject.h~sysfs-backing-store	2003-11-12 16:02:27.000000000 +0530
+++ linux-2.6.0-test9-maneesh/include/linux/kobject.h	2003-11-12 16:02:27.000000000 +0530
@@ -31,7 +31,7 @@ struct kobject {
 	struct kobject		* parent;
 	struct kset		* kset;
 	struct kobj_type	* ktype;
-	struct dentry		* dentry;
+	struct sysfs_dirent	* s_dirent;
 };
 
 extern int kobject_set_name(struct kobject *, const char *, ...)
diff -puN include/linux/sysfs.h~sysfs-backing-store include/linux/sysfs.h
--- linux-2.6.0-test9/include/linux/sysfs.h~sysfs-backing-store	2003-11-12 16:02:27.000000000 +0530
+++ linux-2.6.0-test9-maneesh/include/linux/sysfs.h	2003-11-12 16:14:56.000000000 +0530
@@ -9,6 +9,8 @@
 #ifndef _SYSFS_H_
 #define _SYSFS_H_
 
+#include <linux/rwsem.h>
+
 struct kobject;
 struct module;
 
@@ -63,6 +65,23 @@ struct attribute_group {
 	struct attribute	** attrs;
 };
 
+struct sysfs_dirent {
+	struct list_head	s_sibling;  
+	struct list_head	s_children;
+	void 			* s_element;
+	struct dentry		* s_dentry;
+	int			s_type;
+	struct rw_semaphore	s_rwsem;
+};
+
+/* Types of kobject elements represented by sysfs_dirent */
+#define SYSFS_ROOT		0x0001
+#define	SYSFS_KOBJECT		0x0002
+#define	SYSFS_KOBJ_ATTR		0x0004
+#define	SYSFS_KOBJ_BIN_ATTR	0x0008
+#define	SYSFS_KOBJ_ATTR_GROUP	0x0010
+#define	SYSFS_KOBJ_LINK		0x0020
+
 int sysfs_create_group(struct kobject *, const struct attribute_group *);
 void sysfs_remove_group(struct kobject *, const struct attribute_group *);
 
diff -puN fs/sysfs/mount.c~sysfs-backing-store fs/sysfs/mount.c
--- linux-2.6.0-test9/fs/sysfs/mount.c~sysfs-backing-store	2003-11-12 16:02:27.000000000 +0530
+++ linux-2.6.0-test9-maneesh/fs/sysfs/mount.c	2003-11-12 16:02:27.000000000 +0530
@@ -14,7 +14,6 @@
 /* Random magic number */
 #define SYSFS_MAGIC 0x62656572
 
-struct vfsmount *sysfs_mount;
 struct super_block * sysfs_sb = NULL;
 
 static struct super_operations sysfs_ops = {
@@ -22,6 +21,15 @@ static struct super_operations sysfs_ops
 	.drop_inode	= generic_delete_inode,
 };
 
+struct sysfs_dirent sysfs_root = {
+	.s_sibling	= LIST_HEAD_INIT(sysfs_root.s_sibling),
+	.s_children	= LIST_HEAD_INIT(sysfs_root.s_children),
+	.s_element	= NULL,
+	.s_dentry	= NULL,
+	.s_type		= SYSFS_ROOT,
+	.s_rwsem	= __RWSEM_INITIALIZER(sysfs_root.s_rwsem),
+};
+
 static int sysfs_fill_super(struct super_block *sb, void *data, int silent)
 {
 	struct inode *inode;
@@ -35,10 +43,9 @@ static int sysfs_fill_super(struct super
 
 	inode = sysfs_new_inode(S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO);
 	if (inode) {
-		inode->i_op = &simple_dir_inode_operations;
-		inode->i_fop = &simple_dir_operations;
-		/* directory inodes start off with i_nlink == 2 (for "." entry) */
-		inode->i_nlink++;	
+		inode->i_op = &sysfs_dir_inode_operations;
+		inode->i_fop = &sysfs_dir_operations;
+		inode->i_nlink += sysfs_get_link_count(&sysfs_root);
 	} else {
 		pr_debug("sysfs: could not get root inode\n");
 		return -ENOMEM;
@@ -50,7 +57,10 @@ static int sysfs_fill_super(struct super
 		iput(inode);
 		return -ENOMEM;
 	}
+	root->d_fsdata = &sysfs_root;
+	sysfs_root.s_dentry = root;
 	sb->s_root = root;
+
 	return 0;
 }
 
@@ -60,24 +70,19 @@ static struct super_block *sysfs_get_sb(
 	return get_sb_single(fs_type, flags, data, sysfs_fill_super);
 }
 
+static void sysfs_kill_super(struct super_block * sb)
+{
+	sysfs_root.s_dentry = NULL;
+	kill_anon_super(sb);
+}
+
 static struct file_system_type sysfs_fs_type = {
 	.name		= "sysfs",
 	.get_sb		= sysfs_get_sb,
-	.kill_sb	= kill_litter_super,
+	.kill_sb	= sysfs_kill_super,
 };
 
 int __init sysfs_init(void)
 {
-	int err;
-
-	err = register_filesystem(&sysfs_fs_type);
-	if (!err) {
-		sysfs_mount = kern_mount(&sysfs_fs_type);
-		if (IS_ERR(sysfs_mount)) {
-			printk(KERN_ERR "sysfs: could not mount!\n");
-			err = PTR_ERR(sysfs_mount);
-			sysfs_mount = NULL;
-		}
-	}
-	return err;
+	return register_filesystem(&sysfs_fs_type);
 }
diff -puN fs/sysfs/sysfs.h~sysfs-backing-store fs/sysfs/sysfs.h
--- linux-2.6.0-test9/fs/sysfs/sysfs.h~sysfs-backing-store	2003-11-12 16:02:27.000000000 +0530
+++ linux-2.6.0-test9-maneesh/fs/sysfs/sysfs.h	2003-11-12 16:02:27.000000000 +0530
@@ -1,13 +1,108 @@
 
-extern struct vfsmount * sysfs_mount;
+#include <linux/fs.h>
+
+extern struct sysfs_dirent sysfs_root;
 
 extern struct inode * sysfs_new_inode(mode_t mode);
 extern int sysfs_create(struct dentry *, int mode, int (*init)(struct inode *));
 
 extern struct dentry * sysfs_get_dentry(struct dentry *, const char *);
 
-extern int sysfs_add_file(struct dentry * dir, const struct attribute * attr);
-extern void sysfs_hash_and_remove(struct dentry * dir, const char * name);
+extern int sysfs_add_file(struct sysfs_dirent * , const struct attribute * );
+extern void sysfs_hash_and_remove(struct sysfs_dirent *, const char *);
 
-extern int sysfs_create_subdir(struct kobject *, const char *, struct dentry **);
 extern void sysfs_remove_subdir(struct dentry *);
+extern char * sysfs_get_name(struct sysfs_dirent *);
+extern int sysfs_get_link_count(struct sysfs_dirent *);
+extern struct dentry * sysfs_get_new_dentry(struct dentry *, const char *);
+extern int sysfs_init_file(struct inode * inode);
+extern int sysfs_symlink(struct inode *, struct dentry *, const char *);
+
+extern struct inode_operations sysfs_dir_inode_operations;
+extern struct file_operations sysfs_dir_operations;
+extern struct file_operations bin_fops;
+
+struct dentry * sysfs_lookup(struct inode *, struct dentry *, struct nameidata *);
+int sysfs_dir_open(struct inode *inode, struct file *file);
+int sysfs_dir_close(struct inode *inode, struct file *file);
+loff_t sysfs_dir_lseek(struct file *file, loff_t offset, int origin);
+int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir);
+
+static inline struct kobject * sysfs_get_file_kobject(struct dentry * dentry)
+{
+	struct dentry * parent;
+	struct sysfs_dirent * sd;
+	
+	parent = dentry->d_parent;
+	sd = parent->d_fsdata;
+	if (sd->s_type == SYSFS_KOBJ_ATTR_GROUP)
+		sd = parent->d_parent->d_fsdata;
+
+	return (struct kobject *) sd->s_element;
+		
+}
+
+static inline struct attribute * sysfs_get_file_attr(struct file * filp)
+{
+	struct sysfs_dirent * sd = filp->f_dentry->d_fsdata;
+	return sd->s_element;
+		
+}
+
+static inline struct sysfs_dirent * 
+sysfs_alloc_dirent(struct sysfs_dirent * parent_sd, void * element, int type)
+{
+	struct sysfs_dirent * sd;
+					
+	sd = kmalloc(sizeof(*sd), GFP_KERNEL);
+	if (!sd)
+		return ERR_PTR(-ENOMEM);
+
+	init_rwsem(&sd->s_rwsem);
+	INIT_LIST_HEAD(&sd->s_children);
+	sd->s_element = element;
+	sd->s_type = type;
+	sd->s_dentry = NULL;
+
+	down_write(&parent_sd->s_rwsem);
+	list_add(&sd->s_sibling, &parent_sd->s_children);
+	up_write(&parent_sd->s_rwsem);
+
+	return sd;
+}
+
+static inline void
+sysfs_free_dirent(struct sysfs_dirent * parent_sd, const char * name)
+{
+	struct sysfs_dirent * sd;
+	struct list_head * tmp;
+	
+	down_write(&parent_sd->s_rwsem);
+	tmp = parent_sd->s_children.next;
+	while (tmp != &parent_sd->s_children) {
+		sd = list_entry(tmp, struct sysfs_dirent, s_sibling);
+		tmp = tmp->next;
+		if (!strcmp(name, sysfs_get_name(sd))) {
+			list_del(&sd->s_sibling);
+			kfree(sd);
+		}
+	}
+	up_write(&parent_sd->s_rwsem);
+}
+
+static inline void
+sysfs_free_children(struct sysfs_dirent * parent_sd)
+{
+	struct sysfs_dirent * sd;
+	struct list_head * tmp;
+	
+	down_write(&parent_sd->s_rwsem);
+	tmp = parent_sd->s_children.next;
+	while (tmp != &parent_sd->s_children) {
+		sd = list_entry(tmp, struct sysfs_dirent, s_sibling);
+		tmp = tmp->next;
+		list_del(&sd->s_sibling);
+		kfree(sd);
+	}
+	up_write(&parent_sd->s_rwsem);
+}

_
-- 
Maneesh Soni
Linux Technology Center, 
IBM Software Lab, Bangalore, India
email: maneesh@in.ibm.com
Phone: 91-80-5044999 Fax: 91-80-5268553
T/L : 9243696

  reply	other threads:[~2003-11-12 12:26 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-11-12 12:23 [RFC 0/5] Backing Store for sysfs (Overhauled) Maneesh Soni
2003-11-12 12:25 ` Maneesh Soni [this message]
2003-11-12 12:25   ` [RFC 2/5] sysfs-dir.patch Maneesh Soni
2003-11-12 12:25     ` [RFC 3/5] sysfs-file.patch Maneesh Soni
2003-11-12 12:26       ` [RFC 4/5] sysfs-attr_group.patch Maneesh Soni
2003-11-12 12:26         ` [RFC 5/5] sysfs-symlink.patch Maneesh Soni
2003-11-12 14:39     ` [RFC 2/5] sysfs-dir.patch viro
2003-11-12 16:00 ` [RFC 0/5] Backing Store for sysfs (Overhauled) Greg KH
2003-11-12 16:27   ` Dipankar Sarma
2003-11-12 16:39     ` Greg KH
2003-11-13 19:34 ` Patrick Mochel
2003-11-13 19:55   ` Dipankar Sarma

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=20031112122503.GE14580@in.ibm.com \
    --to=maneesh@in.ibm.com \
    --cc=CBORNTRA@de.ibm.com \
    --cc=dipankar@in.ibm.com \
    --cc=greg@kroah.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mochel@osdl.org \
    --cc=viro@parcelfarce.linux.theplanet.co.uk \
    /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