|
@@ -644,21 +644,33 @@ void ubi_free_volume(struct ubi_device *ubi, int vol_id)
|
|
|
* @ubi: UBI device description object
|
|
|
* @vol_id: volume ID
|
|
|
*/
|
|
|
-static void paranoid_check_volume(const struct ubi_device *ubi, int vol_id)
|
|
|
+static void paranoid_check_volume(struct ubi_device *ubi, int vol_id)
|
|
|
{
|
|
|
int idx = vol_id2idx(ubi, vol_id);
|
|
|
int reserved_pebs, alignment, data_pad, vol_type, name_len, upd_marker;
|
|
|
- const struct ubi_volume *vol = ubi->volumes[idx];
|
|
|
+ const struct ubi_volume *vol;
|
|
|
long long n;
|
|
|
const char *name;
|
|
|
|
|
|
+ spin_lock(&ubi->volumes_lock);
|
|
|
reserved_pebs = be32_to_cpu(ubi->vtbl[vol_id].reserved_pebs);
|
|
|
+ vol = ubi->volumes[idx];
|
|
|
|
|
|
if (!vol) {
|
|
|
if (reserved_pebs) {
|
|
|
ubi_err("no volume info, but volume exists");
|
|
|
goto fail;
|
|
|
}
|
|
|
+ spin_unlock(&ubi->volumes_lock);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (vol->exclusive) {
|
|
|
+ /*
|
|
|
+ * The volume may be being created at the moment, do not check
|
|
|
+ * it (e.g., it may be in the middle of ubi_create_volume().
|
|
|
+ */
|
|
|
+ spin_unlock(&ubi->volumes_lock);
|
|
|
return;
|
|
|
}
|
|
|
|
|
@@ -783,12 +795,14 @@ static void paranoid_check_volume(const struct ubi_device *ubi, int vol_id)
|
|
|
goto fail;
|
|
|
}
|
|
|
|
|
|
+ spin_unlock(&ubi->volumes_lock);
|
|
|
return;
|
|
|
|
|
|
fail:
|
|
|
ubi_err("paranoid check failed for volume %d", vol_id);
|
|
|
ubi_dbg_dump_vol_info(vol);
|
|
|
ubi_dbg_dump_vtbl_record(&ubi->vtbl[vol_id], vol_id);
|
|
|
+ spin_unlock(&ubi->volumes_lock);
|
|
|
BUG();
|
|
|
}
|
|
|
|
|
@@ -801,10 +815,8 @@ static void paranoid_check_volumes(struct ubi_device *ubi)
|
|
|
int i;
|
|
|
|
|
|
mutex_lock(&ubi->vtbl_mutex);
|
|
|
- spin_lock(&ubi->volumes_lock);
|
|
|
for (i = 0; i < ubi->vtbl_slots; i++)
|
|
|
paranoid_check_volume(ubi, i);
|
|
|
- spin_unlock(&ubi->volumes_lock);
|
|
|
mutex_unlock(&ubi->vtbl_mutex);
|
|
|
}
|
|
|
#endif
|