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
3327static int __init tk_aux_sysfs_init(void)3327static int __init tk_aux_sysfs_init(void)
3328{3328{
3329 struct kobject *auxo, *tko = kobject_create_and_add("time", kernel_kobj);3329 struct kobject *auxo, *tko = kobject_create_and_add("time", kernel_kobj);
3330 struct kobject *clks[MAX_AUX_CLOCKS];
3330 int ret = -ENOMEM;3331 int ret = -ENOMEM;
3332 int i;
3331 3333
3332 if (!tko)3334 if (!tko)
3333 return ret;3335 return ret;
@@ -3336,21 +3338,28 @@ static int __init tk_aux_sysfs_init(void) · 2 unmodified lines
3336 if (!auxo)3338 if (!auxo)
3337 goto err_clean;3339 goto err_clean;
3338 3340
3339 for (int i = 0; i < MAX_AUX_CLOCKS; i++) {3341 for (i = 0; i < MAX_AUX_CLOCKS; i++) {
3340 char id[2] = { [0] = '0' + i, };3342 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);
3342 3344
3343 if (!clk) {3345 if (!clks[i]) {
3344 ret = -ENOMEM;3346 ret = -ENOMEM;
3345 goto err_clean;3347 goto err_clks;
3346 }3348 }
3347 3349
3348 ret = sysfs_create_group(clk, &aux_clock_enable_attr_group);3350 ret = sysfs_create_group(clks[i], &aux_clock_enable_attr_group);
3349 if (ret)3351 if (ret)
3350 goto err_clean;3352 goto err_clk;
3351 }3353 }
3352 return 0;3354 return 0;
3353 3355
3356err_clk:
3357 kobject_put(clks[i]);
3358err_clks:
3359 while (--i >= 0) {
3360 sysfs_remove_group(clks[i], &aux_clock_enable_attr_group);
3361 kobject_put(clks[i]);
3362 }
3354err_clean:3363err_clean:
3355 kobject_put(auxo);3364 kobject_put(auxo);
3356 kobject_put(tko);3365 kobject_put(tko);