Commit fc75a1e1 authored by Artem Bityutskiy's avatar Artem Bityutskiy

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: default avatarArtem Bityutskiy <Artem.Bityutskiy@nokia.com>
parent 450f872a
...@@ -112,7 +112,6 @@ static void vol_release(struct device *dev) ...@@ -112,7 +112,6 @@ static void vol_release(struct device *dev)
{ {
struct ubi_volume *vol = container_of(dev, struct ubi_volume, dev); struct ubi_volume *vol = container_of(dev, struct ubi_volume, dev);
ubi_assert(vol->removed);
kfree(vol); kfree(vol);
} }
...@@ -154,9 +153,7 @@ static int volume_sysfs_init(struct ubi_device *ubi, struct ubi_volume *vol) ...@@ -154,9 +153,7 @@ static int volume_sysfs_init(struct ubi_device *ubi, struct ubi_volume *vol)
if (err) if (err)
return err; return err;
err = device_create_file(&vol->dev, &attr_vol_upd_marker); err = device_create_file(&vol->dev, &attr_vol_upd_marker);
if (err)
return err; return err;
return 0;
} }
/** /**
...@@ -188,7 +185,7 @@ static void volume_sysfs_close(struct ubi_volume *vol) ...@@ -188,7 +185,7 @@ static void volume_sysfs_close(struct ubi_volume *vol)
*/ */
int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req) int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
{ {
int i, err, vol_id = req->vol_id; int i, err, vol_id = req->vol_id, dont_free = 0;
struct ubi_volume *vol; struct ubi_volume *vol;
struct ubi_vtbl_record vtbl_rec; struct ubi_vtbl_record vtbl_rec;
uint64_t bytes; uint64_t bytes;
...@@ -317,6 +314,7 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req) ...@@ -317,6 +314,7 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
vol->dev.parent = &ubi->dev; vol->dev.parent = &ubi->dev;
vol->dev.devt = dev; vol->dev.devt = dev;
vol->dev.class = ubi_class; vol->dev.class = ubi_class;
sprintf(&vol->dev.bus_id[0], "%s_%d", ubi->ubi_name, vol->vol_id); sprintf(&vol->dev.bus_id[0], "%s_%d", ubi->ubi_name, vol->vol_id);
err = device_register(&vol->dev); err = device_register(&vol->dev);
if (err) { if (err) {
...@@ -353,8 +351,20 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req) ...@@ -353,8 +351,20 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
mutex_unlock(&ubi->volumes_mutex); mutex_unlock(&ubi->volumes_mutex);
return 0; return 0;
out_sysfs:
/*
* We have degistered our device, we should not free the volume*
* description object in this function in case of an error - it is
* freed by the release function.
*
* Get device reference to prevent the release function from being
* called just after sysfs has been closed.
*/
dont_free = 1;
get_device(&vol->dev);
volume_sysfs_close(vol);
out_gluebi: out_gluebi:
err = ubi_destroy_gluebi(vol); ubi_destroy_gluebi(vol);
out_cdev: out_cdev:
cdev_del(&vol->cdev); cdev_del(&vol->cdev);
out_mapping: out_mapping:
...@@ -367,27 +377,12 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req) ...@@ -367,27 +377,12 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
out_unlock: out_unlock:
spin_unlock(&ubi->volumes_lock); spin_unlock(&ubi->volumes_lock);
mutex_unlock(&ubi->volumes_mutex); mutex_unlock(&ubi->volumes_mutex);
if (dont_free)
put_device(&vol->dev);
else
kfree(vol); kfree(vol);
ubi_err("cannot create volume %d, error %d", vol_id, err); ubi_err("cannot create volume %d, error %d", vol_id, err);
return err; return err;
/*
* We are registered, so @vol is destroyed in the release function and
* we have to de-initialize differently.
*/
out_sysfs:
err = ubi_destroy_gluebi(vol);
cdev_del(&vol->cdev);
kfree(vol->eba_tbl);
spin_lock(&ubi->volumes_lock);
ubi->rsvd_pebs -= vol->reserved_pebs;
ubi->avail_pebs += vol->reserved_pebs;
ubi->volumes[vol_id] = NULL;
spin_unlock(&ubi->volumes_lock);
mutex_unlock(&ubi->volumes_mutex);
volume_sysfs_close(vol);
ubi_err("cannot create volume %d, error %d", vol_id, err);
return err;
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment