49
49
/* Number of physical eraseblocks reserved for atomic LEB change operation */
50
50
#define EBA_RESERVED_PEBS 1
51
51
52
+ /**
53
+ * struct ubi_eba_entry - structure encoding a single LEB -> PEB association
54
+ * @pnum: the physical eraseblock number attached to the LEB
55
+ *
56
+ * This structure is encoding a LEB -> PEB association. Note that the LEB
57
+ * number is not stored here, because it is the index used to access the
58
+ * entries table.
59
+ */
60
+ struct ubi_eba_entry {
61
+ int pnum ;
62
+ };
63
+
64
+ /**
65
+ * struct ubi_eba_table - LEB -> PEB association information
66
+ * @entries: the LEB to PEB mapping (one entry per LEB).
67
+ *
68
+ * This structure is private to the EBA logic and should be kept here.
69
+ * It is encoding the LEB to PEB association table, and is subject to
70
+ * changes.
71
+ */
72
+ struct ubi_eba_table {
73
+ struct ubi_eba_entry * entries ;
74
+ };
75
+
52
76
/**
53
77
* next_sqnum - get next sequence number.
54
78
* @ubi: UBI device description object
@@ -97,7 +121,94 @@ void ubi_eba_get_ldesc(struct ubi_volume *vol, int lnum,
97
121
struct ubi_eba_leb_desc * ldesc )
98
122
{
99
123
ldesc -> lnum = lnum ;
100
- ldesc -> pnum = vol -> eba_tbl [lnum ];
124
+ ldesc -> pnum = vol -> eba_tbl -> entries [lnum ].pnum ;
125
+ }
126
+
127
+ /**
128
+ * ubi_eba_create_table - allocate a new EBA table and initialize it with all
129
+ * LEBs unmapped
130
+ * @vol: volume containing the EBA table to copy
131
+ * @nentries: number of entries in the table
132
+ *
133
+ * Allocate a new EBA table and initialize it with all LEBs unmapped.
134
+ * Returns a valid pointer if it succeed, an ERR_PTR() otherwise.
135
+ */
136
+ struct ubi_eba_table * ubi_eba_create_table (struct ubi_volume * vol ,
137
+ int nentries )
138
+ {
139
+ struct ubi_eba_table * tbl ;
140
+ int err = - ENOMEM ;
141
+ int i ;
142
+
143
+ tbl = kzalloc (sizeof (* tbl ), GFP_KERNEL );
144
+ if (!tbl )
145
+ return ERR_PTR (- ENOMEM );
146
+
147
+ tbl -> entries = kmalloc_array (nentries , sizeof (* tbl -> entries ),
148
+ GFP_KERNEL );
149
+ if (!tbl -> entries )
150
+ goto err ;
151
+
152
+ for (i = 0 ; i < nentries ; i ++ )
153
+ tbl -> entries [i ].pnum = UBI_LEB_UNMAPPED ;
154
+
155
+ return tbl ;
156
+
157
+ err :
158
+ kfree (tbl -> entries );
159
+ kfree (tbl );
160
+
161
+ return ERR_PTR (err );
162
+ }
163
+
164
+ /**
165
+ * ubi_eba_destroy_table - destroy an EBA table
166
+ * @tbl: the table to destroy
167
+ *
168
+ * Destroy an EBA table.
169
+ */
170
+ void ubi_eba_destroy_table (struct ubi_eba_table * tbl )
171
+ {
172
+ if (!tbl )
173
+ return ;
174
+
175
+ kfree (tbl -> entries );
176
+ kfree (tbl );
177
+ }
178
+
179
+ /**
180
+ * ubi_eba_copy_table - copy the EBA table attached to vol into another table
181
+ * @vol: volume containing the EBA table to copy
182
+ * @dst: destination
183
+ * @nentries: number of entries to copy
184
+ *
185
+ * Copy the EBA table stored in vol into the one pointed by dst.
186
+ */
187
+ void ubi_eba_copy_table (struct ubi_volume * vol , struct ubi_eba_table * dst ,
188
+ int nentries )
189
+ {
190
+ struct ubi_eba_table * src ;
191
+ int i ;
192
+
193
+ ubi_assert (dst && vol && vol -> eba_tbl );
194
+
195
+ src = vol -> eba_tbl ;
196
+
197
+ for (i = 0 ; i < nentries ; i ++ )
198
+ dst -> entries [i ].pnum = src -> entries [i ].pnum ;
199
+ }
200
+
201
+ /**
202
+ * ubi_eba_replace_table - assign a new EBA table to a volume
203
+ * @vol: volume containing the EBA table to copy
204
+ * @tbl: new EBA table
205
+ *
206
+ * Assign a new EBA table to the volume and release the old one.
207
+ */
208
+ void ubi_eba_replace_table (struct ubi_volume * vol , struct ubi_eba_table * tbl )
209
+ {
210
+ ubi_eba_destroy_table (vol -> eba_tbl );
211
+ vol -> eba_tbl = tbl ;
101
212
}
102
213
103
214
/**
@@ -337,7 +448,7 @@ static void leb_write_unlock(struct ubi_device *ubi, int vol_id, int lnum)
337
448
*/
338
449
bool ubi_eba_is_mapped (struct ubi_volume * vol , int lnum )
339
450
{
340
- return vol -> eba_tbl [lnum ] >= 0 ;
451
+ return vol -> eba_tbl -> entries [lnum ]. pnum >= 0 ;
341
452
}
342
453
343
454
/**
@@ -362,15 +473,15 @@ int ubi_eba_unmap_leb(struct ubi_device *ubi, struct ubi_volume *vol,
362
473
if (err )
363
474
return err ;
364
475
365
- pnum = vol -> eba_tbl [lnum ];
476
+ pnum = vol -> eba_tbl -> entries [lnum ]. pnum ;
366
477
if (pnum < 0 )
367
478
/* This logical eraseblock is already unmapped */
368
479
goto out_unlock ;
369
480
370
481
dbg_eba ("erase LEB %d:%d, PEB %d" , vol_id , lnum , pnum );
371
482
372
483
down_read (& ubi -> fm_eba_sem );
373
- vol -> eba_tbl [lnum ] = UBI_LEB_UNMAPPED ;
484
+ vol -> eba_tbl -> entries [lnum ]. pnum = UBI_LEB_UNMAPPED ;
374
485
up_read (& ubi -> fm_eba_sem );
375
486
err = ubi_wl_put_peb (ubi , vol_id , lnum , pnum , 0 );
376
487
@@ -409,7 +520,7 @@ int ubi_eba_read_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum,
409
520
if (err )
410
521
return err ;
411
522
412
- pnum = vol -> eba_tbl [lnum ];
523
+ pnum = vol -> eba_tbl -> entries [lnum ]. pnum ;
413
524
if (pnum < 0 ) {
414
525
/*
415
526
* The logical eraseblock is not mapped, fill the whole buffer
@@ -658,7 +769,7 @@ static int try_recover_peb(struct ubi_volume *vol, int pnum, int lnum,
658
769
mutex_unlock (& ubi -> buf_mutex );
659
770
660
771
if (!err )
661
- vol -> eba_tbl [lnum ] = new_pnum ;
772
+ vol -> eba_tbl -> entries [lnum ]. pnum = new_pnum ;
662
773
663
774
out_put :
664
775
up_read (& ubi -> fm_eba_sem );
@@ -749,7 +860,7 @@ static int try_write_vid_and_data(struct ubi_volume *vol, int lnum,
749
860
goto out_put ;
750
861
}
751
862
752
- opnum = vol -> eba_tbl [lnum ];
863
+ opnum = vol -> eba_tbl -> entries [lnum ]. pnum ;
753
864
754
865
dbg_eba ("write VID hdr and %d bytes at offset %d of LEB %d:%d, PEB %d" ,
755
866
len , offset , vol_id , lnum , pnum );
@@ -771,7 +882,7 @@ static int try_write_vid_and_data(struct ubi_volume *vol, int lnum,
771
882
}
772
883
}
773
884
774
- vol -> eba_tbl [lnum ] = pnum ;
885
+ vol -> eba_tbl -> entries [lnum ]. pnum = pnum ;
775
886
776
887
out_put :
777
888
up_read (& ubi -> fm_eba_sem );
@@ -812,7 +923,7 @@ int ubi_eba_write_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum,
812
923
if (err )
813
924
return err ;
814
925
815
- pnum = vol -> eba_tbl [lnum ];
926
+ pnum = vol -> eba_tbl -> entries [lnum ]. pnum ;
816
927
if (pnum >= 0 ) {
817
928
dbg_eba ("write %d bytes at offset %d of LEB %d:%d, PEB %d" ,
818
929
len , offset , vol_id , lnum , pnum );
@@ -930,7 +1041,7 @@ int ubi_eba_write_leb_st(struct ubi_device *ubi, struct ubi_volume *vol,
930
1041
vid_hdr -> used_ebs = cpu_to_be32 (used_ebs );
931
1042
vid_hdr -> data_crc = cpu_to_be32 (crc );
932
1043
933
- ubi_assert (vol -> eba_tbl [lnum ] < 0 );
1044
+ ubi_assert (vol -> eba_tbl -> entries [lnum ]. pnum < 0 );
934
1045
935
1046
for (tries = 0 ; tries <= UBI_IO_RETRIES ; tries ++ ) {
936
1047
err = try_write_vid_and_data (vol , lnum , vid_hdr , buf , 0 , len );
@@ -1140,9 +1251,9 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
1140
1251
* probably waiting on @ubi->move_mutex. No need to continue the work,
1141
1252
* cancel it.
1142
1253
*/
1143
- if (vol -> eba_tbl [lnum ] != from ) {
1254
+ if (vol -> eba_tbl -> entries [lnum ]. pnum != from ) {
1144
1255
dbg_wl ("LEB %d:%d is no longer mapped to PEB %d, mapped to PEB %d, cancel" ,
1145
- vol_id , lnum , from , vol -> eba_tbl [lnum ]);
1256
+ vol_id , lnum , from , vol -> eba_tbl -> entries [lnum ]. pnum );
1146
1257
err = MOVE_CANCEL_RACE ;
1147
1258
goto out_unlock_leb ;
1148
1259
}
@@ -1227,9 +1338,9 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
1227
1338
cond_resched ();
1228
1339
}
1229
1340
1230
- ubi_assert (vol -> eba_tbl [lnum ] == from );
1341
+ ubi_assert (vol -> eba_tbl -> entries [lnum ]. pnum == from );
1231
1342
down_read (& ubi -> fm_eba_sem );
1232
- vol -> eba_tbl [lnum ] = to ;
1343
+ vol -> eba_tbl -> entries [lnum ]. pnum = to ;
1233
1344
up_read (& ubi -> fm_eba_sem );
1234
1345
1235
1346
out_unlock_buf :
@@ -1386,7 +1497,7 @@ int self_check_eba(struct ubi_device *ubi, struct ubi_attach_info *ai_fastmap,
1386
1497
*/
1387
1498
int ubi_eba_init (struct ubi_device * ubi , struct ubi_attach_info * ai )
1388
1499
{
1389
- int i , j , err , num_volumes ;
1500
+ int i , err , num_volumes ;
1390
1501
struct ubi_ainf_volume * av ;
1391
1502
struct ubi_volume * vol ;
1392
1503
struct ubi_ainf_peb * aeb ;
@@ -1402,35 +1513,39 @@ int ubi_eba_init(struct ubi_device *ubi, struct ubi_attach_info *ai)
1402
1513
num_volumes = ubi -> vtbl_slots + UBI_INT_VOL_COUNT ;
1403
1514
1404
1515
for (i = 0 ; i < num_volumes ; i ++ ) {
1516
+ struct ubi_eba_table * tbl ;
1517
+
1405
1518
vol = ubi -> volumes [i ];
1406
1519
if (!vol )
1407
1520
continue ;
1408
1521
1409
1522
cond_resched ();
1410
1523
1411
- vol -> eba_tbl = kmalloc (vol -> reserved_pebs * sizeof (int ),
1412
- GFP_KERNEL );
1413
- if (!vol -> eba_tbl ) {
1414
- err = - ENOMEM ;
1524
+ tbl = ubi_eba_create_table (vol , vol -> reserved_pebs );
1525
+ if (IS_ERR (tbl )) {
1526
+ err = PTR_ERR (tbl );
1415
1527
goto out_free ;
1416
1528
}
1417
1529
1418
- for (j = 0 ; j < vol -> reserved_pebs ; j ++ )
1419
- vol -> eba_tbl [j ] = UBI_LEB_UNMAPPED ;
1530
+ ubi_eba_replace_table (vol , tbl );
1420
1531
1421
1532
av = ubi_find_av (ai , idx2vol_id (ubi , i ));
1422
1533
if (!av )
1423
1534
continue ;
1424
1535
1425
1536
ubi_rb_for_each_entry (rb , aeb , & av -> root , u .rb ) {
1426
- if (aeb -> lnum >= vol -> reserved_pebs )
1537
+ if (aeb -> lnum >= vol -> reserved_pebs ) {
1427
1538
/*
1428
1539
* This may happen in case of an unclean reboot
1429
1540
* during re-size.
1430
1541
*/
1431
1542
ubi_move_aeb_to_list (av , aeb , & ai -> erase );
1432
- else
1433
- vol -> eba_tbl [aeb -> lnum ] = aeb -> pnum ;
1543
+ } else {
1544
+ struct ubi_eba_entry * entry ;
1545
+
1546
+ entry = & vol -> eba_tbl -> entries [aeb -> lnum ];
1547
+ entry -> pnum = aeb -> pnum ;
1548
+ }
1434
1549
}
1435
1550
}
1436
1551
@@ -1467,8 +1582,7 @@ int ubi_eba_init(struct ubi_device *ubi, struct ubi_attach_info *ai)
1467
1582
for (i = 0 ; i < num_volumes ; i ++ ) {
1468
1583
if (!ubi -> volumes [i ])
1469
1584
continue ;
1470
- kfree (ubi -> volumes [i ]-> eba_tbl );
1471
- ubi -> volumes [i ]-> eba_tbl = NULL ;
1585
+ ubi_eba_replace_table (ubi -> volumes [i ], NULL );
1472
1586
}
1473
1587
return err ;
1474
1588
}
0 commit comments