/*
 * fs/logfs/journal.c	- journal handling code
 *
 * As should be obvious for Linux kernel code, license is GPLv2
 *
 * Copyright (c) 2005-2008 Joern Engel <joern@logfs.org>
 */
#include "logfs.h"

static void logfs_calc_free(struct super_block *sb)
{
	struct logfs_super *super = logfs_super(sb);
	u64 reserve, no_segs = super->s_no_segs;
	s64 free;
	int i;

	/* superblock segments */
	no_segs -= 2;
	super->s_no_journal_segs = 0;
	/* journal */
	journal_for_each(i)
		if (super->s_journal_seg[i]) {
			no_segs--;
			super->s_no_journal_segs++;
		}

	/* open segments plus one extra per level for GC */
	no_segs -= 2 * super->s_total_levels;

	free = no_segs * (super->s_segsize - LOGFS_SEGMENT_RESERVE);
	free -= super->s_used_bytes;
	/* just a bit extra */
	free -= super->s_total_levels * 4096;

	/* Bad blocks are 'paid' for with speed reserve - the filesystem
	 * simply gets slower as bad blocks accumulate.  Until the bad blocks
	 * exceed the speed reserve - then the filesystem gets smaller.
	 */
	reserve = super->s_bad_segments + super->s_bad_seg_reserve;
	reserve *= super->s_segsize - LOGFS_SEGMENT_RESERVE;
	reserve = max(reserve, super->s_speed_reserve);
	free -= reserve;
	if (free < 0)
		free = 0;

	super->s_free_bytes = free;
}

static void reserve_sb_and_journal(struct super_block *sb)
{
	struct logfs_super *super = logfs_super(sb);
	struct btree_head32 *head = &super->s_reserved_segments;
	int i, err;

	err = btree_insert32(head, seg_no(sb, super->s_sb_ofs[0]), (void *)1,
			GFP_KERNEL);
	BUG_ON(err);

	err = btree_insert32(head, seg_no(sb, super->s_sb_ofs[1]), (void *)1,
			GFP_KERNEL);
	BUG_ON(err);

	journal_for_each(i) {
		if (!super->s_journal_seg[i])
			continue;
		err = btree_insert32(head, super->s_journal_seg[i], (void *)1,
				GFP_KERNEL);
		BUG_ON(err);
	}
}

static void read_dynsb(struct super_block *sb,
		struct logfs_je_dynsb *dynsb)
{
	struct logfs_super *super = logfs_super(sb);

	super->s_gec		= be64_to_cpu(dynsb->ds_gec);
	super->s_sweeper	= be64_to_cpu(dynsb->ds_sweeper);
	super->s_victim_ino	= be64_to_cpu(dynsb->ds_victim_ino);
	super->s_rename_dir	= be64_to_cpu(dynsb->ds_rename_dir);
	super->s_rename_pos	= be64_to_cpu(dynsb->ds_rename_pos);
	super->s_used_bytes	= be64_to_cpu(dynsb->ds_used_bytes);
	super->s_generation	= be32_to_cpu(dynsb->ds_generation);
}

static void read_anchor(struct super_block *sb,
		struct logfs_je_anchor *da)
{
	struct logfs_super *super = logfs_super(sb);
	struct inode *inode = super->s_master_inode;
	struct logfs_inode *li = logfs_inode(inode);
	int i;

	super->s_last_ino = be64_to_cpu(da->da_last_ino);
	li->li_flags	= 0;
	li->li_height	= da->da_height;
	i_size_write(inode, be64_to_cpu(da->da_size));
	li->li_used_bytes = be64_to_cpu(da->da_used_bytes);

	for (i = 0; i < LOGFS_EMBEDDED_FIELDS; i++)
		li->li_data[i] = be64_to_cpu(da->da_data[i]);
}

static void read_erasecount(struct super_block *sb,
		struct logfs_je_journal_ec *ec)
{
	struct logfs_super *super = logfs_super(sb);
	int i;

	journal_for_each(i)
		super->s_journal_ec[i] = be32_to_cpu(ec->ec[i]);
}

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;
}

