diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/sysfs/dir.c | 73 | ||||
-rw-r--r-- | fs/sysfs/symlink.c | 27 |
2 files changed, 58 insertions, 42 deletions
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c index f09626cc568a..b4c482461403 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c @@ -207,40 +207,53 @@ static int init_symlink(struct inode * inode) return 0; } -static int create_dir(struct kobject * k, struct dentry * p, - const char * n, struct dentry ** d) +static int create_dir(struct kobject *kobj, struct dentry *parent, + const char *name, struct dentry **p_dentry) { int error; umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO; + struct dentry *dentry; + struct sysfs_dirent *sd; - mutex_lock(&p->d_inode->i_mutex); - *d = lookup_one_len(n, p, strlen(n)); - if (!IS_ERR(*d)) { - if (sysfs_dirent_exist(p->d_fsdata, n)) - error = -EEXIST; - else - error = sysfs_make_dirent(p->d_fsdata, *d, k, mode, - SYSFS_DIR); - if (!error) { - error = sysfs_create(*d, mode, init_dir); - if (!error) { - inc_nlink(p->d_inode); - (*d)->d_op = &sysfs_dentry_ops; - d_rehash(*d); - } - } - if (error && (error != -EEXIST)) { - struct sysfs_dirent *sd = (*d)->d_fsdata; - if (sd) { - list_del_init(&sd->s_sibling); - sysfs_put(sd); - } - d_drop(*d); - } - dput(*d); - } else - error = PTR_ERR(*d); - mutex_unlock(&p->d_inode->i_mutex); + mutex_lock(&parent->d_inode->i_mutex); + + dentry = lookup_one_len(name, parent, strlen(name)); + if (IS_ERR(dentry)) { + error = PTR_ERR(dentry); + goto out_unlock; + } + + error = -EEXIST; + if (sysfs_dirent_exist(parent->d_fsdata, name)) + goto out_dput; + + error = sysfs_make_dirent(parent->d_fsdata, dentry, kobj, mode, + SYSFS_DIR); + if (error) + goto out_drop; + + error = sysfs_create(dentry, mode, init_dir); + if (error) + goto out_sput; + + inc_nlink(parent->d_inode); + dentry->d_op = &sysfs_dentry_ops; + d_rehash(dentry); + + *p_dentry = dentry; + error = 0; + goto out_dput; + + out_sput: + sd = dentry->d_fsdata; + list_del_init(&sd->s_sibling); + sysfs_put(sd); + out_drop: + d_drop(dentry); + out_dput: + dput(dentry); + out_unlock: + mutex_unlock(&parent->d_inode->i_mutex); return error; } diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c index 7b9c5bfde920..b463f17f6638 100644 --- a/fs/sysfs/symlink.c +++ b/fs/sysfs/symlink.c @@ -49,30 +49,33 @@ static int sysfs_add_link(struct dentry * parent, const char * name, struct kobj { struct sysfs_dirent * parent_sd = parent->d_fsdata; struct sysfs_symlink * sl; - int error = 0; + int error; error = -ENOMEM; - sl = kmalloc(sizeof(*sl), GFP_KERNEL); + sl = kzalloc(sizeof(*sl), GFP_KERNEL); if (!sl) - goto exit1; + goto err_out; sl->link_name = kmalloc(strlen(name) + 1, GFP_KERNEL); if (!sl->link_name) - goto exit2; + goto err_out; strcpy(sl->link_name, name); sl->target_kobj = kobject_get(target); error = sysfs_make_dirent(parent_sd, NULL, sl, S_IFLNK|S_IRWXUGO, SYSFS_KOBJ_LINK); - if (!error) - return 0; - - kobject_put(target); - kfree(sl->link_name); -exit2: - kfree(sl); -exit1: + if (error) + goto err_out; + + return 0; + + err_out: + if (sl) { + kobject_put(sl->target_kobj); + kfree(sl->link_name); + kfree(sl); + } return error; } |