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

misc: c2port: Calculate bin_attribute size through group callback

Modifying the size of the global bin_attribute instance can be racy.
Instead use the new .bin_size callback to do so safely.

For this to work move the initialization of c2dev->ops before the call
to device_create() as the size callback will need access to it.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
Link: https://lore.kernel.org/r/20241221-sysfs-const-bin_attr-misc-drivers-v2-4-ba5e79fe8771@weissschuh.net
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Thomas Weißschuh and committed by
Greg Kroah-Hartman
85aa1342 c3b8c358

+14 -3
+14 -3
drivers/misc/c2port/core.c
··· 874 874 NULL, 875 875 }; 876 876 877 + static size_t c2port_bin_attr_size(struct kobject *kobj, 878 + const struct bin_attribute *attr, 879 + int i) 880 + { 881 + struct c2port_device *c2dev = dev_get_drvdata(kobj_to_dev(kobj)); 882 + 883 + if (attr == &bin_attr_flash_data) 884 + return c2dev->ops->blocks_num * c2dev->ops->block_size; 885 + 886 + return attr->size; 887 + } 888 + 877 889 static const struct attribute_group c2port_group = { 878 890 .attrs = c2port_attrs, 879 891 .bin_attrs = c2port_bin_attrs, 892 + .bin_size = c2port_bin_attr_size, 880 893 }; 881 894 882 895 static const struct attribute_group *c2port_groups[] = { ··· 925 912 if (ret < 0) 926 913 goto error_idr_alloc; 927 914 c2dev->id = ret; 928 - 929 - bin_attr_flash_data.size = ops->blocks_num * ops->block_size; 915 + c2dev->ops = ops; 930 916 931 917 c2dev->dev = device_create(c2port_class, NULL, 0, c2dev, 932 918 "c2port%d", c2dev->id); ··· 936 924 dev_set_drvdata(c2dev->dev, c2dev); 937 925 938 926 strscpy(c2dev->name, name, sizeof(c2dev->name)); 939 - c2dev->ops = ops; 940 927 mutex_init(&c2dev->mutex); 941 928 942 929 /* By default C2 port access is off */