Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=cae0a77125467c42f0918e78457913ee4a2f925b
Commit:     cae0a77125467c42f0918e78457913ee4a2f925b
Parent:     89b96b69290668351a33b09372ec1c94cb5748e5
Author:     Artem Bityutskiy <[EMAIL PROTECTED]>
AuthorDate: Mon Dec 17 12:46:48 2007 +0200
Committer:  Artem Bityutskiy <[EMAIL PROTECTED]>
CommitDate: Wed Dec 26 19:15:15 2007 +0200

    UBI: tweak volumes locking
    
    Transform vtbl_mutex to volumes_mutex - this just makes code
    easier to understand.
    
    Signed-off-by: Artem Bityutskiy <[EMAIL PROTECTED]>
---
 drivers/mtd/ubi/build.c |    2 +-
 drivers/mtd/ubi/kapi.c  |   11 ++++++-----
 drivers/mtd/ubi/ubi.h   |    5 +++--
 drivers/mtd/ubi/upd.c   |    4 ++++
 drivers/mtd/ubi/vmt.c   |   22 ++++++++++++++++------
 drivers/mtd/ubi/vtbl.c  |   13 ++++---------
 6 files changed, 34 insertions(+), 23 deletions(-)

diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c
index 5d00364..61225f4 100644
--- a/drivers/mtd/ubi/build.c
+++ b/drivers/mtd/ubi/build.c
@@ -264,7 +264,7 @@ static int uif_init(struct ubi_device *ubi)
        int i, err;
        dev_t dev;
 
-       mutex_init(&ubi->vtbl_mutex);
+       mutex_init(&ubi->volumes_mutex);
        spin_lock_init(&ubi->volumes_lock);
 
        sprintf(ubi->ubi_name, UBI_NAME_STR "%d", ubi->ubi_num);
diff --git a/drivers/mtd/ubi/kapi.c b/drivers/mtd/ubi/kapi.c
index c2fafe6..8e15002 100644
--- a/drivers/mtd/ubi/kapi.c
+++ b/drivers/mtd/ubi/kapi.c
@@ -162,15 +162,16 @@ struct ubi_volume_desc *ubi_open_volume(int ubi_num, int 
vol_id, int mode)
        desc->mode = mode;
 
        /*
-        * To prevent simultaneous checks of the same volume we use @vtbl_mutex,
-        * although it is not the purpose it was introduced for.
+        * To prevent simultaneous checks of the same volume we use
+        * @volumes_mutex, although it is not the purpose it was introduced
+        * for.
         */
-       mutex_lock(&ubi->vtbl_mutex);
+       mutex_lock(&ubi->volumes_mutex);
        if (!vol->checked) {
                /* This is the first open - check the volume */
                err = ubi_check_volume(ubi, vol_id);
                if (err < 0) {
-                       mutex_unlock(&ubi->vtbl_mutex);
+                       mutex_unlock(&ubi->volumes_mutex);
                        ubi_close_volume(desc);
                        return ERR_PTR(err);
                }
@@ -181,7 +182,7 @@ struct ubi_volume_desc *ubi_open_volume(int ubi_num, int 
vol_id, int mode)
                }
                vol->checked = 1;
        }
-       mutex_unlock(&ubi->vtbl_mutex);
+       mutex_unlock(&ubi->volumes_mutex);
        return desc;
 
 out_unlock:
diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h
index 0a3a803..69cbee3 100644
--- a/drivers/mtd/ubi/ubi.h
+++ b/drivers/mtd/ubi/ubi.h
@@ -255,7 +255,8 @@ struct ubi_wl_entry;
  * @vtbl_slots: how many slots are available in the volume table
  * @vtbl_size: size of the volume table in bytes
  * @vtbl: in-RAM volume table copy
- * @vtbl_mutex: protects on-flash volume table
+ * @volumes_mutex: protects on-flash volume table and serializes volume
+ *                 changes, like creation, deletion, update, resize
  *
  * @max_ec: current highest erase counter value
  * @mean_ec: current mean erase counter value
