/*
 * fs/logfs/segment.c	- Handling the Object Store
 *
 * As should be obvious for Linux kernel code, license is GPLv2
 *
 * Copyright (c) 2005-2008 Joern Engel <joern@logfs.org>
 *
 * Object store or ostore makes up the complete device with exception of
 * the superblock and journal areas.  Apart from its own metadata it stores
 * three kinds of objects: inodes, dentries and blocks, both data and indirect.
 */
#include "logfs.h"
#include <linux/slab.h>

static int logfs_mark_segment_bad(struct super_block *sb, u32 segno)
{
	struct logfs_super *super = logfs_super(sb);
	struct btree_head32 *head = &super->s_reserved_segments;
	int err;

	err = btree_insert32(head, segno, (void *)1, GFP_NOFS);
	if (err)
		return err;
	logfs_super(sb)->s_bad_segments++;
	/* FIXME: write to journal */
	return 0;
}

int logfs_erase_segment(struct super_block *sb, u32 segno, int ensure_erase)
{
	struct logfs_super *super = logfs_super(sb);

	super->s_gec++;

	return super->s_devops->erase(sb, (u64)segno << super->s_segshift,
			super->s_segsize, ensure_erase);
}

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

static struct page *get_mapping_page(struct super_block *sb, pgoff_t index,
		int use_filler)
{
	struct logfs_super *super = logfs_super(sb);
	struct address_space *mapping = super->s_mapping_inode->i_mapping;
	filler_t *filler = super->s_devops->readpage;
	struct page *page;

	BUG_ON(mapping_gfp_constraint(mapping, __GFP_FS));
	if (use_filler)
		page = read_cache_page(mapping, index, filler, sb);
	else {
		page = find_or_create_page(mapping, index, GFP_NOFS);
		if (page)
			unlock_page(page);
	}
	return page;
}

int __logfs_buf_write(struct logfs_area *area, u64 ofs, void *buf, size_t len,
		int use_filler)
{
	pgoff_t index = ofs >> PAGE_SHIFT;
	struct page *page;
	long offset = ofs & (PAGE_SIZE-1);
	long copylen;

	/* Only logfs_wbuf_recover may use len==0 */
	BUG_ON(!len && !use_filler);
	do {
		copylen = min((ulong)len, PAGE_SIZE - offset);

		page = get_mapping_page(area->a_sb, index, use_filler);
		if (IS_ERR(page))
			return PTR_ERR(page);
		BUG_ON(!page); /* FIXME: reserve a pool */
		SetPageUptodate(page);
		memcpy(page_address(page) + offset, buf, copylen);

		if (!PagePrivate(page)) {
			SetPagePrivate(page);
			get_page(page);
		}
		put_page(page);

		buf += copylen;
		len -= copylen;
		offset = 0;
		index++;
	} while (len);
	return 0;
}

static void pad_partial_page(struct logfs_area *area)
{
	struct super_block *sb = area->a_sb;
	struct page *page;
	u64 ofs = dev_ofs(sb, area->a_segno, area->a_used_bytes);
	pgoff_t index = ofs >> PAGE_SHIFT;
	long offset = ofs & (PAGE_SIZE-1);
	u32 len = PAGE_SIZE - offset;

	if (len % PAGE_SIZE) {
		page = get_mapping_page(sb, index, 0);
		BUG_ON(!page); /* FIXME: reserve a pool */
		memset(page_address(page) + offset, 0xff, len);
		if (!PagePrivate(page)) {
			SetPagePrivate(page);
			get_page(page);
		}
		put_page(page);
	}
}

static void pad_full_pages(struct logfs_area *area)
{
	struct super_block *sb = area->a_sb;
	struct logfs_super *super = logfs_super(sb);
	u64 ofs = dev_ofs(sb, area->a_segno, area->a_used_bytes);
	u32 len = super->s_segsize - area->a_used_bytes;
	pgoff_t index = PAGE_ALIGN(ofs) >> PAGE_SHIFT;
	pgoff_t no_indizes = len >> PAGE_SHIFT;
	struct page *page;

	while (no_indizes) {
		page = get_mapping_page(sb, index, 0);
		BUG_ON(!page); /* FIXME: reserve a pool */
		SetPageUptodate(page);
		memset(page_address(page), 0xff, PAGE_SIZE);
		if (!PagePrivate(page)) {
			SetPagePrivate(page);
			get_page(page);
		}
		put_page(page);
		index++;
		no_indizes--;
	}
}

