Commit 8bd76b3d authored by Koichiro Den's avatar Koichiro Den Committed by Bartosz Golaszewski
Browse files

gpio: sim: lock up configfs that an instantiated device depends on



Once a sim device is instantiated and actively used, allowing rmdir for
its configfs serves no purpose and can be confusing. Effectively,
arbitrary users start depending on its existence.

Make the subsystem itself depend on the configfs entry for a sim device
while it is in active use.

Signed-off-by: default avatarKoichiro Den <koichiro.den@canonical.com>
Link: https://lore.kernel.org/r/20250103141829.430662-5-koichiro.den@canonical.com


Signed-off-by: default avatarBartosz Golaszewski <bartosz.golaszewski@linaro.org>
parent c7c434c1
Loading
Loading
Loading
Loading
+41 −7
Original line number Diff line number Diff line
@@ -1027,6 +1027,30 @@ static void gpio_sim_device_deactivate(struct gpio_sim_device *dev)
	dev->pdev = NULL;
}

static void
gpio_sim_device_lockup_configfs(struct gpio_sim_device *dev, bool lock)
{
	struct configfs_subsystem *subsys = dev->group.cg_subsys;
	struct gpio_sim_bank *bank;
	struct gpio_sim_line *line;

	/*
	 * The device only needs to depend on leaf line entries. This is
	 * sufficient to lock up all the configfs entries that the
	 * instantiated, alive device depends on.
	 */
	list_for_each_entry(bank, &dev->bank_list, siblings) {
		list_for_each_entry(line, &bank->line_list, siblings) {
			if (lock)
				WARN_ON(configfs_depend_item_unlocked(
						subsys, &line->group.cg_item));
			else
				configfs_undepend_item_unlocked(
						&line->group.cg_item);
		}
	}
}

static ssize_t
gpio_sim_device_config_live_store(struct config_item *item,
				  const char *page, size_t count)
@@ -1039,14 +1063,24 @@ gpio_sim_device_config_live_store(struct config_item *item,
	if (ret)
		return ret;

	guard(mutex)(&dev->lock);
	if (live)
		gpio_sim_device_lockup_configfs(dev, true);

	scoped_guard(mutex, &dev->lock) {
		if (live == gpio_sim_device_is_live(dev))
			ret = -EPERM;
		else if (live)
			ret = gpio_sim_device_activate(dev);
		else
			gpio_sim_device_deactivate(dev);
	}

	/*
	 * Undepend is required only if device disablement (live == 0)
	 * succeeds or if device enablement (live == 1) fails.
	 */
	if (live == !!ret)
		gpio_sim_device_lockup_configfs(dev, false);

	return ret ?: count;
}