req.name[req.name_len] = '\0';
+ mutex_lock(&ubi->volumes_mutex);
err = ubi_create_volume(ubi, &req);
+ mutex_unlock(&ubi->volumes_mutex);
if (err)
break;
break;
}
+ mutex_lock(&ubi->volumes_mutex);
err = ubi_remove_volume(desc);
+ mutex_unlock(&ubi->volumes_mutex);
+
/*
- * The volume is deleted, and the 'struct ubi_volume' object
- * will be freed when 'ubi_close_volume()' will call
- * 'put_device()'.
+ * The volume is deleted (unless an error occurred), and the
+ * 'struct ubi_volume' object will be freed when
+ * 'ubi_close_volume()' will call 'put_device()'.
*/
ubi_close_volume(desc);
break;
pebs = !!do_div(tmp, desc->vol->usable_leb_size);
pebs += tmp;
+ mutex_lock(&ubi->volumes_mutex);
err = ubi_resize_volume(desc, pebs);
+ mutex_unlock(&ubi->volumes_mutex);
ubi_close_volume(desc);
break;
}
* This function creates volume described by @req. If @req->vol_id id
* %UBI_VOL_NUM_AUTO, this function automatically assign ID to the new volume
* and saves it in @req->vol_id. Returns zero in case of success and a negative
- * error code in case of failure.
+ * error code in case of failure. Note, the caller has to have the
+ * @ubi->volumes_mutex locked.
*/
int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
{
if (!vol)
return -ENOMEM;
- mutex_lock(&ubi->volumes_mutex);
spin_lock(&ubi->volumes_lock);
if (vol_id == UBI_VOL_NUM_AUTO) {
/* Find unused volume ID */
spin_unlock(&ubi->volumes_lock);
paranoid_check_volumes(ubi);
- mutex_unlock(&ubi->volumes_mutex);
return 0;
out_sysfs:
ubi->avail_pebs += vol->reserved_pebs;
out_unlock:
spin_unlock(&ubi->volumes_lock);
- mutex_unlock(&ubi->volumes_mutex);
if (dont_free)
put_device(&vol->dev);
else
*
* This function removes volume described by @desc. The volume has to be opened
* in "exclusive" mode. Returns zero in case of success and a negative error
- * code in case of failure.
+ * code in case of failure. The caller has to have the @ubi->volumes_mutex
+ * locked.
*/
int ubi_remove_volume(struct ubi_volume_desc *desc)
{
if (ubi->ro_mode)
return -EROFS;
- mutex_lock(&ubi->volumes_mutex);
spin_lock(&ubi->volumes_lock);
if (vol->ref_count > 1) {
/*
spin_unlock(&ubi->volumes_lock);
paranoid_check_volumes(ubi);
- mutex_unlock(&ubi->volumes_mutex);
return 0;
out_err:
ubi->volumes[vol_id] = vol;
out_unlock:
spin_unlock(&ubi->volumes_lock);
- mutex_unlock(&ubi->volumes_mutex);
return err;
}
* @desc: volume descriptor
* @reserved_pebs: new size in physical eraseblocks
*
- * This function returns zero in case of success, and a negative error code in
- * case of failure.
+ * This function re-sizes the volume and returns zero in case of success, and a
+ * negative error code in case of failure. The caller has to have the
+ * @ubi->volumes_mutex locked.
*/
int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs)
{
for (i = 0; i < reserved_pebs; i++)
new_mapping[i] = UBI_LEB_UNMAPPED;
- mutex_lock(&ubi->volumes_mutex);
spin_lock(&ubi->volumes_lock);
if (vol->ref_count > 1) {
spin_unlock(&ubi->volumes_lock);
}
paranoid_check_volumes(ubi);
- mutex_unlock(&ubi->volumes_mutex);
return 0;
out_acc:
}
out_free:
kfree(new_mapping);
- mutex_unlock(&ubi->volumes_mutex);
return err;
}