/*
 * bdev_writeseg will write full pages.  Memset the tail to prevent data leaks.
 * Also make sure we allocate (and memset) all pages for final writeout.
 */
static void pad_wbuf(struct logfs_area *area, int final)
{
	pad_partial_page(area);
	if (final)
		pad_full_pages(area);
}

/*
 * We have to be careful with the alias tree.  Since lookup is done by bix,
 * it needs to be normalized, so 14, 15, 16, etc. all match when dealing with
 * indirect blocks.  So always use it through accessor functions.
 */
static void *alias_tree_lookup(struct super_block *sb, u64 ino, u64 bix,
		level_t level)
{
	struct btree_head128 *head = &logfs_super(sb)->s_object_alias_tree;
	pgoff_t index = logfs_pack_index(bix, level);

	return btree_lookup128(head, ino, index);
}

static int alias_tree_insert(struct super_block *sb, u64 ino, u64 bix,
		level_t level, void *val)
{
	struct btree_head128 *head = &logfs_super(sb)->s_object_alias_tree;
	pgoff_t index = logfs_pack_index(bix, level);

	return btree_insert128(head, ino, index, val, GFP_NOFS);
}

static int btree_write_alias(struct super_block *sb, struct logfs_block *block,
		write_alias_t *write_one_alias)
{
	struct object_alias_item *item;
	int err;

	list_for_each_entry(item, &block->item_list, list) {
		err = write_alias_journal(sb, block->ino, block->bix,
				block->level, item->child_no, item->val);
		if (err)
			return err;
	}
	return 0;
}

static const struct logfs_block_ops btree_block_ops = {
	.write_block	= btree_write_block,
	.free_block	= __free_block,
	.write_alias	= btree_write_alias,
};

int logfs_load_object_aliases(struct super_block *sb,
		struct logfs_obj_alias *oa, int count)
{
	struct logfs_super *super = logfs_super(sb);
	struct logfs_block *block;
	struct object_alias_item *item;
	u64 ino, bix;
	level_t level;
	int i, err;

	super->s_flags |= LOGFS_SB_FLAG_OBJ_ALIAS;
	count /= sizeof(*oa);
	for (i = 0; i < count; i++) {
		item = mempool_alloc(super->s_alias_pool, GFP_NOFS);
		if (!item)
			return -ENOMEM;
		memset(item, 0, sizeof(*item));

		super->s_no_object_aliases++;
		item->val = oa[i].val;
		item->child_no = be16_to_cpu(oa[i].child_no);

		ino = be64_to_cpu(oa[i].ino);
		bix = be64_to_cpu(oa[i].bix);
		level = LEVEL(oa[i].level);

		log_aliases("logfs_load_object_aliases(%llx, %llx, %x, %x) %llx\n",
				ino, bix, level, item->child_no,
				be64_to_cpu(item->val));
		block = alias_tree_lookup(sb, ino, bix, level);
		if (!block) {
			block = __alloc_block(sb, ino, bix, level);
			block->ops = &btree_block_ops;
			err = alias_tree_insert(sb, ino, bix, level, block);
			BUG_ON(err); /* mempool empty */
		}
		if (test_and_set_bit(item->child_no, block->alias_map)) {
			printk(KERN_ERR"LogFS: Alias collision detected\n");
			return -EIO;
		}
		list_move_tail(&block->alias_list, &super->s_object_alias);
		list_add(&item->list, &block->item_list);
	}
	return 0;
}

static void kill_alias(void *_block, unsigned long ignore0,
		u64 ignore1, u64 ignore2, size_t ignore3)
{
	struct logfs_block *block = _block;
	struct super_block *sb = block->sb;
	struct logfs_super *super = logfs_super(sb);
	struct object_alias_item *item;

	while (!list_empty(&block->item_list)) {
		item = list_entry(block->item_list.next, typeof(*item), list);
		list_del(&item->list);
		mempool_free(item, super->s_alias_pool);
	}
	block->ops->free_block(sb, block);
}

static int obj_type(struct inode *inode, level_t level)
{
	if (level == 0) {
		if (S_ISDIR(inode->i_mode))
			return OBJ_DENTRY;
		if (inode->i_ino == LOGFS_INO_MASTER)
			return OBJ_INODE;
	}
	return OBJ_BLOCK;
}

