コード例 #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;
}
コード例 #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;
}
コード例 #3
0
static int read_area(struct super_block *sb, struct logfs_je_area *a)
{
	struct logfs_super *super = logfs_super(sb);
	struct logfs_area *area = super->s_area[a->gc_level];
	u64 ofs;
	u32 writemask = ~(super->s_writesize - 1);

	if (a->gc_level >= LOGFS_NO_AREAS)
		return -EIO;
	if (a->vim != VIM_DEFAULT)
		return -EIO; /* TODO: close area and continue */

	area->a_used_bytes = be32_to_cpu(a->used_bytes);
	area->a_written_bytes = area->a_used_bytes & writemask;
	area->a_segno = be32_to_cpu(a->segno);
	if (area->a_segno)
		area->a_is_open = 1;

	ofs = dev_ofs(sb, area->a_segno, area->a_written_bytes);
	if (super->s_writesize > 1)
		logfs_buf_recover(area, ofs, a + 1, super->s_writesize);
	else
		logfs_buf_recover(area, ofs, NULL, 0);
	return 0;
}
コード例 #4
0
ファイル: segment.c プロジェクト: 12rafael/jellytimekernel
static s64 logfs_get_free_bytes(struct logfs_area *area, size_t bytes)
{
	s32 ofs;

	logfs_open_area(area, bytes);

	ofs = area->a_used_bytes;
	area->a_used_bytes += bytes;
	BUG_ON(area->a_used_bytes >= logfs_super(area->a_sb)->s_segsize);

	return dev_ofs(area->a_sb, area->a_segno, ofs);
}
コード例 #5
0
static int logfs_read_segment(struct super_block *sb, u32 segno)
{
	struct logfs_super *super = logfs_super(sb);
	struct logfs_journal_header *jh = super->s_compressed_je;
	u64 ofs, seg_ofs = dev_ofs(sb, segno, 0);
	u32 h_ofs, last_ofs = 0;
	u16 len, datalen, last_len = 0;
	int i, err;

	
	for (h_ofs = 0; h_ofs < super->s_segsize; h_ofs += sizeof(*jh)) {
		ofs = seg_ofs + h_ofs;
		err = __read_je_header(sb, ofs, jh);
		if (err)
			continue;
		if (jh->h_type != cpu_to_be16(JE_COMMIT))
			continue;
		err = __read_je_payload(sb, ofs, jh);
		if (err)
			continue;
		len = be16_to_cpu(jh->h_len);
		datalen = be16_to_cpu(jh->h_datalen);
		if ((datalen > sizeof(super->s_je_array)) ||
				(datalen % sizeof(__be64)))
			continue;
		last_ofs = h_ofs;
		last_len = datalen;
		h_ofs += ALIGN(len, sizeof(*jh)) - sizeof(*jh);
	}
	
	if (last_ofs == 0)
		return -ENOENT;
	ofs = seg_ofs + last_ofs;
	log_journal("Read commit from %llx\n", ofs);
	err = __read_je(sb, ofs, jh);
	BUG_ON(err); 
	if (err)
		return err;
	
	unpack(jh, super->s_je_array);
	super->s_no_je = last_len / sizeof(__be64);
	
	for (i = 0; i < super->s_no_je; i++) {
		err = read_je(sb, be64_to_cpu(super->s_je_array[i]));
		if (err)
			return err;
	}
	super->s_journal_area->a_segno = segno;
	return 0;
}
コード例 #6
0
static u64 read_gec(struct super_block *sb, u32 segno)
{
	struct logfs_segment_header sh;
	__be32 crc;
	int err;

	if (!segno)
		return 0;
	err = wbuf_read(sb, dev_ofs(sb, segno, 0), sizeof(sh), &sh);
	if (err)
		return 0;
	crc = logfs_crc32(&sh, sizeof(sh), 4);
	if (crc != sh.crc) {
		WARN_ON(sh.gec != cpu_to_be64(0xffffffffffffffffull));
		
		return 0;
	}
	return be64_to_cpu(sh.gec);
}
コード例 #7
0
static void write_wbuf(struct super_block *sb, struct logfs_area *area,
		void *wbuf)
{
	struct logfs_super *super = logfs_super(sb);
	struct address_space *mapping = super->s_mapping_inode->i_mapping;
	u64 ofs;
	pgoff_t index;
	int page_ofs;
	struct page *page;

	ofs = dev_ofs(sb, area->a_segno,
			area->a_used_bytes & ~(super->s_writesize - 1));
	index = ofs >> PAGE_SHIFT;
	page_ofs = ofs & (PAGE_SIZE - 1);

	page = find_lock_page(mapping, index);
	BUG_ON(!page);
	memcpy(wbuf, page_address(page) + page_ofs, super->s_writesize);
	unlock_page(page);
}
コード例 #8
0
static s64 logfs_get_free_bytes(struct logfs_area *area, size_t *bytes,
		int must_pad)
{
	u32 writesize = logfs_super(area->a_sb)->s_writesize;
	s32 ofs;
	int ret;

	ret = logfs_open_area(area, *bytes);
	if (ret)
		return -EAGAIN;

	ofs = area->a_used_bytes;
	area->a_used_bytes += *bytes;

	if (must_pad) {
		area->a_used_bytes = ALIGN(area->a_used_bytes, writesize);
		*bytes = area->a_used_bytes - ofs;
	}

	return dev_ofs(area->a_sb, area->a_segno, ofs);
}