Skip to content

Commit

Permalink
gpio: virtuser: lock up configfs that an instantiated device depends on
Browse files Browse the repository at this point in the history
Once a virtuser device is instantiated and actively used, allowing rmdir
for its configfs serves no purpose and can be confusing. Userspace
interacts with the virtual consumer at arbitrary times, meaning it
depends on its existence.

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

Signed-off-by: Koichiro Den <koichiro.den@canonical.com>
Link: https://lore.kernel.org/r/20250103141829.430662-4-koichiro.den@canonical.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
  • Loading branch information
Koichiro Den authored and Bartosz Golaszewski committed Jan 3, 2025
1 parent 656cc2e commit c7c434c
Showing 1 changed file with 40 additions and 7 deletions.
47 changes: 40 additions & 7 deletions drivers/gpio/gpio-virtuser.c
Original file line number Diff line number Diff line change
Expand Up @@ -1546,6 +1546,30 @@ gpio_virtuser_device_deactivate(struct gpio_virtuser_device *dev)
dev->pdev = NULL;
}

static void
gpio_virtuser_device_lockup_configfs(struct gpio_virtuser_device *dev, bool lock)
{
struct configfs_subsystem *subsys = dev->group.cg_subsys;
struct gpio_virtuser_lookup_entry *entry;
struct gpio_virtuser_lookup *lookup;

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

static ssize_t
gpio_virtuser_device_config_live_store(struct config_item *item,
const char *page, size_t count)
Expand All @@ -1558,15 +1582,24 @@ gpio_virtuser_device_config_live_store(struct config_item *item,
if (ret)
return ret;

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

if (live == gpio_virtuser_device_is_live(dev))
return -EPERM;
scoped_guard(mutex, &dev->lock) {
if (live == gpio_virtuser_device_is_live(dev))
ret = -EPERM;
else if (live)
ret = gpio_virtuser_device_activate(dev);
else
gpio_virtuser_device_deactivate(dev);
}

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

return ret ?: count;
}
Expand Down

0 comments on commit c7c434c

Please sign in to comment.