static void *unpack(void *from, void *to)
{
	struct logfs_journal_header *jh = from;
	void *data = from + sizeof(struct logfs_journal_header);
	int err;
	size_t inlen, outlen;

	inlen = be16_to_cpu(jh->h_len);
	outlen = be16_to_cpu(jh->h_datalen);

	if (jh->h_compr == COMPR_NONE)
		memcpy(to, data, inlen);
	else {
		err = logfs_uncompress(data, to, inlen, outlen);
		BUG_ON(err);
	}
	return to;
}

static int __read_je_header(struct super_block *sb, u64 ofs,
		struct logfs_journal_header *jh)
{
	struct logfs_super *super = logfs_super(sb);
	size_t bufsize = max_t(size_t, sb->s_blocksize, super->s_writesize)
		+ MAX_JOURNAL_HEADER;
	u16 type, len, datalen;
	int err;

	/* read header only */
	err = wbuf_read(sb, ofs, sizeof(*jh), jh);
	if (err)
		return err;
	type = be16_to_cpu(jh->h_type);
	len = be16_to_cpu(jh->h_len);
	datalen = be16_to_cpu(jh->h_datalen);
	if (len > sb->s_blocksize)
		return -EIO;
	if ((type < JE_FIRST) || (type > JE_LAST))
		return -EIO;
	if (datalen > bufsize)
		return -EIO;
	return 0;
}

static int __read_je_payload(struct super_block *sb, u64 ofs,
		struct logfs_journal_header *jh)
{
	u16 len;
	int err;

	len = be16_to_cpu(jh->h_len);
	err = wbuf_read(sb, ofs + sizeof(*jh), len, jh + 1);
	if (err)
		return err;
	if (jh->h_crc != logfs_crc32(jh, len + sizeof(*jh), 4)) {
		/* Old code was confused.  It forgot about the header length
		 * and stopped calculating the crc 16 bytes before the end
		 * of data - ick!
		 * FIXME: Remove this hack once the old code is fixed.
		 */
		if (jh->h_crc == logfs_crc32(jh, len, 4))
			WARN_ON_ONCE(1);
		else
			return -EIO;
	}
	return 0;
}

/*
 * jh needs to be large enough to hold the complete entry, not just the header
 */
static int __read_je(struct super_block *sb, u64 ofs,
		struct logfs_journal_header *jh)
{
	int err;

	err = __read_je_header(sb, ofs, jh);
	if (err)
		return err;
	return __read_je_payload(sb, ofs, jh);
}

static int read_je(struct super_block *sb, u64 ofs)
{
	struct logfs_super *super = logfs_super(sb);
	struct logfs_journal_header *jh = super->s_compressed_je;
	void *scratch = super->s_je;
	u16 type, datalen;
	int err;

	err = __read_je(sb, ofs, jh);
	if (err)
		return err;
	type = be16_to_cpu(jh->h_type);
	datalen = be16_to_cpu(jh->h_datalen);

	switch (type) {
	case JE_DYNSB:
		read_dynsb(sb, unpack(jh, scratch));
		break;
	case JE_ANCHOR:
		read_anchor(sb, unpack(jh, scratch));
		break;
	case JE_ERASECOUNT:
		read_erasecount(sb, unpack(jh, scratch));
		break;
	case JE_AREA:
		read_area(sb, unpack(jh, scratch));
		break;
	case JE_OBJ_ALIAS:
		err = logfs_load_object_aliases(sb, unpack(jh, scratch),
				datalen);
		break;
	default:
		WARN_ON_ONCE(1);
		return -EIO;
	}
	return err;
}

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;

	/* search for most recent commit */
	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);
	}
	/* read commit */
	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); /* We should have caught it in the scan loop already */
	if (err)
		return err;
	/* uncompress */
	unpack(jh, super->s_je_array);
	super->s_no_je = last_len / sizeof(__be64);
	/* iterate over array */
	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;
}

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));
		/* Most likely it was just erased */
		return 0;
	}
	return be64_to_cpu(sh.gec);
}

