History

timekeeping: Unwind aux clock sysfs children on failure

tk_aux_sysfs_init() creates one child kobject per auxiliary clock. If a later child or sysfs group creation fails, the current error path only puts the parent kobjects and leaves earlier children and groups behind. Store the child kobjects during init and remove the successfully created groups and kobjects on failure.

Yuho Choi committed 4 months ago

Commit f2eee7e1 parent 3dee6531 file · +15 −6Browse files

Unified · Split

kernel/time/timekeeping.c+15−6
@@ -3327,7 +3327,9 @@ static const struct attribute_group aux_clock_enable_attr_group = { · 3326 unmodified lines
33273327 static int __init tk_aux_sysfs_init(void)
33283328 {
33293329 struct kobject *auxo, *tko = kobject_create_and_add("time", kernel_kobj);
3330+ struct kobject *clks[MAX_AUX_CLOCKS];
33303331 int ret = -ENOMEM;
3332+ int i;
33313333
33323334 if (!tko)
33333335 return ret;
@@ -3336,21 +3338,28 @@ static int __init tk_aux_sysfs_init(void) · 2 unmodified lines
33363338 if (!auxo)
33373339 goto err_clean;
33383340
3339− for (int i = 0; i < MAX_AUX_CLOCKS; i++) {
3341+ for (i = 0; i < MAX_AUX_CLOCKS; i++) {
33403342 char id[2] = { [0] = '0' + i, };
3341− struct kobject *clk = kobject_create_and_add(id, auxo);
3343+ clks[i] = kobject_create_and_add(id, auxo);
33423344
3343− if (!clk) {
3345+ if (!clks[i]) {
33443346 ret = -ENOMEM;
3345− goto err_clean;
3347+ goto err_clks;
33463348 }
33473349
3348− ret = sysfs_create_group(clk, &aux_clock_enable_attr_group);
3350+ ret = sysfs_create_group(clks[i], &aux_clock_enable_attr_group);
33493351 if (ret)
3350− goto err_clean;
3352+ goto err_clk;
33513353 }
33523354 return 0;
33533355
3356+err_clk:
3357+ kobject_put(clks[i]);
3358+err_clks:
3359+ while (--i >= 0) {
3360+ sysfs_remove_group(clks[i], &aux_clock_enable_attr_group);
3361+ kobject_put(clks[i]);
3362+ }
33543363 err_clean:
33553364 kobject_put(auxo);
33563365 kobject_put(tko);