lkml.org 
[lkml]   [2004]   [Mar]   [3]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[RFC] 6/6 sysfs backing store version 0.2


    => changes in Version 0.2
    > Provided error checking after sysfs_get_dentry() call in
    sysfs_remove_group().
    > 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 | 15 ++++++----
    fs/sysfs/sysfs.h | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
    2 files changed, 85 insertions(+), 7 deletions(-)

    diff -puN fs/sysfs/group.c~sysfs-leaves-misc fs/sysfs/group.c
    --- linux-2.6.4-rc1/fs/sysfs/group.c~sysfs-leaves-misc 2004-03-03 16:24:15.000000000 +0530
    +++ linux-2.6.4-rc1-maneesh/fs/sysfs/group.c 2004-03-03 16:24:15.000000000 +0530
    @@ -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);
    @@ -68,12 +68,15 @@ void sysfs_remove_group(struct kobject *
    if (grp->name)
    dir = sysfs_get_dentry(kobj->dentry,grp->name);
    else
    - dir = kobj->dentry;
    + dir = dget(kobj->dentry);

    - remove_files(dir,grp);
    - dput(dir);
    - if (grp->name)
    - sysfs_remove_subdir(dir);
    + if (!IS_ERR(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 -puN fs/sysfs/sysfs.h~sysfs-leaves-misc fs/sysfs/sysfs.h
    --- linux-2.6.4-rc1/fs/sysfs/sysfs.h~sysfs-leaves-misc 2004-03-03 16:24:15.000000000 +0530
    +++ linux-2.6.4-rc1-maneesh/fs/sysfs/sysfs.h 2004-03-03 16:24:15.000000000 +0530
    @@ -1,4 +1,5 @@

    +#include <linux/fs.h>
    extern struct vfsmount * sysfs_mount;

    extern struct inode * sysfs_new_inode(mode_t mode);
    @@ -6,8 +7,82 @@ extern int sysfs_create(struct dentry *,

    extern struct dentry * sysfs_get_dentry(struct dentry *, const char *);

    -extern int sysfs_add_file(struct dentry * dir, const struct attribute * attr);
    +extern int sysfs_add_file(struct dentry *, const struct attribute *, int);
    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 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 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 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;
    +
    +
    +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) {
    + char ** link_names = sd->s_element;
    + kfree(link_names[0]);
    + kfree(link_names[1]);
    + kfree(sd->s_element);
    + }
    + 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);
    + }
    + }
    + }
    +}
    +
    _
    --
    Maneesh Soni
    Linux Technology Center,
    IBM Software Lab, Bangalore, India
    email: maneesh@in.ibm.com
    Phone: 91-80-25044999 Fax: 91-80-5268553
    T/L : 9243696
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2005-03-22 14:01    [W:0.030 / U:36.068 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site