static int logfs_read_journal(struct super_block *sb)
{
	struct logfs_super *super = logfs_super(sb);
	u64 gec[LOGFS_JOURNAL_SEGS], max;
	u32 segno;
	int i, max_i;

	max = 0;
	max_i = -1;
	journal_for_each(i) {
		segno = super->s_journal_seg[i];
		gec[i] = read_gec(sb, super->s_journal_seg[i]);
		if (gec[i] > max) {
			max = gec[i];
			max_i = i;
		}
	}
	if (max_i == -1)
		return -EIO;
	/* FIXME: Try older segments in case of error */
	return logfs_read_segment(sb, super->s_journal_seg[max_i]);
}

/*
 * First search the current segment (outer loop), then pick the next segment
 * in the array, skipping any zero entries (inner loop).
 */
static void journal_get_free_segment(struct logfs_area *area)
{
	struct logfs_super *super = logfs_super(area->a_sb);
	int i;

	journal_for_each(i) {
		if (area->a_segno != super->s_journal_seg[i])
			continue;

		do {
			i++;
			if (i == LOGFS_JOURNAL_SEGS)
				i = 0;
		} while (!super->s_journal_seg[i]);

		area->a_segno = super->s_journal_seg[i];
		area->a_erase_count = ++(super->s_journal_ec[i]);
		log_journal("Journal now at %x (ec %x)\n", area->a_segno,
				area->a_erase_count);
		return;
	}
	BUG();
}

static void journal_get_erase_count(struct logfs_area *area)
{
	/* erase count is stored globally and incremented in
	 * journal_get_free_segment() - nothing to do here */
}

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);
	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;
}

static size_t __logfs_write_header(struct logfs_super *super,
		struct logfs_journal_header *jh, size_t len, size_t datalen,
		u16 type, u8 compr)
{
	jh->h_len	= cpu_to_be16(len);
	jh->h_type	= cpu_to_be16(type);
	jh->h_version	= cpu_to_be16(++super->s_last_version);
	jh->h_datalen	= cpu_to_be16(datalen);
	jh->h_compr	= compr;
	jh->h_pad[0]	= 'H';
	jh->h_pad[1]	= 'A';
	jh->h_pad[2]	= 'T';
	jh->h_crc	= logfs_crc32(jh, len + sizeof(*jh), 4);
	return ALIGN(len, 16) + sizeof(*jh);
}

static size_t logfs_write_header(struct logfs_super *super,
		struct logfs_journal_header *jh, size_t datalen, u16 type)
{
	size_t len = datalen;

	return __logfs_write_header(super, jh, len, datalen, type, COMPR_NONE);
}

static inline size_t logfs_journal_erasecount_size(struct logfs_super *super)
{
	return LOGFS_JOURNAL_SEGS * sizeof(__be32);
}

static void *logfs_write_erasecount(struct super_block *sb, void *_ec,
		u16 *type, size_t *len)
{
	struct logfs_super *super = logfs_super(sb);
	struct logfs_je_journal_ec *ec = _ec;
	int i;

	journal_for_each(i)
		ec->ec[i] = cpu_to_be32(super->s_journal_ec[i]);
	*type = JE_ERASECOUNT;
	*len = logfs_journal_erasecount_size(super);
	return ec;
}

static void account_shadow(void *_shadow, unsigned long _sb, u64 ignore,
		size_t ignore2)
{
	struct logfs_shadow *shadow = _shadow;
	struct super_block *sb = (void *)_sb;
	struct logfs_super *super = logfs_super(sb);

	/* consume new space */
	super->s_free_bytes	  -= shadow->new_len;
	super->s_used_bytes	  += shadow->new_len;
	super->s_dirty_used_bytes -= shadow->new_len;

	/* free up old space */
	super->s_free_bytes	  += shadow->old_len;
	super->s_used_bytes	  -= shadow->old_len;
	super->s_dirty_free_bytes -= shadow->old_len;

	logfs_set_segment_used(sb, shadow->old_ofs, -shadow->old_len);
	logfs_set_segment_used(sb, shadow->new_ofs, shadow->new_len);

	log_journal("account_shadow(%llx, %llx, %x) %llx->%llx %x->%x\n",
			shadow->ino, shadow->bix, shadow->gc_level,
			shadow->old_ofs, shadow->new_ofs,
			shadow->old_len, shadow->new_len);
	mempool_free(shadow, super->s_shadow_pool);
}

