aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/mtd/ubi/build.c2
-rw-r--r--drivers/mtd/ubi/kapi.c11
-rw-r--r--drivers/mtd/ubi/ubi.h5
-rw-r--r--drivers/mtd/ubi/upd.c4
-rw-r--r--drivers/mtd/ubi/vmt.c22
-rw-r--r--drivers/mtd/ubi/vtbl.c13
6 files changed, 34 insertions, 23 deletions
diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c
index 5d00364d4a4a..61225f493f6d 100644
--- a/drivers/mtd/ubi/build.c
+++ b/drivers/mtd/ubi/build.c
@@ -264,7 +264,7 @@ static int uif_init(struct ubi_device *ubi)
264 int i, err; 264 int i, err;
265 dev_t dev; 265 dev_t dev;
266 266
267 mutex_init(&ubi->vtbl_mutex); 267 mutex_init(&ubi->volumes_mutex);
268 spin_lock_init(&ubi->volumes_lock); 268 spin_lock_init(&ubi->volumes_lock);
269 269
270 sprintf(ubi->ubi_name, UBI_NAME_STR "%d", ubi->ubi_num); 270 sprintf(ubi->ubi_name, UBI_NAME_STR "%d", ubi->ubi_num);
diff --git a/drivers/mtd/ubi/kapi.c b/drivers/mtd/ubi/kapi.c
index c2fafe6fb2da..8e15002a36c3 100644
--- a/drivers/mtd/ubi/kapi.c
+++ b/drivers/mtd/ubi/kapi.c
@@ -162,15 +162,16 @@ struct ubi_volume_desc *ubi_open_volume(int ubi_num, int vol_id, int mode)
162 desc->mode = mode; 162 desc->mode = mode;
163 163
164 /* 164 /*
165 * To prevent simultaneous checks of the same volume we use @vtbl_mutex, 165 * To prevent simultaneous checks of the same volume we use
166 * although it is not the purpose it was introduced for. 166 * @volumes_mutex, although it is not the purpose it was introduced
167 * for.
167 */ 168 */
168 mutex_lock(&ubi->vtbl_mutex); 169 mutex_lock(&ubi->volumes_mutex);
169 if (!vol->checked) { 170 if (!vol->checked) {
170 /* This is the first open - check the volume */ 171 /* This is the first open - check the volume */
171 err = ubi_check_volume(ubi, vol_id); 172 err = ubi_check_volume(ubi, vol_id);
172 if (err < 0) { 173 if (err < 0) {
173 mutex_unlock(&ubi->vtbl_mutex); 174 mutex_unlock(&ubi->volumes_mutex);
174 ubi_close_volume(desc); 175 ubi_close_volume(desc);
175 return ERR_PTR(err); 176 return ERR_PTR(err);
176 } 177 }
@@ -181,7 +182,7 @@ struct ubi_volume_desc *ubi_open_volume(int ubi_num, int vol_id, int mode)
181 } 182 }
182 vol->checked = 1; 183 vol->checked = 1;
183 } 184 }
184 mutex_unlock(&ubi->vtbl_mutex); 185 mutex_unlock(&ubi->volumes_mutex);
185 return desc; 186 return desc;
186 187
187out_unlock: 188out_unlock:
diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h
index 0a3a803dd22f..69cbee3be7a4 100644
--- a/drivers/mtd/ubi/ubi.h
+++ b/drivers/mtd/ubi/ubi.h
@@ -255,7 +255,8 @@ struct ubi_wl_entry;
255 * @vtbl_slots: how many slots are available in the volume table 255 * @vtbl_slots: how many slots are available in the volume table
256 * @vtbl_size: size of the volume table in bytes 256 * @vtbl_size: size of the volume table in bytes
257 * @vtbl: in-RAM volume table copy 257 * @vtbl: in-RAM volume table copy
258 * @vtbl_mutex: protects on-flash volume table 258 * @volumes_mutex: protects on-flash volume table and serializes volume
259 * changes, like creation, deletion, update, resize
259 * 260 *
260 * @max_ec: current highest erase counter value 261 * @max_ec: current highest erase counter value
261 * @mean_ec: current mean erase counter value 262 * @mean_ec: current mean erase counter value
@@ -333,7 +334,7 @@ struct ubi_device {
333 int vtbl_slots; 334 int vtbl_slots;
334 int vtbl_size; 335 int vtbl_size;
335 struct ubi_vtbl_record *vtbl; 336 struct ubi_vtbl_record *vtbl;
336 struct mutex vtbl_mutex; 337 struct mutex volumes_mutex;
337 338
338 int max_ec; 339 int max_ec;
339 int mean_ec; 340 int mean_ec;
diff --git a/drivers/mtd/ubi/upd.c b/drivers/mtd/ubi/upd.c
index a95dcaa4a0c2..e32b04d2e048 100644
--- a/drivers/mtd/ubi/upd.c
+++ b/drivers/mtd/ubi/upd.c
@@ -67,7 +67,9 @@ static int set_update_marker(struct ubi_device *ubi, int vol_id)
67 memcpy(&vtbl_rec, &ubi->vtbl[vol_id], sizeof(struct ubi_vtbl_record)); 67 memcpy(&vtbl_rec, &ubi->vtbl[vol_id], sizeof(struct ubi_vtbl_record));
68 vtbl_rec.upd_marker = 1; 68 vtbl_rec.upd_marker = 1;
69 69
70 mutex_lock(&ubi->volumes_mutex);
70 err = ubi_change_vtbl_record(ubi, vol_id, &vtbl_rec); 71 err = ubi_change_vtbl_record(ubi, vol_id, &vtbl_rec);
72 mutex_unlock(&ubi->volumes_mutex);
71 vol->upd_marker = 1; 73 vol->upd_marker = 1;
72 return err; 74 return err;
73} 75}
@@ -106,7 +108,9 @@ static int clear_update_marker(struct ubi_device *ubi, int vol_id, long long byt
106 vol->last_eb_bytes = vol->usable_leb_size; 108 vol->last_eb_bytes = vol->usable_leb_size;
107 } 109 }
108 110
111 mutex_lock(&ubi->volumes_mutex);
109 err = ubi_change_vtbl_record(ubi, vol_id, &vtbl_rec); 112 err = ubi_change_vtbl_record(ubi, vol_id, &vtbl_rec);
113 mutex_unlock(&ubi->volumes_mutex);
110 vol->upd_marker = 0; 114 vol->upd_marker = 0;
111 return err; 115 return err;
112} 116}
diff --git a/drivers/mtd/ubi/vmt.c b/drivers/mtd/ubi/vmt.c
index d2d12deead5c..ec2dd3c65c43 100644
--- a/drivers/mtd/ubi/vmt.c
+++ b/drivers/mtd/ubi/vmt.c
@@ -201,8 +201,8 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
201 if (!vol) 201 if (!vol)
202 return -ENOMEM; 202 return -ENOMEM;
203 203
204 mutex_lock(&ubi->volumes_mutex);
204 spin_lock(&ubi->volumes_lock); 205 spin_lock(&ubi->volumes_lock);
205
206 if (vol_id == UBI_VOL_NUM_AUTO) { 206 if (vol_id == UBI_VOL_NUM_AUTO) {
207 /* Find unused volume ID */ 207 /* Find unused volume ID */
208 dbg_msg("search for vacant volume ID"); 208 dbg_msg("search for vacant volume ID");
@@ -350,6 +350,7 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
350 spin_unlock(&ubi->volumes_lock); 350 spin_unlock(&ubi->volumes_lock);
351 351
352 paranoid_check_volumes(ubi); 352 paranoid_check_volumes(ubi);
353 mutex_unlock(&ubi->volumes_mutex);
353 return 0; 354 return 0;
354 355
355out_gluebi: 356out_gluebi:
@@ -365,6 +366,7 @@ out_acc:
365 ubi->volumes[vol_id] = NULL; 366 ubi->volumes[vol_id] = NULL;
366out_unlock: 367out_unlock:
367 spin_unlock(&ubi->volumes_lock); 368 spin_unlock(&ubi->volumes_lock);
369 mutex_unlock(&ubi->volumes_mutex);
368 kfree(vol); 370 kfree(vol);
369 ubi_err("cannot create volume %d, error %d", vol_id, err); 371 ubi_err("cannot create volume %d, error %d", vol_id, err);
370 return err; 372 return err;
@@ -382,6 +384,7 @@ out_sysfs:
382 ubi->avail_pebs += vol->reserved_pebs; 384 ubi->avail_pebs += vol->reserved_pebs;
383 ubi->volumes[vol_id] = NULL; 385 ubi->volumes[vol_id] = NULL;
384 spin_unlock(&ubi->volumes_lock); 386 spin_unlock(&ubi->volumes_lock);
387 mutex_unlock(&ubi->volumes_mutex);
385 volume_sysfs_close(vol); 388 volume_sysfs_close(vol);
386 ubi_err("cannot create volume %d, error %d", vol_id, err); 389 ubi_err("cannot create volume %d, error %d", vol_id, err);
387 return err; 390 return err;
@@ -408,18 +411,19 @@ int ubi_remove_volume(struct ubi_volume_desc *desc)
408 if (ubi->ro_mode) 411 if (ubi->ro_mode)
409 return -EROFS; 412 return -EROFS;
410 413
414 mutex_lock(&ubi->volumes_mutex);
411 err = ubi_destroy_gluebi(vol); 415 err = ubi_destroy_gluebi(vol);
412 if (err) 416 if (err)
413 return err; 417 goto out;
414 418
415 err = ubi_change_vtbl_record(ubi, vol_id, NULL); 419 err = ubi_change_vtbl_record(ubi, vol_id, NULL);
416 if (err) 420 if (err)
417 return err; 421 goto out;
418 422
419 for (i = 0; i < vol->reserved_pebs; i++) { 423 for (i = 0; i < vol->reserved_pebs; i++) {
420 err = ubi_eba_unmap_leb(ubi, vol, i); 424 err = ubi_eba_unmap_leb(ubi, vol, i);
421 if (err) 425 if (err)
422 return err; 426 goto out;
423 } 427 }
424 428
425 spin_lock(&ubi->volumes_lock); 429 spin_lock(&ubi->volumes_lock);
@@ -449,8 +453,13 @@ int ubi_remove_volume(struct ubi_volume_desc *desc)
449 spin_unlock(&ubi->volumes_lock); 453 spin_unlock(&ubi->volumes_lock);
450 454
451 paranoid_check_volumes(ubi); 455 paranoid_check_volumes(ubi);
456 mutex_unlock(&ubi->volumes_mutex);
452 module_put(THIS_MODULE); 457 module_put(THIS_MODULE);
453 return 0; 458 return 0;
459
460out:
461 mutex_unlock(&ubi->volumes_mutex);
462 return err;
454} 463}
455 464
456/** 465/**
@@ -496,6 +505,7 @@ int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs)
496 new_mapping[i] = UBI_LEB_UNMAPPED; 505 new_mapping[i] = UBI_LEB_UNMAPPED;
497 506
498 /* Reserve physical eraseblocks */ 507 /* Reserve physical eraseblocks */
508 mutex_lock(&ubi->volumes_mutex);
499 pebs = reserved_pebs - vol->reserved_pebs; 509 pebs = reserved_pebs - vol->reserved_pebs;
500 if (pebs > 0) { 510 if (pebs > 0) {
501 spin_lock(&ubi->volumes_lock); 511 spin_lock(&ubi->volumes_lock);
@@ -556,6 +566,7 @@ int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs)
556 } 566 }
557 567
558 paranoid_check_volumes(ubi); 568 paranoid_check_volumes(ubi);
569 mutex_unlock(&ubi->volumes_mutex);
559 return 0; 570 return 0;
560 571
561out_acc: 572out_acc:
@@ -567,6 +578,7 @@ out_acc:
567 } 578 }
568out_free: 579out_free:
569 kfree(new_mapping); 580 kfree(new_mapping);
581 mutex_unlock(&ubi->volumes_mutex);
570 return err; 582 return err;
571} 583}
572 584
@@ -829,9 +841,7 @@ static void paranoid_check_volumes(struct ubi_device *ubi)
829{ 841{
830 int i; 842 int i;
831 843
832 mutex_lock(&ubi->vtbl_mutex);
833 for (i = 0; i < ubi->vtbl_slots; i++) 844 for (i = 0; i < ubi->vtbl_slots; i++)
834 paranoid_check_volume(ubi, i); 845 paranoid_check_volume(ubi, i);
835 mutex_unlock(&ubi->vtbl_mutex);
836} 846}
837#endif 847#endif
diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c
index 3349c281bf9e..5879fdb3e6d5 100644
--- a/drivers/mtd/ubi/vtbl.c
+++ b/drivers/mtd/ubi/vtbl.c
@@ -89,7 +89,7 @@ int ubi_change_vtbl_record(struct ubi_device *ubi, int idx,
89 struct ubi_volume *layout_vol; 89 struct ubi_volume *layout_vol;
90 90
91 ubi_assert(idx >= 0 && idx < ubi->vtbl_slots); 91 ubi_assert(idx >= 0 && idx < ubi->vtbl_slots);
92 layout_vol = ubi->volumes[vol_id2idx(UBI_LAYOUT_VOL_ID)]; 92 layout_vol = ubi->volumes[vol_id2idx(ubi, UBI_LAYOUT_VOL_ID)];
93 93
94 if (!vtbl_rec) 94 if (!vtbl_rec)
95 vtbl_rec = &empty_vtbl_record; 95 vtbl_rec = &empty_vtbl_record;
@@ -98,24 +98,19 @@ int ubi_change_vtbl_record(struct ubi_device *ubi, int idx,
98 vtbl_rec->crc = cpu_to_be32(crc); 98 vtbl_rec->crc = cpu_to_be32(crc);
99 } 99 }
100 100
101 mutex_lock(&ubi->vtbl_mutex);
102 memcpy(&ubi->vtbl[idx], vtbl_rec, sizeof(struct ubi_vtbl_record)); 101 memcpy(&ubi->vtbl[idx], vtbl_rec, sizeof(struct ubi_vtbl_record));
103 for (i = 0; i < UBI_LAYOUT_VOLUME_EBS; i++) { 102 for (i = 0; i < UBI_LAYOUT_VOLUME_EBS; i++) {
104 err = ubi_eba_unmap_leb(ubi, layout_vol, i); 103 err = ubi_eba_unmap_leb(ubi, layout_vol, i);
105 if (err) { 104 if (err)
106 mutex_unlock(&ubi->vtbl_mutex);
107 return err; 105 return err;
108 } 106
109 err = ubi_eba_write_leb(ubi, layout_vol, i, ubi->vtbl, 0, 107 err = ubi_eba_write_leb(ubi, layout_vol, i, ubi->vtbl, 0,
110 ubi->vtbl_size, UBI_LONGTERM); 108 ubi->vtbl_size, UBI_LONGTERM);
111 if (err) { 109 if (err)
112 mutex_unlock(&ubi->vtbl_mutex);
113 return err; 110 return err;
114 }
115 } 111 }
116 112
117 paranoid_vtbl_check(ubi); 113 paranoid_vtbl_check(ubi);
118 mutex_unlock(&ubi->vtbl_mutex);
119 return ubi_wl_flush(ubi); 114 return ubi_wl_flush(ubi);
120} 115}
121 116