lkml.org 
[lkml]   [2009]   [May]   [28]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Date
    Subject[PATCH 10/24] sysfs: Fix locking and factor out sysfs_sd_setattr
    From: Eric W. Biederman <ebiederm@xmission.com>

    Cleanly separate the work that is specific to setting the
    attributes of a sysfs_dirent from what is needed to update
    the attributes of a vfs inode.

    Additionally grab the sysfs_mutex to keep any nasties from
    surprising us when updating the sysfs_dirent.

    Acked-by: Tejun Heo <tj@kernel.org>
    Signed-off-by: Eric W. Biederman <ebiederm@aristanetworks.com>
    ---
    fs/sysfs/inode.c | 52 ++++++++++++++++++++++++++++++----------------------
    fs/sysfs/sysfs.h | 1 +
    2 files changed, 31 insertions(+), 22 deletions(-)

    diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c
    index 5020a1d..dd154cb 100644
    --- a/fs/sysfs/inode.c
    +++ b/fs/sysfs/inode.c
    @@ -42,33 +42,12 @@ int __init sysfs_inode_init(void)
    return bdi_init(&sysfs_backing_dev_info);
    }

    -int sysfs_setattr(struct dentry * dentry, struct iattr * iattr)
    +int sysfs_sd_setattr(struct sysfs_dirent *sd, struct iattr * iattr)
    {
    - struct inode * inode = dentry->d_inode;
    - struct sysfs_dirent * sd = dentry->d_fsdata;
    struct iattr * sd_iattr;
    unsigned int ia_valid = iattr->ia_valid;
    - int error;
    -
    - if (!sd)
    - return -EINVAL;

    sd_iattr = sd->s_iattr;
    -
    - error = inode_change_ok(inode, iattr);
    - if (error)
    - return error;
    -
    - iattr->ia_valid &= ~ATTR_SIZE; /* ignore size changes */
    - if (iattr->ia_valid & ATTR_MODE) {
    - if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID))
    - iattr->ia_mode &= ~S_ISGID;
    - }
    -
    - error = inode_setattr(inode, iattr);
    - if (error)
    - return error;
    -
    if (!sd_iattr && (ia_valid & ~ATTR_MODE)) {
    /* setting attributes for the first time, allocate now */
    sd_iattr = kzalloc(sizeof(struct iattr), GFP_KERNEL);
    @@ -103,6 +82,35 @@ int sysfs_setattr(struct dentry * dentry, struct iattr * iattr)
    sd_iattr->ia_ctime = iattr->ia_ctime;
    if (ia_valid & ATTR_MODE)
    sd_iattr->ia_mode = iattr->ia_mode;
    + return 0;
    +}
    +
    +int sysfs_setattr(struct dentry * dentry, struct iattr * iattr)
    +{
    + struct inode * inode = dentry->d_inode;
    + struct sysfs_dirent * sd = dentry->d_fsdata;
    + int error;
    +
    + if (!sd)
    + return -EINVAL;
    +
    + error = inode_change_ok(inode, iattr);
    + if (error)
    + return error;
    +
    + iattr->ia_valid &= ~ATTR_SIZE; /* ignore size changes */
    + if (iattr->ia_valid & ATTR_MODE) {
    + if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID))
    + iattr->ia_mode &= ~S_ISGID;
    + }
    +
    + error = inode_setattr(inode, iattr);
    + if (error)
    + return error;
    +
    + mutex_lock(&sysfs_mutex);
    + error = sysfs_sd_setattr(sd, iattr);
    + mutex_unlock(&sysfs_mutex);

    return error;
    }
    diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h
    index abf05f4..043bb13 100644
    --- a/fs/sysfs/sysfs.h
    +++ b/fs/sysfs/sysfs.h
    @@ -146,6 +146,7 @@ static inline void __sysfs_put(struct sysfs_dirent *sd)
    */
    struct inode *sysfs_get_inode(struct sysfs_dirent *sd);
    void sysfs_delete_inode(struct inode *inode);
    +int sysfs_sd_setattr(struct sysfs_dirent *sd, struct iattr *iattr);
    int sysfs_setattr(struct dentry *dentry, struct iattr *iattr);
    int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const char *name);
    int sysfs_inode_init(void);
    --
    1.6.3.1.54.g99dd.dirty


    \
     
     \ /
      Last update: 2009-05-29 01:25    [W:0.030 / U:1.016 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site