static void account_shadows(struct super_block *sb)
{
	struct logfs_super *super = logfs_super(sb);
	struct inode *inode = super->s_master_inode;
	struct logfs_inode *li = logfs_inode(inode);
	struct shadow_tree *tree = &super->s_shadow_tree;

	btree_grim_visitor64(&tree->new, (unsigned long)sb, account_shadow);
	btree_grim_visitor64(&tree->old, (unsigned long)sb, account_shadow);

	if (li->li_block) {
		/*
		 * We never actually use the structure, when attached to the
		 * master inode.  But it is easier to always free it here than
		 * to have checks in several places elsewhere when allocating
		 * it.
		 */
		li->li_block->ops->free_block(sb, li->li_block);
	}
	BUG_ON((s64)li->li_used_bytes < 0);
}

static void *__logfs_write_anchor(struct super_block *sb, void *_da,
		u16 *type, size_t *len)
{
	struct logfs_super *super = logfs_super(sb);
	struct logfs_je_anchor *da = _da;
	struct inode *inode = super->s_master_inode;
	struct logfs_inode *li = logfs_inode(inode);
	int i;

	da->da_height	= li->li_height;
	da->da_last_ino = cpu_to_be64(super->s_last_ino);
	da->da_size	= cpu_to_be64(i_size_read(inode));
	da->da_used_bytes = cpu_to_be64(li->li_used_bytes);
	for (i = 0; i < LOGFS_EMBEDDED_FIELDS; i++)
		da->da_data[i] = cpu_to_be64(li->li_data[i]);
	*type = JE_ANCHOR;
	*len = sizeof(*da);
	return da;
}

static void *logfs_write_dynsb(struct super_block *sb, void *_dynsb,
		u16 *type, size_t *len)
{
	struct logfs_super *super = logfs_super(sb);
	struct logfs_je_dynsb *dynsb = _dynsb;

	dynsb->ds_gec		= cpu_to_be64(super->s_gec);
	dynsb->ds_sweeper	= cpu_to_be64(super->s_sweeper);
	dynsb->ds_victim_ino	= cpu_to_be64(super->s_victim_ino);
	dynsb->ds_rename_dir	= cpu_to_be64(super->s_rename_dir);
	dynsb->ds_rename_pos	= cpu_to_be64(super->s_rename_pos);
	dynsb->ds_used_bytes	= cpu_to_be64(super->s_used_bytes);
	dynsb->ds_generation	= cpu_to_be32(super->s_generation);
	*type = JE_DYNSB;
	*len = sizeof(*dynsb);
	return dynsb;
}

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);
}

static void *logfs_write_area(struct super_block *sb, void *_a,
		u16 *type, size_t *len)
{
	struct logfs_super *super = logfs_super(sb);
	struct logfs_area *area = super->s_area[super->s_sum_index];
	struct logfs_je_area *a = _a;

	a->vim = VIM_DEFAULT;
	a->gc_level = super->s_sum_index;
	a->used_bytes = cpu_to_be32(area->a_used_bytes);
	a->segno = cpu_to_be32(area->a_segno);
	if (super->s_writesize > 1)
		write_wbuf(sb, area, a + 1);

	*type = JE_AREA;
	*len = sizeof(*a) + super->s_writesize;
	return a;
}

static void *logfs_write_commit(struct super_block *sb, void *h,
		u16 *type, size_t *len)
{
	struct logfs_super *super = logfs_super(sb);

	*type = JE_COMMIT;
	*len = super->s_no_je * sizeof(__be64);
	return super->s_je_array;
}

