Lines Matching refs:line
18 * following the line sequence ID.
38 static int pblk_recov_l2p_from_emeta(struct pblk *pblk, struct pblk_line *line)
43 struct pblk_emeta *emeta = line->emeta;
54 data_start = pblk_line_smeta_start(pblk, line) + lm->smeta_sec;
55 data_end = line->emeta_ssec;
62 ppa = addr_to_gen_ppa(pblk, i, line->id);
66 if (test_bit(pos, line->blk_bitmap))
70 spin_lock(&line->lock);
71 if (test_and_set_bit(i, line->invalid_bitmap))
74 le32_add_cpu(line->vsc, -1);
75 spin_unlock(&line->lock);
85 pblk_err(pblk, "line %d - inconsistent lba list(%llu/%llu)\n",
86 line->id, nr_valid_lbas, nr_lbas);
88 line->left_msecs = 0;
93 static void pblk_update_line_wp(struct pblk *pblk, struct pblk_line *line,
100 __pblk_alloc_page(pblk, line, pblk->min_write_pgs);
103 if (written_secs > line->left_msecs) {
108 line->left_msecs = 0;
111 line->left_msecs -= written_secs;
116 static u64 pblk_sec_in_open_line(struct pblk *pblk, struct pblk_line *line)
119 int nr_bb = bitmap_weight(line->blk_bitmap, lm->blk_per_line);
125 struct nvm_chk_meta *chunk = &line->chks[i];
135 pblk_err(pblk, "recovery line %d is bad\n", line->id);
137 pblk_update_line_wp(pblk, line, written_secs - lm->smeta_sec);
172 /* pad line using line bitmap. */
173 static int pblk_recov_pad_line(struct pblk *pblk, struct pblk_line *line,
183 __le64 *lba_list = emeta_to_lbas(pblk, line->emeta->buf);
184 u64 w_ptr = line->cur_sec;
189 spin_lock(&line->lock);
190 left_line_ppas = line->left_msecs;
191 spin_unlock(&line->lock);
210 pblk_err(pblk, "corrupted pad line %d\n", line->id);
236 w_ptr = pblk_alloc_page(pblk, line, pblk->min_write_pgs);
237 ppa = addr_to_gen_ppa(pblk, w_ptr, line->id);
240 while (test_bit(pos, line->blk_bitmap)) {
242 ppa = addr_to_gen_ppa(pblk, w_ptr, line->id);
251 dev_ppa = addr_to_gen_ppa(pblk, w_ptr, line->id);
282 if (!pblk_line_is_full(line))
283 pblk_err(pblk, "corrupted padded line: %d\n", line->id);
291 static int pblk_pad_distance(struct pblk *pblk, struct pblk_line *line)
297 return (distance > line->left_msecs) ? line->left_msecs : distance;
300 /* Return a chunk belonging to a line by stripe(write order) index */
302 struct pblk_line *line,
315 return &line->chks[pos];
319 struct pblk_line *line)
327 i = find_first_zero_bit(line->blk_bitmap, blk_in_line);
329 /* If there is one or zero good chunks in the line,
335 chunk = pblk_get_stripe_chunk(pblk, line, i);
342 i = find_next_zero_bit(line->blk_bitmap, blk_in_line, i + 1);
344 chunk = pblk_get_stripe_chunk(pblk, line, i);
348 i = find_next_zero_bit(line->blk_bitmap, blk_in_line, i + 1);
354 static int pblk_recov_scan_oob(struct pblk *pblk, struct pblk_line *line,
366 u64 paddr = pblk_line_smeta_start(pblk, line) + lm->smeta_sec;
371 u64 left_ppas = pblk_sec_in_open_line(pblk, line) - lm->smeta_sec;
373 if (pblk_line_wps_are_unbalanced(pblk, line))
374 pblk_warn(pblk, "recovering unbalanced line (%d)\n", line->id);
383 lba_list = emeta_to_lbas(pblk, line->emeta->buf);
409 ppa = addr_to_gen_ppa(pblk, paddr, line->id);
412 while (test_bit(pos, line->blk_bitmap)) {
414 ppa = addr_to_gen_ppa(pblk, paddr, line->id);
420 addr_to_gen_ppa(pblk, paddr + j, line->id);
431 /* If a read fails, do a best effort by padding the line and retrying */
440 pad_distance = pblk_pad_distance(pblk, line);
441 ret = pblk_recov_pad_line(pblk, line, pad_distance);
461 line->nr_valid_lbas++;
470 WARN_ON(padded && !pblk_line_is_full(line));
476 /* Scan line for lbas on out of bound area */
477 static int pblk_recov_l2p_from_oob(struct pblk *pblk, struct pblk_line *line)
512 ret = pblk_recov_scan_oob(pblk, line, p);
518 if (pblk_line_is_full(line))
519 pblk_line_recov_close(pblk, line);
532 struct pblk_line *line)
537 if (t->seq_nr > line->seq_nr)
540 __list_add(&line->list, t->list.prev, &t->list);
543 static u64 pblk_line_emeta_start(struct pblk *pblk, struct pblk_line *line)
558 ppa = addr_to_gen_ppa(pblk, emeta_start, line->id);
560 if (!test_bit(pos, line->blk_bitmap))
573 pblk_err(pblk, "line major version mismatch: %d, expected: %d\n",
580 pblk_info(pblk, "newer line minor version found: %d\n",
610 static int pblk_line_was_written(struct pblk_line *line,
621 if (line->state == PBLK_LINESTATE_BAD)
624 smeta_blk = find_first_zero_bit(line->blk_bitmap, lm->blk_per_line);
629 chunk = &line->chks[pblk_ppa_to_pos(geo, bppa)];
639 static bool pblk_line_is_open(struct pblk *pblk, struct pblk_line *line)
645 if (line->chks[i].state & NVM_CHK_ST_OPEN)
655 struct pblk_line *line, *tline, *data_line = NULL;
680 line = &pblk->lines[i];
683 line->smeta = smeta;
684 line->lun_bitmap = ((void *)(smeta_buf)) +
687 if (!pblk_line_was_written(line, pblk))
691 if (pblk_line_smeta_read(pblk, line))
702 pblk_err(pblk, "found incompatible line version %u\n",
716 pblk_debug(pblk, "ignore line %u due to uuid mismatch\n",
721 /* Update line metadata */
722 spin_lock(&line->lock);
723 line->id = le32_to_cpu(smeta_buf->header.id);
724 line->type = le16_to_cpu(smeta_buf->header.type);
725 line->seq_nr = le64_to_cpu(smeta_buf->seq_nr);
726 spin_unlock(&line->lock);
730 if (line->seq_nr >= l_mg->d_seq_nr)
731 l_mg->d_seq_nr = line->seq_nr + 1;
735 if (pblk_line_recov_alloc(pblk, line))
738 pblk_recov_line_add_ordered(&recov_list, line);
740 pblk_debug(pblk, "recovering data line %d, seq:%llu\n",
741 line->id, smeta_buf->seq_nr);
756 list_for_each_entry_safe(line, tline, &recov_list, list) {
759 line->emeta_ssec = pblk_line_emeta_start(pblk, line);
760 line->emeta = emeta;
761 memset(line->emeta->buf, 0, lm->emeta_len[0]);
763 if (pblk_line_is_open(pblk, line)) {
764 pblk_recov_l2p_from_oob(pblk, line);
768 if (pblk_line_emeta_read(pblk, line, line->emeta->buf)) {
769 pblk_recov_l2p_from_oob(pblk, line);
773 if (pblk_recov_check_emeta(pblk, line->emeta->buf)) {
774 pblk_recov_l2p_from_oob(pblk, line);
778 if (pblk_recov_check_line_version(pblk, line->emeta->buf))
781 pblk_recov_wa_counters(pblk, line->emeta->buf);
783 if (pblk_recov_l2p_from_emeta(pblk, line))
784 pblk_recov_l2p_from_oob(pblk, line);
787 if (pblk_line_is_full(line)) {
790 spin_lock(&line->lock);
791 line->state = PBLK_LINESTATE_CLOSED;
792 trace_pblk_line_state(pblk_disk_name(pblk), line->id,
793 line->state);
794 move_list = pblk_line_gc_list(pblk, line);
795 spin_unlock(&line->lock);
798 list_move_tail(&line->list, move_list);
801 mempool_free(line->map_bitmap, l_mg->bitmap_pool);
802 line->map_bitmap = NULL;
803 line->smeta = NULL;
804 line->emeta = NULL;
806 spin_lock(&line->lock);
807 line->state = PBLK_LINESTATE_OPEN;
808 spin_unlock(&line->lock);
810 line->emeta->mem = 0;
811 atomic_set(&line->emeta->sync, 0);
813 trace_pblk_line_state(pblk_disk_name(pblk), line->id,
814 line->state);
816 data_line = line;
817 line->meta_line = meta_line;
831 /* Allocate next line for preparation */
853 * Pad current line
857 struct pblk_line *line;
863 line = l_mg->data_line;
864 left_msecs = line->left_msecs;
867 ret = pblk_recov_pad_line(pblk, line, left_msecs);
873 pblk_line_close_meta(pblk, line);