static int obj_len(struct super_block *sb, int obj_type)
{
	switch (obj_type) {
	case OBJ_DENTRY:
		return sizeof(struct logfs_disk_dentry);
	case OBJ_INODE:
		return sizeof(struct logfs_disk_inode);
	case OBJ_BLOCK:
		return sb->s_blocksize;
	default:
		BUG();
	}
}

static int __logfs_segment_write(struct inode *inode, void *buf,
		struct logfs_shadow *shadow, int type, int len, int compr)
{
	struct logfs_area *area;
	struct super_block *sb = inode->i_sb;
	s64 ofs;
	struct logfs_object_header h;
	int acc_len;

	if (shadow->gc_level == 0)
		acc_len = len;
	else
		acc_len = obj_len(sb, type);

	area = get_area(sb, shadow->gc_level);
	ofs = logfs_get_free_bytes(area, len + LOGFS_OBJECT_HEADERSIZE);
	LOGFS_BUG_ON(ofs <= 0, sb);
	/*
	 * Order is important.  logfs_get_free_bytes(), by modifying the
	 * segment file, may modify the content of the very page we're about
	 * to write now.  Which is fine, as long as the calculated crc and
	 * written data still match.  So do the modifications _before_
	 * calculating the crc.
	 */

	h.len	= cpu_to_be16(len);
	h.type	= type;
	h.compr	= compr;
	h.ino	= cpu_to_be64(inode->i_ino);
	h.bix	= cpu_to_be64(shadow->bix);
	h.crc	= logfs_crc32(&h, sizeof(h) - 4, 4);
	h.data_crc = logfs_crc32(buf, len, 0);

	logfs_buf_write(area, ofs, &h, sizeof(h));
	logfs_buf_write(area, ofs + LOGFS_OBJECT_HEADERSIZE, buf, len);

	shadow->new_ofs = ofs;
	shadow->new_len = acc_len + LOGFS_OBJECT_HEADERSIZE;

	return 0;
}

static s64 logfs_segment_write_compress(struct inode *inode, void *buf,
		struct logfs_shadow *shadow, int type, int len)
{
	struct super_block *sb = inode->i_sb;
	void *compressor_buf = logfs_super(sb)->s_compressed_je;
	ssize_t compr_len;
	int ret;

	mutex_lock(&logfs_super(sb)->s_journal_mutex);
	compr_len = logfs_compress(buf, compressor_buf, len, len);

	if (compr_len >= 0) {
		ret = __logfs_segment_write(inode, compressor_buf, shadow,
				type, compr_len, COMPR_ZLIB);
	} else {
		ret = __logfs_segment_write(inode, buf, shadow, type, len,
				COMPR_NONE);
	}
	mutex_unlock(&logfs_super(sb)->s_journal_mutex);
	return ret;
}

/**
 * logfs_segment_write - write data block to object store
 * @inode:		inode containing data
 *
 * Returns an errno or zero.
 */
int logfs_segment_write(struct inode *inode, struct page *page,
		struct logfs_shadow *shadow)
{
	struct super_block *sb = inode->i_sb;
	struct logfs_super *super = logfs_super(sb);
	int do_compress, type, len;
	int ret;
	void *buf;

	super->s_flags |= LOGFS_SB_FLAG_DIRTY;
	BUG_ON(super->s_flags & LOGFS_SB_FLAG_SHUTDOWN);
	do_compress = logfs_inode(inode)->li_flags & LOGFS_IF_COMPRESSED;
	if (shadow->gc_level != 0) {
		/* temporarily disable compression for indirect blocks */
		do_compress = 0;
	}

	type = obj_type(inode, shrink_level(shadow->gc_level));
	len = obj_len(sb, type);
	buf = kmap(page);
	if (do_compress)
		ret = logfs_segment_write_compress(inode, buf, shadow, type,
				len);
	else
		ret = __logfs_segment_write(inode, buf, shadow, type, len,
				COMPR_NONE);
	kunmap(page);

