Lines Matching refs:ubi
60 unsigned long long ubi_next_sqnum(struct ubi_device *ubi) in ubi_next_sqnum() argument
64 spin_lock(&ubi->ltree_lock); in ubi_next_sqnum()
65 sqnum = ubi->global_sqnum++; in ubi_next_sqnum()
66 spin_unlock(&ubi->ltree_lock); in ubi_next_sqnum()
79 static int ubi_get_compat(const struct ubi_device *ubi, int vol_id) in ubi_get_compat() argument
96 static struct ubi_ltree_entry *ltree_lookup(struct ubi_device *ubi, int vol_id, in ltree_lookup() argument
101 p = ubi->ltree.rb_node; in ltree_lookup()
135 static struct ubi_ltree_entry *ltree_add_entry(struct ubi_device *ubi, in ltree_add_entry() argument
149 spin_lock(&ubi->ltree_lock); in ltree_add_entry()
150 le1 = ltree_lookup(ubi, vol_id, lnum); in ltree_add_entry()
168 p = &ubi->ltree.rb_node; in ltree_add_entry()
187 rb_insert_color(&le->rb, &ubi->ltree); in ltree_add_entry()
190 spin_unlock(&ubi->ltree_lock); in ltree_add_entry()
205 static int leb_read_lock(struct ubi_device *ubi, int vol_id, int lnum) in leb_read_lock() argument
209 le = ltree_add_entry(ubi, vol_id, lnum); in leb_read_lock()
222 static void leb_read_unlock(struct ubi_device *ubi, int vol_id, int lnum) in leb_read_unlock() argument
226 spin_lock(&ubi->ltree_lock); in leb_read_unlock()
227 le = ltree_lookup(ubi, vol_id, lnum); in leb_read_unlock()
232 rb_erase(&le->rb, &ubi->ltree); in leb_read_unlock()
235 spin_unlock(&ubi->ltree_lock); in leb_read_unlock()
247 static int leb_write_lock(struct ubi_device *ubi, int vol_id, int lnum) in leb_write_lock() argument
251 le = ltree_add_entry(ubi, vol_id, lnum); in leb_write_lock()
269 static int leb_write_trylock(struct ubi_device *ubi, int vol_id, int lnum) in leb_write_trylock() argument
273 le = ltree_add_entry(ubi, vol_id, lnum); in leb_write_trylock()
280 spin_lock(&ubi->ltree_lock); in leb_write_trylock()
284 rb_erase(&le->rb, &ubi->ltree); in leb_write_trylock()
287 spin_unlock(&ubi->ltree_lock); in leb_write_trylock()
298 static void leb_write_unlock(struct ubi_device *ubi, int vol_id, int lnum) in leb_write_unlock() argument
302 spin_lock(&ubi->ltree_lock); in leb_write_unlock()
303 le = ltree_lookup(ubi, vol_id, lnum); in leb_write_unlock()
308 rb_erase(&le->rb, &ubi->ltree); in leb_write_unlock()
311 spin_unlock(&ubi->ltree_lock); in leb_write_unlock()
324 int ubi_eba_unmap_leb(struct ubi_device *ubi, struct ubi_volume *vol, in ubi_eba_unmap_leb() argument
329 if (ubi->ro_mode) in ubi_eba_unmap_leb()
332 err = leb_write_lock(ubi, vol_id, lnum); in ubi_eba_unmap_leb()
343 down_read(&ubi->fm_sem); in ubi_eba_unmap_leb()
345 up_read(&ubi->fm_sem); in ubi_eba_unmap_leb()
346 err = ubi_wl_put_peb(ubi, vol_id, lnum, pnum, 0); in ubi_eba_unmap_leb()
349 leb_write_unlock(ubi, vol_id, lnum); in ubi_eba_unmap_leb()
372 int ubi_eba_read_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum, in ubi_eba_read_leb() argument
379 err = leb_read_lock(ubi, vol_id, lnum); in ubi_eba_read_leb()
392 leb_read_unlock(ubi, vol_id, lnum); in ubi_eba_read_leb()
406 vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); in ubi_eba_read_leb()
412 err = ubi_io_read_vid_hdr(ubi, pnum, vid_hdr, 1); in ubi_eba_read_leb()
429 ubi_ro_mode(ubi); in ubi_eba_read_leb()
439 ubi_free_vid_hdr(ubi, vid_hdr); in ubi_eba_read_leb()
442 err = ubi_io_read_data(ubi, buf, pnum, offset, len); in ubi_eba_read_leb()
471 err = ubi_wl_scrub_peb(ubi, pnum); in ubi_eba_read_leb()
473 leb_read_unlock(ubi, vol_id, lnum); in ubi_eba_read_leb()
477 ubi_free_vid_hdr(ubi, vid_hdr); in ubi_eba_read_leb()
479 leb_read_unlock(ubi, vol_id, lnum); in ubi_eba_read_leb()
499 static int recover_peb(struct ubi_device *ubi, int pnum, int vol_id, int lnum, in recover_peb() argument
502 int err, idx = vol_id2idx(ubi, vol_id), new_pnum, data_size, tries = 0; in recover_peb()
503 struct ubi_volume *vol = ubi->volumes[idx]; in recover_peb()
506 vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); in recover_peb()
511 new_pnum = ubi_wl_get_peb(ubi); in recover_peb()
513 ubi_free_vid_hdr(ubi, vid_hdr); in recover_peb()
519 err = ubi_io_read_vid_hdr(ubi, pnum, vid_hdr, 1); in recover_peb()
526 vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi)); in recover_peb()
527 err = ubi_io_write_vid_hdr(ubi, new_pnum, vid_hdr); in recover_peb()
532 mutex_lock(&ubi->buf_mutex); in recover_peb()
533 memset(ubi->peb_buf + offset, 0xFF, len); in recover_peb()
537 err = ubi_io_read_data(ubi, ubi->peb_buf, pnum, 0, offset); in recover_peb()
542 memcpy(ubi->peb_buf + offset, buf, len); in recover_peb()
544 err = ubi_io_write_data(ubi, ubi->peb_buf, new_pnum, 0, data_size); in recover_peb()
546 mutex_unlock(&ubi->buf_mutex); in recover_peb()
550 mutex_unlock(&ubi->buf_mutex); in recover_peb()
551 ubi_free_vid_hdr(ubi, vid_hdr); in recover_peb()
553 down_read(&ubi->fm_sem); in recover_peb()
555 up_read(&ubi->fm_sem); in recover_peb()
556 ubi_wl_put_peb(ubi, vol_id, lnum, pnum, 1); in recover_peb()
562 mutex_unlock(&ubi->buf_mutex); in recover_peb()
564 ubi_wl_put_peb(ubi, vol_id, lnum, new_pnum, 1); in recover_peb()
565 ubi_free_vid_hdr(ubi, vid_hdr); in recover_peb()
574 ubi_wl_put_peb(ubi, vol_id, lnum, new_pnum, 1); in recover_peb()
576 ubi_free_vid_hdr(ubi, vid_hdr); in recover_peb()
597 int ubi_eba_write_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum, in ubi_eba_write_leb() argument
603 if (ubi->ro_mode) in ubi_eba_write_leb()
606 err = leb_write_lock(ubi, vol_id, lnum); in ubi_eba_write_leb()
615 err = ubi_io_write_data(ubi, buf, pnum, offset, len); in ubi_eba_write_leb()
618 if (err == -EIO && ubi->bad_allowed) in ubi_eba_write_leb()
619 err = recover_peb(ubi, pnum, vol_id, lnum, buf, in ubi_eba_write_leb()
622 ubi_ro_mode(ubi); in ubi_eba_write_leb()
624 leb_write_unlock(ubi, vol_id, lnum); in ubi_eba_write_leb()
632 vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); in ubi_eba_write_leb()
634 leb_write_unlock(ubi, vol_id, lnum); in ubi_eba_write_leb()
639 vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi)); in ubi_eba_write_leb()
642 vid_hdr->compat = ubi_get_compat(ubi, vol_id); in ubi_eba_write_leb()
646 pnum = ubi_wl_get_peb(ubi); in ubi_eba_write_leb()
648 ubi_free_vid_hdr(ubi, vid_hdr); in ubi_eba_write_leb()
649 leb_write_unlock(ubi, vol_id, lnum); in ubi_eba_write_leb()
656 err = ubi_io_write_vid_hdr(ubi, pnum, vid_hdr); in ubi_eba_write_leb()
664 err = ubi_io_write_data(ubi, buf, pnum, offset, len); in ubi_eba_write_leb()
672 down_read(&ubi->fm_sem); in ubi_eba_write_leb()
674 up_read(&ubi->fm_sem); in ubi_eba_write_leb()
676 leb_write_unlock(ubi, vol_id, lnum); in ubi_eba_write_leb()
677 ubi_free_vid_hdr(ubi, vid_hdr); in ubi_eba_write_leb()
681 if (err != -EIO || !ubi->bad_allowed) { in ubi_eba_write_leb()
682 ubi_ro_mode(ubi); in ubi_eba_write_leb()
683 leb_write_unlock(ubi, vol_id, lnum); in ubi_eba_write_leb()
684 ubi_free_vid_hdr(ubi, vid_hdr); in ubi_eba_write_leb()
693 err = ubi_wl_put_peb(ubi, vol_id, lnum, pnum, 1); in ubi_eba_write_leb()
695 ubi_ro_mode(ubi); in ubi_eba_write_leb()
696 leb_write_unlock(ubi, vol_id, lnum); in ubi_eba_write_leb()
697 ubi_free_vid_hdr(ubi, vid_hdr); in ubi_eba_write_leb()
701 vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi)); in ubi_eba_write_leb()
728 int ubi_eba_write_leb_st(struct ubi_device *ubi, struct ubi_volume *vol, in ubi_eba_write_leb_st() argument
735 if (ubi->ro_mode) in ubi_eba_write_leb_st()
740 len = ALIGN(data_size, ubi->min_io_size); in ubi_eba_write_leb_st()
742 ubi_assert(!(len & (ubi->min_io_size - 1))); in ubi_eba_write_leb_st()
744 vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); in ubi_eba_write_leb_st()
748 err = leb_write_lock(ubi, vol_id, lnum); in ubi_eba_write_leb_st()
750 ubi_free_vid_hdr(ubi, vid_hdr); in ubi_eba_write_leb_st()
754 vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi)); in ubi_eba_write_leb_st()
757 vid_hdr->compat = ubi_get_compat(ubi, vol_id); in ubi_eba_write_leb_st()
767 pnum = ubi_wl_get_peb(ubi); in ubi_eba_write_leb_st()
769 ubi_free_vid_hdr(ubi, vid_hdr); in ubi_eba_write_leb_st()
770 leb_write_unlock(ubi, vol_id, lnum); in ubi_eba_write_leb_st()
777 err = ubi_io_write_vid_hdr(ubi, pnum, vid_hdr); in ubi_eba_write_leb_st()
784 err = ubi_io_write_data(ubi, buf, pnum, 0, len); in ubi_eba_write_leb_st()
792 down_read(&ubi->fm_sem); in ubi_eba_write_leb_st()
794 up_read(&ubi->fm_sem); in ubi_eba_write_leb_st()
796 leb_write_unlock(ubi, vol_id, lnum); in ubi_eba_write_leb_st()
797 ubi_free_vid_hdr(ubi, vid_hdr); in ubi_eba_write_leb_st()
801 if (err != -EIO || !ubi->bad_allowed) { in ubi_eba_write_leb_st()
807 ubi_ro_mode(ubi); in ubi_eba_write_leb_st()
808 leb_write_unlock(ubi, vol_id, lnum); in ubi_eba_write_leb_st()
809 ubi_free_vid_hdr(ubi, vid_hdr); in ubi_eba_write_leb_st()
813 err = ubi_wl_put_peb(ubi, vol_id, lnum, pnum, 1); in ubi_eba_write_leb_st()
815 ubi_ro_mode(ubi); in ubi_eba_write_leb_st()
816 leb_write_unlock(ubi, vol_id, lnum); in ubi_eba_write_leb_st()
817 ubi_free_vid_hdr(ubi, vid_hdr); in ubi_eba_write_leb_st()
821 vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi)); in ubi_eba_write_leb_st()
843 int ubi_eba_atomic_leb_change(struct ubi_device *ubi, struct ubi_volume *vol, in ubi_eba_atomic_leb_change() argument
850 if (ubi->ro_mode) in ubi_eba_atomic_leb_change()
858 err = ubi_eba_unmap_leb(ubi, vol, lnum); in ubi_eba_atomic_leb_change()
861 return ubi_eba_write_leb(ubi, vol, lnum, NULL, 0, 0); in ubi_eba_atomic_leb_change()
864 vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); in ubi_eba_atomic_leb_change()
868 mutex_lock(&ubi->alc_mutex); in ubi_eba_atomic_leb_change()
869 err = leb_write_lock(ubi, vol_id, lnum); in ubi_eba_atomic_leb_change()
873 vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi)); in ubi_eba_atomic_leb_change()
876 vid_hdr->compat = ubi_get_compat(ubi, vol_id); in ubi_eba_atomic_leb_change()
886 pnum = ubi_wl_get_peb(ubi); in ubi_eba_atomic_leb_change()
895 err = ubi_io_write_vid_hdr(ubi, pnum, vid_hdr); in ubi_eba_atomic_leb_change()
902 err = ubi_io_write_data(ubi, buf, pnum, 0, len); in ubi_eba_atomic_leb_change()
910 err = ubi_wl_put_peb(ubi, vol_id, lnum, vol->eba_tbl[lnum], 0); in ubi_eba_atomic_leb_change()
915 down_read(&ubi->fm_sem); in ubi_eba_atomic_leb_change()
917 up_read(&ubi->fm_sem); in ubi_eba_atomic_leb_change()
920 leb_write_unlock(ubi, vol_id, lnum); in ubi_eba_atomic_leb_change()
922 mutex_unlock(&ubi->alc_mutex); in ubi_eba_atomic_leb_change()
923 ubi_free_vid_hdr(ubi, vid_hdr); in ubi_eba_atomic_leb_change()
927 if (err != -EIO || !ubi->bad_allowed) { in ubi_eba_atomic_leb_change()
933 ubi_ro_mode(ubi); in ubi_eba_atomic_leb_change()
937 err = ubi_wl_put_peb(ubi, vol_id, lnum, pnum, 1); in ubi_eba_atomic_leb_change()
939 ubi_ro_mode(ubi); in ubi_eba_atomic_leb_change()
943 vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi)); in ubi_eba_atomic_leb_change()
989 int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, in ubi_eba_copy_leb() argument
1003 aldata_size = ALIGN(data_size, ubi->min_io_size); in ubi_eba_copy_leb()
1006 ubi->leb_size - be32_to_cpu(vid_hdr->data_pad); in ubi_eba_copy_leb()
1008 idx = vol_id2idx(ubi, vol_id); in ubi_eba_copy_leb()
1009 spin_lock(&ubi->volumes_lock); in ubi_eba_copy_leb()
1016 vol = ubi->volumes[idx]; in ubi_eba_copy_leb()
1017 spin_unlock(&ubi->volumes_lock); in ubi_eba_copy_leb()
1039 err = leb_write_trylock(ubi, vol_id, lnum); in ubi_eba_copy_leb()
1063 mutex_lock(&ubi->buf_mutex); in ubi_eba_copy_leb()
1065 err = ubi_io_read_data(ubi, ubi->peb_buf, from, 0, aldata_size); in ubi_eba_copy_leb()
1085 ubi_calc_data_len(ubi, ubi->peb_buf, data_size); in ubi_eba_copy_leb()
1088 crc = crc32(UBI_CRC32_INIT, ubi->peb_buf, data_size); in ubi_eba_copy_leb()
1102 vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi)); in ubi_eba_copy_leb()
1104 err = ubi_io_write_vid_hdr(ubi, to, vid_hdr); in ubi_eba_copy_leb()
1114 err = ubi_io_read_vid_hdr(ubi, to, vid_hdr, 1); in ubi_eba_copy_leb()
1127 err = ubi_io_write_data(ubi, ubi->peb_buf, to, 0, aldata_size); in ubi_eba_copy_leb()
1140 memset(ubi->peb_buf, 0xFF, aldata_size); in ubi_eba_copy_leb()
1141 err = ubi_io_read_data(ubi, ubi->peb_buf, to, 0, aldata_size); in ubi_eba_copy_leb()
1155 if (crc != crc32(UBI_CRC32_INIT, ubi->peb_buf, data_size)) { in ubi_eba_copy_leb()
1164 down_read(&ubi->fm_sem); in ubi_eba_copy_leb()
1166 up_read(&ubi->fm_sem); in ubi_eba_copy_leb()
1169 mutex_unlock(&ubi->buf_mutex); in ubi_eba_copy_leb()
1171 leb_write_unlock(ubi, vol_id, lnum); in ubi_eba_copy_leb()
1193 static void print_rsvd_warning(struct ubi_device *ubi, in print_rsvd_warning() argument
1201 int min = ubi->beb_rsvd_level / 10; in print_rsvd_warning()
1205 if (ubi->beb_rsvd_pebs > min) in print_rsvd_warning()
1210 ubi->beb_rsvd_pebs, ubi->beb_rsvd_level); in print_rsvd_warning()
1211 if (ubi->corr_peb_count) in print_rsvd_warning()
1213 ubi->corr_peb_count); in print_rsvd_warning()
1226 int self_check_eba(struct ubi_device *ubi, struct ubi_attach_info *ai_fastmap, in self_check_eba() argument
1236 num_volumes = ubi->vtbl_slots + UBI_INT_VOL_COUNT; in self_check_eba()
1249 vol = ubi->volumes[i]; in self_check_eba()
1270 av = ubi_find_av(ai_scan, idx2vol_id(ubi, i)); in self_check_eba()
1277 av = ubi_find_av(ai_fastmap, idx2vol_id(ubi, i)); in self_check_eba()
1300 if (!ubi->volumes[i]) in self_check_eba()
1320 int ubi_eba_init(struct ubi_device *ubi, struct ubi_attach_info *ai) in ubi_eba_init() argument
1330 spin_lock_init(&ubi->ltree_lock); in ubi_eba_init()
1331 mutex_init(&ubi->alc_mutex); in ubi_eba_init()
1332 ubi->ltree = RB_ROOT; in ubi_eba_init()
1334 ubi->global_sqnum = ai->max_sqnum + 1; in ubi_eba_init()
1335 num_volumes = ubi->vtbl_slots + UBI_INT_VOL_COUNT; in ubi_eba_init()
1338 vol = ubi->volumes[i]; in ubi_eba_init()
1354 av = ubi_find_av(ai, idx2vol_id(ubi, i)); in ubi_eba_init()
1369 if (ubi->avail_pebs < EBA_RESERVED_PEBS) { in ubi_eba_init()
1371 ubi->avail_pebs, EBA_RESERVED_PEBS); in ubi_eba_init()
1372 if (ubi->corr_peb_count) in ubi_eba_init()
1374 ubi->corr_peb_count); in ubi_eba_init()
1378 ubi->avail_pebs -= EBA_RESERVED_PEBS; in ubi_eba_init()
1379 ubi->rsvd_pebs += EBA_RESERVED_PEBS; in ubi_eba_init()
1381 if (ubi->bad_allowed) { in ubi_eba_init()
1382 ubi_calculate_reserved(ubi); in ubi_eba_init()
1384 if (ubi->avail_pebs < ubi->beb_rsvd_level) { in ubi_eba_init()
1386 ubi->beb_rsvd_pebs = ubi->avail_pebs; in ubi_eba_init()
1387 print_rsvd_warning(ubi, ai); in ubi_eba_init()
1389 ubi->beb_rsvd_pebs = ubi->beb_rsvd_level; in ubi_eba_init()
1391 ubi->avail_pebs -= ubi->beb_rsvd_pebs; in ubi_eba_init()
1392 ubi->rsvd_pebs += ubi->beb_rsvd_pebs; in ubi_eba_init()
1400 if (!ubi->volumes[i]) in ubi_eba_init()
1402 kfree(ubi->volumes[i]->eba_tbl); in ubi_eba_init()
1403 ubi->volumes[i]->eba_tbl = NULL; in ubi_eba_init()