aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/ubi/attach.c
diff options
context:
space:
mode:
authorJoel Reardon <joel@clambassador.com>2012-05-16 08:20:56 -0400
committerArtem Bityutskiy <artem.bityutskiy@linux.intel.com>2012-05-21 04:34:41 -0400
commit6dd3bc7e6032ffb392477fadca77172c1c9e346b (patch)
tree7578223021e61398f46f84c5f4fb42300ce44d10 /drivers/mtd/ubi/attach.c
parent5cc09420e2bcd75d6a8f701c60a179ebb564cb3c (diff)
UBI: add volume id struct ubi_ainf_peb
This patch adds the volume id to struct ubi_ainf_peb when scanning the LEBs at startup. PEBs now added to the erase queue will know their original LEB number and volume id, if available, and will be -1 otherwise (for instance, if the VID header is unreadable). This was tested by creating an ubi device with 3 volumes and disabiling the ubi_thread's do_work functionality. The different ubi volumes were formatted to ubifs and had files created and erased. The ubi modules was reloaded and the list of LEB's added to the erased list was outputted, confirming the volume ids and LEB numbers were appropriate. Signed-off-by: Joel Reardon <reardonj@inf.ethz.ch> Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Diffstat (limited to 'drivers/mtd/ubi/attach.c')
-rw-r--r--drivers/mtd/ubi/attach.c46
1 files changed, 31 insertions, 15 deletions
diff --git a/drivers/mtd/ubi/attach.c b/drivers/mtd/ubi/attach.c
index f59f748caf23..bd27cbbb4066 100644
--- a/drivers/mtd/ubi/attach.c
+++ b/drivers/mtd/ubi/attach.c
@@ -99,12 +99,16 @@ static struct ubi_vid_hdr *vidh;
99 * add_to_list - add physical eraseblock to a list. 99 * add_to_list - add physical eraseblock to a list.
100 * @ai: attaching information 100 * @ai: attaching information
101 * @pnum: physical eraseblock number to add 101 * @pnum: physical eraseblock number to add
102 * @vol_id: the last used volume id for the PEB
103 * @lnum: the last used LEB number for the PEB
102 * @ec: erase counter of the physical eraseblock 104 * @ec: erase counter of the physical eraseblock
103 * @to_head: if not zero, add to the head of the list 105 * @to_head: if not zero, add to the head of the list
104 * @list: the list to add to 106 * @list: the list to add to
105 * 107 *
106 * This function allocates a 'struct ubi_ainf_peb' object for physical 108 * This function allocates a 'struct ubi_ainf_peb' object for physical
107 * eraseblock @pnum and adds it to the "free", "erase", or "alien" lists. 109 * eraseblock @pnum and adds it to the "free", "erase", or "alien" lists.
110 * It stores the @lnum and @vol_id alongside, which can both be
111 * %UBI_UNKNOWN if they are not available, not readable, or not assigned.
108 * If @to_head is not zero, PEB will be added to the head of the list, which 112 * If @to_head is not zero, PEB will be added to the head of the list, which
109 * basically means it will be processed first later. E.g., we add corrupted 113 * basically means it will be processed first later. E.g., we add corrupted
110 * PEBs (corrupted due to power cuts) to the head of the erase list to make 114 * PEBs (corrupted due to power cuts) to the head of the erase list to make
@@ -112,8 +116,8 @@ static struct ubi_vid_hdr *vidh;
112 * returns zero in case of success and a negative error code in case of 116 * returns zero in case of success and a negative error code in case of
113 * failure. 117 * failure.
114 */ 118 */
115static int add_to_list(struct ubi_attach_info *ai, int pnum, int ec, 119static int add_to_list(struct ubi_attach_info *ai, int pnum, int vol_id,
116 int to_head, struct list_head *list) 120 int lnum, int ec, int to_head, struct list_head *list)
117{ 121{
118 struct ubi_ainf_peb *aeb; 122 struct ubi_ainf_peb *aeb;
119 123
@@ -132,6 +136,8 @@ static int add_to_list(struct ubi_attach_info *ai, int pnum, int ec,
132 return -ENOMEM; 136 return -ENOMEM;
133 137
134 aeb->pnum = pnum; 138 aeb->pnum = pnum;
139 aeb->vol_id = vol_id;
140 aeb->lnum = lnum;
135 aeb->ec = ec; 141 aeb->ec = ec;
136 if (to_head) 142 if (to_head)
137 list_add(&aeb->u.list, list); 143 list_add(&aeb->u.list, list);
@@ -530,13 +536,16 @@ int ubi_add_to_av(struct ubi_device *ubi, struct ubi_attach_info *ai, int pnum,
530 if (err) 536 if (err)
531 return err; 537 return err;
532 538
533 err = add_to_list(ai, aeb->pnum, aeb->ec, cmp_res & 4, 539 err = add_to_list(ai, aeb->pnum, aeb->vol_id,
540 aeb->lnum, aeb->ec, cmp_res & 4,
534 &ai->erase); 541 &ai->erase);
535 if (err) 542 if (err)
536 return err; 543 return err;
537 544
538 aeb->ec = ec; 545 aeb->ec = ec;
539 aeb->pnum = pnum; 546 aeb->pnum = pnum;
547 aeb->vol_id = vol_id;
548 aeb->lnum = lnum;
540 aeb->scrub = ((cmp_res & 2) || bitflips); 549 aeb->scrub = ((cmp_res & 2) || bitflips);
541 aeb->copy_flag = vid_hdr->copy_flag; 550 aeb->copy_flag = vid_hdr->copy_flag;
542 aeb->sqnum = sqnum; 551 aeb->sqnum = sqnum;
@@ -551,8 +560,8 @@ int ubi_add_to_av(struct ubi_device *ubi, struct ubi_attach_info *ai, int pnum,
551 * This logical eraseblock is older than the one found 560 * This logical eraseblock is older than the one found
552 * previously. 561 * previously.
553 */ 562 */
554 return add_to_list(ai, pnum, ec, cmp_res & 4, 563 return add_to_list(ai, pnum, vol_id, lnum, ec,
555 &ai->erase); 564 cmp_res & 4, &ai->erase);
556 } 565 }
557 } 566 }
558 567
@@ -571,6 +580,7 @@ int ubi_add_to_av(struct ubi_device *ubi, struct ubi_attach_info *ai, int pnum,
571 580
572 aeb->ec = ec; 581 aeb->ec = ec;
573 aeb->pnum = pnum; 582 aeb->pnum = pnum;
583 aeb->vol_id = vol_id;
574 aeb->lnum = lnum; 584 aeb->lnum = lnum;
575 aeb->scrub = bitflips; 585 aeb->scrub = bitflips;
576 aeb->copy_flag = vid_hdr->copy_flag; 586 aeb->copy_flag = vid_hdr->copy_flag;
@@ -834,12 +844,12 @@ static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai,
834 break; 844 break;
835 case UBI_IO_FF: 845 case UBI_IO_FF:
836 ai->empty_peb_count += 1; 846 ai->empty_peb_count += 1;
837 return add_to_list(ai, pnum, UBI_UNKNOWN, 0, 847 return add_to_list(ai, pnum, UBI_UNKNOWN, UBI_UNKNOWN,
838 &ai->erase); 848 UBI_UNKNOWN, 0, &ai->erase);
839 case UBI_IO_FF_BITFLIPS: 849 case UBI_IO_FF_BITFLIPS:
840 ai->empty_peb_count += 1; 850 ai->empty_peb_count += 1;
841 return add_to_list(ai, pnum, UBI_UNKNOWN, 1, 851 return add_to_list(ai, pnum, UBI_UNKNOWN, UBI_UNKNOWN,
842 &ai->erase); 852 UBI_UNKNOWN, 1, &ai->erase);
843 case UBI_IO_BAD_HDR_EBADMSG: 853 case UBI_IO_BAD_HDR_EBADMSG:
844 case UBI_IO_BAD_HDR: 854 case UBI_IO_BAD_HDR:
845 /* 855 /*
@@ -950,7 +960,8 @@ static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai,
950 return err; 960 return err;
951 else if (!err) 961 else if (!err)
952 /* This corruption is caused by a power cut */ 962 /* This corruption is caused by a power cut */
953 err = add_to_list(ai, pnum, ec, 1, &ai->erase); 963 err = add_to_list(ai, pnum, UBI_UNKNOWN,
964 UBI_UNKNOWN, ec, 1, &ai->erase);
954 else 965 else
955 /* This is an unexpected corruption */ 966 /* This is an unexpected corruption */
956 err = add_corrupted(ai, pnum, ec); 967 err = add_corrupted(ai, pnum, ec);
@@ -958,15 +969,18 @@ static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai,
958 return err; 969 return err;
959 goto adjust_mean_ec; 970 goto adjust_mean_ec;
960 case UBI_IO_FF_BITFLIPS: 971 case UBI_IO_FF_BITFLIPS:
961 err = add_to_list(ai, pnum, ec, 1, &ai->erase); 972 err = add_to_list(ai, pnum, UBI_UNKNOWN, UBI_UNKNOWN,
973 ec, 1, &ai->erase);
962 if (err) 974 if (err)
963 return err; 975 return err;
964 goto adjust_mean_ec; 976 goto adjust_mean_ec;
965 case UBI_IO_FF: 977 case UBI_IO_FF:
966 if (ec_err) 978 if (ec_err)
967 err = add_to_list(ai, pnum, ec, 1, &ai->erase); 979 err = add_to_list(ai, pnum, UBI_UNKNOWN,
980 UBI_UNKNOWN, ec, 1, &ai->erase);
968 else 981 else
969 err = add_to_list(ai, pnum, ec, 0, &ai->free); 982 err = add_to_list(ai, pnum, UBI_UNKNOWN,
983 UBI_UNKNOWN, ec, 0, &ai->free);
970 if (err) 984 if (err)
971 return err; 985 return err;
972 goto adjust_mean_ec; 986 goto adjust_mean_ec;
@@ -985,7 +999,8 @@ static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai,
985 case UBI_COMPAT_DELETE: 999 case UBI_COMPAT_DELETE:
986 ubi_msg("\"delete\" compatible internal volume %d:%d" 1000 ubi_msg("\"delete\" compatible internal volume %d:%d"
987 " found, will remove it", vol_id, lnum); 1001 " found, will remove it", vol_id, lnum);
988 err = add_to_list(ai, pnum, ec, 1, &ai->erase); 1002 err = add_to_list(ai, pnum, vol_id, lnum,
1003 ec, 1, &ai->erase);
989 if (err) 1004 if (err)
990 return err; 1005 return err;
991 return 0; 1006 return 0;
@@ -1000,7 +1015,8 @@ static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai,
1000 case UBI_COMPAT_PRESERVE: 1015 case UBI_COMPAT_PRESERVE:
1001 ubi_msg("\"preserve\" compatible internal volume %d:%d" 1016 ubi_msg("\"preserve\" compatible internal volume %d:%d"
1002 " found", vol_id, lnum); 1017 " found", vol_id, lnum);
1003 err = add_to_list(ai, pnum, ec, 0, &ai->alien); 1018 err = add_to_list(ai, pnum, vol_id, lnum,
1019 ec, 0, &ai->alien);
1004 if (err) 1020 if (err)
1005 return err; 1021 return err;
1006 return 0; 1022 return 0;