	log_segment("logfs_segment_write(%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);
	/* this BUG_ON did catch a locking bug.  useful */
	BUG_ON(!(shadow->new_ofs & (super->s_segsize - 1)));
	return ret;
}

int wbuf_read(struct super_block *sb, u64 ofs, size_t len, void *buf)
{
	pgoff_t index = ofs >> PAGE_SHIFT;
	struct page *page;
	long offset = ofs & (PAGE_SIZE-1);
	long copylen;

	while (len) {
		copylen = min((ulong)len, PAGE_SIZE - offset);

		page = get_mapping_page(sb, index, 1);
		if (IS_ERR(page))
			return PTR_ERR(page);
		memcpy(buf, page_address(page) + offset, copylen);
		put_page(page);

		buf += copylen;
		len -= copylen;
		offset = 0;
		index++;
	}
	return 0;
}

/*
 * The "position" of indirect blocks is ambiguous.  It can be the position
 * of any data block somewhere behind this indirect block.  So we need to
 * normalize the positions through logfs_block_mask() before comparing.
 */
static int check_pos(struct super_block *sb, u64 pos1, u64 pos2, level_t level)
{
	return	(pos1 & logfs_block_mask(sb, level)) !=
		(pos2 & logfs_block_mask(sb, level));
}

#if 0
static int read_seg_header(struct super_block *sb, u64 ofs,
		struct logfs_segment_header *sh)
{
	__be32 crc;
	int err;

	err = wbuf_read(sb, ofs, sizeof(*sh), sh);
	if (err)
		return err;
	crc = logfs_crc32(sh, sizeof(*sh), 4);
	if (crc != sh->crc) {
		printk(KERN_ERR"LOGFS: header crc error at %llx: expected %x, "
				"got %x\n", ofs, be32_to_cpu(sh->crc),
				be32_to_cpu(crc));
		return -EIO;
	}
	return 0;
}
#endif

static int read_obj_header(struct super_block *sb, u64 ofs,
		struct logfs_object_header *oh)
{
	__be32 crc;
	int err;

