Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 11c3b792 authored by Joel Becker's avatar Joel Becker Committed by Mark Fasheh
Browse files

configfs: Allow ->make_item() and ->make_group() to return detailed errors.



The configfs operations ->make_item() and ->make_group() currently
return a new item/group.  A return of NULL signifies an error.  Because
of this, -ENOMEM is the only return code bubbled up the stack.

Multiple folks have requested the ability to return specific error codes
when these operations fail.  This patch adds that ability by changing the
->make_item/group() ops to return an int.

Also updated are the in-kernel users of configfs.

Signed-off-by: default avatarJoel Becker <joel.becker@oracle.com>
parent 6d8344ba
Loading
Loading
Loading
Loading
+6 −4
Original line number Diff line number Diff line
@@ -233,10 +233,12 @@ accomplished via the group operations specified on the group's
config_item_type.

	struct configfs_group_operations {
		struct config_item *(*make_item)(struct config_group *group,
						 const char *name);
		struct config_group *(*make_group)(struct config_group *group,
						   const char *name);
		int (*make_item)(struct config_group *group,
				 const char *name,
				 struct config_item **new_item);
		int (*make_group)(struct config_group *group,
				  const char *name,
				  struct config_group **new_group);
		int (*commit_item)(struct config_item *item);
		void (*disconnect_notify)(struct config_group *group,
					  struct config_item *item);
+8 −6
Original line number Diff line number Diff line
@@ -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;
}

