diff options
author | Richard Weinberger <richard@nod.at> | 2012-09-26 11:51:42 -0400 |
---|---|---|
committer | Artem Bityutskiy <artem.bityutskiy@linux.intel.com> | 2012-10-03 05:29:37 -0400 |
commit | 5638b33abffd967dda4f984a247925b7af38b23d (patch) | |
tree | 1df7dfde3faec82ce76e169c425c936625cfe017 /drivers | |
parent | 1c865749999efdae63ddfb73b911ee04e1d4e1c8 (diff) |
UBI: Add fastmap stuff to ubi.h
This patch adds fastmap specific data structures to ubi.h.
It moves also struct ubi_work to ubi.h as it is now needed
for more than one c file.
Signed-off-by: Richard Weinberger <richard@nod.at>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mtd/ubi/ubi.h | 116 | ||||
-rw-r--r-- | drivers/mtd/ubi/wl.c | 24 |
2 files changed, 115 insertions, 25 deletions
diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index 383ee43d2425..b0d3ba2a3dea 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h | |||
@@ -133,6 +133,17 @@ enum { | |||
133 | MOVE_RETRY, | 133 | MOVE_RETRY, |
134 | }; | 134 | }; |
135 | 135 | ||
136 | /* | ||
137 | * Return codes of the fastmap sub-system | ||
138 | * | ||
139 | * UBI_NO_FASTMAP: No fastmap super block was found | ||
140 | * UBI_BAD_FASTMAP: A fastmap was found but it's unusable | ||
141 | */ | ||
142 | enum { | ||
143 | UBI_NO_FASTMAP = 1, | ||
144 | UBI_BAD_FASTMAP, | ||
145 | }; | ||
146 | |||
136 | /** | 147 | /** |
137 | * struct ubi_wl_entry - wear-leveling entry. | 148 | * struct ubi_wl_entry - wear-leveling entry. |
138 | * @u.rb: link in the corresponding (free/used) RB-tree | 149 | * @u.rb: link in the corresponding (free/used) RB-tree |
@@ -199,6 +210,41 @@ struct ubi_rename_entry { | |||
199 | struct ubi_volume_desc; | 210 | struct ubi_volume_desc; |
200 | 211 | ||
201 | /** | 212 | /** |
213 | * struct ubi_fastmap_layout - in-memory fastmap data structure. | ||
214 | * @e: PEBs used by the current fastmap | ||
215 | * @to_be_tortured: if non-zero tortured this PEB | ||
216 | * @used_blocks: number of used PEBs | ||
217 | * @max_pool_size: maximal size of the user pool | ||
218 | * @max_wl_pool_size: maximal size of the pool used by the WL sub-system | ||
219 | */ | ||
220 | struct ubi_fastmap_layout { | ||
221 | struct ubi_wl_entry *e[UBI_FM_MAX_BLOCKS]; | ||
222 | int to_be_tortured[UBI_FM_MAX_BLOCKS]; | ||
223 | int used_blocks; | ||
224 | int max_pool_size; | ||
225 | int max_wl_pool_size; | ||
226 | }; | ||
227 | |||
228 | /** | ||
229 | * struct ubi_fm_pool - in-memory fastmap pool | ||
230 | * @pebs: PEBs in this pool | ||
231 | * @used: number of used PEBs | ||
232 | * @size: total number of PEBs in this pool | ||
233 | * @max_size: maximal size of the pool | ||
234 | * | ||
235 | * A pool gets filled with up to max_size. | ||
236 | * If all PEBs within the pool are used a new fastmap will be written | ||
237 | * to the flash and the pool gets refilled with empty PEBs. | ||
238 | * | ||
239 | */ | ||
240 | struct ubi_fm_pool { | ||
241 | int pebs[UBI_FM_MAX_POOL_SIZE]; | ||
242 | int used; | ||
243 | int size; | ||
244 | int max_size; | ||
245 | }; | ||
246 | |||
247 | /** | ||
202 | * struct ubi_volume - UBI volume description data structure. | 248 | * struct ubi_volume - UBI volume description data structure. |
203 | * @dev: device object to make use of the the Linux device model | 249 | * @dev: device object to make use of the the Linux device model |
204 | * @cdev: character device object to create character device | 250 | * @cdev: character device object to create character device |
@@ -333,9 +379,21 @@ struct ubi_wl_entry; | |||
333 | * @ltree: the lock tree | 379 | * @ltree: the lock tree |
334 | * @alc_mutex: serializes "atomic LEB change" operations | 380 | * @alc_mutex: serializes "atomic LEB change" operations |
335 | * | 381 | * |
382 | * @fm_disabled: non-zero if fastmap is disabled (default) | ||
383 | * @fm: in-memory data structure of the currently used fastmap | ||
384 | * @fm_pool: in-memory data structure of the fastmap pool | ||
385 | * @fm_wl_pool: in-memory data structure of the fastmap pool used by the WL | ||
386 | * sub-system | ||
387 | * @fm_mutex: serializes ubi_update_fastmap() and protects @fm_buf | ||
388 | * @fm_buf: vmalloc()'d buffer which holds the raw fastmap | ||
389 | * @fm_size: fastmap size in bytes | ||
390 | * @fm_sem: allows ubi_update_fastmap() to block EBA table changes | ||
391 | * @fm_work: fastmap work queue | ||
392 | * | ||
336 | * @used: RB-tree of used physical eraseblocks | 393 | * @used: RB-tree of used physical eraseblocks |
337 | * @erroneous: RB-tree of erroneous used physical eraseblocks | 394 | * @erroneous: RB-tree of erroneous used physical eraseblocks |
338 | * @free: RB-tree of free physical eraseblocks | 395 | * @free: RB-tree of free physical eraseblocks |
396 | * @free_count: Contains the number of elements in @free | ||
339 | * @scrub: RB-tree of physical eraseblocks which need scrubbing | 397 | * @scrub: RB-tree of physical eraseblocks which need scrubbing |
340 | * @pq: protection queue (contain physical eraseblocks which are temporarily | 398 | * @pq: protection queue (contain physical eraseblocks which are temporarily |
341 | * protected from the wear-leveling worker) | 399 | * protected from the wear-leveling worker) |
@@ -426,10 +484,22 @@ struct ubi_device { | |||
426 | struct rb_root ltree; | 484 | struct rb_root ltree; |
427 | struct mutex alc_mutex; | 485 | struct mutex alc_mutex; |
428 | 486 | ||
487 | /* Fastmap stuff */ | ||
488 | int fm_disabled; | ||
489 | struct ubi_fastmap_layout *fm; | ||
490 | struct ubi_fm_pool fm_pool; | ||
491 | struct ubi_fm_pool fm_wl_pool; | ||
492 | struct rw_semaphore fm_sem; | ||
493 | struct mutex fm_mutex; | ||
494 | void *fm_buf; | ||
495 | size_t fm_size; | ||
496 | struct work_struct fm_work; | ||
497 | |||
429 | /* Wear-leveling sub-system's stuff */ | 498 | /* Wear-leveling sub-system's stuff */ |
430 | struct rb_root used; | 499 | struct rb_root used; |
431 | struct rb_root erroneous; | 500 | struct rb_root erroneous; |
432 | struct rb_root free; | 501 | struct rb_root free; |
502 | int free_count; | ||
433 | struct rb_root scrub; | 503 | struct rb_root scrub; |
434 | struct list_head pq[UBI_PROT_QUEUE_LEN]; | 504 | struct list_head pq[UBI_PROT_QUEUE_LEN]; |
435 | int pq_head; | 505 | int pq_head; |
@@ -596,6 +666,32 @@ struct ubi_attach_info { | |||
596 | struct kmem_cache *aeb_slab_cache; | 666 | struct kmem_cache *aeb_slab_cache; |
597 | }; | 667 | }; |
598 | 668 | ||
669 | /** | ||
670 | * struct ubi_work - UBI work description data structure. | ||
671 | * @list: a link in the list of pending works | ||
672 | * @func: worker function | ||
673 | * @e: physical eraseblock to erase | ||
674 | * @vol_id: the volume ID on which this erasure is being performed | ||
675 | * @lnum: the logical eraseblock number | ||
676 | * @torture: if the physical eraseblock has to be tortured | ||
677 | * @anchor: produce a anchor PEB to by used by fastmap | ||
678 | * | ||
679 | * The @func pointer points to the worker function. If the @cancel argument is | ||
680 | * not zero, the worker has to free the resources and exit immediately. The | ||
681 | * worker has to return zero in case of success and a negative error code in | ||
682 | * case of failure. | ||
683 | */ | ||
684 | struct ubi_work { | ||
685 | struct list_head list; | ||
686 | int (*func)(struct ubi_device *ubi, struct ubi_work *wrk, int cancel); | ||
687 | /* The below fields are only relevant to erasure works */ | ||
688 | struct ubi_wl_entry *e; | ||
689 | int vol_id; | ||
690 | int lnum; | ||
691 | int torture; | ||
692 | int anchor; | ||
693 | }; | ||
694 | |||
599 | #include "debug.h" | 695 | #include "debug.h" |
600 | 696 | ||
601 | extern struct kmem_cache *ubi_wl_entry_slab; | 697 | extern struct kmem_cache *ubi_wl_entry_slab; |
@@ -606,7 +702,7 @@ extern struct class *ubi_class; | |||
606 | extern struct mutex ubi_devices_mutex; | 702 | extern struct mutex ubi_devices_mutex; |
607 | extern struct blocking_notifier_head ubi_notifiers; | 703 | extern struct blocking_notifier_head ubi_notifiers; |
608 | 704 | ||
609 | /* scan.c */ | 705 | /* attach.c */ |
610 | int ubi_add_to_av(struct ubi_device *ubi, struct ubi_attach_info *ai, int pnum, | 706 | int ubi_add_to_av(struct ubi_device *ubi, struct ubi_attach_info *ai, int pnum, |
611 | int ec, const struct ubi_vid_hdr *vid_hdr, int bitflips); | 707 | int ec, const struct ubi_vid_hdr *vid_hdr, int bitflips); |
612 | struct ubi_ainf_volume *ubi_find_av(const struct ubi_attach_info *ai, | 708 | struct ubi_ainf_volume *ubi_find_av(const struct ubi_attach_info *ai, |
@@ -664,6 +760,9 @@ int ubi_eba_atomic_leb_change(struct ubi_device *ubi, struct ubi_volume *vol, | |||
664 | int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, | 760 | int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, |
665 | struct ubi_vid_hdr *vid_hdr); | 761 | struct ubi_vid_hdr *vid_hdr); |
666 | int ubi_eba_init(struct ubi_device *ubi, struct ubi_attach_info *ai); | 762 | int ubi_eba_init(struct ubi_device *ubi, struct ubi_attach_info *ai); |
763 | unsigned long long ubi_next_sqnum(struct ubi_device *ubi); | ||
764 | int self_check_eba(struct ubi_device *ubi, struct ubi_attach_info *ai_fastmap, | ||
765 | struct ubi_attach_info *ai_scan); | ||
667 | 766 | ||
668 | /* wl.c */ | 767 | /* wl.c */ |
669 | int ubi_wl_get_peb(struct ubi_device *ubi); | 768 | int ubi_wl_get_peb(struct ubi_device *ubi); |
@@ -674,6 +773,12 @@ int ubi_wl_scrub_peb(struct ubi_device *ubi, int pnum); | |||
674 | int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai); | 773 | int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai); |
675 | void ubi_wl_close(struct ubi_device *ubi); | 774 | void ubi_wl_close(struct ubi_device *ubi); |
676 | int ubi_thread(void *u); | 775 | int ubi_thread(void *u); |
776 | struct ubi_wl_entry *ubi_wl_get_fm_peb(struct ubi_device *ubi, int anchor); | ||
777 | int ubi_wl_put_fm_peb(struct ubi_device *ubi, struct ubi_wl_entry *used_e, | ||
778 | int lnum, int torture); | ||
779 | int ubi_is_erase_work(struct ubi_work *wrk); | ||
780 | void ubi_refill_pools(struct ubi_device *ubi); | ||
781 | int ubi_ensure_anchor_pebs(struct ubi_device *ubi); | ||
677 | 782 | ||
678 | /* io.c */ | 783 | /* io.c */ |
679 | int ubi_io_read(const struct ubi_device *ubi, void *buf, int pnum, int offset, | 784 | int ubi_io_read(const struct ubi_device *ubi, void *buf, int pnum, int offset, |
@@ -711,6 +816,15 @@ void ubi_free_internal_volumes(struct ubi_device *ubi); | |||
711 | void ubi_do_get_device_info(struct ubi_device *ubi, struct ubi_device_info *di); | 816 | void ubi_do_get_device_info(struct ubi_device *ubi, struct ubi_device_info *di); |
712 | void ubi_do_get_volume_info(struct ubi_device *ubi, struct ubi_volume *vol, | 817 | void ubi_do_get_volume_info(struct ubi_device *ubi, struct ubi_volume *vol, |
713 | struct ubi_volume_info *vi); | 818 | struct ubi_volume_info *vi); |
819 | /* scan.c */ | ||
820 | int ubi_compare_lebs(struct ubi_device *ubi, const struct ubi_ainf_peb *aeb, | ||
821 | int pnum, const struct ubi_vid_hdr *vid_hdr); | ||
822 | |||
823 | /* fastmap.c */ | ||
824 | size_t ubi_calc_fm_size(struct ubi_device *ubi); | ||
825 | int ubi_update_fastmap(struct ubi_device *ubi); | ||
826 | int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai, | ||
827 | int fm_anchor); | ||
714 | 828 | ||
715 | /* | 829 | /* |
716 | * ubi_rb_for_each_entry - walk an RB-tree. | 830 | * ubi_rb_for_each_entry - walk an RB-tree. |
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index 032fc57f1090..f4d06dbdb2a9 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c | |||
@@ -135,30 +135,6 @@ | |||
135 | */ | 135 | */ |
136 | #define WL_MAX_FAILURES 32 | 136 | #define WL_MAX_FAILURES 32 |
137 | 137 | ||
138 | /** | ||
139 | * struct ubi_work - UBI work description data structure. | ||
140 | * @list: a link in the list of pending works | ||
141 | * @func: worker function | ||
142 | * @e: physical eraseblock to erase | ||
143 | * @vol_id: the volume ID on which this erasure is being performed | ||
144 | * @lnum: the logical eraseblock number | ||
145 | * @torture: if the physical eraseblock has to be tortured | ||
146 | * | ||
147 | * The @func pointer points to the worker function. If the @cancel argument is | ||
148 | * not zero, the worker has to free the resources and exit immediately. The | ||
149 | * worker has to return zero in case of success and a negative error code in | ||
150 | * case of failure. | ||
151 | */ | ||
152 | struct ubi_work { | ||
153 | struct list_head list; | ||
154 | int (*func)(struct ubi_device *ubi, struct ubi_work *wrk, int cancel); | ||
155 | /* The below fields are only relevant to erasure works */ | ||
156 | struct ubi_wl_entry *e; | ||
157 | int vol_id; | ||
158 | int lnum; | ||
159 | int torture; | ||
160 | }; | ||
161 | |||
162 | static int self_check_ec(struct ubi_device *ubi, int pnum, int ec); | 138 | static int self_check_ec(struct ubi_device *ubi, int pnum, int ec); |
163 | static int self_check_in_wl_tree(const struct ubi_device *ubi, | 139 | static int self_check_in_wl_tree(const struct ubi_device *ubi, |
164 | struct ubi_wl_entry *e, struct rb_root *root); | 140 | struct ubi_wl_entry *e, struct rb_root *root); |