static size_t __logfs_write_je(struct super_block *sb, void *buf, u16 type,
		size_t len)
{
	struct logfs_super *super = logfs_super(sb);
	void *header = super->s_compressed_je;
	void *data = header + sizeof(struct logfs_journal_header);
	ssize_t compr_len, pad_len;
	u8 compr = COMPR_ZLIB;

	if (len == 0)
		return logfs_write_header(super, header, 0, type);

	compr_len = logfs_compress(buf, data, len, sb->s_blocksize);
	if (compr_len < 0 || type == JE_ANCHOR) {
		BUG_ON(len > sb->s_blocksize);
		memcpy(data, buf, len);
		compr_len = len;
		compr = COMPR_NONE;
	}

	pad_len = ALIGN(compr_len, 16);
	memset(data + compr_len, 0, pad_len - compr_len);

	return __logfs_write_header(super, header, compr_len, len, type, compr);
}

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);
}

static int logfs_write_je_buf(struct super_block *sb, void *buf, u16 type,
		size_t buf_len)
{
	struct logfs_super *super = logfs_super(sb);
	struct logfs_area *area = super->s_journal_area;
	struct logfs_journal_header *jh = super->s_compressed_je;
	size_t len;
	int must_pad = 0;
	s64 ofs;

	len = __logfs_write_je(sb, buf, type, buf_len);
	if (jh->h_type == cpu_to_be16(JE_COMMIT))
		must_pad = 1;

	ofs = logfs_get_free_bytes(area, &len, must_pad);
	if (ofs < 0)
		return ofs;
	logfs_buf_write(area, ofs, super->s_compressed_je, len);
	super->s_je_array[super->s_no_je++] = cpu_to_be64(ofs);
	return 0;
}

static int logfs_write_je(struct super_block *sb,
		void* (*write)(struct super_block *sb, void *scratch,
			u16 *type, size_t *len))
{
	void *buf;
	size_t len;
	u16 type;

	buf = write(sb, logfs_super(sb)->s_je, &type, &len);
	return logfs_write_je_buf(sb, buf, type, len);
}

int write_alias_journal(struct super_block *sb, u64 ino, u64 bix,
		level_t level, int child_no, __be64 val)
{
	struct logfs_super *super = logfs_super(sb);
	struct logfs_obj_alias *oa = super->s_je;
	int err = 0, fill = super->s_je_fill;

	log_aliases("logfs_write_obj_aliases #%x(%llx, %llx, %x, %x) %llx\n",
			fill, ino, bix, level, child_no, be64_to_cpu(val));
	oa[fill].ino = cpu_to_be64(ino);
	oa[fill].bix = cpu_to_be64(bix);
	oa[fill].val = val;
	oa[fill].level = (__force u8)level;
	oa[fill].child_no = cpu_to_be16(child_no);
	fill++;
	if (fill >= sb->s_blocksize / sizeof(*oa)) {
		err = logfs_write_je_buf(sb, oa, JE_OBJ_ALIAS, sb->s_blocksize);
		fill = 0;
	}

	super->s_je_fill = fill;
	return err;
}

static int logfs_write_obj_aliases(struct super_block *sb)
{
	struct logfs_super *super = logfs_super(sb);
	int err;

	log_journal("logfs_write_obj_aliases: %d aliases to write\n",
			super->s_no_object_aliases);
	super->s_je_fill = 0;
	err = logfs_write_obj_aliases_pagecache(sb);
	if (err)
		return err;

	if (super->s_je_fill)
		err = logfs_write_je_buf(sb, super->s_je, JE_OBJ_ALIAS,
				super->s_je_fill
				* sizeof(struct logfs_obj_alias));
	return err;
}

/*
 * Write all journal entries.  The goto logic ensures that all journal entries
 * are written whenever a new segment is used.  It is ugly and potentially a
 * bit wasteful, but robustness is more important.  With this we can *always*
 * erase all journal segments except the one containing the most recent commit.
 */
