aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/ubi/vtbl.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/ubi/vtbl.c')
-rw-r--r--drivers/mtd/ubi/vtbl.c45
1 files changed, 27 insertions, 18 deletions
diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c
index 25b3bd61c7ec..56fc3fbce838 100644
--- a/drivers/mtd/ubi/vtbl.c
+++ b/drivers/mtd/ubi/vtbl.c
@@ -86,8 +86,10 @@ int ubi_change_vtbl_record(struct ubi_device *ubi, int idx,
86{ 86{
87 int i, err; 87 int i, err;
88 uint32_t crc; 88 uint32_t crc;
89 struct ubi_volume *layout_vol;
89 90
90 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, UBI_LAYOUT_VOLUME_ID)];
91 93
92 if (!vtbl_rec) 94 if (!vtbl_rec)
93 vtbl_rec = &empty_vtbl_record; 95 vtbl_rec = &empty_vtbl_record;
@@ -96,31 +98,25 @@ int ubi_change_vtbl_record(struct ubi_device *ubi, int idx,
96 vtbl_rec->crc = cpu_to_be32(crc); 98 vtbl_rec->crc = cpu_to_be32(crc);
97 } 99 }
98 100
99 mutex_lock(&ubi->vtbl_mutex);
100 memcpy(&ubi->vtbl[idx], vtbl_rec, sizeof(struct ubi_vtbl_record)); 101 memcpy(&ubi->vtbl[idx], vtbl_rec, sizeof(struct ubi_vtbl_record));
101 for (i = 0; i < UBI_LAYOUT_VOLUME_EBS; i++) { 102 for (i = 0; i < UBI_LAYOUT_VOLUME_EBS; i++) {
102 err = ubi_eba_unmap_leb(ubi, UBI_LAYOUT_VOL_ID, i); 103 err = ubi_eba_unmap_leb(ubi, layout_vol, i);
103 if (err) { 104 if (err)
104 mutex_unlock(&ubi->vtbl_mutex);
105 return err; 105 return err;
106 } 106
107 err = ubi_eba_write_leb(ubi, UBI_LAYOUT_VOL_ID, i, ubi->vtbl, 0, 107 err = ubi_eba_write_leb(ubi, layout_vol, i, ubi->vtbl, 0,
108 ubi->vtbl_size, UBI_LONGTERM); 108 ubi->vtbl_size, UBI_LONGTERM);
109 if (err) { 109 if (err)
110 mutex_unlock(&ubi->vtbl_mutex);
111 return err; 110 return err;
112 }
113 } 111 }
114 112
115 paranoid_vtbl_check(ubi); 113 paranoid_vtbl_check(ubi);
116 mutex_unlock(&ubi->vtbl_mutex); 114 return 0;
117 return ubi_wl_flush(ubi);
118} 115}
119 116
120/** 117/**
121 * vol_til_check - check if volume table is not corrupted and contains sensible 118 * vtbl_check - check if volume table is not corrupted and contains sensible
122 * data. 119 * data.
123 *
124 * @ubi: UBI device description object 120 * @ubi: UBI device description object
125 * @vtbl: volume table 121 * @vtbl: volume table
126 * 122 *
@@ -273,7 +269,7 @@ static int create_vtbl(struct ubi_device *ubi, struct ubi_scan_info *si,
273 * this volume table copy was found during scanning. It has to be wiped 269 * this volume table copy was found during scanning. It has to be wiped
274 * out. 270 * out.
275 */ 271 */
276 sv = ubi_scan_find_sv(si, UBI_LAYOUT_VOL_ID); 272 sv = ubi_scan_find_sv(si, UBI_LAYOUT_VOLUME_ID);
277 if (sv) 273 if (sv)
278 old_seb = ubi_scan_find_seb(sv, copy); 274 old_seb = ubi_scan_find_seb(sv, copy);
279 275
@@ -285,7 +281,7 @@ retry:
285 } 281 }
286 282
287 vid_hdr->vol_type = UBI_VID_DYNAMIC; 283 vid_hdr->vol_type = UBI_VID_DYNAMIC;
288 vid_hdr->vol_id = cpu_to_be32(UBI_LAYOUT_VOL_ID); 284 vid_hdr->vol_id = cpu_to_be32(UBI_LAYOUT_VOLUME_ID);
289 vid_hdr->compat = UBI_LAYOUT_VOLUME_COMPAT; 285 vid_hdr->compat = UBI_LAYOUT_VOLUME_COMPAT;
290 vid_hdr->data_size = vid_hdr->used_ebs = 286 vid_hdr->data_size = vid_hdr->used_ebs =
291 vid_hdr->data_pad = cpu_to_be32(0); 287 vid_hdr->data_pad = cpu_to_be32(0);
@@ -518,6 +514,17 @@ static int init_volumes(struct ubi_device *ubi, const struct ubi_scan_info *si,
518 vol->name[vol->name_len] = '\0'; 514 vol->name[vol->name_len] = '\0';
519 vol->vol_id = i; 515 vol->vol_id = i;
520 516
517 if (vtbl[i].flags & UBI_VTBL_AUTORESIZE_FLG) {
518 /* Auto re-size flag may be set only for one volume */
519 if (ubi->autoresize_vol_id != -1) {
520 ubi_err("more then one auto-resize volume (%d "
521 "and %d)", ubi->autoresize_vol_id, i);
522 return -EINVAL;
523 }
524
525 ubi->autoresize_vol_id = i;
526 }
527
521 ubi_assert(!ubi->volumes[i]); 528 ubi_assert(!ubi->volumes[i]);
522 ubi->volumes[i] = vol; 529 ubi->volumes[i] = vol;
523 ubi->vol_count += 1; 530 ubi->vol_count += 1;
@@ -568,6 +575,7 @@ static int init_volumes(struct ubi_device *ubi, const struct ubi_scan_info *si,
568 vol->last_eb_bytes = sv->last_data_size; 575 vol->last_eb_bytes = sv->last_data_size;
569 } 576 }
570 577
578 /* And add the layout volume */
571 vol = kzalloc(sizeof(struct ubi_volume), GFP_KERNEL); 579 vol = kzalloc(sizeof(struct ubi_volume), GFP_KERNEL);
572 if (!vol) 580 if (!vol)
573 return -ENOMEM; 581 return -ENOMEM;
@@ -582,7 +590,8 @@ static int init_volumes(struct ubi_device *ubi, const struct ubi_scan_info *si,
582 vol->last_eb_bytes = vol->reserved_pebs; 590 vol->last_eb_bytes = vol->reserved_pebs;
583 vol->used_bytes = 591 vol->used_bytes =
584 (long long)vol->used_ebs * (ubi->leb_size - vol->data_pad); 592 (long long)vol->used_ebs * (ubi->leb_size - vol->data_pad);
585 vol->vol_id = UBI_LAYOUT_VOL_ID; 593 vol->vol_id = UBI_LAYOUT_VOLUME_ID;
594 vol->ref_count = 1;
586 595
587 ubi_assert(!ubi->volumes[i]); 596 ubi_assert(!ubi->volumes[i]);
588 ubi->volumes[vol_id2idx(ubi, vol->vol_id)] = vol; 597 ubi->volumes[vol_id2idx(ubi, vol->vol_id)] = vol;
@@ -734,7 +743,7 @@ int ubi_read_volume_table(struct ubi_device *ubi, struct ubi_scan_info *si)
734 ubi->vtbl_size = ubi->vtbl_slots * UBI_VTBL_RECORD_SIZE; 743 ubi->vtbl_size = ubi->vtbl_slots * UBI_VTBL_RECORD_SIZE;
735 ubi->vtbl_size = ALIGN(ubi->vtbl_size, ubi->min_io_size); 744 ubi->vtbl_size = ALIGN(ubi->vtbl_size, ubi->min_io_size);
736 745
737 sv = ubi_scan_find_sv(si, UBI_LAYOUT_VOL_ID); 746 sv = ubi_scan_find_sv(si, UBI_LAYOUT_VOLUME_ID);
738 if (!sv) { 747 if (!sv) {
739 /* 748 /*
740 * No logical eraseblocks belonging to the layout volume were 749 * No logical eraseblocks belonging to the layout volume were