Return-Path: Received: from mbligh ([unix socket]) (authenticated user=mbligh bits=0) by mbligh (Cyrus v2.1.16-IPv6-Debian-2.1.16-4) with LMTP; Wed, 05 May 2004 06:12:26 -0700 X-Sieve: CMU Sieve 2.2 Return-Path: X-Original-To: mbligh@localhost Delivered-To: mbligh@localhost.beaverton.ibm.com Received: from mail.aracnet.com (localhost [127.0.0.1]) by mbligh.beaverton.ibm.com (Postfix) with ESMTP id ECFEAF3205 for ; Wed, 5 May 2004 06:12:25 -0700 (PDT) Received: from psmtp.com (exprod5mx1.postini.com [12.158.34.141]) by obsidian.spiritone.com (8.12.10/8.12.8) with SMTP id i45DDBvZ015905 for ; Wed, 5 May 2004 06:13:11 -0700 Delivered-To: Received: from source ([67.72.78.212]) by exprod5mx1.postini.com ([12.158.34.245]) with SMTP; Wed, 05 May 2004 09:13:02 EDT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S264659AbUEENAM (ORCPT ); Wed, 5 May 2004 09:00:12 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S264649AbUEEM7g (ORCPT ); Wed, 5 May 2004 08:59:36 -0400 Received: from e32.co.us.ibm.com ([32.97.110.130]:61865 "EHLO e32.co.us.ibm.com") by vger.kernel.org with ESMTP id S264647AbUEEM4r (ORCPT ); Wed, 5 May 2004 08:56:47 -0400 Received: from westrelay02.boulder.ibm.com (westrelay02.boulder.ibm.com [9.17.195.11]) by e32.co.us.ibm.com (8.12.10/8.12.2) with ESMTP id i45CuXnU794056; Wed, 5 May 2004 08:56:33 -0400 Received: from bigbang.in.ibm.com (d03av02.boulder.ibm.com [9.17.195.168]) by westrelay02.boulder.ibm.com (8.12.10/NCO/VER6.6) with ESMTP id i45CuTko333808; Wed, 5 May 2004 06:56:31 -0600 Received: by bigbang.in.ibm.com (Postfix, from userid 500) id 0B37E1C734; Wed, 5 May 2004 08:59:50 -0400 (EDT) Date: Wed, 5 May 2004 18:29:49 +0530 From: Maneesh Soni To: LKML Cc: Al Viro , Greg KH Subject: [RFC 6/6] sysfs backing store ver 0.5 Message-ID: <20040505125949.GG1244@in.ibm.com> Reply-To: maneesh@in.ibm.com References: <20040505125702.GA1244@in.ibm.com> <20040505125755.GB1244@in.ibm.com> <20040505125815.GC1244@in.ibm.com> <20040505125833.GD1244@in.ibm.com> <20040505125902.GE1244@in.ibm.com> <20040505125925.GF1244@in.ibm.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20040505125925.GF1244@in.ibm.com> User-Agent: Mutt/1.4.1i Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org => changes in version 0.5 o New additions like struct sysfs_symlink. and changes to sysfs_get_kobject() => changes in version 0.4 o Nil, just re-diffed => changes in version 0.3 o Corrected dentry ref counting for sysfs_create_group() and sysfs_remove_group(). => changes in Version 0.2 o Provided error checking after sysfs_get_dentry() call in sysfs_remove_group(). o kfree the symlink name while freeing the corresponding sysfs_dirent in sysfs_put(). ================ o This patch has the changes required for attribute groups and misc. routines. fs/sysfs/group.c | 18 ++++++---- fs/sysfs/sysfs.h | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 101 insertions(+), 10 deletions(-) diff -upN reference/fs/sysfs/group.c current/fs/sysfs/group.c --- reference/fs/sysfs/group.c 2004-04-07 14:54:31.000000000 -0700 +++ current/fs/sysfs/group.c 2004-05-09 13:45:22.000000000 -0700 @@ -10,7 +10,7 @@ #include #include -#include +#include #include #include "sysfs.h" @@ -31,7 +31,7 @@ static int create_files(struct dentry * int error = 0; for (attr = grp->attrs; *attr && !error; attr++) { - error = sysfs_add_file(dir,*attr); + error = sysfs_add_file(dir, *attr, SYSFS_KOBJ_ATTR); } if (error) remove_files(dir,grp); @@ -70,11 +70,15 @@ void sysfs_remove_group(struct kobject * else dir = dget(kobj->dentry); - remove_files(dir,grp); - if (grp->name) - sysfs_remove_subdir(dir); - /* release the ref. taken in this routine */ - dput(dir); + if (!IS_ERR(dir)) { + if (dir && dir->d_inode) { + remove_files(dir,grp); + if (grp->name) + sysfs_remove_subdir(dir); + /* release the ref. taken in this routine */ + dput(dir); + } + } } diff -upN reference/fs/sysfs/sysfs.h current/fs/sysfs/sysfs.h --- reference/fs/sysfs/sysfs.h 2004-05-09 13:45:22.000000000 -0700 +++ current/fs/sysfs/sysfs.h 2004-05-09 13:45:22.000000000 -0700 @@ -1,28 +1,115 @@ +#include extern struct vfsmount * sysfs_mount; +extern struct super_block * sysfs_sb; 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 *, const struct attribute *, int); -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_create_subdir(struct kobject *, const char *, struct dentry **); extern void sysfs_remove_subdir(struct dentry *); +extern int sysfs_dir_open(struct inode *inode, struct file *file); +extern int sysfs_dir_close(struct inode *inode, struct file *file); +extern loff_t sysfs_dir_lseek(struct file *, loff_t, int); +extern int sysfs_readdir(struct file *, void *, filldir_t); +extern void sysfs_umount_begin(struct super_block *); +extern const unsigned char * sysfs_get_name(struct sysfs_dirent *); +extern struct dentry * sysfs_lookup(struct inode *, struct dentry *, struct nameidata *); +extern int sysfs_symlink(struct inode * dir, struct dentry *dentry, const char * symname); +extern int init_symlink(struct inode * inode); extern int sysfs_readlink(struct dentry *, char __user *, int ); extern int sysfs_follow_link(struct dentry *, struct nameidata *); extern struct rw_semaphore sysfs_rename_sem; +extern struct file_operations sysfs_file_operations; +extern struct file_operations bin_fops; +extern struct inode_operations sysfs_dir_inode_operations; +extern struct file_operations sysfs_dir_operations; + +struct sysfs_symlink { + char * link_name; + struct kobject * target_kobj; +}; + +static inline +struct sysfs_dirent * sysfs_new_dirent(struct sysfs_dirent * p, void * e, int t) +{ + struct sysfs_dirent * sd; + + sd = kmalloc(sizeof(*sd), GFP_KERNEL); + if (!sd) + return NULL; + memset(sd, 0, sizeof(*sd)); + atomic_set(&sd->s_count, 1); + sd->s_element = e; + sd->s_type = t; + sd->s_dentry = NULL; + INIT_LIST_HEAD(&sd->s_children); + list_add(&sd->s_sibling, &p->s_children); + + return sd; +} + +static inline struct sysfs_dirent * sysfs_get(struct sysfs_dirent * sd) +{ + if (sd) { + WARN_ON(!atomic_read(&sd->s_count)); + atomic_inc(&sd->s_count); + } + return sd; +} + +static inline void sysfs_put(struct sysfs_dirent * sd) +{ + if (atomic_dec_and_test(&sd->s_count)) { + 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); + } + kfree(sd); + } +} + +static inline +void sysfs_remove_dirent(struct sysfs_dirent * parent_sd, const char * name) +{ + struct list_head * tmp; + + tmp = parent_sd->s_children.next; + while (tmp != & parent_sd->s_children) { + struct sysfs_dirent * sd; + sd = list_entry(tmp, struct sysfs_dirent, s_sibling); + tmp = tmp->next; + if (sd->s_type & SYSFS_NOT_PINNED) { + if (!strcmp(sysfs_get_name(sd), name)) { + list_del_init(&sd->s_sibling); + sysfs_put(sd); + } + } + } +} + static inline struct kobject *sysfs_get_kobject(struct dentry *dentry) { struct kobject * kobj = NULL; spin_lock(&dcache_lock); - if (!d_unhashed(dentry)) - kobj = kobject_get(dentry->d_fsdata); + if (!d_unhashed(dentry)) { + struct sysfs_dirent * sd = dentry->d_fsdata; + if (sd->s_type & SYSFS_KOBJ_LINK) { + struct sysfs_symlink * sl = sd->s_element; + kobj = kobject_get(sl->target_kobj); + } else + kobj = kobject_get(sd->s_element); + } spin_unlock(&dcache_lock); return kobj;