@@ -333,7 +334,7 @@ struct ubi_device {
        int vtbl_slots;
        int vtbl_size;
        struct ubi_vtbl_record *vtbl;
-       struct mutex vtbl_mutex;
+       struct mutex volumes_mutex;
 
        int max_ec;
        int mean_ec;
diff --git a/drivers/mtd/ubi/upd.c b/drivers/mtd/ubi/upd.c
index a95dcaa..e32b04d 100644
--- a/drivers/mtd/ubi/upd.c
+++ b/drivers/mtd/ubi/upd.c
@@ -67,7 +67,9 @@ static int set_update_marker(struct ubi_device *ubi, int 
vol_id)
        memcpy(&vtbl_rec, &ubi->vtbl[vol_id], sizeof(struct ubi_vtbl_record));
        vtbl_rec.upd_marker = 1;
 
+       mutex_lock(&ubi->volumes_mutex);
        err = ubi_change_vtbl_record(ubi, vol_id, &vtbl_rec);
+       mutex_unlock(&ubi->volumes_mutex);
        vol->upd_marker = 1;
        return err;
 }
@@ -106,7 +108,9 @@ static int clear_update_marker(struct ubi_device *ubi, int 
vol_id, long long byt
                        vol->last_eb_bytes = vol->usable_leb_size;
        }
 
+       mutex_lock(&ubi->volumes_mutex);
        err = ubi_change_vtbl_record(ubi, vol_id, &vtbl_rec);
+       mutex_unlock(&ubi->volumes_mutex);
        vol->upd_marker = 0;
        return err;
 }
diff --git a/drivers/mtd/ubi/vmt.c b/drivers/mtd/ubi/vmt.c
index d2d12de..ec2dd3c 100644
--- a/drivers/mtd/ubi/vmt.c
+++ b/drivers/mtd/ubi/vmt.c
@@ -201,8 +201,8 @@ int ubi_create_volume(struct ubi_device *ubi, struct 
ubi_mkvol_req *req)
        if (!vol)
                return -ENOMEM;
 
+       mutex_lock(&ubi->volumes_mutex);
        spin_lock(&ubi->volumes_lock);
-
        if (vol_id == UBI_VOL_NUM_AUTO) {
                /* Find unused volume ID */
                dbg_msg("search for vacant volume ID");
@@ -350,6 +350,7 @@ int ubi_create_volume(struct ubi_device *ubi, struct 
ubi_mkvol_req *req)
        spin_unlock(&ubi->volumes_lock);
 
        paranoid_check_volumes(ubi);
+       mutex_unlock(&ubi->volumes_mutex);
        return 0;
 
 out_gluebi:
@@ -365,6 +366,7 @@ out_acc:
        ubi->volumes[vol_id] = NULL;
 out_unlock:
        spin_unlock(&ubi->volumes_lock);
+       mutex_unlock(&ubi->volumes_mutex);
        kfree(vol);
        ubi_err("cannot create volume %d, error %d", vol_id, err);
        return err;
@@ -382,6 +384,7 @@ out_sysfs:
        ubi->avail_pebs += vol->reserved_pebs;
        ubi->volumes[vol_id] = NULL;
        spin_unlock(&ubi->volumes_lock);
+       mutex_unlock(&ubi->volumes_mutex);
        volume_sysfs_close(vol);
        ubi_err("cannot create volume %d, error %d", vol_id, err);
        return err;
@@ -408,18 +411,19 @@ int ubi_remove_volume(struct ubi_volume_desc *desc)
        if (ubi->ro_mode)
                return -EROFS;
 
+       mutex_lock(&ubi->volumes_mutex);
        err = ubi_destroy_gluebi(vol);
        if (err)
-               return err;
+               goto out;
 
        err = ubi_change_vtbl_record(ubi, vol_id, NULL);
        if (err)
-               return err;
+               goto out;
 
        for (i = 0; i < vol->reserved_pebs; i++) {
                err = ubi_eba_unmap_leb(ubi, vol, i);
                if (err)
-                       return err;
+                       goto out;
        }
 
        spin_lock(&ubi->volumes_lock);
@@ -449,8 +453,13 @@ int ubi_remove_volume(struct ubi_volume_desc *desc)
        spin_unlock(&ubi->volumes_lock);
 
        paranoid_check_volumes(ubi);
+       mutex_unlock(&ubi->volumes_mutex);
        module_put(THIS_MODULE);
        return 0;
+
+out:
+       mutex_unlock(&ubi->volumes_mutex);
+       return err;
 }
 
 /**
@@ -496,6 +505,7 @@ int ubi_resize_volume(struct ubi_volume_desc *desc, int 
reserved_pebs)
                new_mapping[i] = UBI_LEB_UNMAPPED;
 
        /* Reserve physical eraseblocks */
