static int journal_erase_segment(struct logfs_area *area) { struct super_block *sb = area->a_sb; union { struct logfs_segment_header sh; unsigned char c[ALIGN(sizeof(struct logfs_segment_header), 16)]; } u; u64 ofs; int err; err = logfs_erase_segment(sb, area->a_segno, 1); if (err) return err; memset(&u, 0, sizeof(u)); u.sh.pad = 0; u.sh.type = SEG_JOURNAL; u.sh.level = 0; u.sh.segno = cpu_to_be32(area->a_segno); u.sh.ec = cpu_to_be32(area->a_erase_count); u.sh.gec = cpu_to_be64(logfs_super(sb)->s_gec); u.sh.crc = logfs_crc32(&u.sh, sizeof(u.sh), 4); ofs = dev_ofs(sb, area->a_segno, 0); area->a_used_bytes = sizeof(u); logfs_buf_write(area, ofs, &u, sizeof(u)); return 0; }
static int journal_erase_segment(struct logfs_area *area) { struct super_block *sb = area->a_sb; struct logfs_segment_header sh; u64 ofs; int err; err = logfs_erase_segment(sb, area->a_segno, 1); if (err) return err; sh.pad = 0; sh.type = SEG_JOURNAL; sh.level = 0; sh.segno = cpu_to_be32(area->a_segno); sh.ec = cpu_to_be32(area->a_erase_count); sh.gec = cpu_to_be64(logfs_super(sb)->s_gec); sh.crc = logfs_crc32(&sh, sizeof(sh), 4); /* This causes a bug in segment.c. Not yet. */ //logfs_set_segment_erased(sb, area->a_segno, area->a_erase_count, 0); ofs = dev_ofs(sb, area->a_segno, 0); area->a_used_bytes = ALIGN(sizeof(sh), 16); logfs_buf_write(area, ofs, &sh, sizeof(sh)); return 0; }
void do_logfs_journal_wl_pass(struct super_block *sb) { struct logfs_super *super = logfs_super(sb); struct logfs_area *area = super->s_journal_area; struct btree_head32 *head = &super->s_reserved_segments; u32 segno, ec; int i, err; log_journal("Journal requires wear-leveling.\n"); journal_for_each(i) if (super->s_journal_seg[i]) { btree_remove32(head, super->s_journal_seg[i]); logfs_set_segment_unreserved(sb, super->s_journal_seg[i], super->s_journal_ec[i]); super->s_journal_seg[i] = 0; super->s_journal_ec[i] = 0; } for (i = 0; i < super->s_no_journal_segs; i++) { segno = get_best_cand(sb, &super->s_reserve_list, &ec); super->s_journal_seg[i] = segno; super->s_journal_ec[i] = ec; logfs_set_segment_reserved(sb, segno); err = btree_insert32(head, segno, (void *)1, GFP_NOFS); BUG_ON(err); err = logfs_erase_segment(sb, segno, 1); BUG_ON(err); } freeseg(sb, area->a_segno); area->a_segno = super->s_journal_seg[0]; area->a_is_open = 0; area->a_used_bytes = 0; logfs_write_anchor(sb); err = logfs_write_sb(sb); BUG_ON(err); }
void do_logfs_journal_wl_pass(struct super_block *sb) { struct logfs_super *super = logfs_super(sb); struct logfs_area *area = super->s_journal_area; struct btree_head32 *head = &super->s_reserved_segments; u32 segno, ec; int i, err; log_journal("Journal requires wear-leveling.\n"); /* Drop old segments */ journal_for_each(i) if (super->s_journal_seg[i]) { btree_remove32(head, super->s_journal_seg[i]); logfs_set_segment_unreserved(sb, super->s_journal_seg[i], super->s_journal_ec[i]); super->s_journal_seg[i] = 0; super->s_journal_ec[i] = 0; } /* Get new segments */ for (i = 0; i < super->s_no_journal_segs; i++) { segno = get_best_cand(sb, &super->s_reserve_list, &ec); super->s_journal_seg[i] = segno; super->s_journal_ec[i] = ec; logfs_set_segment_reserved(sb, segno); err = btree_insert32(head, segno, (void *)1, GFP_KERNEL); BUG_ON(err); /* mempool should prevent this */ err = logfs_erase_segment(sb, segno, 1); BUG_ON(err); /* FIXME: remount-ro would be nicer */ } /* Manually move journal_area */ freeseg(sb, area->a_segno); area->a_segno = super->s_journal_seg[0]; area->a_is_open = 0; area->a_used_bytes = 0; /* Write journal */ logfs_write_anchor(sb); /* Write superblocks */ err = logfs_write_sb(sb); BUG_ON(err); }