void logfs_write_anchor(struct inode *inode)
{
	struct super_block *sb = inode->i_sb;
	struct logfs_super *super = logfs_super(sb);
	struct logfs_area *area = super->s_journal_area;
	int i, err;

	BUG_ON(logfs_super(sb)->s_flags & LOGFS_SB_FLAG_SHUTDOWN);
	mutex_lock(&super->s_journal_mutex);

	/* Do this first or suffer corruption */
	logfs_sync_segments(sb);
	account_shadows(sb);

again:
	super->s_no_je = 0;
	for_each_area(i) {
		if (!super->s_area[i]->a_is_open)
			continue;
		super->s_sum_index = i;
		err = logfs_write_je(sb, logfs_write_area);
		if (err)
			goto again;
	}
	err = logfs_write_obj_aliases(sb);
	if (err)
		goto again;
	err = logfs_write_je(sb, logfs_write_erasecount);
	if (err)
		goto again;
	err = logfs_write_je(sb, __logfs_write_anchor);
	if (err)
		goto again;
	err = logfs_write_je(sb, logfs_write_dynsb);
	if (err)
		goto again;
	/*
	 * Order is imperative.  First we sync all writes, including the
	 * non-committed journal writes.  Then we write the final commit and
	 * sync the current journal segment.
	 * There is a theoretical bug here.  Syncing the journal segment will
	 * write a number of journal entries and the final commit.  All these
	 * are written in a single operation.  If the device layer writes the
	 * data back-to-front, the commit will precede the other journal
	 * entries, leaving a race window.
	 * Two fixes are possible.  Preferred is to fix the device layer to
	 * ensure writes happen front-to-back.  Alternatively we can insert
	 * another logfs_sync_area() super->s_devops->sync() combo before
	 * writing the commit.
	 */
	/*
	 * On another subject, super->s_devops->sync is usually not necessary.
	 * Unless called from sys_sync or friends, a barrier would suffice.
	 */
	super->s_devops->sync(sb);
	err = logfs_write_je(sb, logfs_write_commit);
	if (err)
		goto again;
	log_journal("Write commit to %llx\n",
			be64_to_cpu(super->s_je_array[super->s_no_je - 1]));
	logfs_sync_area(area);
	BUG_ON(area->a_used_bytes != area->a_written_bytes);
	super->s_devops->sync(sb);

	mutex_unlock(&super->s_journal_mutex);
	return;
}

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;
	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]) {
			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);
	}
	/* Manually move journal_area */
	area->a_segno = super->s_journal_seg[0];
	area->a_is_open = 0;
	area->a_used_bytes = 0;
	/* Write journal */
	logfs_write_anchor(super->s_master_inode);
	/* Write superblocks */
	err = logfs_write_sb(sb);
	BUG_ON(err);
}

static const struct logfs_area_ops journal_area_ops = {
	.get_free_segment	= journal_get_free_segment,
	.get_erase_count	= journal_get_erase_count,
	.erase_segment		= journal_erase_segment,
};

int logfs_init_journal(struct super_block *sb)
{
	struct logfs_super *super = logfs_super(sb);
	size_t bufsize = max_t(size_t, sb->s_blocksize, super->s_writesize)
		+ MAX_JOURNAL_HEADER;
	int ret = -ENOMEM;

	mutex_init(&super->s_journal_mutex);
	btree_init_mempool32(&super->s_reserved_segments, super->s_btree_pool);

	super->s_je = kzalloc(bufsize, GFP_KERNEL);
	if (!super->s_je)
		return ret;

	super->s_compressed_je = kzalloc(bufsize, GFP_KERNEL);
	if (!super->s_compressed_je)
		return ret;

	super->s_master_inode = logfs_new_meta_inode(sb, LOGFS_INO_MASTER);
	if (IS_ERR(super->s_master_inode))
		return PTR_ERR(super->s_master_inode);

	ret = logfs_read_journal(sb);
	if (ret)
		return -EIO;

	reserve_sb_and_journal(sb);
	logfs_calc_free(sb);

	super->s_journal_area->a_ops = &journal_area_ops;
	return 0;
}

void logfs_cleanup_journal(struct super_block *sb)
{
	struct logfs_super *super = logfs_super(sb);

	btree_grim_visitor32(&super->s_reserved_segments, 0, NULL);
	destroy_meta_inode(super->s_master_inode);
	super->s_master_inode = NULL;

	kfree(super->s_compressed_je);
	kfree(super->s_je);
}
