aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/ubi
diff options
context:
space:
mode:
authorArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2008-06-04 10:58:37 -0400
committerArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2008-07-24 06:32:55 -0400
commit472018f73e7308a7f29b753ee8c742b6f45f103f (patch)
tree327c1e008a30b79fc527daf26802b795f3a99b32 /drivers/mtd/ubi
parent505d1caa79cd61a70615e9a7eae2eab85e797a83 (diff)
UBI: fix memory leak on error path
Normally UBI volumes are freed in the release function of the struct device object. However, on error path they may have to be freed before the struct device objects have been initialized. Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Diffstat (limited to 'drivers/mtd/ubi')
-rw-r--r--drivers/mtd/ubi/build.c34
1 files changed, 30 insertions, 4 deletions
diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c
index 33205e4c1f5b..a5b19944eca8 100644
--- a/drivers/mtd/ubi/build.c
+++ b/drivers/mtd/ubi/build.c
@@ -355,15 +355,34 @@ static void kill_volumes(struct ubi_device *ubi)
355} 355}
356 356
357/** 357/**
358 * free_user_volumes - free all user volumes.
359 * @ubi: UBI device description object
360 *
361 * Normally the volumes are freed at the release function of the volume device
362 * objects. However, on error paths the volumes have to be freed before the
363 * device objects have been initialized.
364 */
365static void free_user_volumes(struct ubi_device *ubi)
366{
367 int i;
368
369 for (i = 0; i < ubi->vtbl_slots; i++)
370 if (ubi->volumes[i]) {
371 kfree(ubi->volumes[i]->eba_tbl);
372 kfree(ubi->volumes[i]);
373 }
374}
375
376/**
358 * uif_init - initialize user interfaces for an UBI device. 377 * uif_init - initialize user interfaces for an UBI device.
359 * @ubi: UBI device description object 378 * @ubi: UBI device description object
360 * 379 *
361 * This function returns zero in case of success and a negative error code in 380 * This function returns zero in case of success and a negative error code in
362 * case of failure. 381 * case of failure. Note, this function destroys all volumes if it failes.
363 */ 382 */
364static int uif_init(struct ubi_device *ubi) 383static int uif_init(struct ubi_device *ubi)
365{ 384{
366 int i, err; 385 int i, err, do_free = 0;
367 dev_t dev; 386 dev_t dev;
368 387
369 sprintf(ubi->ubi_name, UBI_NAME_STR "%d", ubi->ubi_num); 388 sprintf(ubi->ubi_name, UBI_NAME_STR "%d", ubi->ubi_num);
@@ -410,10 +429,13 @@ static int uif_init(struct ubi_device *ubi)
410 429
411out_volumes: 430out_volumes:
412 kill_volumes(ubi); 431 kill_volumes(ubi);
432 do_free = 0;
413out_sysfs: 433out_sysfs:
414 ubi_sysfs_close(ubi); 434 ubi_sysfs_close(ubi);
415 cdev_del(&ubi->cdev); 435 cdev_del(&ubi->cdev);
416out_unreg: 436out_unreg:
437 if (do_free)
438 free_user_volumes(ubi);
417 unregister_chrdev_region(ubi->cdev.dev, ubi->vtbl_slots + 1); 439 unregister_chrdev_region(ubi->cdev.dev, ubi->vtbl_slots + 1);
418 ubi_err("cannot initialize UBI %s, error %d", ubi->ubi_name, err); 440 ubi_err("cannot initialize UBI %s, error %d", ubi->ubi_name, err);
419 return err; 441 return err;
@@ -722,7 +744,7 @@ static int autoresize(struct ubi_device *ubi, int vol_id)
722int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) 744int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset)
723{ 745{
724 struct ubi_device *ubi; 746 struct ubi_device *ubi;
725 int i, err; 747 int i, err, do_free = 1;
726 748
727 /* 749 /*
728 * Check if we already have the same MTD device attached. 750 * Check if we already have the same MTD device attached.
@@ -822,7 +844,7 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset)
822 844
823 err = uif_init(ubi); 845 err = uif_init(ubi);
824 if (err) 846 if (err)
825 goto out_detach; 847 goto out_nofree;
826 848
827 ubi->bgt_thread = kthread_create(ubi_thread, ubi, ubi->bgt_name); 849 ubi->bgt_thread = kthread_create(ubi_thread, ubi, ubi->bgt_name);
828 if (IS_ERR(ubi->bgt_thread)) { 850 if (IS_ERR(ubi->bgt_thread)) {
@@ -859,8 +881,12 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset)
859 881
860out_uif: 882out_uif:
861 uif_close(ubi); 883 uif_close(ubi);
884out_nofree:
885 do_free = 0;
862out_detach: 886out_detach:
863 ubi_wl_close(ubi); 887 ubi_wl_close(ubi);
888 if (do_free)
889 free_user_volumes(ubi);
864 free_internal_volumes(ubi); 890 free_internal_volumes(ubi);
865 vfree(ubi->vtbl); 891 vfree(ubi->vtbl);
866out_free: 892out_free: