Commit f7df406d authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'configfs-fixup-ptr-error' of git://oss.oracle.com/git/jlbec/linux-2.6

* 'configfs-fixup-ptr-error' of git://oss.oracle.com/git/jlbec/linux-2.6:
  configfs: Allow ->make_item() and ->make_group() to return detailed errors.
  Revert "configfs: Allow ->make_item() and ->make_group() to return detailed errors."
parents 5e248ac9 a6795e9e
...@@ -233,12 +233,10 @@ accomplished via the group operations specified on the group's ...@@ -233,12 +233,10 @@ accomplished via the group operations specified on the group's
config_item_type. config_item_type.
struct configfs_group_operations { struct configfs_group_operations {
int (*make_item)(struct config_group *group, struct config_item *(*make_item)(struct config_group *group,
const char *name, const char *name);
struct config_item **new_item); struct config_group *(*make_group)(struct config_group *group,
int (*make_group)(struct config_group *group, const char *name);
const char *name,
struct config_group **new_group);
int (*commit_item)(struct config_item *item); int (*commit_item)(struct config_item *item);
void (*disconnect_notify)(struct config_group *group, void (*disconnect_notify)(struct config_group *group,
struct config_item *item); struct config_item *item);
......
...@@ -273,13 +273,13 @@ static inline struct simple_children *to_simple_children(struct config_item *ite ...@@ -273,13 +273,13 @@ static inline struct simple_children *to_simple_children(struct config_item *ite
return item ? container_of(to_config_group(item), struct simple_children, group) : NULL; return item ? container_of(to_config_group(item), struct simple_children, group) : NULL;
} }
static int simple_children_make_item(struct config_group *group, const char *name, struct config_item **new_item) static struct config_item *simple_children_make_item(struct config_group *group, const char *name)
{ {
struct simple_child *simple_child; struct simple_child *simple_child;
simple_child = kzalloc(sizeof(struct simple_child), GFP_KERNEL); simple_child = kzalloc(sizeof(struct simple_child), GFP_KERNEL);
if (!simple_child) if (!simple_child)
return -ENOMEM; return ERR_PTR(-ENOMEM);
config_item_init_type_name(&simple_child->item, name, config_item_init_type_name(&simple_child->item, name,
...@@ -287,8 +287,7 @@ static int simple_children_make_item(struct config_group *group, const char *nam ...@@ -287,8 +287,7 @@ static int simple_children_make_item(struct config_group *group, const char *nam
simple_child->storeme = 0; simple_child->storeme = 0;
*new_item = &simple_child->item; return &simple_child->item;
return 0;
} }
static struct configfs_attribute simple_children_attr_description = { static struct configfs_attribute simple_children_attr_description = {
...@@ -360,21 +359,20 @@ static struct configfs_subsystem simple_children_subsys = { ...@@ -360,21 +359,20 @@ static struct configfs_subsystem simple_children_subsys = {
* children of its own. * children of its own.
*/ */
static int group_children_make_group(struct config_group *group, const char *name, struct config_group **new_group) static struct config_group *group_children_make_group(struct config_group *group, const char *name)
{ {
struct simple_children *simple_children; struct simple_children *simple_children;
simple_children = kzalloc(sizeof(struct simple_children), simple_children = kzalloc(sizeof(struct simple_children),
GFP_KERNEL); GFP_KERNEL);
if (!simple_children) if (!simple_children)
return -ENOMEM; return ERR_PTR(-ENOMEM);
config_group_init_type_name(&simple_children->group, name, config_group_init_type_name(&simple_children->group, name,
&simple_children_type); &simple_children_type);
*new_group = &simple_children->group; return &simple_children->group;
return 0;
} }
static struct configfs_attribute group_children_attr_description = { static struct configfs_attribute group_children_attr_description = {
......
...@@ -585,9 +585,8 @@ static struct config_item_type netconsole_target_type = { ...@@ -585,9 +585,8 @@ static struct config_item_type netconsole_target_type = {
* Group operations and type for netconsole_subsys. * Group operations and type for netconsole_subsys.
*/ */
static int make_netconsole_target(struct config_group *group, static struct config_item *make_netconsole_target(struct config_group *group,
const char *name, const char *name)
struct config_item **new_item)
{ {
unsigned long flags; unsigned long flags;
struct netconsole_target *nt; struct netconsole_target *nt;
...@@ -599,7 +598,7 @@ static int make_netconsole_target(struct config_group *group, ...@@ -599,7 +598,7 @@ static int make_netconsole_target(struct config_group *group,
nt = kzalloc(sizeof(*nt), GFP_KERNEL); nt = kzalloc(sizeof(*nt), GFP_KERNEL);
if (!nt) { if (!nt) {
printk(KERN_ERR "netconsole: failed to allocate memory\n"); printk(KERN_ERR "netconsole: failed to allocate memory\n");
return -ENOMEM; return ERR_PTR(-ENOMEM);
} }
nt->np.name = "netconsole"; nt->np.name = "netconsole";
...@@ -616,8 +615,7 @@ static int make_netconsole_target(struct config_group *group, ...@@ -616,8 +615,7 @@ static int make_netconsole_target(struct config_group *group,
list_add(&nt->list, &target_list); list_add(&nt->list, &target_list);
spin_unlock_irqrestore(&target_list_lock, flags); spin_unlock_irqrestore(&target_list_lock, flags);
*new_item = &nt->item; return &nt->item;
return 0;
} }
static void drop_netconsole_target(struct config_group *group, static void drop_netconsole_target(struct config_group *group,
......
...@@ -1027,9 +1027,10 @@ EXPORT_SYMBOL(configfs_undepend_item); ...@@ -1027,9 +1027,10 @@ EXPORT_SYMBOL(configfs_undepend_item);
static int configfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) static int configfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
{ {
int ret, module_got = 0; int ret = 0;
struct config_group *group; int module_got = 0;
struct config_item *item; struct config_group *group = NULL;
struct config_item *item = NULL;
struct config_item *parent_item; struct config_item *parent_item;
struct configfs_subsystem *subsys; struct configfs_subsystem *subsys;
struct configfs_dirent *sd; struct configfs_dirent *sd;
...@@ -1070,25 +1071,30 @@ static int configfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) ...@@ -1070,25 +1071,30 @@ static int configfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
snprintf(name, dentry->d_name.len + 1, "%s", dentry->d_name.name); snprintf(name, dentry->d_name.len + 1, "%s", dentry->d_name.name);
mutex_lock(&subsys->su_mutex); mutex_lock(&subsys->su_mutex);
group = NULL;
item = NULL;
if (type->ct_group_ops->make_group) { if (type->ct_group_ops->make_group) {
ret = type->ct_group_ops->make_group(to_config_group(parent_item), name, &group); group = type->ct_group_ops->make_group(to_config_group(parent_item), name);
if (!ret) { if (!group)
group = ERR_PTR(-ENOMEM);
if (!IS_ERR(group)) {
link_group(to_config_group(parent_item), group); link_group(to_config_group(parent_item), group);
item = &group->cg_item; item = &group->cg_item;
} } else
ret = PTR_ERR(group);
} else { } else {
ret = type->ct_group_ops->make_item(to_config_group(parent_item), name, &item); item = type->ct_group_ops->make_item(to_config_group(parent_item), name);
if (!ret) if (!item)
item = ERR_PTR(-ENOMEM);
if (!IS_ERR(item))
link_obj(parent_item, item); link_obj(parent_item, item);
else
ret = PTR_ERR(item);
} }
mutex_unlock(&subsys->su_mutex); mutex_unlock(&subsys->su_mutex);
kfree(name); kfree(name);
if (ret) { if (ret) {
/* /*
* If ret != 0, then link_obj() was never called. * If item == NULL, then link_obj() was never called.
* There are no extra references to clean up. * There are no extra references to clean up.
*/ */
goto out_put; goto out_put;
......
...@@ -41,20 +41,16 @@ struct comm; ...@@ -41,20 +41,16 @@ struct comm;
struct nodes; struct nodes;
struct node; struct node;
static int make_cluster(struct config_group *, const char *, static struct config_group *make_cluster(struct config_group *, const char *);
struct config_group **);
static void drop_cluster(struct config_group *, struct config_item *); static void drop_cluster(struct config_group *, struct config_item *);
static void release_cluster(struct config_item *); static void release_cluster(struct config_item *);
static int make_space(struct config_group *, const char *, static struct config_group *make_space(struct config_group *, const char *);
struct config_group **);
static void drop_space(struct config_group *, struct config_item *); static void drop_space(struct config_group *, struct config_item *);
static void release_space(struct config_item *); static void release_space(struct config_item *);
static int make_comm(struct config_group *, const char *, static struct config_item *make_comm(struct config_group *, const char *);
struct config_item **);
static void drop_comm(struct config_group *, struct config_item *); static void drop_comm(struct config_group *, struct config_item *);
static void release_comm(struct config_item *); static void release_comm(struct config_item *);
static int make_node(struct config_group *, const char *, static struct config_item *make_node(struct config_group *, const char *);
struct config_item **);
static void drop_node(struct config_group *, struct config_item *); static void drop_node(struct config_group *, struct config_item *);
static void release_node(struct config_item *); static void release_node(struct config_item *);
...@@ -396,8 +392,8 @@ static struct node *to_node(struct config_item *i) ...@@ -396,8 +392,8 @@ static struct node *to_node(struct config_item *i)
return i ? container_of(i, struct node, item) : NULL; return i ? container_of(i, struct node, item) : NULL;
} }
static int make_cluster(struct config_group *g, const char *name, static struct config_group *make_cluster(struct config_group *g,
struct config_group **new_g) const char *name)
{ {
struct cluster *cl = NULL; struct cluster *cl = NULL;
struct spaces *sps = NULL; struct spaces *sps = NULL;
...@@ -435,15 +431,14 @@ static int make_cluster(struct config_group *g, const char *name, ...@@ -435,15 +431,14 @@ static int make_cluster(struct config_group *g, const char *name,
space_list = &sps->ss_group; space_list = &sps->ss_group;
comm_list = &cms->cs_group; comm_list = &cms->cs_group;
*new_g = &cl->group; return &cl->group;
return 0;
fail: fail:
kfree(cl); kfree(cl);
kfree(gps); kfree(gps);
kfree(sps); kfree(sps);
kfree(cms); kfree(cms);
return -ENOMEM; return ERR_PTR(-ENOMEM);
} }
static void drop_cluster(struct config_group *g, struct config_item *i) static void drop_cluster(struct config_group *g, struct config_item *i)
...@@ -471,8 +466,7 @@ static void release_cluster(struct config_item *i) ...@@ -471,8 +466,7 @@ static void release_cluster(struct config_item *i)
kfree(cl); kfree(cl);
} }
static int make_space(struct config_group *g, const char *name, static struct config_group *make_space(struct config_group *g, const char *name)
struct config_group **new_g)
{ {
struct space *sp = NULL; struct space *sp = NULL;
struct nodes *nds = NULL; struct nodes *nds = NULL;
...@@ -495,14 +489,13 @@ static int make_space(struct config_group *g, const char *name, ...@@ -495,14 +489,13 @@ static int make_space(struct config_group *g, const char *name,
INIT_LIST_HEAD(&sp->members); INIT_LIST_HEAD(&sp->members);
mutex_init(&sp->members_lock); mutex_init(&sp->members_lock);
sp->members_count = 0; sp->members_count = 0;
*new_g = &sp->group; return &sp->group;
return 0;
fail: fail:
kfree(sp); kfree(sp);
kfree(gps); kfree(gps);
kfree(nds); kfree(nds);
return -ENOMEM; return ERR_PTR(-ENOMEM);
} }
static void drop_space(struct config_group *g, struct config_item *i) static void drop_space(struct config_group *g, struct config_item *i)
...@@ -529,21 +522,19 @@ static void release_space(struct config_item *i) ...@@ -529,21 +522,19 @@ static void release_space(struct config_item *i)
kfree(sp); kfree(sp);
} }
static int make_comm(struct config_group *g, const char *name, static struct config_item *make_comm(struct config_group *g, const char *name)
struct config_item **new_i)
{ {
struct comm *cm; struct comm *cm;
cm = kzalloc(sizeof(struct comm), GFP_KERNEL); cm = kzalloc(sizeof(struct comm), GFP_KERNEL);
if (!cm) if (!cm)
return -ENOMEM; return ERR_PTR(-ENOMEM);
config_item_init_type_name(&cm->item, name, &comm_type); config_item_init_type_name(&cm->item, name, &comm_type);
cm->nodeid = -1; cm->nodeid = -1;
cm->local = 0; cm->local = 0;
cm->addr_count = 0; cm->addr_count = 0;
*new_i = &cm->item; return &cm->item;
return 0;
} }
static void drop_comm(struct config_group *g, struct config_item *i) static void drop_comm(struct config_group *g, struct config_item *i)
...@@ -563,15 +554,14 @@ static void release_comm(struct config_item *i) ...@@ -563,15 +554,14 @@ static void release_comm(struct config_item *i)
kfree(cm); kfree(cm);
} }
static int make_node(struct config_group *g, const char *name, static struct config_item *make_node(struct config_group *g, const char *name)
struct config_item **new_i)
{ {
struct space *sp = to_space(g->cg_item.ci_parent); struct space *sp = to_space(g->cg_item.ci_parent);
struct node *nd; struct node *nd;
nd = kzalloc(sizeof(struct node), GFP_KERNEL); nd = kzalloc(sizeof(struct node), GFP_KERNEL);
if (!nd) if (!nd)
return -ENOMEM; return ERR_PTR(-ENOMEM);
config_item_init_type_name(&nd->item, name, &node_type); config_item_init_type_name(&nd->item, name, &node_type);
nd->nodeid = -1; nd->nodeid = -1;
...@@ -583,8 +573,7 @@ static int make_node(struct config_group *g, const char *name, ...@@ -583,8 +573,7 @@ static int make_node(struct config_group *g, const char *name,
sp->members_count++; sp->members_count++;
mutex_unlock(&sp->members_lock); mutex_unlock(&sp->members_lock);
*new_i = &nd->item; return &nd->item;
return 0;
} }
static void drop_node(struct config_group *g, struct config_item *i) static void drop_node(struct config_group *g, struct config_item *i)
......
...@@ -1489,31 +1489,22 @@ static struct o2hb_heartbeat_group *to_o2hb_heartbeat_group(struct config_group ...@@ -1489,31 +1489,22 @@ static struct o2hb_heartbeat_group *to_o2hb_heartbeat_group(struct config_group
: NULL; : NULL;
} }
static int o2hb_heartbeat_group_make_item(struct config_group *group, static struct config_item *o2hb_heartbeat_group_make_item(struct config_group *group,
const char *name, const char *name)
struct config_item **new_item)
{ {
struct o2hb_region *reg = NULL; struct o2hb_region *reg = NULL;
int ret = 0;
reg = kzalloc(sizeof(struct o2hb_region), GFP_KERNEL); reg = kzalloc(sizeof(struct o2hb_region), GFP_KERNEL);
if (reg == NULL) { if (reg == NULL)
ret = -ENOMEM; return ERR_PTR(-ENOMEM);
goto out;
}
config_item_init_type_name(&reg->hr_item, name, &o2hb_region_type); config_item_init_type_name(&reg->hr_item, name, &o2hb_region_type);
*new_item = &reg->hr_item;
spin_lock(&o2hb_live_lock); spin_lock(&o2hb_live_lock);
list_add_tail(&reg->hr_all_item, &o2hb_all_regions); list_add_tail(&reg->hr_all_item, &o2hb_all_regions);
spin_unlock(&o2hb_live_lock); spin_unlock(&o2hb_live_lock);
out:
if (ret)
kfree(reg);
return ret; return &reg->hr_item;
} }
static void o2hb_heartbeat_group_drop_item(struct config_group *group, static void o2hb_heartbeat_group_drop_item(struct config_group *group,
......
...@@ -644,35 +644,23 @@ static ssize_t o2nm_cluster_store(struct config_item *item, ...@@ -644,35 +644,23 @@ static ssize_t o2nm_cluster_store(struct config_item *item,
return ret; return ret;
} }
static int o2nm_node_group_make_item(struct config_group *group, static struct config_item *o2nm_node_group_make_item(struct config_group *group,
const char *name, const char *name)
struct config_item **new_item)
{ {
struct o2nm_node *node = NULL; struct o2nm_node *node = NULL;
int ret = 0;
if (strlen(name) > O2NM_MAX_NAME_LEN) { if (strlen(name) > O2NM_MAX_NAME_LEN)
ret = -ENAMETOOLONG; return ERR_PTR(-ENAMETOOLONG);
goto out;
}
node = kzalloc(sizeof(struct o2nm_node), GFP_KERNEL); node = kzalloc(sizeof(struct o2nm_node), GFP_KERNEL);
if (node == NULL) { if (node == NULL)
ret = -ENOMEM; return ERR_PTR(-ENOMEM);
goto out;
}
strcpy(node->nd_name, name); /* use item.ci_namebuf instead? */ strcpy(node->nd_name, name); /* use item.ci_namebuf instead? */
config_item_init_type_name(&node->nd_item, name, &o2nm_node_type); config_item_init_type_name(&node->nd_item, name, &o2nm_node_type);
spin_lock_init(&node->nd_lock); spin_lock_init(&node->nd_lock);
*new_item = &node->nd_item; return &node->nd_item;
out:
if (ret)
kfree(node);
return ret;
} }
static void o2nm_node_group_drop_item(struct config_group *group, static void o2nm_node_group_drop_item(struct config_group *group,
...@@ -756,31 +744,25 @@ static struct o2nm_cluster_group *to_o2nm_cluster_group(struct config_group *gro ...@@ -756,31 +744,25 @@ static struct o2nm_cluster_group *to_o2nm_cluster_group(struct config_group *gro
} }
#endif #endif
static int o2nm_cluster_group_make_group(struct config_group *group, static struct config_group *o2nm_cluster_group_make_group(struct config_group *group,
const char *name, const char *name)
struct config_group **new_group)
{ {
struct o2nm_cluster *cluster = NULL; struct o2nm_cluster *cluster = NULL;
struct o2nm_node_group *ns = NULL; struct o2nm_node_group *ns = NULL;
struct config_group *o2hb_group = NULL; struct config_group *o2hb_group = NULL, *ret = NULL;
void *defs = NULL; void *defs = NULL;
int ret = 0;
/* this runs under the parent dir's i_mutex; there can be only /* this runs under the parent dir's i_mutex; there can be only
* one caller in here at a time */ * one caller in here at a time */
if (o2nm_single_cluster) { if (o2nm_single_cluster)
ret = -ENOSPC; return ERR_PTR(-ENOSPC);
goto out;
}
cluster = kzalloc(sizeof(struct o2nm_cluster), GFP_KERNEL); cluster = kzalloc(sizeof(struct o2nm_cluster), GFP_KERNEL);
ns = kzalloc(sizeof(struct o2nm_node_group), GFP_KERNEL); ns = kzalloc(sizeof(struct o2nm_node_group), GFP_KERNEL);
defs = kcalloc(3, sizeof(struct config_group *), GFP_KERNEL); defs = kcalloc(3, sizeof(struct config_group *), GFP_KERNEL);
o2hb_group = o2hb_alloc_hb_set(); o2hb_group = o2hb_alloc_hb_set();
if (cluster == NULL || ns == NULL || o2hb_group == NULL || defs == NULL) { if (cluster == NULL || ns == NULL || o2hb_group == NULL || defs == NULL)
ret = -ENOMEM;
goto out; goto out;
}
config_group_init_type_name(&cluster->cl_group, name, config_group_init_type_name(&cluster->cl_group, name,
&o2nm_cluster_type); &o2nm_cluster_type);
...@@ -797,15 +779,16 @@ static int o2nm_cluster_group_make_group(struct config_group *group, ...@@ -797,15 +779,16 @@ static int o2nm_cluster_group_make_group(struct config_group *group,
cluster->cl_idle_timeout_ms = O2NET_IDLE_TIMEOUT_MS_DEFAULT; cluster->cl_idle_timeout_ms = O2NET_IDLE_TIMEOUT_MS_DEFAULT;
cluster->cl_keepalive_delay_ms = O2NET_KEEPALIVE_DELAY_MS_DEFAULT; cluster->cl_keepalive_delay_ms = O2NET_KEEPALIVE_DELAY_MS_DEFAULT;
*new_group = &cluster->cl_group; ret = &cluster->cl_group;
o2nm_single_cluster = cluster; o2nm_single_cluster = cluster;
out: out:
if (ret) { if (ret == NULL) {
kfree(cluster); kfree(cluster);
kfree(ns); kfree(ns);
o2hb_free_hb_set(o2hb_group); o2hb_free_hb_set(o2hb_group);
kfree(defs); kfree(defs);
ret = ERR_PTR(-ENOMEM);
} }
return ret; return ret;
......
...@@ -148,7 +148,8 @@ struct configfs_attribute { ...@@ -148,7 +148,8 @@ struct configfs_attribute {
* items. If the item is a group, it may support mkdir(2). * items. If the item is a group, it may support mkdir(2).
* Groups supply one of make_group() and make_item(). If the * Groups supply one of make_group() and make_item(). If the
* group supports make_group(), one can create group children. If it * group supports make_group(), one can create group children. If it
* supports make_item(), one can create config_item children. If it has * supports make_item(), one can create config_item children. make_group()
* and make_item() return ERR_PTR() on errors. If it has
* default_groups on group->default_groups, it has automatically created * default_groups on group->default_groups, it has automatically created
* group children. default_groups may coexist alongsize make_group() or * group children. default_groups may coexist alongsize make_group() or
* make_item(), but if the group wishes to have only default_groups * make_item(), but if the group wishes to have only default_groups
...@@ -165,8 +166,8 @@ struct configfs_item_operations { ...@@ -165,8 +166,8 @@ struct configfs_item_operations {
}; };
struct configfs_group_operations { struct configfs_group_operations {
int (*make_item)(struct config_group *group, const char *name, struct config_item **new_item); struct config_item *(*make_item)(struct config_group *group, const char *name);
int (*make_group)(struct config_group *group, const char *name, struct config_group **new_group); struct config_group *(*make_group)(struct config_group *group, const char *name);
int (*commit_item)(struct config_item *item); int (*commit_item)(struct config_item *item);
void (*disconnect_notify)(struct config_group *group, struct config_item *item); void (*disconnect_notify)(struct config_group *group, struct config_item *item);
void (*drop_item)(struct config_group *group, struct config_item *item); void (*drop_item)(struct config_group *group, struct config_item *item);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment