UBI: add auto-resize feature
[safe/jmp/linux-2.6] / drivers / mtd / ubi / wl.c
index 8421c7a..8bfb743 100644 (file)
@@ -259,7 +259,6 @@ static int do_work(struct ubi_device *ubi)
         */
        down_read(&ubi->work_sem);
        spin_lock(&ubi->wl_lock);
-
        if (list_empty(&ubi->works)) {
                spin_unlock(&ubi->wl_lock);
                up_read(&ubi->work_sem);
@@ -268,6 +267,8 @@ static int do_work(struct ubi_device *ubi)
 
        wrk = list_entry(ubi->works.next, struct ubi_work, list);
        list_del(&wrk->list);
+       ubi->works_count -= 1;
+       ubi_assert(ubi->works_count >= 0);
        spin_unlock(&ubi->wl_lock);
 
        /*
@@ -278,12 +279,8 @@ static int do_work(struct ubi_device *ubi)
        err = wrk->func(ubi, wrk, 0);
        if (err)
                ubi_err("work failed with error code %d", err);
-
-       spin_lock(&ubi->wl_lock);
-       ubi->works_count -= 1;
-       ubi_assert(ubi->works_count >= 0);
-       spin_unlock(&ubi->wl_lock);
        up_read(&ubi->work_sem);
+
        return err;
 }
 
@@ -1358,7 +1355,7 @@ static void tree_destroy(struct rb_root *root)
  * ubi_thread - UBI background thread.
  * @u: the UBI device description object pointer
  */
-static int ubi_thread(void *u)
+int ubi_thread(void *u)
 {
        int failures = 0;
        struct ubi_device *ubi = u;
@@ -1456,18 +1453,10 @@ int ubi_wl_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si)
 
        sprintf(ubi->bgt_name, UBI_BGT_NAME_PATTERN, ubi->ubi_num);
 
-       ubi->bgt_thread = kthread_create(ubi_thread, ubi, ubi->bgt_name);
-       if (IS_ERR(ubi->bgt_thread)) {
-               err = PTR_ERR(ubi->bgt_thread);
-               ubi_err("cannot spawn \"%s\", error %d", ubi->bgt_name,
-                       err);
-               return err;
-       }
-
        err = -ENOMEM;
        ubi->lookuptbl = kzalloc(ubi->peb_count * sizeof(void *), GFP_KERNEL);
        if (!ubi->lookuptbl)
-               goto out_free;
+               return err;
 
        list_for_each_entry_safe(seb, tmp, &si->erase, u.list) {
                cond_resched();
@@ -1600,10 +1589,6 @@ static void protection_trees_destroy(struct ubi_device *ubi)
  */
 void ubi_wl_close(struct ubi_device *ubi)
 {
-       dbg_wl("disable \"%s\"", ubi->bgt_name);
-       if (ubi->bgt_thread)
-               kthread_stop(ubi->bgt_thread);
-
        dbg_wl("close the UBI wear-leveling unit");
 
        cancel_pending(ubi);