aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2007-12-17 07:02:09 -0500
committerArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2007-12-26 12:15:15 -0500
commitfc75a1e166268e0c3366c3b30888a024125f6665 (patch)
tree82dc34795ee9299d6184a31fb87b4e9b8925f6a2
parent450f872a8e1763c883c9f723e6937b7ed223e6d3 (diff)
UBI: fix error path
Error path in volume creation is bogus. First of, it ovverrides the 'err' variable and returns zero to the caller. Second, ubi_assert() in the release function is wrong. Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
-rw-r--r--drivers/mtd/ubi/vmt.c45
1 files changed, 20 insertions, 25 deletions
diff --git a/drivers/mtd/ubi/vmt.c b/drivers/mtd/ubi/vmt.c
index 9dd3689aecd3..3d6ac029c177 100644
--- a/drivers/mtd/ubi/vmt.c
+++ b/drivers/mtd/ubi/vmt.c
@@ -112,7 +112,6 @@ static void vol_release(struct device *dev)
112{ 112{
113 struct ubi_volume *vol = container_of(dev, struct ubi_volume, dev); 113 struct ubi_volume *vol = container_of(dev, struct ubi_volume, dev);
114 114
115 ubi_assert(vol->removed);
116 kfree(vol); 115 kfree(vol);
117} 116}
118 117
@@ -154,9 +153,7 @@ static int volume_sysfs_init(struct ubi_device *ubi, struct ubi_volume *vol)
154 if (err) 153 if (err)
155 return err; 154 return err;
156 err = device_create_file(&vol->dev, &attr_vol_upd_marker); 155 err = device_create_file(&vol->dev, &attr_vol_upd_marker);
157 if (err) 156 return err;
158 return err;
159 return 0;
160} 157}
161 158
162/** 159/**
@@ -188,7 +185,7 @@ static void volume_sysfs_close(struct ubi_volume *vol)
188 */ 185 */
189int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req) 186int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
190{ 187{
191 int i, err, vol_id = req->vol_id; 188 int i, err, vol_id = req->vol_id, dont_free = 0;
192 struct ubi_volume *vol; 189 struct ubi_volume *vol;
193 struct ubi_vtbl_record vtbl_rec; 190 struct ubi_vtbl_record vtbl_rec;
194 uint64_t bytes; 191 uint64_t bytes;
@@ -317,6 +314,7 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
317 vol->dev.parent = &ubi->dev; 314 vol->dev.parent = &ubi->dev;
318 vol->dev.devt = dev; 315 vol->dev.devt = dev;
319 vol->dev.class = ubi_class; 316 vol->dev.class = ubi_class;
317
320 sprintf(&vol->dev.bus_id[0], "%s_%d", ubi->ubi_name, vol->vol_id); 318 sprintf(&vol->dev.bus_id[0], "%s_%d", ubi->ubi_name, vol->vol_id);
321 err = device_register(&vol->dev); 319 err = device_register(&vol->dev);
322 if (err) { 320 if (err) {
@@ -353,8 +351,20 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
353 mutex_unlock(&ubi->volumes_mutex); 351 mutex_unlock(&ubi->volumes_mutex);
354 return 0; 352 return 0;
355 353
354out_sysfs:
355 /*
356 * We have degistered our device, we should not free the volume*
357 * description object in this function in case of an error - it is
358 * freed by the release function.
359 *
360 * Get device reference to prevent the release function from being
361 * called just after sysfs has been closed.
362 */
363 dont_free = 1;
364 get_device(&vol->dev);
365 volume_sysfs_close(vol);
356out_gluebi: 366out_gluebi:
357 err = ubi_destroy_gluebi(vol); 367 ubi_destroy_gluebi(vol);
358out_cdev: 368out_cdev:
359 cdev_del(&vol->cdev); 369 cdev_del(&vol->cdev);
360out_mapping: 370out_mapping:
@@ -367,25 +377,10 @@ out_acc:
367out_unlock: 377out_unlock:
368 spin_unlock(&ubi->volumes_lock); 378 spin_unlock(&ubi->volumes_lock);
369 mutex_unlock(&ubi->volumes_mutex); 379 mutex_unlock(&ubi->volumes_mutex);
370 kfree(vol); 380 if (dont_free)
371 ubi_err("cannot create volume %d, error %d", vol_id, err); 381 put_device(&vol->dev);
372 return err; 382 else
373 383 kfree(vol);
374 /*
375 * We are registered, so @vol is destroyed in the release function and
376 * we have to de-initialize differently.
377 */
378out_sysfs:
379 err = ubi_destroy_gluebi(vol);
380 cdev_del(&vol->cdev);
381 kfree(vol->eba_tbl);
382 spin_lock(&ubi->volumes_lock);
383 ubi->rsvd_pebs -= vol->reserved_pebs;
384 ubi->avail_pebs += vol->reserved_pebs;
385 ubi->volumes[vol_id] = NULL;
386 spin_unlock(&ubi->volumes_lock);
387 mutex_unlock(&ubi->volumes_mutex);
388 volume_sysfs_close(vol);
389 ubi_err("cannot create volume %d, error %d", vol_id, err); 384 ubi_err("cannot create volume %d, error %d", vol_id, err);
390 return err; 385 return err;
391} 386}