static ssize_t userdatum_value_store(struct config_item *item, const char *buf, @@ -937,7 +953,9 @@ static ssize_t userdatum_value_store(struct config_item *item, const char *buf,
ud = to_userdata(item->ci_parent); nt = userdata_to_target(ud);
update_userdata(nt);
ret = update_userdata(nt);if (ret < 0)goto out_unlock; ret = count;out_unlock: mutex_unlock(&dynamic_netconsole_mutex); @@ -1193,7 +1211,10 @@ static struct configfs_attribute *netconsole_target_attrs[] = {
static void netconsole_target_release(struct config_item *item) {
kfree(to_target(item));
struct netconsole_target *nt = to_target(item);Thinking about this now, I suppose netconsole might be reading this in parallel, and then we are freeing userdata mid-air.
Don't we need the target_list_lock in here ?
This method is called after drop_netconsole_target(), which removes the target from target_list. This guarantees that we won't race with write_ext_msg(). Also, a config_group cannot be removed while it still has child items. This guarantees that we won't race with userdata or attribute operations. So I believe this is safe.
Thanks for checking it!
--breno