Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 107386
b: refs/heads/master
c: 70526b6
h: refs/heads/master
v: v3
  • Loading branch information
Joel Becker authored and Mark Fasheh committed Jul 31, 2008
1 parent b691663 commit 1f276ab
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 10 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 99cefda42ac550863b5ae1df9e60322e377decf9
refs/heads/master: 70526b67443a980d5029d9cf06903bef731a4e96
42 changes: 33 additions & 9 deletions trunk/fs/configfs/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -1100,7 +1100,7 @@ static int configfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
struct configfs_subsystem *subsys;
struct configfs_dirent *sd;
struct config_item_type *type;
struct module *owner = NULL;
struct module *subsys_owner = NULL, *new_item_owner = NULL;
char *name;

if (dentry->d_parent == configfs_sb->s_root) {
Expand Down Expand Up @@ -1137,10 +1137,25 @@ static int configfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
goto out_put;
}

/*
* The subsystem may belong to a different module than the item
* being created. We don't want to safely pin the new item but
* fail to pin the subsystem it sits under.
*/
if (!subsys->su_group.cg_item.ci_type) {
ret = -EINVAL;
goto out_put;
}
subsys_owner = subsys->su_group.cg_item.ci_type->ct_owner;
if (!try_module_get(subsys_owner)) {
ret = -EINVAL;
goto out_put;
}

name = kmalloc(dentry->d_name.len + 1, GFP_KERNEL);
if (!name) {
ret = -ENOMEM;
goto out_put;
goto out_subsys_put;
}

snprintf(name, dentry->d_name.len + 1, "%s", dentry->d_name.name);
Expand Down Expand Up @@ -1172,7 +1187,7 @@ static int configfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
* If ret != 0, then link_obj() was never called.
* There are no extra references to clean up.
*/
goto out_put;
goto out_subsys_put;
}

/*
Expand All @@ -1186,8 +1201,8 @@ static int configfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
goto out_unlink;
}

owner = type->ct_owner;
if (!try_module_get(owner)) {
new_item_owner = type->ct_owner;
if (!try_module_get(new_item_owner)) {
ret = -EINVAL;
goto out_unlink;
}
Expand Down Expand Up @@ -1236,9 +1251,13 @@ static int configfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
mutex_unlock(&subsys->su_mutex);

if (module_got)
module_put(owner);
module_put(new_item_owner);
}

out_subsys_put:
if (ret)
module_put(subsys_owner);

out_put:
/*
* link_obj()/link_group() took a reference from child->parent,
Expand All @@ -1257,7 +1276,7 @@ static int configfs_rmdir(struct inode *dir, struct dentry *dentry)
struct config_item *item;
struct configfs_subsystem *subsys;
struct configfs_dirent *sd;
struct module *owner = NULL;
struct module *subsys_owner = NULL, *dead_item_owner = NULL;
int ret;

if (dentry->d_parent == configfs_sb->s_root)
Expand All @@ -1284,6 +1303,10 @@ static int configfs_rmdir(struct inode *dir, struct dentry *dentry)
return -EINVAL;
}

/* configfs_mkdir() shouldn't have allowed this */
BUG_ON(!subsys->su_group.cg_item.ci_type);
subsys_owner = subsys->su_group.cg_item.ci_type->ct_owner;

/*
* Ensure that no racing symlink() will make detach_prep() fail while
* the new link is temporarily attached
Expand Down Expand Up @@ -1321,7 +1344,7 @@ static int configfs_rmdir(struct inode *dir, struct dentry *dentry)
config_item_put(parent_item);

if (item->ci_type)
owner = item->ci_type->ct_owner;
dead_item_owner = item->ci_type->ct_owner;

if (sd->s_type & CONFIGFS_USET_DIR) {
configfs_detach_group(item);
Expand All @@ -1343,7 +1366,8 @@ static int configfs_rmdir(struct inode *dir, struct dentry *dentry)
/* Drop our reference from above */
config_item_put(item);

module_put(owner);
module_put(dead_item_owner);
module_put(subsys_owner);

return 0;
}
Expand Down

0 comments on commit 1f276ab

Please sign in to comment.