	err = wbuf_read(sb, ofs, sizeof(*oh), oh);
	if (err)
		return err;
	crc = logfs_crc32(oh, sizeof(*oh) - 4, 4);
	if (crc != oh->crc) {
		printk(KERN_ERR"LOGFS: header crc error at %llx: expected %x, "
				"got %x\n", ofs, be32_to_cpu(oh->crc),
				be32_to_cpu(crc));
		return -EIO;
	}
	return 0;
}

static void move_btree_to_page(struct inode *inode, struct page *page,
		__be64 *data)
{
	struct super_block *sb = inode->i_sb;
	struct logfs_super *super = logfs_super(sb);
	struct btree_head128 *head = &super->s_object_alias_tree;
	struct logfs_block *block;
	struct object_alias_item *item, *next;

	if (!(super->s_flags & LOGFS_SB_FLAG_OBJ_ALIAS))
		return;

	block = btree_remove128(head, inode->i_ino, page->index);
	if (!block)
		return;

	log_blockmove("move_btree_to_page(%llx, %llx, %x)\n",
			block->ino, block->bix, block->level);
	list_for_each_entry_safe(item, next, &block->item_list, list) {
		data[item->child_no] = item->val;
		list_del(&item->list);
		mempool_free(item, super->s_alias_pool);
	}
	block->page = page;

	if (!PagePrivate(page)) {
		SetPagePrivate(page);
		get_page(page);
		set_page_private(page, (unsigned long) block);
	}
	block->ops = &indirect_block_ops;
	initialize_block_counters(page, block, data, 0);
}

/*
 * This silences a false, yet annoying gcc warning.  I hate it when my editor
 * jumps into bitops.h each time I recompile this file.
 * TODO: Complain to gcc folks about this and upgrade compiler.
 */
static unsigned long fnb(const unsigned long *addr,
		unsigned long size, unsigned long offset)
{
	return find_next_bit(addr, size, offset);
}

void move_page_to_btree(struct page *page)
{
	struct logfs_block *block = logfs_block(page);
	struct super_block *sb = block->sb;
	struct logfs_super *super = logfs_super(sb);
	struct object_alias_item *item;
	unsigned long pos;
	__be64 *child;
	int err;

	if (super->s_flags & LOGFS_SB_FLAG_SHUTDOWN) {
		block->ops->free_block(sb, block);
		return;
	}
	log_blockmove("move_page_to_btree(%llx, %llx, %x)\n",
			block->ino, block->bix, block->level);
	super->s_flags |= LOGFS_SB_FLAG_OBJ_ALIAS;

	for (pos = 0; ; pos++) {
		pos = fnb(block->alias_map, LOGFS_BLOCK_FACTOR, pos);
		if (pos >= LOGFS_BLOCK_FACTOR)
			break;

		item = mempool_alloc(super->s_alias_pool, GFP_NOFS);
		BUG_ON(!item); /* mempool empty */
		memset(item, 0, sizeof(*item));

		child = kmap_atomic(page);
		item->val = child[pos];
		kunmap_atomic(child);
		item->child_no = pos;
		list_add(&item->list, &block->item_list);
	}
	block->page = NULL;

	if (PagePrivate(page)) {
		ClearPagePrivate(page);
		put_page(page);
		set_page_private(page, 0);
	}
	block->ops = &btree_block_ops;
	err = alias_tree_insert(block->sb, block->ino, block->bix, block->level,
			block);
	BUG_ON(err); /* mempool empty */
	ClearPageUptodate(page);
}

static int __logfs_segment_read(struct inode *inode, void *buf,
		u64 ofs, u64 bix, level_t level)
{
	struct super_block *sb = inode->i_sb;
	void *compressor_buf = logfs_super(sb)->s_compressed_je;
	struct logfs_object_header oh;
	__be32 crc;
	u16 len;
	int err, block_len;

	block_len = obj_len(sb, obj_type(inode, level));
	err = read_obj_header(sb, ofs, &oh);
	if (err)
		goto out_err;

	err = -EIO;
	if (be64_to_cpu(oh.ino) != inode->i_ino
			|| check_pos(sb, be64_to_cpu(oh.bix), bix, level)) {
		printk(KERN_ERR"LOGFS: (ino, bix) don't match at %llx: "
				"expected (%lx, %llx), got (%llx, %llx)\n",
				ofs, inode->i_ino, bix,
				be64_to_cpu(oh.ino), be64_to_cpu(oh.bix));
		goto out_err;
	}

	len = be16_to_cpu(oh.len);

	switch (oh.compr) {
	case COMPR_NONE:
		err = wbuf_read(sb, ofs + LOGFS_OBJECT_HEADERSIZE, len, buf);
		if (err)
			goto out_err;
		crc = logfs_crc32(buf, len, 0);
		if (crc != oh.data_crc) {
			printk(KERN_ERR"LOGFS: uncompressed data crc error at "
					"%llx: expected %x, got %x\n", ofs,
					be32_to_cpu(oh.data_crc),
					be32_to_cpu(crc));
			goto out_err;
		}
		break;
	case COMPR_ZLIB:
		mutex_lock(&logfs_super(sb)->s_journal_mutex);
		err = wbuf_read(sb, ofs + LOGFS_OBJECT_HEADERSIZE, len,
				compressor_buf);
		if (err) {
			mutex_unlock(&logfs_super(sb)->s_journal_mutex);
			goto out_err;
		}
		crc = logfs_crc32(compressor_buf, len, 0);
		if (crc != oh.data_crc) {
			printk(KERN_ERR"LOGFS: compressed data crc error at "
					"%llx: expected %x, got %x\n", ofs,
					be32_to_cpu(oh.data_crc),
					be32_to_cpu(crc));
			mutex_unlock(&logfs_super(sb)->s_journal_mutex);
			goto out_err;
		}
		err = logfs_uncompress(compressor_buf, buf, len, block_len);
		mutex_unlock(&logfs_super(sb)->s_journal_mutex);
		if (err) {
			printk(KERN_ERR"LOGFS: uncompress error at %llx\n", ofs);
			goto out_err;
		}
		break;
	default:
		LOGFS_BUG(sb);
		err = -EIO;
		goto out_err;
	}
	return 0;

out_err:
	logfs_set_ro(sb);
	printk(KERN_ERR"LOGFS: device is read-only now\n");
	LOGFS_BUG(sb);
	return err;
}

/**
 * logfs_segment_read - read data block from object store
 * @inode:		inode containing data
 * @buf:		data buffer
 * @ofs:		physical data offset
 * @bix:		block index
 * @level:		block level
 *
 * Returns 0 on success or a negative errno.
 */
int logfs_segment_read(struct inode *inode, struct page *page,
		u64 ofs, u64 bix, level_t level)
{
	int err;
	void *buf;

	if (PageUptodate(page))
		return 0;

	ofs &= ~LOGFS_FULLY_POPULATED;

	buf = kmap(page);
	err = __logfs_segment_read(inode, buf, ofs, bix, level);
	if (!err) {
		move_btree_to_page(inode, page, buf);
		SetPageUptodate(page);
	}
	kunmap(page);
	log_segment("logfs_segment_read(%lx, %llx, %x) %llx (%d)\n",
			inode->i_ino, bix, level, ofs, err);
	return err;
}

int logfs_segment_delete(struct inode *inode, struct logfs_shadow *shadow)
{
	struct super_block *sb = inode->i_sb;
	struct logfs_super *super = logfs_super(sb);
	struct logfs_object_header h;
	u16 len;
	int err;

	super->s_flags |= LOGFS_SB_FLAG_DIRTY;
	BUG_ON(super->s_flags & LOGFS_SB_FLAG_SHUTDOWN);
	BUG_ON(shadow->old_ofs & LOGFS_FULLY_POPULATED);
	if (!shadow->old_ofs)
		return 0;

	log_segment("logfs_segment_delete(%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);
	err = read_obj_header(sb, shadow->old_ofs, &h);
	LOGFS_BUG_ON(err, sb);
	LOGFS_BUG_ON(be64_to_cpu(h.ino) != inode->i_ino, sb);
	LOGFS_BUG_ON(check_pos(sb, shadow->bix, be64_to_cpu(h.bix),
				shrink_level(shadow->gc_level)), sb);

	if (shadow->gc_level == 0)
		len = be16_to_cpu(h.len);
	else
		len = obj_len(sb, h.type);
	shadow->old_len = len + sizeof(h);
	return 0;
}

void freeseg(struct super_block *sb, u32 segno)
{
	struct logfs_super *super = logfs_super(sb);
	struct address_space *mapping = super->s_mapping_inode->i_mapping;
	struct page *page;
	u64 ofs, start, end;

	start = dev_ofs(sb, segno, 0);
	end = dev_ofs(sb, segno + 1, 0);
	for (ofs = start; ofs < end; ofs += PAGE_SIZE) {
		page = find_get_page(mapping, ofs >> PAGE_SHIFT);
		if (!page)
			continue;
		if (PagePrivate(page)) {
			ClearPagePrivate(page);
			put_page(page);
		}
		put_page(page);
	}
}

int logfs_open_area(struct logfs_area *area, size_t bytes)
{
	struct super_block *sb = area->a_sb;
	struct logfs_super *super = logfs_super(sb);
	int err, closed = 0;

	if (area->a_is_open && area->a_used_bytes + bytes <= super->s_segsize)
		return 0;

	if (area->a_is_open) {
		u64 ofs = dev_ofs(sb, area->a_segno, area->a_written_bytes);
		u32 len = super->s_segsize - area->a_written_bytes;

		log_gc("logfs_close_area(%x)\n", area->a_segno);
		pad_wbuf(area, 1);
		super->s_devops->writeseg(area->a_sb, ofs, len);
		freeseg(sb, area->a_segno);
		closed = 1;
	}

	area->a_used_bytes = 0;
	area->a_written_bytes = 0;
again:
	area->a_ops->get_free_segment(area);
	area->a_ops->get_erase_count(area);

	log_gc("logfs_open_area(%x, %x)\n", area->a_segno, area->a_level);
	err = area->a_ops->erase_segment(area);
	if (err) {
		printk(KERN_WARNING "LogFS: Error erasing segment %x\n",
				area->a_segno);
		logfs_mark_segment_bad(sb, area->a_segno);
		goto again;
	}
	area->a_is_open = 1;
	return closed;
}

void logfs_sync_area(struct logfs_area *area)
{
	struct super_block *sb = area->a_sb;
	struct logfs_super *super = logfs_super(sb);
	u64 ofs = dev_ofs(sb, area->a_segno, area->a_written_bytes);
	u32 len = (area->a_used_bytes - area->a_written_bytes);

	if (super->s_writesize)
		len &= ~(super->s_writesize - 1);
	if (len == 0)
		return;
	pad_wbuf(area, 0);
	super->s_devops->writeseg(sb, ofs, len);
	area->a_written_bytes += len;
}

void logfs_sync_segments(struct super_block *sb)
{
	struct logfs_super *super = logfs_super(sb);
	int i;

	for_each_area(i)
		logfs_sync_area(super->s_area[i]);
}

/*
 * Pick a free segment to be used for this area.  Effectively takes a
 * candidate from the free list (not really a candidate anymore).
 */
static void ostore_get_free_segment(struct logfs_area *area)
{
	struct super_block *sb = area->a_sb;
	struct logfs_super *super = logfs_super(sb);

	if (super->s_free_list.count == 0) {
		printk(KERN_ERR"LOGFS: ran out of free segments\n");
		LOGFS_BUG(sb);
	}

	area->a_segno = get_best_cand(sb, &super->s_free_list, NULL);
}

static void ostore_get_erase_count(struct logfs_area *area)
{
	struct logfs_segment_entry se;
	u32 ec_level;

	logfs_get_segment_entry(area->a_sb, area->a_segno, &se);
	BUG_ON(se.ec_level == cpu_to_be32(BADSEG) ||
			se.valid == cpu_to_be32(RESERVED));

	ec_level = be32_to_cpu(se.ec_level);
	area->a_erase_count = (ec_level >> 4) + 1;
}

static int ostore_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, 0);
	if (err)
		return err;

