Merge branch 'stable-3.2' into pandora-3.2
[pandora-kernel.git] / drivers / mtd / ubi / vmt.c
index 863835f..9df07ad 100644 (file)
 #include <linux/export.h>
 #include "ubi.h"
 
-#ifdef CONFIG_MTD_UBI_DEBUG
-static int paranoid_check_volumes(struct ubi_device *ubi);
-#else
-#define paranoid_check_volumes(ubi) 0
-#endif
+static int self_check_volumes(struct ubi_device *ubi);
 
 static ssize_t vol_attribute_show(struct device *dev,
                                  struct device_attribute *attr, char *buf);
@@ -227,7 +223,7 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
                        }
 
                if (vol_id == UBI_VOL_NUM_AUTO) {
-                       dbg_err("out of volume IDs");
+                       ubi_err("out of volume IDs");
                        err = -ENFILE;
                        goto out_unlock;
                }
@@ -241,7 +237,7 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
        /* Ensure that this volume does not exist */
        err = -EEXIST;
        if (ubi->volumes[vol_id]) {
-               dbg_err("volume %d already exists", vol_id);
+               ubi_err("volume %d already exists", vol_id);
                goto out_unlock;
        }
 
@@ -250,7 +246,7 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
                if (ubi->volumes[i] &&
                    ubi->volumes[i]->name_len == req->name_len &&
                    !strcmp(ubi->volumes[i]->name, req->name)) {
-                       dbg_err("volume \"%s\" exists (ID %d)", req->name, i);
+                       ubi_err("volume \"%s\" exists (ID %d)", req->name, i);
                        goto out_unlock;
                }
 
@@ -261,9 +257,9 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
 
        /* Reserve physical eraseblocks */
        if (vol->reserved_pebs > ubi->avail_pebs) {
-               dbg_err("not enough PEBs, only %d available", ubi->avail_pebs);
+               ubi_err("not enough PEBs, only %d available", ubi->avail_pebs);
                if (ubi->corr_peb_count)
-                       dbg_err("%d PEBs are corrupted and not used",
+                       ubi_err("%d PEBs are corrupted and not used",
                                ubi->corr_peb_count);
                err = -ENOSPC;
                goto out_unlock;
@@ -284,7 +280,7 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
         * Finish all pending erases because there may be some LEBs belonging
         * to the same volume ID.
         */
-       err = ubi_wl_flush(ubi);
+       err = ubi_wl_flush(ubi, vol_id, UBI_ALL);
        if (err)
                goto out_acc;
 
@@ -312,6 +308,12 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
                        vol->last_eb_bytes = vol->usable_leb_size;
        }
 
+       /* Make volume "available" before it becomes accessible via sysfs */
+       spin_lock(&ubi->volumes_lock);
+       ubi->volumes[vol_id] = vol;
+       ubi->vol_count += 1;
+       spin_unlock(&ubi->volumes_lock);
+
        /* Register character device for the volume */
        cdev_init(&vol->cdev, &ubi_vol_cdev_operations);
        vol->cdev.owner = THIS_MODULE;
@@ -354,14 +356,8 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
        if (err)
                goto out_sysfs;
 
-       spin_lock(&ubi->volumes_lock);
-       ubi->volumes[vol_id] = vol;
-       ubi->vol_count += 1;
-       spin_unlock(&ubi->volumes_lock);
-
        ubi_volume_notify(ubi, vol, UBI_VOLUME_ADDED);
-       if (paranoid_check_volumes(ubi))
-               dbg_err("check failed while creating volume %d", vol_id);
+       self_check_volumes(ubi);
        return err;
 
 out_sysfs:
@@ -379,6 +375,10 @@ out_sysfs:
 out_cdev:
        cdev_del(&vol->cdev);
 out_mapping:
+       spin_lock(&ubi->volumes_lock);
+       ubi->volumes[vol_id] = NULL;
+       ubi->vol_count -= 1;
+       spin_unlock(&ubi->volumes_lock);
        if (do_free)
                kfree(vol->eba_tbl);
 out_acc:
@@ -461,8 +461,8 @@ int ubi_remove_volume(struct ubi_volume_desc *desc, int no_vtbl)
        spin_unlock(&ubi->volumes_lock);
 
        ubi_volume_notify(ubi, vol, UBI_VOLUME_REMOVED);
-       if (!no_vtbl && paranoid_check_volumes(ubi))
-               dbg_err("check failed while removing volume %d", vol_id);
+       if (!no_vtbl)
+               self_check_volumes(ubi);
 
        return err;
 
@@ -500,7 +500,7 @@ int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs)
 
        if (vol->vol_type == UBI_STATIC_VOLUME &&
            reserved_pebs < vol->used_ebs) {
-               dbg_err("too small size %d, %d LEBs contain data",
+               ubi_err("too small size %d, %d LEBs contain data",
                        reserved_pebs, vol->used_ebs);
                return -EINVAL;
        }
@@ -529,10 +529,10 @@ int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs)
        if (pebs > 0) {
                spin_lock(&ubi->volumes_lock);
                if (pebs > ubi->avail_pebs) {
-                       dbg_err("not enough PEBs: requested %d, available %d",
+                       ubi_err("not enough PEBs: requested %d, available %d",
                                pebs, ubi->avail_pebs);
                        if (ubi->corr_peb_count)
-                               dbg_err("%d PEBs are corrupted and not used",
+                               ubi_err("%d PEBs are corrupted and not used",
                                        ubi->corr_peb_count);
                        spin_unlock(&ubi->volumes_lock);
                        err = -ENOSPC;
@@ -588,8 +588,7 @@ int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs)
        }
 
        ubi_volume_notify(ubi, vol, UBI_VOLUME_RESIZED);
-       if (paranoid_check_volumes(ubi))
-               dbg_err("check failed while re-sizing volume %d", vol_id);
+       self_check_volumes(ubi);
        return err;
 
 out_acc:
@@ -638,8 +637,8 @@ int ubi_rename_volumes(struct ubi_device *ubi, struct list_head *rename_list)
                }
        }
 
