diff options
author | Dmitry Pervushin <dpervushin@embeddedalley.com> | 2009-04-29 17:29:38 +0200 |
---|---|---|
committer | Artem Bityutskiy <Artem.Bityutskiy@nokia.com> | 2009-06-02 12:53:35 +0200 |
commit | 0e0ee1cc33de8f0cc603269b354085dee340afa0 (patch) | |
tree | 5dfd658b85eabadfbf0c94bee94d46f8d74b839b /drivers/mtd/ubi/vmt.c | |
parent | UBI: do not switch to R/O mode on read errors (diff) | |
download | linux-0e0ee1cc33de8f0cc603269b354085dee340afa0.tar.xz linux-0e0ee1cc33de8f0cc603269b354085dee340afa0.zip |
UBI: add notification API
UBI volume notifications are intended to create the API to get clients
notified about volume creation/deletion, renaming and re-sizing. A
client can subscribe to these notifications using 'ubi_volume_register()'
and cancel the subscription using 'ubi_volume_unregister()'. When UBI
volumes change, a blocking notifier is called. Clients also can request
"added" events on all volumes that existed before client subscribed
to the notifications.
If we use notifications instead of calling functions like 'ubi_gluebi_xxx()',
we can make the MTD emulation layer to be more flexible: build it as a
separate module and load/unload it on demand.
[Artem: many cleanups, rework locking, add "updated" event, provide
device/volume info in notifiers]
Signed-off-by: Dmitry Pervushin <dpervushin@embeddedalley.com>
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Diffstat (limited to 'drivers/mtd/ubi/vmt.c')
-rw-r--r-- | drivers/mtd/ubi/vmt.c | 4 |
1 files changed, 4 insertions, 0 deletions
diff --git a/drivers/mtd/ubi/vmt.c b/drivers/mtd/ubi/vmt.c index 8e8d6fae7a02..e151862a3a98 100644 --- a/drivers/mtd/ubi/vmt.c +++ b/drivers/mtd/ubi/vmt.c @@ -358,6 +358,7 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req) 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); return err; @@ -466,6 +467,7 @@ int ubi_remove_volume(struct ubi_volume_desc *desc, int no_vtbl) ubi->vol_count -= 1; 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); @@ -589,6 +591,7 @@ int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs) (long long)vol->used_ebs * vol->usable_leb_size; } + ubi_volume_notify(ubi, vol, UBI_VOLUME_RESIZED); if (paranoid_check_volumes(ubi)) dbg_err("check failed while re-sizing volume %d", vol_id); return err; @@ -635,6 +638,7 @@ int ubi_rename_volumes(struct ubi_device *ubi, struct list_head *rename_list) vol->name_len = re->new_name_len; memcpy(vol->name, re->new_name, re->new_name_len + 1); spin_unlock(&ubi->volumes_lock); + ubi_volume_notify(ubi, vol, UBI_VOLUME_RENAMED); } } |