	sh.pad = 0;
	sh.type = SEG_OSTORE;
	sh.level = (__force u8)area->a_level;
	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);

	logfs_set_segment_erased(sb, area->a_segno, area->a_erase_count,
			area->a_level);

	ofs = dev_ofs(sb, area->a_segno, 0);
	area->a_used_bytes = sizeof(sh);
	logfs_buf_write(area, ofs, &sh, sizeof(sh));
	return 0;
}

static const struct logfs_area_ops ostore_area_ops = {
	.get_free_segment	= ostore_get_free_segment,
	.get_erase_count	= ostore_get_erase_count,
	.erase_segment		= ostore_erase_segment,
};

static void free_area(struct logfs_area *area)
{
	if (area)
		freeseg(area->a_sb, area->a_segno);
	kfree(area);
}

void free_areas(struct super_block *sb)
{
	struct logfs_super *super = logfs_super(sb);
	int i;

	for_each_area(i)
		free_area(super->s_area[i]);
	free_area(super->s_journal_area);
}

static struct logfs_area *alloc_area(struct super_block *sb)
{
	struct logfs_area *area;

	area = kzalloc(sizeof(*area), GFP_KERNEL);
	if (!area)
		return NULL;

	area->a_sb = sb;
	return area;
}

static void map_invalidatepage(struct page *page, unsigned int o,
			       unsigned int l)
{
	return;
}

