Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=78d87c95b89ccf86c142494beada3082810ed368
Commit:     78d87c95b89ccf86c142494beada3082810ed368
Parent:     c4e90ec0134d7bedebbe3fe58ed5d431293886d4
Author:     Artem Bityutskiy <[EMAIL PROTECTED]>
AuthorDate: Sat May 5 11:24:02 2007 +0300
Committer:  Artem Bityutskiy <[EMAIL PROTECTED]>
CommitDate: Wed Jul 18 16:52:32 2007 +0300

    UBI: fix error path in create_vtbl()
    
    There were several bugs in volume table creation error path. Thanks to
    Satyam Sharma <[EMAIL PROTECTED]> and Florin Malita <[EMAIL PROTECTED]>
    for finding and analysing them: http://lkml.org/lkml/2007/5/3/274
    
    This patch makes ubi_scan_add_to_list() static and renames it to
    add_to_list(), just because it is not needed outside scan.c anymore.
    
    Signed-off-by: Artem Bityutskiy <[EMAIL PROTECTED]>
---
 drivers/mtd/ubi/scan.c |   46 +++++++++++++++++++++++++++-------------------
 drivers/mtd/ubi/scan.h |    2 --
 drivers/mtd/ubi/vtbl.c |   14 ++++++++------
 3 files changed, 35 insertions(+), 27 deletions(-)

diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c
index e445686..30d536e 100644
--- a/drivers/mtd/ubi/scan.c
+++ b/drivers/mtd/ubi/scan.c
@@ -24,7 +24,7 @@
  * This unit is responsible for scanning the flash media, checking UBI
  * headers and providing complete information about the UBI flash image.
  *
- * The scanning information is reoresented by a &struct ubi_scan_info' object.
+ * The scanning information is represented by a &struct ubi_scan_info' object.
  * Information about found volumes is represented by &struct ubi_scan_volume
  * objects which are kept in volume RB-tree with root at the @volumes field.
  * The RB-tree is indexed by the volume ID.
