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

Commit a6795e9e authored by Joel Becker's avatar Joel Becker
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 ERR_PTR() values.  These errors are
bubbled up appropriately.  NULL returns are changed to -ENOMEM for
compatibility.

Also updated are the in-kernel users of configfs.

This is a rework of reverted commit 11c3b792.

Signed-off-by: default avatarJoel Becker <joel.becker@oracle.com>
parent f89ab861
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -279,7 +279,7 @@ static struct config_item *simple_children_make_item(struct config_group *group,

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


	config_item_init_type_name(&simple_child->item, name,
@@ -366,7 +366,7 @@ static struct config_group *group_children_make_group(struct config_group *group
	simple_children = kzalloc(sizeof(struct simple_children),
				  GFP_KERNEL);
	if (!simple_children)
		return NULL;
		return ERR_PTR(-ENOMEM);


	config_group_init_type_name(&simple_children->group, name,
+1 −1
Original line number Diff line number Diff line
@@ -598,7 +598,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 ERR_PTR(-ENOMEM);
	}

	nt->np.name = "netconsole";
+15 −10
Original line number Diff line number Diff line
@@ -1027,9 +1027,10 @@ EXPORT_SYMBOL(configfs_undepend_item);

static int configfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
{
	int ret, module_got = 0;
	struct config_group *group;
	struct config_item *item;
	int ret = 0;
	int module_got = 0;
	struct config_group *group = NULL;
	struct config_item *item = NULL;
	struct config_item *parent_item;
	struct configfs_subsystem *subsys;
	struct configfs_dirent *sd;
@@ -1070,28 +1071,32 @@ static int configfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
	snprintf(name, dentry->d_name.len + 1, "%s", dentry->d_name.name);

	mutex_lock(&subsys->su_mutex);
	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) {
		if (!group)
			group = ERR_PTR(-ENOMEM);
		if (!IS_ERR(group)) {
			link_group(to_config_group(parent_item), group);
			item = &group->cg_item;
		}
		} else
			ret = PTR_ERR(group);
	} else {
		item = type->ct_group_ops->make_item(to_config_group(parent_item), name);
		if (item)
		if (!item)
			item = ERR_PTR(-ENOMEM);
		if (!IS_ERR(item))
			link_obj(parent_item, item);
		else
			ret = PTR_ERR(item);
	}
	mutex_unlock(&subsys->su_mutex);

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

+4 −4
Original line number Diff line number Diff line
@@ -438,7 +438,7 @@ static struct config_group *make_cluster(struct config_group *g,
	kfree(gps);
	kfree(sps);
	kfree(cms);
	return NULL;
	return ERR_PTR(-ENOMEM);
}

static void drop_cluster(struct config_group *g, struct config_item *i)
@@ -495,7 +495,7 @@ static struct config_group *make_space(struct config_group *g, const char *name)
	kfree(sp);
	kfree(gps);
	kfree(nds);
	return NULL;
	return ERR_PTR(-ENOMEM);
}

static void drop_space(struct config_group *g, struct config_item *i)
@@ -528,7 +528,7 @@ static struct config_item *make_comm(struct config_group *g, const char *name)

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

	config_item_init_type_name(&cm->item, name, &comm_type);
	cm->nodeid = -1;
@@ -561,7 +561,7 @@ static struct config_item *make_node(struct config_group *g, const char *name)

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

	config_item_init_type_name(&nd->item, name, &node_type);
	nd->nodeid = -1;
+2 −8
Original line number Diff line number Diff line
@@ -1493,24 +1493,18 @@ static struct config_item *o2hb_heartbeat_group_make_item(struct config_group *g
							  const char *name)
{
	struct o2hb_region *reg = NULL;
	struct config_item *ret = NULL;

	reg = kzalloc(sizeof(struct o2hb_region), GFP_KERNEL);
	if (reg == NULL)
		goto out; /* ENOMEM */
		return ERR_PTR(-ENOMEM);

	config_item_init_type_name(&reg->hr_item, name, &o2hb_region_type);

	ret = &reg->hr_item;

	spin_lock(&o2hb_live_lock);
	list_add_tail(&reg->hr_all_item, &o2hb_all_regions);
	spin_unlock(&o2hb_live_lock);
out:
	if (ret == NULL)
		kfree(reg);

	return ret;
	return &reg->hr_item;
}

static void o2hb_heartbeat_group_drop_item(struct config_group *group,
Loading