+       mutex_lock(&ubi->volumes_mutex);
        pebs = reserved_pebs - vol->reserved_pebs;
        if (pebs > 0) {
                spin_lock(&ubi->volumes_lock);
@@ -556,6 +566,7 @@ int ubi_resize_volume(struct ubi_volume_desc *desc, int 
reserved_pebs)
        }
 
        paranoid_check_volumes(ubi);
+       mutex_unlock(&ubi->volumes_mutex);
        return 0;
 
 out_acc:
@@ -567,6 +578,7 @@ out_acc:
        }
 out_free:
        kfree(new_mapping);
+       mutex_unlock(&ubi->volumes_mutex);
        return err;
 }
 
@@ -829,9 +841,7 @@ static void paranoid_check_volumes(struct ubi_device *ubi)
 {
        int i;
 
-       mutex_lock(&ubi->vtbl_mutex);
        for (i = 0; i < ubi->vtbl_slots; i++)
                paranoid_check_volume(ubi, i);
-       mutex_unlock(&ubi->vtbl_mutex);
 }
 #endif
diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c
index 3349c28..5879fdb 100644
--- a/drivers/mtd/ubi/vtbl.c
+++ b/drivers/mtd/ubi/vtbl.c
@@ -89,7 +89,7 @@ int ubi_change_vtbl_record(struct ubi_device *ubi, int idx,
        struct ubi_volume *layout_vol;
 
        ubi_assert(idx >= 0 && idx < ubi->vtbl_slots);
-       layout_vol = ubi->volumes[vol_id2idx(UBI_LAYOUT_VOL_ID)];
+       layout_vol = ubi->volumes[vol_id2idx(ubi, UBI_LAYOUT_VOL_ID)];
 
        if (!vtbl_rec)
                vtbl_rec = &empty_vtbl_record;
@@ -98,24 +98,19 @@ int ubi_change_vtbl_record(struct ubi_device *ubi, int idx,
                vtbl_rec->crc = cpu_to_be32(crc);
        }
 
-       mutex_lock(&ubi->vtbl_mutex);
        memcpy(&ubi->vtbl[idx], vtbl_rec, sizeof(struct ubi_vtbl_record));
        for (i = 0; i < UBI_LAYOUT_VOLUME_EBS; i++) {
                err = ubi_eba_unmap_leb(ubi, layout_vol, i);
-               if (err) {
-                       mutex_unlock(&ubi->vtbl_mutex);
+               if (err)
                        return err;
-               }
+
                err = ubi_eba_write_leb(ubi, layout_vol, i, ubi->vtbl, 0,
                                        ubi->vtbl_size, UBI_LONGTERM);
-               if (err) {
-                       mutex_unlock(&ubi->vtbl_mutex);
+               if (err)
                        return err;
-               }
        }
 
        paranoid_vtbl_check(ubi);
-       mutex_unlock(&ubi->vtbl_mutex);
        return ubi_wl_flush(ubi);
 }
 
-
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