static struct config_item *simple_children_make_item(struct config_group *group, const char *name)
static int simple_children_make_item(struct config_group *group, const char *name, struct config_item **new_item)
{
	struct simple_child *simple_child;

	simple_child = kzalloc(sizeof(struct simple_child), GFP_KERNEL);
	if (!simple_child)
		return NULL;
		return -ENOMEM;


	config_item_init_type_name(&simple_child->item, name,
@@ -287,7 +287,8 @@ static struct config_item *simple_children_make_item(struct config_group *group,

	simple_child->storeme = 0;

	return &simple_child->item;
	*new_item = &simple_child->item;
	return 0;
}

static struct configfs_attribute simple_children_attr_description = {
@@ -359,20 +360,21 @@ static struct configfs_subsystem simple_children_subsys = {
 * children of its own.
 */

static struct config_group *group_children_make_group(struct config_group *group, const char *name)
static int group_children_make_group(struct config_group *group, const char *name, struct config_group **new_group)
{
	struct simple_children *simple_children;

	simple_children = kzalloc(sizeof(struct simple_children),
				  GFP_KERNEL);
	if (!simple_children)
		return NULL;
		return -ENOMEM;


	config_group_init_type_name(&simple_children->group, name,
				    &simple_children_type);

	return &simple_children->group;
	*new_group = &simple_children->group;
	return 0;
}

static struct configfs_attribute group_children_attr_description = {
+6 −4
Original line number Diff line number Diff line
@@ -585,8 +585,9 @@ static struct config_item_type netconsole_target_type = {
 * Group operations and type for netconsole_subsys.
 */

static struct config_item *make_netconsole_target(struct config_group *group,
						  const char *name)
static int make_netconsole_target(struct config_group *group,
				  const char *name,
				  struct config_item **new_item)
{
	unsigned long flags;
	struct netconsole_target *nt;
@@ -598,7 +599,7 @@ static struct config_item *make_netconsole_target(struct config_group *group,
	nt = kzalloc(sizeof(*nt), GFP_KERNEL);
	if (!nt) {
		printk(KERN_ERR "netconsole: failed to allocate memory\n");
		return NULL;
		return -ENOMEM;
	}

	nt->np.name = "netconsole";
@@ -615,7 +616,8 @@ static struct config_item *make_netconsole_target(struct config_group *group,
	list_add(&nt->list, &target_list);
	spin_unlock_irqrestore(&target_list_lock, flags);

	return &nt->item;
	*new_item = &nt->item;
	return 0;
}

static void drop_netconsole_target(struct config_group *group,
+6 −7
Original line number Diff line number Diff line
@@ -1073,25 +1073,24 @@ static int configfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
	group = NULL;
	item = NULL;
	if (type->ct_group_ops->make_group) {
		group = type->ct_group_ops->make_group(to_config_group(parent_item), name);
		if (group) {
		ret = type->ct_group_ops->make_group(to_config_group(parent_item), name, &group);
		if (!ret) {
			link_group(to_config_group(parent_item), group);
			item = &group->cg_item;
		}
	} else {
		item = type->ct_group_ops->make_item(to_config_group(parent_item), name);
		if (item)
		ret = type->ct_group_ops->make_item(to_config_group(parent_item), name, &item);
		if (!ret)
			link_obj(parent_item, item);
	}
	mutex_unlock(&subsys->su_mutex);

	kfree(name);
	if (!item) {
	if (ret) {
		/*
		 * If item == NULL, then link_obj() was never called.
		 * If ret != 0, then link_obj() was never called.
		 * There are no extra references to clean up.
		 */
		ret = -ENOMEM;
		goto out_put;
	}

+28 −17
Original line number Diff line number Diff line
@@ -41,16 +41,20 @@ struct comm;
struct nodes;
struct node;

static struct config_group *make_cluster(struct config_group *, const char *);
static int make_cluster(struct config_group *, const char *,
			struct config_group **);
static void drop_cluster(struct config_group *, struct config_item *);
static void release_cluster(struct config_item *);
static struct config_group *make_space(struct config_group *, const char *);
static int make_space(struct config_group *, const char *,
		      struct config_group **);
static void drop_space(struct config_group *, struct config_item *);
static void release_space(struct config_item *);
static struct config_item *make_comm(struct config_group *, const char *);
static int make_comm(struct config_group *, const char *,
		     struct config_item **);
static void drop_comm(struct config_group *, struct config_item *);
static void release_comm(struct config_item *);
static struct config_item *make_node(struct config_group *, const char *);
static int make_node(struct config_group *, const char *,
		     struct config_item **);
static void drop_node(struct config_group *, struct config_item *);
static void release_node(struct config_item *);

@@ -392,8 +396,8 @@ static struct node *to_node(struct config_item *i)
	return i ? container_of(i, struct node, item) : NULL;
}

static struct config_group *make_cluster(struct config_group *g,
					 const char *name)
static int make_cluster(struct config_group *g, const char *name,
			struct config_group **new_g)
{
	struct cluster *cl = NULL;
	struct spaces *sps = NULL;
@@ -431,14 +435,15 @@ static struct config_group *make_cluster(struct config_group *g,

	space_list = &sps->ss_group;
	comm_list = &cms->cs_group;
	return &cl->group;
	*new_g = &cl->group;
	return 0;

 fail:
	kfree(cl);
	kfree(gps);
	kfree(sps);
	kfree(cms);
	return NULL;
	return -ENOMEM;
}

static void drop_cluster(struct config_group *g, struct config_item *i)
@@ -466,7 +471,8 @@ static void release_cluster(struct config_item *i)
	kfree(cl);
}

static struct config_group *make_space(struct config_group *g, const char *name)
static int make_space(struct config_group *g, const char *name,
		      struct config_group **new_g)
{
	struct space *sp = NULL;
	struct nodes *nds = NULL;
@@ -489,13 +495,14 @@ static struct config_group *make_space(struct config_group *g, const char *name)
	INIT_LIST_HEAD(&sp->members);
	mutex_init(&sp->members_lock);
	sp->members_count = 0;
	return &sp->group;
	*new_g = &sp->group;
	return 0;

 fail:
	kfree(sp);
	kfree(gps);
	kfree(nds);
	return NULL;
	return -ENOMEM;
}

static void drop_space(struct config_group *g, struct config_item *i)
@@ -522,19 +529,21 @@ static void release_space(struct config_item *i)
	kfree(sp);
}

static struct config_item *make_comm(struct config_group *g, const char *name)
static int make_comm(struct config_group *g, const char *name,
		     struct config_item **new_i)
{
	struct comm *cm;

	cm = kzalloc(sizeof(struct comm), GFP_KERNEL);
	if (!cm)
		return NULL;
		return -ENOMEM;

	config_item_init_type_name(&cm->item, name, &comm_type);
	cm->nodeid = -1;
	cm->local = 0;
	cm->addr_count = 0;
	return &cm->item;
	*new_i = &cm->item;
	return 0;
}

static void drop_comm(struct config_group *g, struct config_item *i)
@@ -554,14 +563,15 @@ static void release_comm(struct config_item *i)
	kfree(cm);
}

static struct config_item *make_node(struct config_group *g, const char *name)
static int 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 node *nd;

	nd = kzalloc(sizeof(struct node), GFP_KERNEL);
	if (!nd)
		return NULL;
		return -ENOMEM;

	config_item_init_type_name(&nd->item, name, &node_type);
	nd->nodeid = -1;
@@ -573,7 +583,8 @@ static struct config_item *make_node(struct config_group *g, const char *name)
	sp->members_count++;
	mutex_unlock(&sp->members_lock);

	return &nd->item;
	*new_i = &nd->item;
	return 0;
}

static void drop_node(struct config_group *g, struct config_item *i)
Loading