Skip to content

Commit c7c434c

Browse files
lkpdnBartosz Golaszewski
authored andcommitted
gpio: virtuser: lock up configfs that an instantiated device depends on
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 <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Bartosz Golaszewski <[email protected]>
1 parent 656cc2e commit c7c434c

File tree

1 file changed

+40
-7
lines changed

1 file changed

+40
-7
lines changed

drivers/gpio/gpio-virtuser.c

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1546,6 +1546,30 @@ gpio_virtuser_device_deactivate(struct gpio_virtuser_device *dev)
15461546
dev->pdev = NULL;
15471547
}
15481548

1549+
static void
1550+
gpio_virtuser_device_lockup_configfs(struct gpio_virtuser_device *dev, bool lock)
1551+
{
1552+
struct configfs_subsystem *subsys = dev->group.cg_subsys;
1553+
struct gpio_virtuser_lookup_entry *entry;
1554+
struct gpio_virtuser_lookup *lookup;
1555+
1556+
/*
1557+
* The device only needs to depend on leaf lookup entries. This is
1558+
* sufficient to lock up all the configfs entries that the
1559+
* instantiated, alive device depends on.
1560+
*/
1561+
list_for_each_entry(lookup, &dev->lookup_list, siblings) {
1562+
list_for_each_entry(entry, &lookup->entry_list, siblings) {
1563+
if (lock)
1564+
WARN_ON(configfs_depend_item_unlocked(
1565+
subsys, &entry->group.cg_item));
1566+
else
1567+
configfs_undepend_item_unlocked(
1568+
&entry->group.cg_item);
1569+
}
1570+
}
1571+
}
1572+
15491573
static ssize_t
15501574
gpio_virtuser_device_config_live_store(struct config_item *item,
15511575
const char *page, size_t count)
@@ -1558,15 +1582,24 @@ gpio_virtuser_device_config_live_store(struct config_item *item,
15581582
if (ret)
15591583
return ret;
15601584

1561-
guard(mutex)(&dev->lock);
1585+
if (live)
1586+
gpio_virtuser_device_lockup_configfs(dev, true);
15621587

1563-
if (live == gpio_virtuser_device_is_live(dev))
1564-
return -EPERM;
1588+
scoped_guard(mutex, &dev->lock) {
1589+
if (live == gpio_virtuser_device_is_live(dev))
1590+
ret = -EPERM;
1591+
else if (live)
1592+
ret = gpio_virtuser_device_activate(dev);
1593+
else
1594+
gpio_virtuser_device_deactivate(dev);
1595+
}
15651596

1566-
if (live)
1567-
ret = gpio_virtuser_device_activate(dev);
1568-
else
1569-
gpio_virtuser_device_deactivate(dev);
1597+
/*
1598+
* Undepend is required only if device disablement (live == 0)
1599+
* succeeds or if device enablement (live == 1) fails.
1600+
*/
1601+
if (live == !!ret)
1602+
gpio_virtuser_device_lockup_configfs(dev, false);
15701603

15711604
return ret ?: count;
15721605
}

0 commit comments

Comments
 (0)