Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Koichiro Den <koichiro.den@canonical.com>
Link: https://lore.kernel.org/r/20250103141829.430662-5-koichiro.den@canonical.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>

authored by

Koichiro Den and committed by
Bartosz Golaszewski
8bd76b3d c7c434c1

+41 -7
+41 -7
drivers/gpio/gpio-sim.c
··· 1027 1027 dev->pdev = NULL; 1028 1028 } 1029 1029 1030 + static void 1031 + gpio_sim_device_lockup_configfs(struct gpio_sim_device *dev, bool lock) 1032 + { 1033 + struct configfs_subsystem *subsys = dev->group.cg_subsys; 1034 + struct gpio_sim_bank *bank; 1035 + struct gpio_sim_line *line; 1036 + 1037 + /* 1038 + * The device only needs to depend on leaf line entries. This is 1039 + * sufficient to lock up all the configfs entries that the 1040 + * instantiated, alive device depends on. 1041 + */ 1042 + list_for_each_entry(bank, &dev->bank_list, siblings) { 1043 + list_for_each_entry(line, &bank->line_list, siblings) { 1044 + if (lock) 1045 + WARN_ON(configfs_depend_item_unlocked( 1046 + subsys, &line->group.cg_item)); 1047 + else 1048 + configfs_undepend_item_unlocked( 1049 + &line->group.cg_item); 1050 + } 1051 + } 1052 + } 1053 + 1030 1054 static ssize_t 1031 1055 gpio_sim_device_config_live_store(struct config_item *item, 1032 1056 const char *page, size_t count) ··· 1063 1039 if (ret) 1064 1040 return ret; 1065 1041 1066 - guard(mutex)(&dev->lock); 1042 + if (live) 1043 + gpio_sim_device_lockup_configfs(dev, true); 1067 1044 1068 - if (live == gpio_sim_device_is_live(dev)) 1069 - ret = -EPERM; 1070 - else if (live) 1071 - ret = gpio_sim_device_activate(dev); 1072 - else 1073 - gpio_sim_device_deactivate(dev); 1045 + scoped_guard(mutex, &dev->lock) { 1046 + if (live == gpio_sim_device_is_live(dev)) 1047 + ret = -EPERM; 1048 + else if (live) 1049 + ret = gpio_sim_device_activate(dev); 1050 + else 1051 + gpio_sim_device_deactivate(dev); 1052 + } 1053 + 1054 + /* 1055 + * Undepend is required only if device disablement (live == 0) 1056 + * succeeds or if device enablement (live == 1) fails. 1057 + */ 1058 + if (live == !!ret) 1059 + gpio_sim_device_lockup_configfs(dev, false); 1074 1060 1075 1061 return ret ?: count; 1076 1062 }