-       if (!err && paranoid_check_volumes(ubi))
-               ;
+       if (!err)
+               self_check_volumes(ubi);
        return err;
 }
 
@@ -686,8 +685,7 @@ int ubi_add_volume(struct ubi_device *ubi, struct ubi_volume *vol)
                return err;
        }
 
-       if (paranoid_check_volumes(ubi))
-               dbg_err("check failed while adding volume %d", vol_id);
+       self_check_volumes(ubi);
        return err;
 
 out_cdev:
@@ -712,16 +710,14 @@ void ubi_free_volume(struct ubi_device *ubi, struct ubi_volume *vol)
        volume_sysfs_close(vol);
 }
 
-#ifdef CONFIG_MTD_UBI_DEBUG
-
 /**
- * paranoid_check_volume - check volume information.
+ * self_check_volume - check volume information.
  * @ubi: UBI device description object
  * @vol_id: volume ID
  *
  * Returns zero if volume is all right and a a negative error code if not.
  */
-static int paranoid_check_volume(struct ubi_device *ubi, int vol_id)
+static int self_check_volume(struct ubi_device *ubi, int vol_id)
 {
        int idx = vol_id2idx(ubi, vol_id);
        int reserved_pebs, alignment, data_pad, vol_type, name_len, upd_marker;
@@ -771,7 +767,7 @@ static int paranoid_check_volume(struct ubi_device *ubi, int vol_id)
        }
 
        if (vol->upd_marker && vol->corrupted) {
-               dbg_err("update marker and corrupted simultaneously");
+               ubi_err("update marker and corrupted simultaneously");
                goto fail;
        }
 
@@ -853,22 +849,22 @@ static int paranoid_check_volume(struct ubi_device *ubi, int vol_id)
        return 0;
 
 fail:
-       ubi_err("paranoid check failed for volume %d", vol_id);
+       ubi_err("self-check failed for volume %d", vol_id);
        if (vol)
-               ubi_dbg_dump_vol_info(vol);
-       ubi_dbg_dump_vtbl_record(&ubi->vtbl[vol_id], vol_id);
+               ubi_dump_vol_info(vol);
+       ubi_dump_vtbl_record(&ubi->vtbl[vol_id], vol_id);
        dump_stack();
        spin_unlock(&ubi->volumes_lock);
        return -EINVAL;
 }
 
 /**
- * paranoid_check_volumes - check information about all volumes.
+ * self_check_volumes - check information about all volumes.
  * @ubi: UBI device description object
  *
  * Returns zero if volumes are all right and a a negative error code if not.
  */
-static int paranoid_check_volumes(struct ubi_device *ubi)
+static int self_check_volumes(struct ubi_device *ubi)
 {
        int i, err = 0;
 
@@ -876,11 +872,10 @@ static int paranoid_check_volumes(struct ubi_device *ubi)
                return 0;
 
        for (i = 0; i < ubi->vtbl_slots; i++) {
-               err = paranoid_check_volume(ubi, i);
+               err = self_check_volume(ubi, i);
                if (err)
                        break;
        }
 
        return err;
 }
-#endif