Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
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;
}
Ejemplo n.º 3
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);
}
Ejemplo n.º 4
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");
	/* 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);
}