|
@@ -25,6 +25,24 @@
|
|
|
#include <asm/div64.h>
|
|
|
#include "ubi.h"
|
|
|
|
|
|
+/**
|
|
|
+ * ubi_do_get_device_info - get information about UBI device.
|
|
|
+ * @ubi: UBI device description object
|
|
|
+ * @di: the information is stored here
|
|
|
+ *
|
|
|
+ * This function is the same as 'ubi_get_device_info()', but it assumes the UBI
|
|
|
+ * device is locked and cannot disappear.
|
|
|
+ */
|
|
|
+void ubi_do_get_device_info(struct ubi_device *ubi, struct ubi_device_info *di)
|
|
|
+{
|
|
|
+ di->ubi_num = ubi->ubi_num;
|
|
|
+ di->leb_size = ubi->leb_size;
|
|
|
+ di->min_io_size = ubi->min_io_size;
|
|
|
+ di->ro_mode = ubi->ro_mode;
|
|
|
+ di->cdev = ubi->cdev.dev;
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(ubi_do_get_device_info);
|
|
|
+
|
|
|
/**
|
|
|
* ubi_get_device_info - get information about UBI device.
|
|
|
* @ubi_num: UBI device number
|
|
@@ -39,33 +57,24 @@ int ubi_get_device_info(int ubi_num, struct ubi_device_info *di)
|
|
|
|
|
|
if (ubi_num < 0 || ubi_num >= UBI_MAX_DEVICES)
|
|
|
return -EINVAL;
|
|
|
-
|
|
|
ubi = ubi_get_device(ubi_num);
|
|
|
if (!ubi)
|
|
|
return -ENODEV;
|
|
|
-
|
|
|
- di->ubi_num = ubi->ubi_num;
|
|
|
- di->leb_size = ubi->leb_size;
|
|
|
- di->min_io_size = ubi->min_io_size;
|
|
|
- di->ro_mode = ubi->ro_mode;
|
|
|
- di->cdev = ubi->cdev.dev;
|
|
|
-
|
|
|
+ ubi_do_get_device_info(ubi, di);
|
|
|
ubi_put_device(ubi);
|
|
|
return 0;
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(ubi_get_device_info);
|
|
|
|
|
|
/**
|
|
|
- * ubi_get_volume_info - get information about UBI volume.
|
|
|
- * @desc: volume descriptor
|
|
|
+ * ubi_do_get_volume_info - get information about UBI volume.
|
|
|
+ * @ubi: UBI device description object
|
|
|
+ * @vol: volume description object
|
|
|
* @vi: the information is stored here
|
|
|
*/
|
|
|
-void ubi_get_volume_info(struct ubi_volume_desc *desc,
|
|
|
- struct ubi_volume_info *vi)
|
|
|
+void ubi_do_get_volume_info(struct ubi_device *ubi, struct ubi_volume *vol,
|
|
|
+ struct ubi_volume_info *vi)
|
|
|
{
|
|
|
- const struct ubi_volume *vol = desc->vol;
|
|
|
- const struct ubi_device *ubi = vol->ubi;
|
|
|
-
|
|
|
vi->vol_id = vol->vol_id;
|
|
|
vi->ubi_num = ubi->ubi_num;
|
|
|
vi->size = vol->reserved_pebs;
|
|
@@ -79,6 +88,17 @@ void ubi_get_volume_info(struct ubi_volume_desc *desc,
|
|
|
vi->name = vol->name;
|
|
|
vi->cdev = vol->cdev.dev;
|
|
|
}
|
|
|
+
|
|
|
+/**
|
|
|
+ * ubi_get_volume_info - get information about UBI volume.
|
|
|
+ * @desc: volume descriptor
|
|
|
+ * @vi: the information is stored here
|
|
|
+ */
|
|
|
+void ubi_get_volume_info(struct ubi_volume_desc *desc,
|
|
|
+ struct ubi_volume_info *vi)
|
|
|
+{
|
|
|
+ ubi_do_get_volume_info(desc->vol->ubi, desc->vol, vi);
|
|
|
+}
|
|
|
EXPORT_SYMBOL_GPL(ubi_get_volume_info);
|
|
|
|
|
|
/**
|
|
@@ -561,7 +581,7 @@ int ubi_leb_unmap(struct ubi_volume_desc *desc, int lnum)
|
|
|
EXPORT_SYMBOL_GPL(ubi_leb_unmap);
|
|
|
|
|
|
/**
|
|
|
- * ubi_leb_map - map logical erasblock to a physical eraseblock.
|
|
|
+ * ubi_leb_map - map logical eraseblock to a physical eraseblock.
|
|
|
* @desc: volume descriptor
|
|
|
* @lnum: logical eraseblock number
|
|
|
* @dtype: expected data type
|
|
@@ -659,3 +679,59 @@ int ubi_sync(int ubi_num)
|
|
|
return 0;
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(ubi_sync);
|
|
|
+
|
|
|
+BLOCKING_NOTIFIER_HEAD(ubi_notifiers);
|
|
|
+
|
|
|
+/**
|
|
|
+ * ubi_register_volume_notifier - register a volume notifier.
|
|
|
+ * @nb: the notifier description object
|
|
|
+ * @ignore_existing: if non-zero, do not send "added" notification for all
|
|
|
+ * already existing volumes
|
|
|
+ *
|
|
|
+ * This function registers a volume notifier, which means that
|
|
|
+ * 'nb->notifier_call()' will be invoked when an UBI volume is created,
|
|
|
+ * removed, re-sized, re-named, or updated. The first argument of the function
|
|
|
+ * is the notification type. The second argument is pointer to a
|
|
|
+ * &struct ubi_notification object which describes the notification event.
|
|
|
+ * Using UBI API from the volume notifier is prohibited.
|
|
|
+ *
|
|
|
+ * This function returns zero in case of success and a negative error code
|
|
|
+ * in case of failure.
|
|
|
+ */
|
|
|
+int ubi_register_volume_notifier(struct notifier_block *nb,
|
|
|
+ int ignore_existing)
|
|
|
+{
|
|
|
+ int err;
|
|
|
+
|
|
|
+ err = blocking_notifier_chain_register(&ubi_notifiers, nb);
|
|
|
+ if (err != 0)
|
|
|
+ return err;
|
|
|
+ if (ignore_existing)
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * We are going to walk all UBI devices and all volumes, and
|
|
|
+ * notify the user about existing volumes by the %UBI_VOLUME_ADDED
|
|
|
+ * event. We have to lock the @ubi_devices_mutex to make sure UBI
|
|
|
+ * devices do not disappear.
|
|
|
+ */
|
|
|
+ mutex_lock(&ubi_devices_mutex);
|
|
|
+ ubi_enumerate_volumes(nb);
|
|
|
+ mutex_unlock(&ubi_devices_mutex);
|
|
|
+
|
|
|
+ return err;
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(ubi_register_volume_notifier);
|
|
|
+
|
|
|
+/**
|
|
|
+ * ubi_unregister_volume_notifier - unregister the volume notifier.
|
|
|
+ * @nb: the notifier description object
|
|
|
+ *
|
|
|
+ * This function unregisters volume notifier @nm and returns zero in case of
|
|
|
+ * success and a negative error code in case of failure.
|
|
|
+ */
|
|
|
+int ubi_unregister_volume_notifier(struct notifier_block *nb)
|
|
|
+{
|
|
|
+ return blocking_notifier_chain_unregister(&ubi_notifiers, nb);
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(ubi_unregister_volume_notifier);
|