@@ -55,8 +55,19 @@ static int paranoid_check_si(const struct ubi_device *ubi,
 static struct ubi_ec_hdr *ech;
 static struct ubi_vid_hdr *vidh;
 
-int ubi_scan_add_to_list(struct ubi_scan_info *si, int pnum, int ec,
-                        struct list_head *list)
+/*
+ * add_to_list - add physical eraseblock to a list.
+ * @si: scanning information
+ * @pnum: physical eraseblock number to add
+ * @ec: erase counter of the physical eraseblock
+ * @list: the list to add to
+ *
+ * This function adds physical eraseblock @pnum to free, erase, corrupted or
+ * alien lists. Returns zero in case of success and a negative error code in
+ * case of failure.
+ */
+static int add_to_list(struct ubi_scan_info *si, int pnum, int ec,
+                      struct list_head *list)
 {
        struct ubi_scan_leb *seb;
 
@@ -492,11 +503,11 @@ int ubi_scan_add_used(const struct ubi_device *ubi, 
struct ubi_scan_info *si,
                                return err;
 
                        if (cmp_res & 4)
-                               err = ubi_scan_add_to_list(si, seb->pnum,
-                                                          seb->ec, &si->corr);
+                               err = add_to_list(si, seb->pnum, seb->ec,
+                                                 &si->corr);
                        else
-                               err = ubi_scan_add_to_list(si, seb->pnum,
-                                                          seb->ec, &si->erase);
+                               err = add_to_list(si, seb->pnum, seb->ec,
+                                                 &si->erase);
                        if (err)
                                return err;
 
@@ -517,11 +528,9 @@ int ubi_scan_add_used(const struct ubi_device *ubi, struct 
ubi_scan_info *si,
                         * previously.
                         */
                        if (cmp_res & 4)
-                               return ubi_scan_add_to_list(si, pnum, ec,
-                                                           &si->corr);
+                               return add_to_list(si, pnum, ec, &si->corr);
                        else
-                               return ubi_scan_add_to_list(si, pnum, ec,
-                                                           &si->erase);
+                               return add_to_list(si, pnum, ec, &si->erase);
                }
        }
 
@@ -754,7 +763,7 @@ struct ubi_scan_leb *ubi_scan_get_free_peb(const struct 
ubi_device *ubi,
  * @si: scanning information
  * @pnum: the physical eraseblock number
  *
- * This function returns a zero if the physical eraseblock was succesfully
+ * This function returns a zero if the physical eraseblock was successfully
  * handled and a negative error code in case of failure.
  */
 static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si, int 
pnum)
@@ -783,8 +792,7 @@ static int process_eb(struct ubi_device *ubi, struct 
ubi_scan_info *si, int pnum
        else if (err == UBI_IO_BITFLIPS)
                bitflips = 1;
        else if (err == UBI_IO_PEB_EMPTY)
-               return ubi_scan_add_to_list(si, pnum, UBI_SCAN_UNKNOWN_EC,
-                                           &si->erase);
+               return add_to_list(si, pnum, UBI_SCAN_UNKNOWN_EC, &si->erase);
        else if (err == UBI_IO_BAD_EC_HDR) {
                /*
                 * We have to also look at the VID header, possibly it is not
@@ -832,13 +840,13 @@ static int process_eb(struct ubi_device *ubi, struct 
ubi_scan_info *si, int pnum
        else if (err == UBI_IO_BAD_VID_HDR ||
                 (err == UBI_IO_PEB_FREE && ec_corr)) {
                /* VID header is corrupted */
-               err = ubi_scan_add_to_list(si, pnum, ec, &si->corr);
+               err = add_to_list(si, pnum, ec, &si->corr);
                if (err)
                        return err;
                goto adjust_mean_ec;
        } else if (err == UBI_IO_PEB_FREE) {
                /* No VID header - the physical eraseblock is free */
-               err = ubi_scan_add_to_list(si, pnum, ec, &si->free);
+               err = add_to_list(si, pnum, ec, &si->free);
                if (err)
                        return err;
                goto adjust_mean_ec;
@@ -853,7 +861,7 @@ static int process_eb(struct ubi_device *ubi, struct 
ubi_scan_info *si, int pnum
                case UBI_COMPAT_DELETE:
                        ubi_msg("\"delete\" compatible internal volume %d:%d"
                                " found, remove it", vol_id, lnum);
-                       err = ubi_scan_add_to_list(si, pnum, ec, &si->corr);
+                       err = add_to_list(si, pnum, ec, &si->corr);
                        if (err)
                                return err;
                        break;
@@ -868,7 +876,7 @@ static int process_eb(struct ubi_device *ubi, struct 
ubi_scan_info *si, int pnum
                case UBI_COMPAT_PRESERVE:
                        ubi_msg("\"preserve\" compatible internal volume %d:%d"
                                " found", vol_id, lnum);
-                       err = ubi_scan_add_to_list(si, pnum, ec, &si->alien);
+                       err = add_to_list(si, pnum, ec, &si->alien);
                        if (err)
                                return err;
                        si->alien_peb_count += 1;
@@ -1109,7 +1117,7 @@ static int paranoid_check_si(const struct ubi_device *ubi,
        uint8_t *buf;
 
        /*
-        * At first, check that scanning information is ok.
+        * At first, check that scanning information is OK.
         */
        ubi_rb_for_each_entry(rb1, sv, &si->volumes, rb) {
                int leb_count = 0;
diff --git a/drivers/mtd/ubi/scan.h b/drivers/mtd/ubi/scan.h
index 3949f61..140e82e 100644
--- a/drivers/mtd/ubi/scan.h
+++ b/drivers/mtd/ubi/scan.h
@@ -147,8 +147,6 @@ static inline void ubi_scan_move_to_list(struct 
ubi_scan_volume *sv,
                list_add_tail(&seb->u.list, list);
 }
 
-int ubi_scan_add_to_list(struct ubi_scan_info *si, int pnum, int ec,
-                        struct list_head *list);
 int ubi_scan_add_used(const struct ubi_device *ubi, struct ubi_scan_info *si,
                      int pnum, int ec, const struct ubi_vid_hdr *vid_hdr,
                      int bitflips);
diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c
index 83236c3..9926f1f 100644
--- a/drivers/mtd/ubi/vtbl.c
+++ b/drivers/mtd/ubi/vtbl.c
@@ -317,13 +317,15 @@ retry:
        return err;
 
 write_error:
-       /* Maybe this physical eraseblock went bad, try to pick another one */
-       if (++tries <= 5)
-               err = ubi_scan_add_to_list(si, new_seb->pnum, new_seb->ec,
-                                          &si->corr);
-       kfree(new_seb);
-       if (!err)
+       if (err == -EIO && ++tries <= 5) {
+               /*
+                * Probably this physical eraseblock went bad, try to pick
+                * another one.
+                */
+               list_add_tail(&new_seb->u.list, &si->corr);
                goto retry;
+       }
+       kfree(new_seb);
 out_free:
        ubi_free_vid_hdr(ubi, vid_hdr);
        return err;
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to