Commit 40e4d0c1 authored by Artem Bityutskiy's avatar Artem Bityutskiy

UBI: tweak volumes locking some more

Make the code more consistent by requiring the caller to lock the
ubi->volume_mutex, because this is what we do for updates.
Signed-off-by: default avatarArtem Bityutskiy <Artem.Bityutskiy@nokia.com>
parent d05c77a8
...@@ -605,7 +605,9 @@ static int ubi_cdev_ioctl(struct inode *inode, struct file *file, ...@@ -605,7 +605,9 @@ static int ubi_cdev_ioctl(struct inode *inode, struct file *file,
req.name[req.name_len] = '\0'; req.name[req.name_len] = '\0';
mutex_lock(&ubi->volumes_mutex);
err = ubi_create_volume(ubi, &req); err = ubi_create_volume(ubi, &req);
mutex_unlock(&ubi->volumes_mutex);
if (err) if (err)
break; break;
...@@ -634,11 +636,14 @@ static int ubi_cdev_ioctl(struct inode *inode, struct file *file, ...@@ -634,11 +636,14 @@ static int ubi_cdev_ioctl(struct inode *inode, struct file *file,
break; break;
} }
mutex_lock(&ubi->volumes_mutex);
err = ubi_remove_volume(desc); err = ubi_remove_volume(desc);
mutex_unlock(&ubi->volumes_mutex);
/* /*
* The volume is deleted, and the 'struct ubi_volume' object * The volume is deleted (unless an error occurred), and the
* will be freed when 'ubi_close_volume()' will call * 'struct ubi_volume' object will be freed when
* 'put_device()'. * 'ubi_close_volume()' will call 'put_device()'.
*/ */
ubi_close_volume(desc); ubi_close_volume(desc);
break; break;
...@@ -673,7 +678,9 @@ static int ubi_cdev_ioctl(struct inode *inode, struct file *file, ...@@ -673,7 +678,9 @@ static int ubi_cdev_ioctl(struct inode *inode, struct file *file,
pebs = !!do_div(tmp, desc->vol->usable_leb_size); pebs = !!do_div(tmp, desc->vol->usable_leb_size);
pebs += tmp; pebs += tmp;
mutex_lock(&ubi->volumes_mutex);
err = ubi_resize_volume(desc, pebs); err = ubi_resize_volume(desc, pebs);
mutex_unlock(&ubi->volumes_mutex);
ubi_close_volume(desc); ubi_close_volume(desc);
break; break;
} }
......
...@@ -189,7 +189,8 @@ static void volume_sysfs_close(struct ubi_volume *vol) ...@@ -189,7 +189,8 @@ static void volume_sysfs_close(struct ubi_volume *vol)
* This function creates volume described by @req. If @req->vol_id id * 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 * %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 * 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) int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
{ {
...@@ -206,7 +207,6 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req) ...@@ -206,7 +207,6 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
if (!vol) if (!vol)
return -ENOMEM; return -ENOMEM;
mutex_lock(&ubi->volumes_mutex);
spin_lock(&ubi->volumes_lock); spin_lock(&ubi->volumes_lock);
if (vol_id == UBI_VOL_NUM_AUTO) { if (vol_id == UBI_VOL_NUM_AUTO) {
/* Find unused volume ID */ /* Find unused volume ID */
...@@ -356,7 +356,6 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req) ...@@ -356,7 +356,6 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
spin_unlock(&ubi->volumes_lock); spin_unlock(&ubi->volumes_lock);
paranoid_check_volumes(ubi); paranoid_check_volumes(ubi);
mutex_unlock(&ubi->volumes_mutex);
return 0; return 0;
out_sysfs: out_sysfs:
...@@ -383,7 +382,6 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req) ...@@ -383,7 +382,6 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
ubi->avail_pebs += vol->reserved_pebs; ubi->avail_pebs += vol->reserved_pebs;
out_unlock: out_unlock:
spin_unlock(&ubi->volumes_lock); spin_unlock(&ubi->volumes_lock);
mutex_unlock(&ubi->volumes_mutex);
if (dont_free) if (dont_free)
put_device(&vol->dev); put_device(&vol->dev);
else else
...@@ -398,7 +396,8 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req) ...@@ -398,7 +396,8 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
* *
* This function removes volume described by @desc. The volume has to be opened * 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 * 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) int ubi_remove_volume(struct ubi_volume_desc *desc)
{ {
...@@ -413,7 +412,6 @@ int ubi_remove_volume(struct ubi_volume_desc *desc) ...@@ -413,7 +412,6 @@ int ubi_remove_volume(struct ubi_volume_desc *desc)
if (ubi->ro_mode) if (ubi->ro_mode)
return -EROFS; return -EROFS;
mutex_lock(&ubi->volumes_mutex);
spin_lock(&ubi->volumes_lock); spin_lock(&ubi->volumes_lock);
if (vol->ref_count > 1) { if (vol->ref_count > 1) {
/* /*
...@@ -461,7 +459,6 @@ int ubi_remove_volume(struct ubi_volume_desc *desc) ...@@ -461,7 +459,6 @@ int ubi_remove_volume(struct ubi_volume_desc *desc)
spin_unlock(&ubi->volumes_lock); spin_unlock(&ubi->volumes_lock);
paranoid_check_volumes(ubi); paranoid_check_volumes(ubi);
mutex_unlock(&ubi->volumes_mutex);
return 0; return 0;
out_err: out_err:
...@@ -470,7 +467,6 @@ int ubi_remove_volume(struct ubi_volume_desc *desc) ...@@ -470,7 +467,6 @@ int ubi_remove_volume(struct ubi_volume_desc *desc)
ubi->volumes[vol_id] = vol; ubi->volumes[vol_id] = vol;
out_unlock: out_unlock:
spin_unlock(&ubi->volumes_lock); spin_unlock(&ubi->volumes_lock);
mutex_unlock(&ubi->volumes_mutex);
return err; return err;
} }
...@@ -479,8 +475,9 @@ int ubi_remove_volume(struct ubi_volume_desc *desc) ...@@ -479,8 +475,9 @@ int ubi_remove_volume(struct ubi_volume_desc *desc)
* @desc: volume descriptor * @desc: volume descriptor
* @reserved_pebs: new size in physical eraseblocks * @reserved_pebs: new size in physical eraseblocks
* *
* This function returns zero in case of success, and a negative error code in * This function re-sizes the volume and returns zero in case of success, and a
* case of failure. * 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) int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs)
{ {
...@@ -516,7 +513,6 @@ int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs) ...@@ -516,7 +513,6 @@ int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs)
for (i = 0; i < reserved_pebs; i++) for (i = 0; i < reserved_pebs; i++)
new_mapping[i] = UBI_LEB_UNMAPPED; new_mapping[i] = UBI_LEB_UNMAPPED;
mutex_lock(&ubi->volumes_mutex);
spin_lock(&ubi->volumes_lock); spin_lock(&ubi->volumes_lock);
if (vol->ref_count > 1) { if (vol->ref_count > 1) {
spin_unlock(&ubi->volumes_lock); spin_unlock(&ubi->volumes_lock);
...@@ -587,7 +583,6 @@ int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs) ...@@ -587,7 +583,6 @@ int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs)
} }
paranoid_check_volumes(ubi); paranoid_check_volumes(ubi);
mutex_unlock(&ubi->volumes_mutex);
return 0; return 0;
out_acc: out_acc:
...@@ -599,7 +594,6 @@ int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs) ...@@ -599,7 +594,6 @@ int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs)
} }
out_free: out_free:
kfree(new_mapping); kfree(new_mapping);
mutex_unlock(&ubi->volumes_mutex);
return 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