static int map_releasepage(struct page *page, gfp_t g)
{
	/* Don't release these pages */
	return 0;
}

static const struct address_space_operations mapping_aops = {
	.invalidatepage = map_invalidatepage,
	.releasepage	= map_releasepage,
	.set_page_dirty = __set_page_dirty_nobuffers,
};

int logfs_init_mapping(struct super_block *sb)
{
	struct logfs_super *super = logfs_super(sb);
	struct address_space *mapping;
	struct inode *inode;

	inode = logfs_new_meta_inode(sb, LOGFS_INO_MAPPING);
	if (IS_ERR(inode))
		return PTR_ERR(inode);
	super->s_mapping_inode = inode;
	mapping = inode->i_mapping;
	mapping->a_ops = &mapping_aops;
	/* Would it be possible to use __GFP_HIGHMEM as well? */
	mapping_set_gfp_mask(mapping, GFP_NOFS);
	return 0;
}

int logfs_init_areas(struct super_block *sb)
{
	struct logfs_super *super = logfs_super(sb);
	int i = -1;

	super->s_alias_pool = mempool_create_kmalloc_pool(600,
			sizeof(struct object_alias_item));
	if (!super->s_alias_pool)
		return -ENOMEM;

	super->s_journal_area = alloc_area(sb);
	if (!super->s_journal_area)
		goto err;

	for_each_area(i) {
		super->s_area[i] = alloc_area(sb);
		if (!super->s_area[i])
			goto err;
		super->s_area[i]->a_level = GC_LEVEL(i);
		super->s_area[i]->a_ops = &ostore_area_ops;
	}
	btree_init_mempool128(&super->s_object_alias_tree,
			super->s_btree_pool);
	return 0;

err:
	for (i--; i >= 0; i--)
		free_area(super->s_area[i]);
	free_area(super->s_journal_area);
	logfs_mempool_destroy(super->s_alias_pool);
	return -ENOMEM;
}

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

	btree_grim_visitor128(&super->s_object_alias_tree, 0, kill_alias);
}
