// SPDX-License-Identifier: GPL-2.0
/*
 * Write ahead logging implementation copyright Chris Mason 2000
 *
 * The background commits make this code very interrelated, and
 * overly complex.  I need to rethink things a bit....The major players:
 *
 * journal_begin -- call with the number of blocks you expect to log.
 *                  If the current transaction is too
 *		    old, it will block until the current transaction is
 *		    finished, and then start a new one.
 *		    Usually, your transaction will get joined in with
 *                  previous ones for speed.
 *
 * journal_join  -- same as journal_begin, but won't block on the current
 *                  transaction regardless of age.  Don't ever call
 *                  this.  Ever.  There are only two places it should be
 *                  called from, and they are both inside this file.
 *
 * journal_mark_dirty -- adds blocks into this transaction.  clears any flags
 *                       that might make them get sent to disk
 *                       and then marks them BH_JDirty.  Puts the buffer head
 *                       into the current transaction hash.
 *
 * journal_end -- if the current transaction is batchable, it does nothing
 *                   otherwise, it could do an async/synchronous commit, or
 *                   a full flush of all log and real blocks in the
 *                   transaction.
 *
 * flush_old_commits -- if the current transaction is too old, it is ended and
 *                      commit blocks are sent to disk.  Forces commit blocks
 *                      to disk for all backgrounded commits that have been
 *                      around too long.
 *		     -- Note, if you call this as an immediate flush from
 *		        from within kupdate, it will ignore the immediate flag
 */

#include <linux/time.h>
#include <linux/semaphore.h>
#include <linux/vmalloc.h>
#include "reiserfs.h"
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/fcntl.h>
#include <linux/stat.h>
#include <linux/string.h>
#include <linux/buffer_head.h>
#include <linux/workqueue.h>
#include <linux/writeback.h>
#include <linux/blkdev.h>
#include <linux/backing-dev.h>
#include <linux/uaccess.h>
#include <linux/slab.h>


/* gets a struct reiserfs_journal_list * from a list head */
#define JOURNAL_LIST_ENTRY(h) (list_entry((h), struct reiserfs_journal_list, \
                               j_list))
#define JOURNAL_WORK_ENTRY(h) (list_entry((h), struct reiserfs_journal_list, \
                               j_working_list))

/* must be correct to keep the desc and commit structs at 4k */
#define JOURNAL_TRANS_HALF 1018
#define BUFNR 64		/*read ahead */

/* cnode stat bits.  Move these into reiserfs_fs.h */

/* this block was freed, and can't be written.  */
#define BLOCK_FREED 2
/* this block was freed during this transaction, and can't be written */
#define BLOCK_FREED_HOLDER 3

/* used in flush_journal_list */
#define BLOCK_NEEDS_FLUSH 4
#define BLOCK_DIRTIED 5

/* journal list state bits */
#define LIST_TOUCHED 1
#define LIST_DIRTY   2
#define LIST_COMMIT_PENDING  4	/* someone will commit this list */

/* flags for do_journal_end */
#define FLUSH_ALL   1		/* flush commit and real blocks */
#define COMMIT_NOW  2		/* end and commit this transaction */
#define WAIT        4		/* wait for the log blocks to hit the disk */

static int do_journal_end(struct reiserfs_transaction_handle *, int flags);
static int flush_journal_list(struct super_block *s,
			      struct reiserfs_journal_list *jl, int flushall);
static int flush_commit_list(struct super_block *s,
			     struct reiserfs_journal_list *jl, int flushall);
static int can_dirty(struct reiserfs_journal_cnode *cn);
static int journal_join(struct reiserfs_transaction_handle *th,
			struct super_block *sb);
static void release_journal_dev(struct super_block *super,
			       struct reiserfs_journal *journal);
static int dirty_one_transaction(struct super_block *s,
				 struct reiserfs_journal_list *jl);
static void flush_async_commits(struct work_struct *work);
static void queue_log_writer(struct super_block *s);

/* values for join in do_journal_begin_r */
enum {
	JBEGIN_REG = 0,		/* regular journal begin */
	/* join the running transaction if at all possible */
	JBEGIN_JOIN = 1,
	/* called from cleanup code, ignores aborted flag */
	JBEGIN_ABORT = 2,
};

static int do_journal_begin_r(struct reiserfs_transaction_handle *th,
			      struct super_block *sb,
			      unsigned long nblocks, int join);

static void init_journal_hash(struct super_block *sb)
{
	struct reiserfs_journal *journal = SB_JOURNAL(sb);
	memset(journal->j_hash_table, 0,
	       JOURNAL_HASH_SIZE * sizeof(struct reiserfs_journal_cnode *));
}

/*
 * clears BH_Dirty and sticks the buffer on the clean list.  Called because
 * I can't allow refile_buffer to make schedule happen after I've freed a
 * block.  Look at remove_from_transaction and journal_mark_freed for
 * more details.
 */
static int reiserfs_clean_and_file_buffer(struct buffer_head *bh)
{
	if (bh) {
		clear_buffer_dirty(bh);
		clear_buffer_journal_test(bh);
	}
	return 0;
}

static struct reiserfs_bitmap_node *allocate_bitmap_node(struct super_block
							 *sb)
{
	struct reiserfs_bitmap_node *bn;
	static int id;

	bn = kmalloc(sizeof(struct reiserfs_bitmap_node), GFP_NOFS);
	if (!bn) {
		return NULL;
	}
	bn->data = kzalloc(sb->s_blocksize, GFP_NOFS);
	if (!bn->data) {
		kfree(bn);
		return NULL;
	}
	bn->id = id++;
	INIT_LIST_HEAD(&bn->list);
	return bn;
}

static struct reiserfs_bitmap_node *get_bitmap_node(struct super_block *sb)
{
	struct reiserfs_journal *journal = SB_JOURNAL(sb);
	struct reiserfs_bitmap_node *bn = NULL;
	struct list_head *entry = journal->j_bitmap_nodes.next;

	journal->j_used_bitmap_nodes++;
repeat:

	if (entry != &journal->j_bitmap_nodes) {
		bn = list_entry(entry, struct reiserfs_bitmap_node, list);
		list_del(entry);
		memset(bn->data, 0, sb->s_blocksize);
		journal->j_free_bitmap_nodes--;
		return bn;
	}
	bn = allocate_bitmap_node(sb);
	if (!bn) {
		yield();
		goto repeat;
	}
	return bn;
}
static inline void free_bitmap_node(struct super_block *sb,
				    struct reiserfs_bitmap_node *bn)
{
	struct reiserfs_journal *journal = SB_JOURNAL(sb);
	journal->j_used_bitmap_nodes--;
	if (journal->j_free_bitmap_nodes > REISERFS_MAX_BITMAP_NODES) {
		kfree(bn->data);
		kfree(bn);
	} else {
		list_add(&bn->list, &journal->j_bitmap_nodes);
		journal->j_free_bitmap_nodes++;
	}
}

static void allocate_bitmap_nodes(struct super_block *sb)
{
	int i;
	struct reiserfs_journal *journal = SB_JOURNAL(sb);
	struct reiserfs_bitmap_node *bn = NULL;
	for (i = 0; i < REISERFS_MIN_BITMAP_NODES; i++) {
		bn = allocate_bitmap_node(sb);
		if (bn) {
			list_add(&bn->list, &journal->j_bitmap_nodes);
			journal->j_free_bitmap_nodes++;
		} else {
			/* this is ok, we'll try again when more are needed */
			break;
		}
	}
}

static int set_bit_in_list_bitmap(struct super_block *sb,
				  b_blocknr_t block,
				  struct reiserfs_list_bitmap *jb)
{
	unsigned int bmap_nr = block / (sb->s_blocksize << 3);
	unsigned int bit_nr = block % (sb->s_blocksize << 3);

	if (!jb->bitmaps[bmap_nr]) {
		jb->bitmaps[bmap_nr] = get_bitmap_node(sb);
	}
	set_bit(bit_nr, (unsigned long *)jb->bitmaps[bmap_nr]->data);
	return 0;
}

static void cleanup_bitmap_list(struct super_block *sb,
				struct reiserfs_list_bitmap *jb)
{
	int i;
	if (jb->bitmaps == NULL)
		return;

	for (i = 0; i < reiserfs_bmap_count(sb); i++) {
		if (jb->bitmaps[i]) {
			free_bitmap_node(sb, jb->bitmaps[i]);
			jb->bitmaps[i] = NULL;
		}
	}
}

/*
 * only call this on FS unmount.
 */
static int free_list_bitmaps(struct super_block *sb,
			     struct reiserfs_list_bitmap *jb_array)
{
	int i;
	struct reiserfs_list_bitmap *jb;
	for (i = 0; i < JOURNAL_NUM_BITMAPS; i++) {
		jb = jb_array + i;
		jb->journal_list = NULL;
		cleanup_bitmap_list(sb, jb);
		vfree(jb->bitmaps);
		jb->bitmaps = NULL;
	}
	return 0;
}

static int free_bitmap_nodes(struct super_block *sb)
{
	struct reiserfs_journal *journal = SB_JOURNAL(sb);
	struct list_head *next = journal->j_bitmap_nodes.next;
	struct reiserfs_bitmap_node *bn;

	while (next != &journal->j_bitmap_nodes) {
		bn = list_entry(next, struct reiserfs_bitmap_node, list);
		list_del(next);
		kfree(bn->data);
		kfree(bn);
		next = journal->j_bitmap_nodes.next;
		journal->j_free_bitmap_nodes--;
	}

	return 0;
}

/*
 * get memory for JOURNAL_NUM_BITMAPS worth of bitmaps.
 * jb_array is the array to be filled in.
 */
int reiserfs_allocate_list_bitmaps(struct super_block *sb,
				   struct reiserfs_list_bitmap *jb_array,
				   unsigned int bmap_nr)
{
	int i;
	int failed = 0;
	struct reiserfs_list_bitmap *jb;
	int mem = bmap_nr * sizeof(struct reiserfs_bitmap_node *);

	for (i = 0; i < JOURNAL_NUM_BITMAPS; i++) {
		jb = jb_array + i;
		jb->journal_list = NULL;
		jb->bitmaps = vzalloc(mem);
		if (!jb->bitmaps) {
			reiserfs_warning(sb, "clm-2000", "unable to "
					 "allocate bitmaps for journal lists");
			failed = 1;
			break;
		}
	}
	if (failed) {
		free_list_bitmaps(sb, jb_array);
		return -1;
	}
	return 0;
}

/*
 * find an available list bitmap.  If you can't find one, flush a commit list
 * and try again
 */
static struct reiserfs_list_bitmap *get_list_bitmap(struct super_block *sb,
						    struct reiserfs_journal_list
						    *jl)
{
	int i, j;
	struct reiserfs_journal *journal = SB_JOURNAL(sb);
	struct reiserfs_list_bitmap *jb = NULL;

	for (j = 0; j < (JOURNAL_NUM_BITMAPS * 3); j++) {
		i = journal->j_list_bitmap_index;
		journal->j_list_bitmap_index = (i + 1) % JOURNAL_NUM_BITMAPS;
		jb = journal->j_list_bitmap + i;
		if (journal->j_list_bitmap[i].journal_list) {
			flush_commit_list(sb,
					  journal->j_list_bitmap[i].
					  journal_list, 1);
			if (!journal->j_list_bitmap[i].journal_list) {
				break;
			}
		} else {
			break;
		}
	}
	/* double check to make sure if flushed correctly */
	if (jb->journal_list)
		return NULL;
	jb->journal_list = jl;
	return jb;
}

/*
 * allocates a new chunk of X nodes, and links them all together as a list.
 * Uses the cnode->next and cnode->prev pointers
 * returns NULL on failure
 */
static struct reiserfs_journal_cnode *allocate_cnodes(int num_cnodes)
{
	struct reiserfs_journal_cnode *head;
	int i;
	if (num_cnodes <= 0) {
		return NULL;
	}
	head = vzalloc(num_cnodes * sizeof(struct reiserfs_journal_cnode));
	if (!head) {
		return NULL;
	}
	head[0].prev = NULL;
	head[0].next = head + 1;
	for (i = 1; i < num_cnodes; i++) {
		head[i].prev = head + (i - 1);
		head[i].next = head + (i + 1);	/* if last one, overwrite it after the if */
	}
	head[num_cnodes - 1].next = NULL;
	return head;
}

/* pulls a cnode off the free list, or returns NULL on failure */
static struct reiserfs_journal_cnode *get_cnode(struct super_block *sb)
{
	struct reiserfs_journal_cnode *cn;
	struct reiserfs_journal *journal = SB_JOURNAL(sb);

	reiserfs_check_lock_depth(sb, "get_cnode");

	if (journal->j_cnode_free <= 0) {
		return NULL;
	}
	journal->j_cnode_used++;
	journal->j_cnode_free--;
	cn = journal->j_cnode_free_list;
	if (!cn) {
		return cn;
	}
	if (cn->next) {
		cn->next->prev = NULL;
	}
	journal->j_cnode_free_list = cn->next;
	memset(cn, 0, sizeof(struct reiserfs_journal_cnode));
	return cn;
}

/*
 * returns a cnode to the free list
 */
static void free_cnode(struct super_block *sb,
		       struct reiserfs_journal_cnode *cn)
{
	struct reiserfs_journal *journal = SB_JOURNAL(sb);

	reiserfs_check_lock_depth(sb, "free_cnode");

	journal->j_cnode_used--;
	journal->j_cnode_free++;
	/* memset(cn, 0, sizeof(struct reiserfs_journal_cnode)) ; */
	cn->next = journal->j_cnode_free_list;
	if (journal->j_cnode_free_list) {
		journal->j_cnode_free_list->prev = cn;
	}
	cn->prev = NULL;	/* not needed with the memset, but I might kill the memset, and forget to do this */
	journal->j_cnode_free_list = cn;
}

static void clear_prepared_bits(struct buffer_head *bh)
{
	clear_buffer_journal_prepared(bh);
	clear_buffer_journal_restore_dirty(bh);
}

/*
 * return a cnode with same dev, block number and size in table,
 * or null if not found
 */
static inline struct reiserfs_journal_cnode *get_journal_hash_dev(struct
								  super_block
								  *sb,
								  struct
								  reiserfs_journal_cnode
								  **table,
								  long bl)
{
	struct reiserfs_journal_cnode *cn;
	cn = journal_hash(table, sb, bl);
	while (cn) {
		if (cn->blocknr == bl && cn->sb == sb)
			return cn;
		cn = cn->hnext;
	}
	return (struct reiserfs_journal_cnode *)0;
}

/*
 * this actually means 'can this block be reallocated yet?'.  If you set
 * search_all, a block can only be allocated if it is not in the current
 * transaction, was not freed by the current transaction, and has no chance
 * of ever being overwritten by a replay after crashing.
 *
 * If you don't set search_all, a block can only be allocated if it is not
 * in the current transaction.  Since deleting a block removes it from the
 * current transaction, this case should never happen.  If you don't set
 * search_all, make sure you never write the block without logging it.
 *
 * next_zero_bit is a suggestion about the next block to try for find_forward.
 * when bl is rejected because it is set in a journal list bitmap, we search
 * for the next zero bit in the bitmap that rejected bl.  Then, we return
 * that through next_zero_bit for find_forward to try.
 *
 * Just because we return something in next_zero_bit does not mean we won't
 * reject it on the next call to reiserfs_in_journal
 */
int reiserfs_in_journal(struct super_block *sb,
			unsigned int bmap_nr, int bit_nr, int search_all,
			b_blocknr_t * next_zero_bit)
{
	struct reiserfs_journal *journal = SB_JOURNAL(sb);
	struct reiserfs_journal_cnode *cn;
	struct reiserfs_list_bitmap *jb;
	int i;
	unsigned long bl;

	*next_zero_bit = 0;	/* always start this at zero. */

	PROC_INFO_INC(sb, journal.in_journal);
	/*
	 * If we aren't doing a search_all, this is a metablock, and it
	 * will be logged before use.  if we crash before the transaction
	 * that freed it commits,  this transaction won't have committed
	 * either, and the block will never be written
	 */
	if (search_all) {
		for (i = 0; i < JOURNAL_NUM_BITMAPS; i++) {
			PROC_INFO_INC(sb, journal.in_journal_bitmap);
			jb = journal->j_list_bitmap + i;
			if (jb->journal_list && jb->bitmaps[bmap_nr] &&
			    test_bit(bit_nr,
				     (unsigned long *)jb->bitmaps[bmap_nr]->
				     data)) {
				*next_zero_bit =
				    find_next_zero_bit((unsigned long *)
						       (jb->bitmaps[bmap_nr]->
							data),
						       sb->s_blocksize << 3,
						       bit_nr + 1);
				return 1;
			}
		}
	}

	bl = bmap_nr * (sb->s_blocksize << 3) + bit_nr;
	/* is it in any old transactions? */
	if (search_all
	    && (cn =
		get_journal_hash_dev(sb, journal->j_list_hash_table, bl))) {
		return 1;
	}

	/* is it in the current transaction.  This should never happen */
	if ((cn = get_journal_hash_dev(sb, journal->j_hash_table, bl))) {
		BUG();
		return 1;
	}

	PROC_INFO_INC(sb, journal.in_journal_reusable);
	/* safe for reuse */
	return 0;
}

/* insert cn into table */
static inline void insert_journal_hash(struct reiserfs_journal_cnode **table,
				       struct reiserfs_journal_cnode *cn)
{
	struct reiserfs_journal_cnode *cn_orig;

	cn_orig = journal_hash(table, cn->sb, cn->blocknr);
	cn->hnext = cn_orig;
	cn->hprev = NULL;
	if (cn_orig) {
		cn_orig->hprev = cn;
	}
	journal_hash(table, cn->sb, cn->blocknr) = cn;
}

/* lock the current transaction */
static inline void lock_journal(struct super_block *sb)
{
	PROC_INFO_INC(sb, journal.lock_journal);

	reiserfs_mutex_lock_safe(&SB_JOURNAL(sb)->j_mutex, sb);
}

/* unlock the current transaction */
static inline void unlock_journal(struct super_block *sb)
{
	mutex_unlock(&SB_JOURNAL(sb)->j_mutex);
}

static inline void get_journal_list(struct reiserfs_journal_list *jl)
{
	jl->j_refcount++;
}

static inline void put_journal_list(struct super_block *s,
				    struct reiserfs_journal_list *jl)
{
	if (jl->j_refcount < 1) {
		reiserfs_panic(s, "journal-2", "trans id %u, refcount at %d",
			       jl->j_trans_id, jl->j_refcount);
	}
	if (--jl->j_refcount == 0)
		kfree(jl);
}

/*
 * this used to be much more involved, and I'm keeping it just in case
 * things get ugly again.  it gets called by flush_commit_list, and
 * cleans up any data stored about blocks freed during a transaction.
 */
static void cleanup_freed_for_journal_list(struct super_block *sb,
					   struct reiserfs_journal_list *jl)
{

	struct reiserfs_list_bitmap *jb = jl->j_list_bitmap;
	if (jb) {
		cleanup_bitmap_list(sb, jb);
	}
	jl->j_list_bitmap->journal_list = NULL;
	jl->j_list_bitmap = NULL;
}

static int journal_list_still_alive(struct super_block *s,
				    unsigned int trans_id)
{
	struct reiserfs_journal *journal = SB_JOURNAL(s);
	struct list_head *entry = &journal->j_journal_list;
	struct reiserfs_journal_list *jl;

	if (!list_empty(entry)) {
		jl = JOURNAL_LIST_ENTRY(entry->next);
		if (jl->j_trans_id <= trans_id) {
			return 1;
		}
	}
	return 0;
}

/*
 * If page->mapping was null, we failed to truncate this page for
 * some reason.  Most likely because it was truncated after being
 * logged via data=journal.
 *
 * This does a check to see if the buffer belongs to one of these
 * lost pages before doing the final put_bh.  If page->mapping was
 * null, it tries to free buffers on the page, which should make the
 * final put_page drop the page from the lru.
 */
static void release_buffer_page(struct buffer_head *bh)
{
	struct page *page = bh->b_page;
	if (!page->mapping && trylock_page(page)) {
		get_page(page);
		put_bh(bh);
		if (!page->mapping)
			try_to_free_buffers(page);
		unlock_page(page);
		put_page(page);
	} else {
		put_bh(bh);
	}
}

static void reiserfs_end_buffer_io_sync(struct buffer_head *bh, int uptodate)
{
	if (buffer_journaled(bh)) {
		reiserfs_warning(NULL, "clm-2084",
				 "pinned buffer %lu:%pg sent to disk",
				 bh->b_blocknr, bh->b_bdev);
	}
	if (uptodate)
		set_buffer_uptodate(bh);
	else
		clear_buffer_uptodate(bh);

	unlock_buffer(bh);
	release_buffer_page(bh);
}

static void reiserfs_end_ordered_io(struct buffer_head *bh, int uptodate)
{
	if (uptodate)
		set_buffer_uptodate(bh);
	else
		clear_buffer_uptodate(bh);
	unlock_buffer(bh);
	put_bh(bh);
}

static void submit_logged_buffer(struct buffer_head *bh)
{
	get_bh(bh);
	bh->b_end_io = reiserfs_end_buffer_io_sync;
	clear_buffer_journal_new(bh);
	clear_buffer_dirty(bh);
	if (!test_clear_buffer_journal_test(bh))
		BUG();
	if (!buffer_uptodate(bh))
		BUG();
	submit_bh(REQ_OP_WRITE, 0, bh);
}

static void submit_ordered_buffer(struct buffer_head *bh)
{
	get_bh(bh);
	bh->b_end_io = reiserfs_end_ordered_io;
	clear_buffer_dirty(bh);
	if (!buffer_uptodate(bh))
		BUG();
	submit_bh(REQ_OP_WRITE, 0, bh);
}

#define CHUNK_SIZE 32
struct buffer_chunk {
	struct buffer_head *bh[CHUNK_SIZE];
	int nr;
};

static void write_chunk(struct buffer_chunk *chunk)
{
	int i;
	for (i = 0; i < chunk->nr; i++) {
		submit_logged_buffer(chunk->bh[i]);
	}
	chunk->nr = 0;
}

static void write_ordered_chunk(struct buffer_chunk *chunk)
{
	int i;
	for (i = 0; i < chunk->nr; i++) {
		submit_ordered_buffer(chunk->bh[i]);
	}
	chunk->nr = 0;
}

static int add_to_chunk(struct buffer_chunk *chunk, struct buffer_head *bh,
			spinlock_t * lock, void (fn) (struct buffer_chunk *))
{
	int ret = 0;
	BUG_ON(chunk->nr >= CHUNK_SIZE);
	chunk->bh[chunk->nr++] = bh;
	if (chunk->nr >= CHUNK_SIZE) {
		ret = 1;
		if (lock) {
			spin_unlock(lock);
			fn(chunk);
			spin_lock(lock);
		} else {
			fn(chunk);
		}
	}
	return ret;
}

static atomic_t nr_reiserfs_jh = ATOMIC_INIT(0);
static struct reiserfs_jh *alloc_jh(void)
{
	struct reiserfs_jh *jh;
	while (1) {
		jh = kmalloc(sizeof(*jh), GFP_NOFS);
		if (jh) {
			atomic_inc(&nr_reiserfs_jh);
			return jh;
		}
		yield();
	}
}

/*
 * we want to free the jh when the buffer has been written
 * and waited on
 */
void reiserfs_free_jh(struct buffer_head *bh)
{
	struct reiserfs_jh *jh;

	jh = bh->b_private;
	if (jh) {
		bh->b_private = NULL;
		jh->bh = NULL;
		list_del_init(&jh->list);
		kfree(jh);
		if (atomic_read(&nr_reiserfs_jh) <= 0)
			BUG();
		atomic_dec(&nr_reiserfs_jh);
		put_bh(bh);
	}
}

static inline int __add_jh(struct reiserfs_journal *j, struct buffer_head *bh,
			   int tail)
{
	struct reiserfs_jh *jh;

	if (bh->b_private) {
		spin_lock(&j->j_dirty_buffers_lock);
		if (!bh->b_private) {
			spin_unlock(&j->j_dirty_buffers_lock);
			goto no_jh;
		}
		jh = bh->b_private;
		list_del_init(&jh->list);
	} else {
no_jh:
		get_bh(bh);
		jh = alloc_jh();
		spin_lock(&j->j_dirty_buffers_lock);
		/*
		 * buffer must be locked for __add_jh, should be able to have
		 * two adds at the same time
		 */
		BUG_ON(bh->b_private);
		jh->bh = bh;
		bh->b_private = jh;
	}
	jh->jl = j->j_current_jl;
	if (tail)
		list_add_tail(&jh->list, &jh->jl->j_tail_bh_list);
	else {
		list_add_tail(&jh->list, &jh->jl->j_bh_list);
	}
	spin_unlock(&j->j_dirty_buffers_lock);
	return 0;
}

int reiserfs_add_tail_list(struct inode *inode, struct buffer_head *bh)
{
	return __add_jh(SB_JOURNAL(inode->i_sb), bh, 1);
}
int reiserfs_add_ordered_list(struct inode *inode, struct buffer_head *bh)
{
	return __add_jh(SB_JOURNAL(inode->i_sb), bh, 0);
}

#define JH_ENTRY(l) list_entry((l), struct reiserfs_jh, list)
static int write_ordered_buffers(spinlock_t * lock,
				 struct reiserfs_journal *j,
				 struct reiserfs_journal_list *jl,
				 struct list_head *list)
{
	struct buffer_head *bh;
	struct reiserfs_jh *jh;
	int ret = j->j_errno;
	struct buffer_chunk chunk;
	struct list_head tmp;
	INIT_LIST_HEAD(&tmp);

	chunk.nr = 0;
	spin_lock(lock);
	while (!list_empty(list)) {
		jh = JH_ENTRY(list->next);
		bh = jh->bh;
		get_bh(bh);
		if (!trylock_buffer(bh)) {
			if (!buffer_dirty(bh)) {
				list_move(&jh->list, &tmp);
				goto loop_next;
			}
			spin_unlock(lock);
			if (chunk.nr)
				write_ordered_chunk(&chunk);
			wait_on_buffer(bh);
			cond_resched();
			spin_lock(lock);
			goto loop_next;
		}
		/*
		 * in theory, dirty non-uptodate buffers should never get here,
		 * but the upper layer io error paths still have a few quirks.
		 * Handle them here as gracefully as we can
		 */
		if (!buffer_uptodate(bh) && buffer_dirty(bh)) {
			clear_buffer_dirty(bh);
			ret = -EIO;
		}
		if (buffer_dirty(bh)) {
			list_move(&jh->list, &tmp);
			add_to_chunk(&chunk, bh, lock, write_ordered_chunk);
		} else {
			reiserfs_free_jh(bh);
			unlock_buffer(bh);
		}
loop_next:
		put_bh(bh);
		cond_resched_lock(lock);
	}
	if (chunk.nr) {
		spin_unlock(lock);
		write_ordered_chunk(&chunk);
		spin_lock(lock);
	}
	while (!list_empty(&tmp)) {
		jh = JH_ENTRY(tmp.prev);
		bh = jh->bh;
		get_bh(bh);
		reiserfs_free_jh(bh);

		if (buffer_locked(bh)) {
			spin_unlock(lock);
			wait_on_buffer(bh);
			spin_lock(lock);
		}
		if (!buffer_uptodate(bh)) {
			ret = -EIO;
		}
		/*
		 * ugly interaction with invalidatepage here.
		 * reiserfs_invalidate_page will pin any buffer that has a
		 * valid journal head from an older transaction.  If someone
		 * else sets our buffer dirty after we write it in the first
		 * loop, and then someone truncates the page away, nobody
		 * will ever write the buffer. We're safe if we write the
		 * page one last time after freeing the journal header.
		 */
		if (buffer_dirty(bh) && unlikely(bh->b_page->mapping == NULL)) {
			spin_unlock(lock);
			ll_rw_block(REQ_OP_WRITE, 0, 1, &bh);
			spin_lock(lock);
		}
		put_bh(bh);
		cond_resched_lock(lock);
	}
	spin_unlock(lock);
	return ret;
}

static int flush_older_commits(struct super_block *s,
			       struct reiserfs_journal_list *jl)
{
	struct reiserfs_journal *journal = SB_JOURNAL(s);
	struct reiserfs_journal_list *other_jl;
	struct reiserfs_journal_list *first_jl;
	struct list_head *entry;
	unsigned int trans_id = jl->j_trans_id;
	unsigned int other_trans_id;
	unsigned int first_trans_id;

find_first:
	/*
	 * first we walk backwards to find the oldest uncommitted transation
	 */
	first_jl = jl;
	entry = jl->j_list.prev;
	while (1) {
		other_jl = JOURNAL_LIST_ENTRY(entry);
		if (entry == &journal->j_journal_list ||
		    atomic_read(&other_jl->j_older_commits_done))
			break;

		first_jl = other_jl;
		entry = other_jl->j_list.prev;
	}

	/* if we didn't find any older uncommitted transactions, return now */
	if (first_jl == jl) {
		return 0;
	}

	first_trans_id = first_jl->j_trans_id;

	entry = &first_jl->j_list;
	while (1) {
		other_jl = JOURNAL_LIST_ENTRY(entry);
		other_trans_id = other_jl->j_trans_id;

		if (other_trans_id < trans_id) {
			if (atomic_read(&other_jl->j_commit_left) != 0) {
				flush_commit_list(s, other_jl, 0);

				/* list we were called with is gone, return */
				if (!journal_list_still_alive(s, trans_id))
					return 1;

				/*
				 * the one we just flushed is gone, this means
				 * all older lists are also gone, so first_jl
				 * is no longer valid either.  Go back to the
				 * beginning.
				 */
				if (!journal_list_still_alive
				    (s, other_trans_id)) {
					goto find_first;
				}
			}
			entry = entry->next;
			if (entry == &journal->j_journal_list)
				return 0;
		} else {
			return 0;
		}
	}
	return 0;
}

static int reiserfs_async_progress_wait(struct super_block *s)
{
	struct reiserfs_journal *j = SB_JOURNAL(s);

	if (atomic_read(&j->j_async_throttle)) {
		int depth;

		depth = reiserfs_write_unlock_nested(s);
		congestion_wait(BLK_RW_ASYNC, HZ / 10);
		reiserfs_write_lock_nested(s, depth);
	}

	return 0;
}

/*
 * if this journal list still has commit blocks unflushed, send them to disk.
 *
 * log areas must be flushed in order (transaction 2 can't commit before
 * transaction 1) Before the commit block can by written, every other log
 * block must be safely on disk
 */
static int flush_commit_list(struct super_block *s,
			     struct reiserfs_journal_list *jl, int flushall)
{
	int i;
	b_blocknr_t bn;
	struct buffer_head *tbh = NULL;
	unsigned int trans_id = jl->j_trans_id;
	struct reiserfs_journal *journal = SB_JOURNAL(s);
	int retval = 0;
	int write_len;
	int depth;

	reiserfs_check_lock_depth(s, "flush_commit_list");

	if (atomic_read(&jl->j_older_commits_done)) {
		return 0;
	}

	/*
	 * before we can put our commit blocks on disk, we have to make
	 * sure everyone older than us is on disk too
	 */
	BUG_ON(jl->j_len <= 0);
	BUG_ON(trans_id == journal->j_trans_id);

	get_journal_list(jl);
	if (flushall) {
		if (flush_older_commits(s, jl) == 1) {
			/*
			 * list disappeared during flush_older_commits.
			 * return
			 */
			goto put_jl;
		}
	}

	/* make sure nobody is trying to flush this one at the same time */
	reiserfs_mutex_lock_safe(&jl->j_commit_mutex, s);

	if (!journal_list_still_alive(s, trans_id)) {
		mutex_unlock(&jl->j_commit_mutex);
		goto put_jl;
	}
	BUG_ON(jl->j_trans_id == 0);

	/* this commit is done, exit */
	if (atomic_read(&jl->j_commit_left) <= 0) {
		if (flushall) {
			atomic_set(&jl->j_older_commits_done, 1);
		}
		mutex_unlock(&jl->j_commit_mutex);
		goto put_jl;
	}

	if (!list_empty(&jl->j_bh_list)) {
		int ret;

		/*
		 * We might sleep in numerous places inside
		 * write_ordered_buffers. Relax the write lock.
		 */
		depth = reiserfs_write_unlock_nested(s);
		ret = write_ordered_buffers(&journal->j_dirty_buffers_lock,
					    journal, jl, &jl->j_bh_list);
		if (ret < 0 && retval == 0)
			retval = ret;
		reiserfs_write_lock_nested(s, depth);
	}
	BUG_ON(!list_empty(&jl->j_bh_list));
	/*
	 * for the description block and all the log blocks, submit any buffers
	 * that haven't already reached the disk.  Try to write at least 256
	 * log blocks. later on, we will only wait on blocks that correspond
	 * to this transaction, but while we're unplugging we might as well
	 * get a chunk of data on there.
	 */
	atomic_inc(&journal->j_async_throttle);
	write_len = jl->j_len + 1;
	if (write_len < 256)
		write_len = 256;
	for (i = 0 ; i < write_len ; i++) {
		bn = SB_ONDISK_JOURNAL_1st_BLOCK(s) + (jl->j_start + i) %
		    SB_ONDISK_JOURNAL_SIZE(s);
		tbh = journal_find_get_block(s, bn);
		if (tbh) {
			if (buffer_dirty(tbh)) {
		            depth = reiserfs_write_unlock_nested(s);
			    ll_rw_block(REQ_OP_WRITE, 0, 1, &tbh);
			    reiserfs_write_lock_nested(s, depth);
			}
			put_bh(tbh) ;
		}
	}
	atomic_dec(&journal->j_async_throttle);

	for (i = 0; i < (jl->j_len + 1); i++) {
		bn = SB_ONDISK_JOURNAL_1st_BLOCK(s) +
		    (jl->j_start + i) % SB_ONDISK_JOURNAL_SIZE(s);
		tbh = journal_find_get_block(s, bn);

		depth = reiserfs_write_unlock_nested(s);
		__wait_on_buffer(tbh);
		reiserfs_write_lock_nested(s, depth);
		/*
		 * since we're using ll_rw_blk above, it might have skipped
		 * over a locked buffer.  Double check here
		 */
		/* redundant, sync_dirty_buffer() checks */
		if (buffer_dirty(tbh)) {
			depth = reiserfs_write_unlock_nested(s);
			sync_dirty_buffer(tbh);
			reiserfs_write_lock_nested(s, depth);
		}
		if (unlikely(!buffer_uptodate(tbh))) {
#ifdef CONFIG_REISERFS_CHECK
			reiserfs_warning(s, "journal-601",
					 "buffer write failed");
#endif
			retval = -EIO;
		}
		/* once for journal_find_get_block */
		put_bh(tbh);
		/* once due to original getblk in do_journal_end */
		put_bh(tbh);
		atomic_dec(&jl->j_commit_left);
	}

	BUG_ON(atomic_read(&jl->j_commit_left) != 1);

	/*
	 * If there was a write error in the journal - we can't commit
	 * this transaction - it will be invalid and, if successful,
	 * will just end up propagating the write error out to
	 * the file system.
	 */
	if (likely(!retval && !reiserfs_is_journal_aborted (journal))) {
		if (buffer_dirty(jl->j_commit_bh))
			BUG();
		mark_buffer_dirty(jl->j_commit_bh) ;
		depth = reiserfs_write_unlock_nested(s);
		if (reiserfs_barrier_flush(s))
			__sync_dirty_buffer(jl->j_commit_bh,
					REQ_SYNC | REQ_PREFLUSH | REQ_FUA);
		else
			sync_dirty_buffer(jl->j_commit_bh);
		reiserfs_write_lock_nested(s, depth);
	}

	/*
	 * If there was a write error in the journal - we can't commit this
	 * transaction - it will be invalid and, if successful, will just end
	 * up propagating the write error out to the filesystem.
	 */
	if (unlikely(!buffer_uptodate(jl->j_commit_bh))) {
#ifdef CONFIG_REISERFS_CHECK
		reiserfs_warning(s, "journal-615", "buffer write failed");
#endif
		retval = -EIO;
	}
	bforget(jl->j_commit_bh);
	if (journal->j_last_commit_id != 0 &&
	    (jl->j_trans_id - journal->j_last_commit_id) != 1) {
		reiserfs_warning(s, "clm-2200", "last commit %lu, current %lu",
				 journal->j_last_commit_id, jl->j_trans_id);
	}
	journal->j_last_commit_id = jl->j_trans_id;

	/*
	 * now, every commit block is on the disk.  It is safe to allow
	 * blocks freed during this transaction to be reallocated
	 */
	cleanup_freed_for_journal_list(s, jl);

	retval = retval ? retval : journal->j_errno;

	/* mark the metadata dirty */
	if (!retval)
		dirty_one_transaction(s, jl);
	atomic_dec(&jl->j_commit_left);

	if (flushall) {
		atomic_set(&jl->j_older_commits_done, 1);
	}
	mutex_unlock(&jl->j_commit_mutex);
put_jl:
	put_journal_list(s, jl);

	if (retval)
		reiserfs_abort(s, retval, "Journal write error in %s",
			       __func__);
	return retval;
}

/*
 * flush_journal_list frequently needs to find a newer transaction for a
 * given block.  This does that, or returns NULL if it can't find anything
 */
static struct reiserfs_journal_list *find_newer_jl_for_cn(struct
							  reiserfs_journal_cnode
							  *cn)
{
	struct super_block *sb = cn->sb;
	b_blocknr_t blocknr = cn->blocknr;

	cn = cn->hprev;
	while (cn) {
		if (cn->sb == sb && cn->blocknr == blocknr && cn->jlist) {
			return cn->jlist;
		}
		cn = cn->hprev;
	}
	return NULL;
}

static void remove_journal_hash(struct super_block *,
				struct reiserfs_journal_cnode **,
				struct reiserfs_journal_list *, unsigned long,
				int);

/*
 * once all the real blocks have been flushed, it is safe to remove them
 * from the journal list for this transaction.  Aside from freeing the
 * cnode, this also allows the block to be reallocated for data blocks
 * if it had been deleted.
 */
static void remove_all_from_journal_list(struct super_block *sb,
					 struct reiserfs_journal_list *jl,
					 int debug)
{
	struct reiserfs_journal *journal = SB_JOURNAL(sb);
	struct reiserfs_journal_cnode *cn, *last;
	cn = jl->j_realblock;

	/*
	 * which is better, to lock once around the whole loop, or
	 * to lock for each call to remove_journal_hash?
	 */
	while (cn) {
		if (cn->blocknr != 0) {
			if (debug) {
				reiserfs_warning(sb, "reiserfs-2201",
						 "block %u, bh is %d, state %ld",
						 cn->blocknr, cn->bh ? 1 : 0,
						 cn->state);
			}
			cn->state = 0;
			remove_journal_hash(sb, journal->j_list_hash_table,
					    jl, cn->blocknr, 1);
		}
		last = cn;
		cn = cn->next;
		free_cnode(sb, last);
	}
	jl->j_realblock = NULL;
}

/*
 * if this timestamp is greater than the timestamp we wrote last to the
 * header block, write it to the header block.  once this is done, I can
 * safely say the log area for this transaction won't ever be replayed,
 * and I can start releasing blocks in this transaction for reuse as data
 * blocks.  called by flush_journal_list, before it calls
 * remove_all_from_journal_list
 */
static int _update_journal_header_block(struct super_block *sb,
					unsigned long offset,
					unsigned int trans_id)
{
	struct reiserfs_journal_header *jh;
	struct reiserfs_journal *journal = SB_JOURNAL(sb);
	int depth;

	if (reiserfs_is_journal_aborted(journal))
		return -EIO;

	if (trans_id >= journal->j_last_flush_trans_id) {
		if (buffer_locked((journal->j_header_bh))) {
			depth = reiserfs_write_unlock_nested(sb);
			__wait_on_buffer(journal->j_header_bh);
			reiserfs_write_lock_nested(sb, depth);
			if (unlikely(!buffer_uptodate(journal->j_header_bh))) {
#ifdef CONFIG_REISERFS_CHECK
				reiserfs_warning(sb, "journal-699",
						 "buffer write failed");
#endif
				return -EIO;
			}
		}
		journal->j_last_flush_trans_id = trans_id;
		journal->j_first_unflushed_offset = offset;
		jh = (struct reiserfs_journal_header *)(journal->j_header_bh->
							b_data);
		jh->j_last_flush_trans_id = cpu_to_le32(trans_id);
		jh->j_first_unflushed_offset = cpu_to_le32(offset);
		jh->j_mount_id = cpu_to_le32(journal->j_mount_id);

		set_buffer_dirty(journal->j_header_bh);
		depth = reiserfs_write_unlock_nested(sb);

		if (reiserfs_barrier_flush(sb))
			__sync_dirty_buffer(journal->j_header_bh,
					REQ_SYNC | REQ_PREFLUSH | REQ_FUA);
		else
			sync_dirty_buffer(journal->j_header_bh);

		reiserfs_write_lock_nested(sb, depth);
		if (!buffer_uptodate(journal->j_header_bh)) {
			reiserfs_warning(sb, "journal-837",
					 "IO error during journal replay");
			return -EIO;
		}
	}
	return 0;
}

static int update_journal_header_block(struct super_block *sb,
				       unsigned long offset,
				       unsigned int trans_id)
{
	return _update_journal_header_block(sb, offset, trans_id);
}

/*
** flush any and all journal lists older than you are
** can only be called from flush_journal_list
*/
static int flush_older_journal_lists(struct super_block *sb,
				     struct reiserfs_journal_list *jl)
{
	struct list_head *entry;
	struct reiserfs_journal_list *other_jl;
	struct reiserfs_journal *journal = SB_JOURNAL(sb);
	unsigned int trans_id = jl->j_trans_id;

	/*
	 * we know we are the only ones flushing things, no extra race
	 * protection is required.
	 */
restart:
	entry = journal->j_journal_list.next;
	/* Did we wrap? */
	if (entry == &journal->j_journal_list)
		return 0;
	other_jl = JOURNAL_LIST_ENTRY(entry);
	if (other_jl->j_trans_id < trans_id) {
		BUG_ON(other_jl->j_refcount <= 0);
		/* do not flush all */
		flush_journal_list(sb, other_jl, 0);

		/* other_jl is now deleted from the list */
		goto restart;
	}
	return 0;
}

static void del_from_work_list(struct super_block *s,
			       struct reiserfs_journal_list *jl)
{
	struct reiserfs_journal *journal = SB_JOURNAL(s);
	if (!list_empty(&jl->j_working_list)) {
		list_del_init(&jl->j_working_list);
		journal->j_num_work_lists--;
	}
}

/*
 * flush a journal list, both commit and real blocks
 *
 * always set flushall to 1, unless you are calling from inside
 * flush_journal_list
 *
 * IMPORTANT.  This can only be called while there are no journal writers,
 * and the journal is locked.  That means it can only be called from
 * do_journal_end, or by journal_release
 */
static int flush_journal_list(struct super_block *s,
			      struct reiserfs_journal_list *jl, int flushall)
{
	struct reiserfs_journal_list *pjl;
	struct reiserfs_journal_cnode *cn, *last;
	int count;
	int was_jwait = 0;
	int was_dirty = 0;
	struct buffer_head *saved_bh;
	unsigned long j_len_saved = jl->j_len;
	struct reiserfs_journal *journal = SB_JOURNAL(s);
	int err = 0;
	int depth;

	BUG_ON(j_len_saved <= 0);

	if (atomic_read(&journal->j_wcount) != 0) {
		reiserfs_warning(s, "clm-2048", "called with wcount %d",
				 atomic_read(&journal->j_wcount));
	}

	/* if flushall == 0, the lock is already held */
	if (flushall) {
		reiserfs_mutex_lock_safe(&journal->j_flush_mutex, s);
	} else if (mutex_trylock(&journal->j_flush_mutex)) {
		BUG();
	}

	count = 0;
	if (j_len_saved > journal->j_trans_max) {
		reiserfs_panic(s, "journal-715", "length is %lu, trans id %lu",
			       j_len_saved, jl->j_trans_id);
		return 0;
	}

	/* if all the work is already done, get out of here */
	if (atomic_read(&jl->j_nonzerolen) <= 0 &&
	    atomic_read(&jl->j_commit_left) <= 0) {
		goto flush_older_and_return;
	}

	/*
	 * start by putting the commit list on disk.  This will also flush
	 * the commit lists of any olders transactions
	 */
	flush_commit_list(s, jl, 1);

	if (!(jl->j_state & LIST_DIRTY)
	    && !reiserfs_is_journal_aborted(journal))
		BUG();

	/* are we done now? */
	if (atomic_read(&jl->j_nonzerolen) <= 0 &&
	    atomic_read(&jl->j_commit_left) <= 0) {
		goto flush_older_and_return;
	}

	/*
	 * loop through each cnode, see if we need to write it,
	 * or wait on a more recent transaction, or just ignore it
	 */
	if (atomic_read(&journal->j_wcount) != 0) {
		reiserfs_panic(s, "journal-844", "journal list is flushing, "
			       "wcount is not 0");
	}
	cn = jl->j_realblock;
	while (cn) {
		was_jwait = 0;
		was_dirty = 0;
		saved_bh = NULL;
		/* blocknr of 0 is no longer in the hash, ignore it */
		if (cn->blocknr == 0) {
			goto free_cnode;
		}

		/*
		 * This transaction failed commit.
		 * Don't write out to the disk
		 */
		if (!(jl->j_state & LIST_DIRTY))
			goto free_cnode;

		pjl = find_newer_jl_for_cn(cn);
		/*
		 * the order is important here.  We check pjl to make sure we
		 * don't clear BH_JDirty_wait if we aren't the one writing this
		 * block to disk
		 */
		if (!pjl && cn->bh) {
			saved_bh = cn->bh;

			/*
			 * we do this to make sure nobody releases the
			 * buffer while we are working with it
			 */
			get_bh(saved_bh);

			if (buffer_journal_dirty(saved_bh)) {
				BUG_ON(!can_dirty(cn));
				was_jwait = 1;
				was_dirty = 1;
			} else if (can_dirty(cn)) {
				/*
				 * everything with !pjl && jwait
				 * should be writable
				 */
				BUG();
			}
		}

		/*
		 * if someone has this block in a newer transaction, just make
		 * sure they are committed, and don't try writing it to disk
		 */
		if (pjl) {
			if (atomic_read(&pjl->j_commit_left))
				flush_commit_list(s, pjl, 1);
			goto free_cnode;
		}

		/*
		 * bh == NULL when the block got to disk on its own, OR,
		 * the block got freed in a future transaction
		 */
		if (saved_bh == NULL) {
			goto free_cnode;
		}

		/*
		 * this should never happen.  kupdate_one_transaction has
		 * this list locked while it works, so we should never see a
		 * buffer here that is not marked JDirty_wait
		 */
		if ((!was_jwait) && !buffer_locked(saved_bh)) {
			reiserfs_warning(s, "journal-813",
					 "BAD! buffer %llu %cdirty %cjwait, "
					 "not in a newer transaction",
					 (unsigned long long)saved_bh->
					 b_blocknr, was_dirty ? ' ' : '!',
					 was_jwait ? ' ' : '!');
		}
		if (was_dirty) {
			/*
			 * we inc again because saved_bh gets decremented
			 * at free_cnode
			 */
			get_bh(saved_bh);
			set_bit(BLOCK_NEEDS_FLUSH, &cn->state);
			lock_buffer(saved_bh);
			BUG_ON(cn->blocknr != saved_bh->b_blocknr);
			if (buffer_dirty(saved_bh))
				submit_logged_buffer(saved_bh);
			else
				unlock_buffer(saved_bh);
			count++;
		} else {
			reiserfs_warning(s, "clm-2082",
					 "Unable to flush buffer %llu in %s",
					 (unsigned long long)saved_bh->
					 b_blocknr, __func__);
		}
free_cnode:
		last = cn;
		cn = cn->next;
		if (saved_bh) {
			/*
			 * we incremented this to keep others from
			 * taking the buffer head away
			 */
			put_bh(saved_bh);
			if (atomic_read(&saved_bh->b_count) < 0) {
				reiserfs_warning(s, "journal-945",
						 "saved_bh->b_count < 0");
			}
		}
	}
	if (count > 0) {
		cn = jl->j_realblock;
		while (cn) {
			if (test_bit(BLOCK_NEEDS_FLUSH, &cn->state)) {
				if (!cn->bh) {
					reiserfs_panic(s, "journal-1011",
						       "cn->bh is NULL");
				}

				depth = reiserfs_write_unlock_nested(s);
				__wait_on_buffer(cn->bh);
				reiserfs_write_lock_nested(s, depth);

				if (!cn->bh) {
					reiserfs_panic(s, "journal-1012",
						       "cn->bh is NULL");
				}
				if (unlikely(!buffer_uptodate(cn->bh))) {
#ifdef CONFIG_REISERFS_CHECK
					reiserfs_warning(s, "journal-949",
							 "buffer write failed");
#endif
					err = -EIO;
				}
				/*
				 * note, we must clear the JDirty_wait bit
				 * after the up to date check, otherwise we
				 * race against our flushpage routine
				 */
				BUG_ON(!test_clear_buffer_journal_dirty
				       (cn->bh));

				/* drop one ref for us */
				put_bh(cn->bh);
				/* drop one ref for journal_mark_dirty */
				release_buffer_page(cn->bh);
			}
			cn = cn->next;
		}
	}

	if (err)
		reiserfs_abort(s, -EIO,
			       "Write error while pushing transaction to disk in %s",
			       __func__);
flush_older_and_return:

	/*
	 * before we can update the journal header block, we _must_ flush all
	 * real blocks from all older transactions to disk.  This is because
	 * once the header block is updated, this transaction will not be
	 * replayed after a crash
	 */
	if (flushall) {
		flush_older_journal_lists(s, jl);
	}

	err = journal->j_errno;
	/*
	 * before we can remove everything from the hash tables for this
	 * transaction, we must make sure it can never be replayed
	 *
	 * since we are only called from do_journal_end, we know for sure there
	 * are no allocations going on while we are flushing journal lists.  So,
	 * we only need to update the journal header block for the last list
	 * being flushed
	 */
	if (!err && flushall) {
		err =
		    update_journal_header_block(s,
						(jl->j_start + jl->j_len +
						 2) % SB_ONDISK_JOURNAL_SIZE(s),
						jl->j_trans_id);
		if (err)
			reiserfs_abort(s, -EIO,
				       "Write error while updating journal header in %s",
				       __func__);
	}
	remove_all_from_journal_list(s, jl, 0);
	list_del_init(&jl->j_list);
	journal->j_num_lists--;
	del_from_work_list(s, jl);

	if (journal->j_last_flush_id != 0 &&
	    (jl->j_trans_id - journal->j_last_flush_id) != 1) {
		reiserfs_warning(s, "clm-2201", "last flush %lu, current %lu",
				 journal->j_last_flush_id, jl->j_trans_id);
	}
	journal->j_last_flush_id = jl->j_trans_id;

	/*
	 * not strictly required since we are freeing the list, but it should
	 * help find code using dead lists later on
	 */
	jl->j_len = 0;
	atomic_set(&jl->j_nonzerolen, 0);
	jl->j_start = 0;
	jl->j_realblock = NULL;
	jl->j_commit_bh = NULL;
	jl->j_trans_id = 0;
	jl->j_state = 0;
	put_journal_list(s, jl);
	if (flushall)
		mutex_unlock(&journal->j_flush_mutex);
	return err;
}

static int write_one_transaction(struct super_block *s,
				 struct reiserfs_journal_list *jl,
				 struct buffer_chunk *chunk)
{
	struct reiserfs_journal_cnode *cn;
	int ret = 0;

	jl->j_state |= LIST_TOUCHED;
	del_from_work_list(s, jl);
	if (jl->j_len == 0 || atomic_read(&jl->j_nonzerolen) == 0) {
		return 0;
	}

	cn = jl->j_realblock;
	while (cn) {
		/*
		 * if the blocknr == 0, this has been cleared from the hash,
		 * skip it
		 */
		if (cn->blocknr == 0) {
			goto next;
		}
		if (cn->bh && can_dirty(cn) && buffer_dirty(cn->bh)) {
			struct buffer_head *tmp_bh;
			/*
			 * we can race against journal_mark_freed when we try
			 * to lock_buffer(cn->bh), so we have to inc the buffer
			 * count, and recheck things after locking
			 */
			tmp_bh = cn->bh;
			get_bh(tmp_bh);
			lock_buffer(tmp_bh);
			if (cn->bh && can_dirty(cn) && buffer_dirty(tmp_bh)) {
				if (!buffer_journal_dirty(tmp_bh) ||
				    buffer_journal_prepared(tmp_bh))
					BUG();
				add_to_chunk(chunk, tmp_bh, NULL, write_chunk);
				ret++;
			} else {
				/* note, cn->bh might be null now */
				unlock_buffer(tmp_bh);
			}
			put_bh(tmp_bh);
		}
next:
		cn = cn->next;
		cond_resched();
	}
	return ret;
}

/* used by flush_commit_list */
static int dirty_one_transaction(struct super_block *s,
				 struct reiserfs_journal_list *jl)
{
	struct reiserfs_journal_cnode *cn;
	struct reiserfs_journal_list *pjl;
	int ret = 0;

	jl->j_state |= LIST_DIRTY;
	cn = jl->j_realblock;
	while (cn) {
		/*
		 * look for a more recent transaction that logged this
		 * buffer.  Only the most recent transaction with a buffer in
		 * it is allowed to send that buffer to disk
		 */
		pjl = find_newer_jl_for_cn(cn);
		if (!pjl && cn->blocknr && cn->bh
		    && buffer_journal_dirty(cn->bh)) {
			BUG_ON(!can_dirty(cn));
			/*
			 * if the buffer is prepared, it will either be logged
			 * or restored.  If restored, we need to make sure
			 * it actually gets marked dirty
			 */
			clear_buffer_journal_new(cn->bh);
			if (buffer_journal_prepared(cn->bh)) {
				set_buffer_journal_restore_dirty(cn->bh);
			} else {
				set_buffer_journal_test(cn->bh);
				mark_buffer_dirty(cn->bh);
			}
		}
		cn = cn->next;
	}
	return ret;
}

static int kupdate_transactions(struct super_block *s,
				struct reiserfs_journal_list *jl,
				struct reiserfs_journal_list **next_jl,
				unsigned int *next_trans_id,
				int num_blocks, int num_trans)
{
	int ret = 0;
	int written = 0;
	int transactions_flushed = 0;
	unsigned int orig_trans_id = jl->j_trans_id;
	struct buffer_chunk chunk;
	struct list_head *entry;
	struct reiserfs_journal *journal = SB_JOURNAL(s);
	chunk.nr = 0;

	reiserfs_mutex_lock_safe(&journal->j_flush_mutex, s);
	if (!journal_list_still_alive(s, orig_trans_id)) {
		goto done;
	}

	/*
	 * we've got j_flush_mutex held, nobody is going to delete any
	 * of these lists out from underneath us
	 */
	while ((num_trans && transactions_flushed < num_trans) ||
	       (!num_trans && written < num_blocks)) {

		if (jl->j_len == 0 || (jl->j_state & LIST_TOUCHED) ||
		    atomic_read(&jl->j_commit_left)
		    || !(jl->j_state & LIST_DIRTY)) {
			del_from_work_list(s, jl);
			break;
		}
		ret = write_one_transaction(s, jl, &chunk);

		if (ret < 0)
			goto done;
		transactions_flushed++;
		written += ret;
		entry = jl->j_list.next;

		/* did we wrap? */
		if (entry == &journal->j_journal_list) {
			break;
		}
		jl = JOURNAL_LIST_ENTRY(entry);

		/* don't bother with older transactions */
		if (jl->j_trans_id <= orig_trans_id)
			break;
	}
	if (chunk.nr) {
		write_chunk(&chunk);
	}

done:
	mutex_unlock(&journal->j_flush_mutex);
	return ret;
}

/*
 * for o_sync and fsync heavy applications, they tend to use
 * all the journa list slots with tiny transactions.  These
 * trigger lots and lots of calls to update the header block, which
 * adds seeks and slows things down.
 *
 * This function tries to clear out a large chunk of the journal lists
 * at once, which makes everything faster since only the newest journal
 * list updates the header block
 */
static int flush_used_journal_lists(struct super_block *s,
				    struct reiserfs_journal_list *jl)
{
	unsigned long len = 0;
	unsigned long cur_len;
	int ret;
	int i;
	int limit = 256;
	struct reiserfs_journal_list *tjl;
	struct reiserfs_journal_list *flush_jl;
	unsigned int trans_id;
	struct reiserfs_journal *journal = SB_JOURNAL(s);

	flush_jl = tjl = jl;

	/* in data logging mode, try harder to flush a lot of blocks */
	if (reiserfs_data_log(s))
		limit = 1024;
	/* flush for 256 transactions or limit blocks, whichever comes first */
	for (i = 0; i < 256 && len < limit; i++) {
		if (atomic_read(&tjl->j_commit_left) ||
		    tjl->j_trans_id < jl->j_trans_id) {
			break;
		}
		cur_len = atomic_read(&tjl->j_nonzerolen);
		if (cur_len > 0) {
			tjl->j_state &= ~LIST_TOUCHED;
		}
		len += cur_len;
		flush_jl = tjl;
		if (tjl->j_list.next == &journal->j_journal_list)
			break;
		tjl = JOURNAL_LIST_ENTRY(tjl->j_list.next);
	}
	get_journal_list(jl);
	get_journal_list(flush_jl);

	/*
	 * try to find a group of blocks we can flush across all the
	 * transactions, but only bother if we've actually spanned
	 * across multiple lists
	 */
	if (flush_jl != jl) {
		ret = kupdate_transactions(s, jl, &tjl, &trans_id, len, i);
	}
	flush_journal_list(s, flush_jl, 1);
	put_journal_list(s, flush_jl);
	put_journal_list(s, jl);
	return 0;
}

/*
 * removes any nodes in table with name block and dev as bh.
 * only touchs the hnext and hprev pointers.
 */
void remove_journal_hash(struct super_block *sb,
			 struct reiserfs_journal_cnode **table,
			 struct reiserfs_journal_list *jl,
			 unsigned long block, int remove_freed)
{
	struct reiserfs_journal_cnode *cur;
	struct reiserfs_journal_cnode **head;

	head = &(journal_hash(table, sb, block));
	if (!head) {
		return;
	}
	cur = *head;
	while (cur) {
		if (cur->blocknr == block && cur->sb == sb
		    && (jl == NULL || jl == cur->jlist)
		    && (!test_bit(BLOCK_FREED, &cur->state) || remove_freed)) {
			if (cur->hnext) {
				cur->hnext->hprev = cur->hprev;
			}
			if (cur->hprev) {
				cur->hprev->hnext = cur->hnext;
			} else {
				*head = cur->hnext;
			}
			cur->blocknr = 0;
			cur->sb = NULL;
			cur->state = 0;
			/*
			 * anybody who clears the cur->bh will also
			 * dec the nonzerolen
			 */
			if (cur->bh && cur->jlist)
				atomic_dec(&cur->jlist->j_nonzerolen);
			cur->bh = NULL;
			cur->jlist = NULL;
		}
		cur = cur->hnext;
	}
}

static void free_journal_ram(struct super_block *sb)
{
	struct reiserfs_journal *journal = SB_JOURNAL(sb);
	kfree(journal->j_current_jl);
	journal->j_num_lists--;

	vfree(journal->j_cnode_free_orig);
	free_list_bitmaps(sb, journal->j_list_bitmap);
	free_bitmap_nodes(sb);	/* must be after free_list_bitmaps */
	if (journal->j_header_bh) {
		brelse(journal->j_header_bh);
	}
	/*
	 * j_header_bh is on the journal dev, make sure
	 * not to release the journal dev until we brelse j_header_bh
	 */
	release_journal_dev(sb, journal);
	vfree(journal);
}

/*
 * call on unmount.  Only set error to 1 if you haven't made your way out
 * of read_super() yet.  Any other caller must keep error at 0.
 */
static int do_journal_release(struct reiserfs_transaction_handle *th,
			      struct super_block *sb, int error)
{
	struct reiserfs_transaction_handle myth;
	int flushed = 0;
	struct reiserfs_journal *journal = SB_JOURNAL(sb);

	/*
	 * we only want to flush out transactions if we were
	 * called with error == 0
	 */
	if (!error && !sb_rdonly(sb)) {
		/* end the current trans */
		BUG_ON(!th->t_trans_id);
		do_journal_end(th, FLUSH_ALL);

		/*
		 * make sure something gets logged to force
		 * our way into the flush code
		 */
		if (!journal_join(&myth, sb)) {
			reiserfs_prepare_for_journal(sb,
						     SB_BUFFER_WITH_SB(sb),
						     1);
			journal_mark_dirty(&myth, SB_BUFFER_WITH_SB(sb));
			do_journal_end(&myth, FLUSH_ALL);
			flushed = 1;
		}
	}

	/* this also catches errors during the do_journal_end above */
	if (!error && reiserfs_is_journal_aborted(journal)) {
		memset(&myth, 0, sizeof(myth));
		if (!journal_join_abort(&myth, sb)) {
			reiserfs_prepare_for_journal(sb,
						     SB_BUFFER_WITH_SB(sb),
						     1);
			journal_mark_dirty(&myth, SB_BUFFER_WITH_SB(sb));
			do_journal_end(&myth, FLUSH_ALL);
		}
	}


	/*
	 * We must release the write lock here because
	 * the workqueue job (flush_async_commit) needs this lock
	 */
	reiserfs_write_unlock(sb);

	/*
	 * Cancel flushing of old commits. Note that neither of these works
	 * will be requeued because superblock is being shutdown and doesn't
	 * have MS_ACTIVE set.
	 */
	reiserfs_cancel_old_flush(sb);
	/* wait for all commits to finish */
	cancel_delayed_work_sync(&SB_JOURNAL(sb)->j_work);

	free_journal_ram(sb);

	reiserfs_write_lock(sb);

	return 0;
}

/* * call on unmount.  flush all journal trans, release all alloc'd ram */
int journal_release(struct reiserfs_transaction_handle *th,
		    struct super_block *sb)
{
	return do_journal_release(th, sb, 0);
}

/* only call from an error condition inside reiserfs_read_super!  */
int journal_release_error(struct reiserfs_transaction_handle *th,
			  struct super_block *sb)
{
	return do_journal_release(th, sb, 1);
}

/*
 * compares description block with commit block.
 * returns 1 if they differ, 0 if they are the same
 */
static int journal_compare_desc_commit(struct super_block *sb,
				       struct reiserfs_journal_desc *desc,
				       struct reiserfs_journal_commit *commit)
{
	if (get_commit_trans_id(commit) != get_desc_trans_id(desc) ||
	    get_commit_trans_len(commit) != get_desc_trans_len(desc) ||
	    get_commit_trans_len(commit) > SB_JOURNAL(sb)->j_trans_max ||
	    get_commit_trans_len(commit) <= 0) {
		return 1;
	}
	return 0;
}

/*
 * returns 0 if it did not find a description block
 * returns -1 if it found a corrupt commit block
 * returns 1 if both desc and commit were valid
 * NOTE: only called during fs mount
 */
static int journal_transaction_is_valid(struct super_block *sb,
					struct buffer_head *d_bh,
					unsigned int *oldest_invalid_trans_id,
					unsigned long *newest_mount_id)
{
	struct reiserfs_journal_desc *desc;
	struct reiserfs_journal_commit *commit;
	struct buffer_head *c_bh;
	unsigned long offset;

	if (!d_bh)
		return 0;

	desc = (struct reiserfs_journal_desc *)d_bh->b_data;
	if (get_desc_trans_len(desc) > 0
	    && !memcmp(get_journal_desc_magic(d_bh), JOURNAL_DESC_MAGIC, 8)) {
		if (oldest_invalid_trans_id && *oldest_invalid_trans_id
		    && get_desc_trans_id(desc) > *oldest_invalid_trans_id) {
			reiserfs_debug(sb, REISERFS_DEBUG_CODE,
				       "journal-986: transaction "
				       "is valid returning because trans_id %d is greater than "
				       "oldest_invalid %lu",
				       get_desc_trans_id(desc),
				       *oldest_invalid_trans_id);
			return 0;
		}
		if (newest_mount_id
		    && *newest_mount_id > get_desc_mount_id(desc)) {
			reiserfs_debug(sb, REISERFS_DEBUG_CODE,
				       "journal-1087: transaction "
				       "is valid returning because mount_id %d is less than "
				       "newest_mount_id %lu",
				       get_desc_mount_id(desc),
				       *newest_mount_id);
			return -1;
		}
		if (get_desc_trans_len(desc) > SB_JOURNAL(sb)->j_trans_max) {
			reiserfs_warning(sb, "journal-2018",
					 "Bad transaction length %d "
					 "encountered, ignoring transaction",
					 get_desc_trans_len(desc));
			return -1;
		}
		offset = d_bh->b_blocknr - SB_ONDISK_JOURNAL_1st_BLOCK(sb);

		/*
		 * ok, we have a journal description block,
		 * let's see if the transaction was valid
		 */
		c_bh =
		    journal_bread(sb,
				  SB_ONDISK_JOURNAL_1st_BLOCK(sb) +
				  ((offset + get_desc_trans_len(desc) +
				    1) % SB_ONDISK_JOURNAL_SIZE(sb)));
		if (!c_bh)
			return 0;
		commit = (struct reiserfs_journal_commit *)c_bh->b_data;
		if (journal_compare_desc_commit(sb, desc, commit)) {
			reiserfs_debug(sb, REISERFS_DEBUG_CODE,
				       "journal_transaction_is_valid, commit offset %ld had bad "
				       "time %d or length %d",
				       c_bh->b_blocknr -
				       SB_ONDISK_JOURNAL_1st_BLOCK(sb),
				       get_commit_trans_id(commit),
				       get_commit_trans_len(commit));
			brelse(c_bh);
			if (oldest_invalid_trans_id) {
				*oldest_invalid_trans_id =
				    get_desc_trans_id(desc);
				reiserfs_debug(sb, REISERFS_DEBUG_CODE,
					       "journal-1004: "
					       "transaction_is_valid setting oldest invalid trans_id "
					       "to %d",
					       get_desc_trans_id(desc));
			}
			return -1;
		}
		brelse(c_bh);
		reiserfs_debug(sb, REISERFS_DEBUG_CODE,
			       "journal-1006: found valid "
			       "transaction start offset %llu, len %d id %d",
			       d_bh->b_blocknr -
			       SB_ONDISK_JOURNAL_1st_BLOCK(sb),
			       get_desc_trans_len(desc),
			       get_desc_trans_id(desc));
		return 1;
	} else {
		return 0;
	}
}

static void brelse_array(struct buffer_head **heads, int num)
{
	int i;
	for (i = 0; i < num; i++) {
		brelse(heads[i]);
	}
}

/*
 * given the start, and values for the oldest acceptable transactions,
 * this either reads in a replays a transaction, or returns because the
 * transaction is invalid, or too old.
 * NOTE: only called during fs mount
 */
static int journal_read_transaction(struct super_block *sb,
				    unsigned long cur_dblock,
				    unsigned long oldest_start,
				    unsigned int oldest_trans_id,
				    unsigned long newest_mount_id)
{
	struct reiserfs_journal *journal = SB_JOURNAL(sb);
	struct reiserfs_journal_desc *desc;
	struct reiserfs_journal_commit *commit;
	unsigned int trans_id = 0;
	struct buffer_head *c_bh;
	struct buffer_head *d_bh;
	struct buffer_head **log_blocks = NULL;
	struct buffer_head **real_blocks = NULL;
	unsigned int trans_offset;
	int i;
	int trans_half;

	d_bh = journal_bread(sb, cur_dblock);
	if (!d_bh)
		return 1;
	desc = (struct reiserfs_journal_desc *)d_bh->b_data;
	trans_offset = d_bh->b_blocknr - SB_ONDISK_JOURNAL_1st_BLOCK(sb);
	reiserfs_debug(sb, REISERFS_DEBUG_CODE, "journal-1037: "
		       "journal_read_transaction, offset %llu, len %d mount_id %d",
		       d_bh->b_blocknr - SB_ONDISK_JOURNAL_1st_BLOCK(sb),
		       get_desc_trans_len(desc), get_desc_mount_id(desc));
	if (get_desc_trans_id(desc) < oldest_trans_id) {
		reiserfs_debug(sb, REISERFS_DEBUG_CODE, "journal-1039: "
			       "journal_read_trans skipping because %lu is too old",
			       cur_dblock -
			       SB_ONDISK_JOURNAL_1st_BLOCK(sb));
		brelse(d_bh);
		return 1;
	}
	if (get_desc_mount_id(desc) != newest_mount_id) {
		reiserfs_debug(sb, REISERFS_DEBUG_CODE, "journal-1146: "
			       "journal_read_trans skipping because %d is != "
			       "newest_mount_id %lu", get_desc_mount_id(desc),
			       newest_mount_id);
		brelse(d_bh);
		return 1;
	}
	c_bh = journal_bread(sb, SB_ONDISK_JOURNAL_1st_BLOCK(sb) +
			     ((trans_offset + get_desc_trans_len(desc) + 1) %
			      SB_ONDISK_JOURNAL_SIZE(sb)));
	if (!c_bh) {
		brelse(d_bh);
		return 1;
	}
	commit = (struct reiserfs_journal_commit *)c_bh->b_data;
	if (journal_compare_desc_commit(sb, desc, commit)) {
		reiserfs_debug(sb, REISERFS_DEBUG_CODE,
			       "journal_read_transaction, "
			       "commit offset %llu had bad time %d or length %d",
			       c_bh->b_blocknr -
			       SB_ONDISK_JOURNAL_1st_BLOCK(sb),
			       get_commit_trans_id(commit),
			       get_commit_trans_len(commit));
		brelse(c_bh);
		brelse(d_bh);
		return 1;
	}

	if (bdev_read_only(sb->s_bdev)) {
		reiserfs_warning(sb, "clm-2076",
				 "device is readonly, unable to replay log");
		brelse(c_bh);
		brelse(d_bh);
		return -EROFS;
	}

	trans_id = get_desc_trans_id(desc);
	/*
	 * now we know we've got a good transaction, and it was
	 * inside the valid time ranges
	 */
	log_blocks = kmalloc(get_desc_trans_len(desc) *
			     sizeof(struct buffer_head *), GFP_NOFS);
	real_blocks = kmalloc(get_desc_trans_len(desc) *
			      sizeof(struct buffer_head *), GFP_NOFS);
	if (!log_blocks || !real_blocks) {
		brelse(c_bh);
		brelse(d_bh);
		kfree(log_blocks);
		kfree(real_blocks);
		reiserfs_warning(sb, "journal-1169",
				 "kmalloc failed, unable to mount FS");
		return -1;
	}
	/* get all the buffer heads */
	trans_half = journal_trans_half(sb->s_blocksize);
	for (i = 0; i < get_desc_trans_len(desc); i++) {
		log_blocks[i] =
		    journal_getblk(sb,
				   SB_ONDISK_JOURNAL_1st_BLOCK(sb) +
				   (trans_offset + 1 +
				    i) % SB_ONDISK_JOURNAL_SIZE(sb));
		if (i < trans_half) {
			real_blocks[i] =
			    sb_getblk(sb,
				      le32_to_cpu(desc->j_realblock[i]));
		} else {
			real_blocks[i] =
			    sb_getblk(sb,
				      le32_to_cpu(commit->
						  j_realblock[i - trans_half]));
		}
		if (real_blocks[i]->b_blocknr > SB_BLOCK_COUNT(sb)) {
			reiserfs_warning(sb, "journal-1207",
					 "REPLAY FAILURE fsck required! "
					 "Block to replay is outside of "
					 "filesystem");
			goto abort_replay;
		}
		/* make sure we don't try to replay onto log or reserved area */
		if (is_block_in_log_or_reserved_area
		    (sb, real_blocks[i]->b_blocknr)) {
			reiserfs_warning(sb, "journal-1204",
					 "REPLAY FAILURE fsck required! "
					 "Trying to replay onto a log block");
abort_replay:
			brelse_array(log_blocks, i);
			brelse_array(real_blocks, i);
			brelse(c_bh);
			brelse(d_bh);
			kfree(log_blocks);
			kfree(real_blocks);
			return -1;
		}
	}
	/* read in the log blocks, memcpy to the corresponding real block */
	ll_rw_block(REQ_OP_READ, 0, get_desc_trans_len(desc), log_blocks);
	for (i = 0; i < get_desc_trans_len(desc); i++) {

		wait_on_buffer(log_blocks[i]);
		if (!buffer_uptodate(log_blocks[i])) {
			reiserfs_warning(sb, "journal-1212",
					 "REPLAY FAILURE fsck required! "
					 "buffer write failed");
			brelse_array(log_blocks + i,
				     get_desc_trans_len(desc) - i);
			brelse_array(real_blocks, get_desc_trans_len(desc));
			brelse(c_bh);
			brelse(d_bh);
			kfree(log_blocks);
			kfree(real_blocks);
			return -1;
		}
		memcpy(real_blocks[i]->b_data, log_blocks[i]->b_data,
		       real_blocks[i]->b_size);
		set_buffer_uptodate(real_blocks[i]);
		brelse(log_blocks[i]);
	}
	/* flush out the real blocks */
	for (i = 0; i < get_desc_trans_len(desc); i++) {
		set_buffer_dirty(real_blocks[i]);
		write_dirty_buffer(real_blocks[i], 0);
	}
	for (i = 0; i < get_desc_trans_len(desc); i++) {
		wait_on_buffer(real_blocks[i]);
		if (!buffer_uptodate(real_blocks[i])) {
			reiserfs_warning(sb, "journal-1226",
					 "REPLAY FAILURE, fsck required! "
					 "buffer write failed");
			brelse_array(real_blocks + i,
				     get_desc_trans_len(desc) - i);
			brelse(c_bh);
			brelse(d_bh);
			kfree(log_blocks);
			kfree(real_blocks);
			return -1;
		}
		brelse(real_blocks[i]);
	}
	cur_dblock =
	    SB_ONDISK_JOURNAL_1st_BLOCK(sb) +
	    ((trans_offset + get_desc_trans_len(desc) +
	      2) % SB_ONDISK_JOURNAL_SIZE(sb));
	reiserfs_debug(sb, REISERFS_DEBUG_CODE,
		       "journal-1095: setting journal " "start to offset %ld",
		       cur_dblock - SB_ONDISK_JOURNAL_1st_BLOCK(sb));

	/*
	 * init starting values for the first transaction, in case
	 * this is the last transaction to be replayed.
	 */
	journal->j_start = cur_dblock - SB_ONDISK_JOURNAL_1st_BLOCK(sb);
	journal->j_last_flush_trans_id = trans_id;
	journal->j_trans_id = trans_id + 1;
	/* check for trans_id overflow */
	if (journal->j_trans_id == 0)
		journal->j_trans_id = 10;
	brelse(c_bh);
	brelse(d_bh);
	kfree(log_blocks);
	kfree(real_blocks);
	return 0;
}

/*
 * This function reads blocks starting from block and to max_block of bufsize
 * size (but no more than BUFNR blocks at a time). This proved to improve
 * mounting speed on self-rebuilding raid5 arrays at least.
 * Right now it is only used from journal code. But later we might use it
 * from other places.
 * Note: Do not use journal_getblk/sb_getblk functions here!
 */
static struct buffer_head *reiserfs_breada(struct block_device *dev,
					   b_blocknr_t block, int bufsize,
					   b_blocknr_t max_block)
{
	struct buffer_head *bhlist[BUFNR];
	unsigned int blocks = BUFNR;
	struct buffer_head *bh;
	int i, j;

	bh = __getblk(dev, block, bufsize);
	if (buffer_uptodate(bh))
		return (bh);

	if (block + BUFNR > max_block) {
		blocks = max_block - block;
	}
	bhlist[0] = bh;
	j = 1;
	for (i = 1; i < blocks; i++) {
		bh = __getblk(dev, block + i, bufsize);
		if (buffer_uptodate(bh)) {
			brelse(bh);
			break;
		} else
			bhlist[j++] = bh;
	}
	ll_rw_block(REQ_OP_READ, 0, j, bhlist);
	for (i = 1; i < j; i++)
		brelse(bhlist[i]);
	bh = bhlist[0];
	wait_on_buffer(bh);
	if (buffer_uptodate(bh))
		return bh;
	brelse(bh);
	return NULL;
}

/*
 * read and replay the log
 * on a clean unmount, the journal header's next unflushed pointer will be
 * to an invalid transaction.  This tests that before finding all the
 * transactions in the log, which makes normal mount times fast.
 *
 * After a crash, this starts with the next unflushed transaction, and
 * replays until it finds one too old, or invalid.
 *
 * On exit, it sets things up so the first transaction will work correctly.
 * NOTE: only called during fs mount
 */
static int journal_read(struct super_block *sb)
{
	struct reiserfs_journal *journal = SB_JOURNAL(sb);
	struct reiserfs_journal_desc *desc;
	unsigned int oldest_trans_id = 0;
	unsigned int oldest_invalid_trans_id = 0;
	time_t start;
	unsigned long oldest_start = 0;
	unsigned long cur_dblock = 0;
	unsigned long newest_mount_id = 9;
	struct buffer_head *d_bh;
	struct reiserfs_journal_header *jh;
	int valid_journal_header = 0;
	int replay_count = 0;
	int continue_replay = 1;
	int ret;

	cur_dblock = SB_ONDISK_JOURNAL_1st_BLOCK(sb);
	reiserfs_info(sb, "checking transaction log (%pg)\n",
		      journal->j_dev_bd);
	start = get_seconds();

	/*
	 * step 1, read in the journal header block.  Check the transaction
	 * it says is the first unflushed, and if that transaction is not
	 * valid, replay is done
	 */
	journal->j_header_bh = journal_bread(sb,
					     SB_ONDISK_JOURNAL_1st_BLOCK(sb)
					     + SB_ONDISK_JOURNAL_SIZE(sb));
	if (!journal->j_header_bh) {
		return 1;
	}
	jh = (struct reiserfs_journal_header *)(journal->j_header_bh->b_data);
	if (le32_to_cpu(jh->j_first_unflushed_offset) <
	    SB_ONDISK_JOURNAL_SIZE(sb)
	    && le32_to_cpu(jh->j_last_flush_trans_id) > 0) {
		oldest_start =
		    SB_ONDISK_JOURNAL_1st_BLOCK(sb) +
		    le32_to_cpu(jh->j_first_unflushed_offset);
		oldest_trans_id = le32_to_cpu(jh->j_last_flush_trans_id) + 1;
		newest_mount_id = le32_to_cpu(jh->j_mount_id);
		reiserfs_debug(sb, REISERFS_DEBUG_CODE,
			       "journal-1153: found in "
			       "header: first_unflushed_offset %d, last_flushed_trans_id "
			       "%lu", le32_to_cpu(jh->j_first_unflushed_offset),
			       le32_to_cpu(jh->j_last_flush_trans_id));
		valid_journal_header = 1;

		/*
		 * now, we try to read the first unflushed offset.  If it
		 * is not valid, there is nothing more we can do, and it
		 * makes no sense to read through the whole log.
		 */
		d_bh =
		    journal_bread(sb,
				  SB_ONDISK_JOURNAL_1st_BLOCK(sb) +
				  le32_to_cpu(jh->j_first_unflushed_offset));
		ret = journal_transaction_is_valid(sb, d_bh, NULL, NULL);
		if (!ret) {
			continue_replay = 0;
		}
		brelse(d_bh);
		goto start_log_replay;
	}

	/*
	 * ok, there are transactions that need to be replayed.  start
	 * with the first log block, find all the valid transactions, and
	 * pick out the oldest.
	 */
	while (continue_replay
	       && cur_dblock <
	       (SB_ONDISK_JOURNAL_1st_BLOCK(sb) +
		SB_ONDISK_JOURNAL_SIZE(sb))) {
		/*
		 * Note that it is required for blocksize of primary fs
		 * device and journal device to be the same
		 */
		d_bh =
		    reiserfs_breada(journal->j_dev_bd, cur_dblock,
				    sb->s_blocksize,
				    SB_ONDISK_JOURNAL_1st_BLOCK(sb) +
				    SB_ONDISK_JOURNAL_SIZE(sb));
		ret =
		    journal_transaction_is_valid(sb, d_bh,
						 &oldest_invalid_trans_id,
						 &newest_mount_id);
		if (ret == 1) {
			desc = (struct reiserfs_journal_desc *)d_bh->b_data;
			if (oldest_start == 0) {	/* init all oldest_ values */
				oldest_trans_id = get_desc_trans_id(desc);
				oldest_start = d_bh->b_blocknr;
				newest_mount_id = get_desc_mount_id(desc);
				reiserfs_debug(sb, REISERFS_DEBUG_CODE,
					       "journal-1179: Setting "
					       "oldest_start to offset %llu, trans_id %lu",
					       oldest_start -
					       SB_ONDISK_JOURNAL_1st_BLOCK
					       (sb), oldest_trans_id);
			} else if (oldest_trans_id > get_desc_trans_id(desc)) {
				/* one we just read was older */
				oldest_trans_id = get_desc_trans_id(desc);
				oldest_start = d_bh->b_blocknr;
				reiserfs_debug(sb, REISERFS_DEBUG_CODE,
					       "journal-1180: Resetting "
					       "oldest_start to offset %lu, trans_id %lu",
					       oldest_start -
					       SB_ONDISK_JOURNAL_1st_BLOCK
					       (sb), oldest_trans_id);
			}
			if (newest_mount_id < get_desc_mount_id(desc)) {
				newest_mount_id = get_desc_mount_id(desc);
				reiserfs_debug(sb, REISERFS_DEBUG_CODE,
					       "journal-1299: Setting "
					       "newest_mount_id to %d",
					       get_desc_mount_id(desc));
			}
			cur_dblock += get_desc_trans_len(desc) + 2;
		} else {
			cur_dblock++;
		}
		brelse(d_bh);
	}

start_log_replay:
	cur_dblock = oldest_start;
	if (oldest_trans_id) {
		reiserfs_debug(sb, REISERFS_DEBUG_CODE,
			       "journal-1206: Starting replay "
			       "from offset %llu, trans_id %lu",
			       cur_dblock - SB_ONDISK_JOURNAL_1st_BLOCK(sb),
			       oldest_trans_id);

	}
	replay_count = 0;
	while (continue_replay && oldest_trans_id > 0) {
		ret =
		    journal_read_transaction(sb, cur_dblock, oldest_start,
					     oldest_trans_id, newest_mount_id);
		if (ret < 0) {
			return ret;
		} else if (ret != 0) {
			break;
		}
		cur_dblock =
		    SB_ONDISK_JOURNAL_1st_BLOCK(sb) + journal->j_start;
		replay_count++;
		if (cur_dblock == oldest_start)
			break;
	}

	if (oldest_trans_id == 0) {
		reiserfs_debug(sb, REISERFS_DEBUG_CODE,
			       "journal-1225: No valid " "transactions found");
	}
	/*
	 * j_start does not get set correctly if we don't replay any
	 * transactions.  if we had a valid journal_header, set j_start
	 * to the first unflushed transaction value, copy the trans_id
	 * from the header
	 */
	if (valid_journal_header && replay_count == 0) {
		journal->j_start = le32_to_cpu(jh->j_first_unflushed_offset);
		journal->j_trans_id =
		    le32_to_cpu(jh->j_last_flush_trans_id) + 1;
		/* check for trans_id overflow */
		if (journal->j_trans_id == 0)
			journal->j_trans_id = 10;
		journal->j_last_flush_trans_id =
		    le32_to_cpu(jh->j_last_flush_trans_id);
		journal->j_mount_id = le32_to_cpu(jh->j_mount_id) + 1;
	} else {
		journal->j_mount_id = newest_mount_id + 1;
	}
	reiserfs_debug(sb, REISERFS_DEBUG_CODE, "journal-1299: Setting "
		       "newest_mount_id to %lu", journal->j_mount_id);
	journal->j_first_unflushed_offset = journal->j_start;
	if (replay_count > 0) {
		reiserfs_info(sb,
			      "replayed %d transactions in %lu seconds\n",
			      replay_count, get_seconds() - start);
	}
	/* needed to satisfy the locking in _update_journal_header_block */
	reiserfs_write_lock(sb);
	if (!bdev_read_only(sb->s_bdev) &&
	    _update_journal_header_block(sb, journal->j_start,
					 journal->j_last_flush_trans_id)) {
		reiserfs_write_unlock(sb);
		/*
		 * replay failed, caller must call free_journal_ram and abort
		 * the mount
		 */
		return -1;
	}
	reiserfs_write_unlock(sb);
	return 0;
}

static struct reiserfs_journal_list *alloc_journal_list(struct super_block *s)
{
	struct reiserfs_journal_list *jl;
	jl = kzalloc(sizeof(struct reiserfs_journal_list),
		     GFP_NOFS | __GFP_NOFAIL);
	INIT_LIST_HEAD(&jl->j_list);
	INIT_LIST_HEAD(&jl->j_working_list);
	INIT_LIST_HEAD(&jl->j_tail_bh_list);
	INIT_LIST_HEAD(&jl->j_bh_list);
	mutex_init(&jl->j_commit_mutex);
	SB_JOURNAL(s)->j_num_lists++;
	get_journal_list(jl);
	return jl;
}

static void journal_list_init(struct super_block *sb)
{
	SB_JOURNAL(sb)->j_current_jl = alloc_journal_list(sb);
}

static void release_journal_dev(struct super_block *super,
			       struct reiserfs_journal *journal)
{
	if (journal->j_dev_bd != NULL) {
		blkdev_put(journal->j_dev_bd, journal->j_dev_mode);
		journal->j_dev_bd = NULL;
	}
}

static int journal_init_dev(struct super_block *super,
			    struct reiserfs_journal *journal,
			    const char *jdev_name)
{
	int result;
	dev_t jdev;
	fmode_t blkdev_mode = FMODE_READ | FMODE_WRITE | FMODE_EXCL;
	char b[BDEVNAME_SIZE];

	result = 0;

	journal->j_dev_bd = NULL;
	jdev = SB_ONDISK_JOURNAL_DEVICE(super) ?
	    new_decode_dev(SB_ONDISK_JOURNAL_DEVICE(super)) : super->s_dev;

	if (bdev_read_only(super->s_bdev))
		blkdev_mode = FMODE_READ;

	/* there is no "jdev" option and journal is on separate device */
	if ((!jdev_name || !jdev_name[0])) {
		if (jdev == super->s_dev)
			blkdev_mode &= ~FMODE_EXCL;
		journal->j_dev_bd = blkdev_get_by_dev(jdev, blkdev_mode,
						      journal);
		journal->j_dev_mode = blkdev_mode;
		if (IS_ERR(journal->j_dev_bd)) {
			result = PTR_ERR(journal->j_dev_bd);
			journal->j_dev_bd = NULL;
			reiserfs_warning(super, "sh-458",
					 "cannot init journal device '%s': %i",
					 __bdevname(jdev, b), result);
			return result;
		} else if (jdev != super->s_dev)
			set_blocksize(journal->j_dev_bd, super->s_blocksize);

		return 0;
	}

	journal->j_dev_mode = blkdev_mode;
	journal->j_dev_bd = blkdev_get_by_path(jdev_name, blkdev_mode, journal);
	if (IS_ERR(journal->j_dev_bd)) {
		result = PTR_ERR(journal->j_dev_bd);
		journal->j_dev_bd = NULL;
		reiserfs_warning(super,
				 "journal_init_dev: Cannot open '%s': %i",
				 jdev_name, result);
		return result;
	}

	set_blocksize(journal->j_dev_bd, super->s_blocksize);
	reiserfs_info(super,
		      "journal_init_dev: journal device: %pg\n",
		      journal->j_dev_bd);
	return 0;
}

/*
 * When creating/tuning a file system user can assign some
 * journal params within boundaries which depend on the ratio
 * blocksize/standard_blocksize.
 *
 * For blocks >= standard_blocksize transaction size should
 * be not less then JOURNAL_TRANS_MIN_DEFAULT, and not more
 * then JOURNAL_TRANS_MAX_DEFAULT.
 *
 * For blocks < standard_blocksize these boundaries should be
 * decreased proportionally.
 */
#define REISERFS_STANDARD_BLKSIZE (4096)

static int check_advise_trans_params(struct super_block *sb,
				     struct reiserfs_journal *journal)
{
        if (journal->j_trans_max) {
		/* Non-default journal params.  Do sanity check for them. */
	        int ratio = 1;
		if (sb->s_blocksize < REISERFS_STANDARD_BLKSIZE)
		        ratio = REISERFS_STANDARD_BLKSIZE / sb->s_blocksize;

		if (journal->j_trans_max > JOURNAL_TRANS_MAX_DEFAULT / ratio ||
		    journal->j_trans_max < JOURNAL_TRANS_MIN_DEFAULT / ratio ||
		    SB_ONDISK_JOURNAL_SIZE(sb) / journal->j_trans_max <
		    JOURNAL_MIN_RATIO) {
			reiserfs_warning(sb, "sh-462",
					 "bad transaction max size (%u). "
					 "FSCK?", journal->j_trans_max);
			return 1;
		}
		if (journal->j_max_batch != (journal->j_trans_max) *
		        JOURNAL_MAX_BATCH_DEFAULT/JOURNAL_TRANS_MAX_DEFAULT) {
			reiserfs_warning(sb, "sh-463",
					 "bad transaction max batch (%u). "
					 "FSCK?", journal->j_max_batch);
			return 1;
		}
	} else {
		/*
		 * Default journal params.
		 * The file system was created by old version
		 * of mkreiserfs, so some fields contain zeros,
		 * and we need to advise proper values for them
		 */
		if (sb->s_blocksize != REISERFS_STANDARD_BLKSIZE) {
			reiserfs_warning(sb, "sh-464", "bad blocksize (%u)",
					 sb->s_blocksize);
			return 1;
		}
		journal->j_trans_max = JOURNAL_TRANS_MAX_DEFAULT;
		journal->j_max_batch = JOURNAL_MAX_BATCH_DEFAULT;
		journal->j_max_commit_age = JOURNAL_MAX_COMMIT_AGE;
	}
	return 0;
}

/* must be called once on fs mount.  calls journal_read for you */
int journal_init(struct super_block *sb, const char *j_dev_name,
		 int old_format, unsigned int commit_max_age)
{
	int num_cnodes = SB_ONDISK_JOURNAL_SIZE(sb) * 2;
	struct buffer_head *bhjh;
	struct reiserfs_super_block *rs;
	struct reiserfs_journal_header *jh;
	struct reiserfs_journal *journal;
	struct reiserfs_journal_list *jl;
	int ret;

	journal = SB_JOURNAL(sb) = vzalloc(sizeof(struct reiserfs_journal));
	if (!journal) {
		reiserfs_warning(sb, "journal-1256",
				 "unable to get memory for journal structure");
		return 1;
	}
	INIT_LIST_HEAD(&journal->j_bitmap_nodes);
	INIT_LIST_HEAD(&journal->j_prealloc_list);
	INIT_LIST_HEAD(&journal->j_working_list);
	INIT_LIST_HEAD(&journal->j_journal_list);
	journal->j_persistent_trans = 0;
	if (reiserfs_allocate_list_bitmaps(sb, journal->j_list_bitmap,
					   reiserfs_bmap_count(sb)))
		goto free_and_return;

	allocate_bitmap_nodes(sb);

	/* reserved for journal area support */
	SB_JOURNAL_1st_RESERVED_BLOCK(sb) = (old_format ?
						 REISERFS_OLD_DISK_OFFSET_IN_BYTES
						 / sb->s_blocksize +
						 reiserfs_bmap_count(sb) +
						 1 :
						 REISERFS_DISK_OFFSET_IN_BYTES /
						 sb->s_blocksize + 2);

	/*
	 * Sanity check to see is the standard journal fitting
	 * within first bitmap (actual for small blocksizes)
	 */
	if (!SB_ONDISK_JOURNAL_DEVICE(sb) &&
	    (SB_JOURNAL_1st_RESERVED_BLOCK(sb) +
	     SB_ONDISK_JOURNAL_SIZE(sb) > sb->s_blocksize * 8)) {
		reiserfs_warning(sb, "journal-1393",
				 "journal does not fit for area addressed "
				 "by first of bitmap blocks. It starts at "
				 "%u and its size is %u. Block size %ld",
				 SB_JOURNAL_1st_RESERVED_BLOCK(sb),
				 SB_ONDISK_JOURNAL_SIZE(sb),
				 sb->s_blocksize);
		goto free_and_return;
	}

	if (journal_init_dev(sb, journal, j_dev_name) != 0) {
		reiserfs_warning(sb, "sh-462",
				 "unable to initialize journal device");
		goto free_and_return;
	}

	rs = SB_DISK_SUPER_BLOCK(sb);

	/* read journal header */
	bhjh = journal_bread(sb,
			     SB_ONDISK_JOURNAL_1st_BLOCK(sb) +
			     SB_ONDISK_JOURNAL_SIZE(sb));
	if (!bhjh) {
		reiserfs_warning(sb, "sh-459",
				 "unable to read journal header");
		goto free_and_return;
	}
	jh = (struct reiserfs_journal_header *)(bhjh->b_data);

	/* make sure that journal matches to the super block */
	if (is_reiserfs_jr(rs)
	    && (le32_to_cpu(jh->jh_journal.jp_journal_magic) !=
		sb_jp_journal_magic(rs))) {
		reiserfs_warning(sb, "sh-460",
				 "journal header magic %x (device %pg) does "
				 "not match to magic found in super block %x",
				 jh->jh_journal.jp_journal_magic,
				 journal->j_dev_bd,
				 sb_jp_journal_magic(rs));
		brelse(bhjh);
		goto free_and_return;
	}

	journal->j_trans_max = le32_to_cpu(jh->jh_journal.jp_journal_trans_max);
	journal->j_max_batch = le32_to_cpu(jh->jh_journal.jp_journal_max_batch);
	journal->j_max_commit_age =
	    le32_to_cpu(jh->jh_journal.jp_journal_max_commit_age);
	journal->j_max_trans_age = JOURNAL_MAX_TRANS_AGE;

	if (check_advise_trans_params(sb, journal) != 0)
	        goto free_and_return;
	journal->j_default_max_commit_age = journal->j_max_commit_age;

	if (commit_max_age != 0) {
		journal->j_max_commit_age = commit_max_age;
		journal->j_max_trans_age = commit_max_age;
	}

	reiserfs_info(sb, "journal params: device %pg, size %u, "
		      "journal first block %u, max trans len %u, max batch %u, "
		      "max commit age %u, max trans age %u\n",
		      journal->j_dev_bd,
		      SB_ONDISK_JOURNAL_SIZE(sb),
		      SB_ONDISK_JOURNAL_1st_BLOCK(sb),
		      journal->j_trans_max,
		      journal->j_max_batch,
		      journal->j_max_commit_age, journal->j_max_trans_age);

	brelse(bhjh);

	journal->j_list_bitmap_index = 0;
	journal_list_init(sb);

	memset(journal->j_list_hash_table, 0,
	       JOURNAL_HASH_SIZE * sizeof(struct reiserfs_journal_cnode *));

	INIT_LIST_HEAD(&journal->j_dirty_buffers);
	spin_lock_init(&journal->j_dirty_buffers_lock);

	journal->j_start = 0;
	journal->j_len = 0;
	journal->j_len_alloc = 0;
	atomic_set(&journal->j_wcount, 0);
	atomic_set(&journal->j_async_throttle, 0);
	journal->j_bcount = 0;
	journal->j_trans_start_time = 0;
	journal->j_last = NULL;
	journal->j_first = NULL;
	init_waitqueue_head(&journal->j_join_wait);
	mutex_init(&journal->j_mutex);
	mutex_init(&journal->j_flush_mutex);

	journal->j_trans_id = 10;
	journal->j_mount_id = 10;
	journal->j_state = 0;
	atomic_set(&journal->j_jlock, 0);
	journal->j_cnode_free_list = allocate_cnodes(num_cnodes);
	journal->j_cnode_free_orig = journal->j_cnode_free_list;
	journal->j_cnode_free = journal->j_cnode_free_list ? num_cnodes : 0;
	journal->j_cnode_used = 0;
	journal->j_must_wait = 0;

	if (journal->j_cnode_free == 0) {
		reiserfs_warning(sb, "journal-2004", "Journal cnode memory "
		                 "allocation failed (%ld bytes). Journal is "
		                 "too large for available memory. Usually "
		                 "this is due to a journal that is too large.",
		                 sizeof (struct reiserfs_journal_cnode) * num_cnodes);
        	goto free_and_return;
	}

	init_journal_hash(sb);
	jl = journal->j_current_jl;

	/*
	 * get_list_bitmap() may call flush_commit_list() which
	 * requires the lock. Calling flush_commit_list() shouldn't happen
	 * this early but I like to be paranoid.
	 */
	reiserfs_write_lock(sb);
	jl->j_list_bitmap = get_list_bitmap(sb, jl);
	reiserfs_write_unlock(sb);
	if (!jl->j_list_bitmap) {
		reiserfs_warning(sb, "journal-2005",
				 "get_list_bitmap failed for journal list 0");
		goto free_and_return;
	}

	ret = journal_read(sb);
	if (ret < 0) {
		reiserfs_warning(sb, "reiserfs-2006",
				 "Replay Failure, unable to mount");
		goto free_and_return;
	}

	INIT_DELAYED_WORK(&journal->j_work, flush_async_commits);
	journal->j_work_sb = sb;
	return 0;
free_and_return:
	free_journal_ram(sb);
	return 1;
}

/*
 * test for a polite end of the current transaction.  Used by file_write,
 * and should be used by delete to make sure they don't write more than
 * can fit inside a single transaction
 */
int journal_transaction_should_end(struct reiserfs_transaction_handle *th,
				   int new_alloc)
{
	struct reiserfs_journal *journal = SB_JOURNAL(th->t_super);
	time_t now = get_seconds();
	/* cannot restart while nested */
	BUG_ON(!th->t_trans_id);
	if (th->t_refcount > 1)
		return 0;
	if (journal->j_must_wait > 0 ||
	    (journal->j_len_alloc + new_alloc) >= journal->j_max_batch ||
	    atomic_read(&journal->j_jlock) ||
	    (now - journal->j_trans_start_time) > journal->j_max_trans_age ||
	    journal->j_cnode_free < (journal->j_trans_max * 3)) {
		return 1;
	}

	journal->j_len_alloc += new_alloc;
	th->t_blocks_allocated += new_alloc ;
	return 0;
}

/* this must be called inside a transaction */
void reiserfs_block_writes(struct reiserfs_transaction_handle *th)
{
	struct reiserfs_journal *journal = SB_JOURNAL(th->t_super);
	BUG_ON(!th->t_trans_id);
	journal->j_must_wait = 1;
	set_bit(J_WRITERS_BLOCKED, &journal->j_state);
	return;
}

/* this must be called without a transaction started */
void reiserfs_allow_writes(struct super_block *s)
{
	struct reiserfs_journal *journal = SB_JOURNAL(s);
	clear_bit(J_WRITERS_BLOCKED, &journal->j_state);
	wake_up(&journal->j_join_wait);
}

/* this must be called without a transaction started */
void reiserfs_wait_on_write_block(struct super_block *s)
{
	struct reiserfs_journal *journal = SB_JOURNAL(s);
	wait_event(journal->j_join_wait,
		   !test_bit(J_WRITERS_BLOCKED, &journal->j_state));
}

static void queue_log_writer(struct super_block *s)
{
	wait_queue_entry_t wait;
	struct reiserfs_journal *journal = SB_JOURNAL(s);
	set_bit(J_WRITERS_QUEUED, &journal->j_state);

	/*
	 * we don't want to use wait_event here because
	 * we only want to wait once.
	 */
	init_waitqueue_entry(&wait, current);
	add_wait_queue(&journal->j_join_wait, &wait);
	set_current_state(TASK_UNINTERRUPTIBLE);
	if (test_bit(J_WRITERS_QUEUED, &journal->j_state)) {
		int depth = reiserfs_write_unlock_nested(s);
		schedule();
		reiserfs_write_lock_nested(s, depth);
	}
	__set_current_state(TASK_RUNNING);
	remove_wait_queue(&journal->j_join_wait, &wait);
}

static void wake_queued_writers(struct super_block *s)
{
	struct reiserfs_journal *journal = SB_JOURNAL(s);
	if (test_and_clear_bit(J_WRITERS_QUEUED, &journal->j_state))
		wake_up(&journal->j_join_wait);
}

static void let_transaction_grow(struct super_block *sb, unsigned int trans_id)
{
	struct reiserfs_journal *journal = SB_JOURNAL(sb);
	unsigned long bcount = journal->j_bcount;
	while (1) {
		int depth;

		depth = reiserfs_write_unlock_nested(sb);
		schedule_timeout_uninterruptible(1);
		reiserfs_write_lock_nested(sb, depth);

		journal->j_current_jl->j_state |= LIST_COMMIT_PENDING;
		while ((atomic_read(&journal->j_wcount) > 0 ||
			atomic_read(&journal->j_jlock)) &&
		       journal->j_trans_id == trans_id) {
			queue_log_writer(sb);
		}
		if (journal->j_trans_id != trans_id)
			break;
		if (bcount == journal->j_bcount)
			break;
		bcount = journal->j_bcount;
	}
}

/*
 * join == true if you must join an existing transaction.
 * join == false if you can deal with waiting for others to finish
 *
 * this will block until the transaction is joinable.  send the number of
 * blocks you expect to use in nblocks.
*/
static int do_journal_begin_r(struct reiserfs_transaction_handle *th,
			      struct super_block *sb, unsigned long nblocks,
			      int join)
{
	time_t now = get_seconds();
	unsigned int old_trans_id;
	struct reiserfs_journal *journal = SB_JOURNAL(sb);
	struct reiserfs_transaction_handle myth;
	int sched_count = 0;
	int retval;
	int depth;

	reiserfs_check_lock_depth(sb, "journal_begin");
	BUG_ON(nblocks > journal->j_trans_max);

	PROC_INFO_INC(sb, journal.journal_being);
	/* set here for journal_join */
	th->t_refcount = 1;
	th->t_super = sb;

relock:
	lock_journal(sb);
	if (join != JBEGIN_ABORT && reiserfs_is_journal_aborted(journal)) {
		unlock_journal(sb);
		retval = journal->j_errno;
		goto out_fail;
	}
	journal->j_bcount++;

	if (test_bit(J_WRITERS_BLOCKED, &journal->j_state)) {
		unlock_journal(sb);
		depth = reiserfs_write_unlock_nested(sb);
		reiserfs_wait_on_write_block(sb);
		reiserfs_write_lock_nested(sb, depth);
		PROC_INFO_INC(sb, journal.journal_relock_writers);
		goto relock;
	}
	now = get_seconds();

	/*
	 * if there is no room in the journal OR
	 * if this transaction is too old, and we weren't called joinable,
	 * wait for it to finish before beginning we don't sleep if there
	 * aren't other writers
	 */

	if ((!join && journal->j_must_wait > 0) ||
	    (!join
	     && (journal->j_len_alloc + nblocks + 2) >= journal->j_max_batch)
	    || (!join && atomic_read(&journal->j_wcount) > 0
		&& journal->j_trans_start_time > 0
		&& (now - journal->j_trans_start_time) >
		journal->j_max_trans_age) || (!join
					      && atomic_read(&journal->j_jlock))
	    || (!join && journal->j_cnode_free < (journal->j_trans_max * 3))) {

		old_trans_id = journal->j_trans_id;
		/* allow others to finish this transaction */
		unlock_journal(sb);

		if (!join && (journal->j_len_alloc + nblocks + 2) >=
		    journal->j_max_batch &&
		    ((journal->j_len + nblocks + 2) * 100) <
		    (journal->j_len_alloc * 75)) {
			if (atomic_read(&journal->j_wcount) > 10) {
				sched_count++;
				queue_log_writer(sb);
				goto relock;
			}
		}
		/*
		 * don't mess with joining the transaction if all we
		 * have to do is wait for someone else to do a commit
		 */
		if (atomic_read(&journal->j_jlock)) {
			while (journal->j_trans_id == old_trans_id &&
			       atomic_read(&journal->j_jlock)) {
				queue_log_writer(sb);
			}
			goto relock;
		}
		retval = journal_join(&myth, sb);
		if (retval)
			goto out_fail;

		/* someone might have ended the transaction while we joined */
		if (old_trans_id != journal->j_trans_id) {
			retval = do_journal_end(&myth, 0);
		} else {
			retval = do_journal_end(&myth, COMMIT_NOW);
		}

		if (retval)
			goto out_fail;

		PROC_INFO_INC(sb, journal.journal_relock_wcount);
		goto relock;
	}
	/* we are the first writer, set trans_id */
	if (journal->j_trans_start_time == 0) {
		journal->j_trans_start_time = get_seconds();
	}
	atomic_inc(&journal->j_wcount);
	journal->j_len_alloc += nblocks;
	th->t_blocks_logged = 0;
	th->t_blocks_allocated = nblocks;
	th->t_trans_id = journal->j_trans_id;
	unlock_journal(sb);
	INIT_LIST_HEAD(&th->t_list);
	return 0;

out_fail:
	memset(th, 0, sizeof(*th));
	/*
	 * Re-set th->t_super, so we can properly keep track of how many
	 * persistent transactions there are. We need to do this so if this
	 * call is part of a failed restart_transaction, we can free it later
	 */
	th->t_super = sb;
	return retval;
}

struct reiserfs_transaction_handle *reiserfs_persistent_transaction(struct
								    super_block
								    *s,
								    int nblocks)
{
	int ret;
	struct reiserfs_transaction_handle *th;

	/*
	 * if we're nesting into an existing transaction.  It will be
	 * persistent on its own
	 */
	if (reiserfs_transaction_running(s)) {
		th = current->journal_info;
		th->t_refcount++;
		BUG_ON(th->t_refcount < 2);

		return th;
	}
	th = kmalloc(sizeof(struct reiserfs_transaction_handle), GFP_NOFS);
	if (!th)
		return NULL;
	ret = journal_begin(th, s, nblocks);
	if (ret) {
		kfree(th);
		return NULL;
	}

	SB_JOURNAL(s)->j_persistent_trans++;
	return th;
}

int reiserfs_end_persistent_transaction(struct reiserfs_transaction_handle *th)
{
	struct super_block *s = th->t_super;
	int ret = 0;
	if (th->t_trans_id)
		ret = journal_end(th);
	else
		ret = -EIO;
	if (th->t_refcount == 0) {
		SB_JOURNAL(s)->j_persistent_trans--;
		kfree(th);
	}
	return ret;
}

static int journal_join(struct reiserfs_transaction_handle *th,
			struct super_block *sb)
{
	struct reiserfs_transaction_handle *cur_th = current->journal_info;

	/*
	 * this keeps do_journal_end from NULLing out the
	 * current->journal_info pointer
	 */
	th->t_handle_save = cur_th;
	BUG_ON(cur_th && cur_th->t_refcount > 1);
	return do_journal_begin_r(th, sb, 1, JBEGIN_JOIN);
}

int journal_join_abort(struct reiserfs_transaction_handle *th,
		       struct super_block *sb)
{
	struct reiserfs_transaction_handle *cur_th = current->journal_info;

	/*
	 * this keeps do_journal_end from NULLing out the
	 * current->journal_info pointer
	 */
	th->t_handle_save = cur_th;
	BUG_ON(cur_th && cur_th->t_refcount > 1);
	return do_journal_begin_r(th, sb, 1, JBEGIN_ABORT);
}

int journal_begin(struct reiserfs_transaction_handle *th,
		  struct super_block *sb, unsigned long nblocks)
{
	struct reiserfs_transaction_handle *cur_th = current->journal_info;
	int ret;

	th->t_handle_save = NULL;
	if (cur_th) {
		/* we are nesting into the current transaction */
		if (cur_th->t_super == sb) {
			BUG_ON(!cur_th->t_refcount);
			cur_th->t_refcount++;
			memcpy(th, cur_th, sizeof(*th));
			if (th->t_refcount <= 1)
				reiserfs_warning(sb, "reiserfs-2005",
						 "BAD: refcount <= 1, but "
						 "journal_info != 0");
			return 0;
		} else {
			/*
			 * we've ended up with a handle from a different
			 * filesystem.  save it and restore on journal_end.
			 * This should never really happen...
			 */
			reiserfs_warning(sb, "clm-2100",
					 "nesting info a different FS");
			th->t_handle_save = current->journal_info;
			current->journal_info = th;
		}
	} else {
		current->journal_info = th;
	}
	ret = do_journal_begin_r(th, sb, nblocks, JBEGIN_REG);
	BUG_ON(current->journal_info != th);

	/*
	 * I guess this boils down to being the reciprocal of clm-2100 above.
	 * If do_journal_begin_r fails, we need to put it back, since
	 * journal_end won't be called to do it. */
	if (ret)
		current->journal_info = th->t_handle_save;
	else
		BUG_ON(!th->t_refcount);

	return ret;
}

/*
 * puts bh into the current transaction.  If it was already there, reorders
 * removes the old pointers from the hash, and puts new ones in (to make
 * sure replay happen in the right order).
 *
 * if it was dirty, cleans and files onto the clean list.  I can't let it
 * be dirty again until the transaction is committed.
 *
 * if j_len, is bigger than j_len_alloc, it pushes j_len_alloc to 10 + j_len.
 */
int journal_mark_dirty(struct reiserfs_transaction_handle *th,
		       struct buffer_head *bh)
{
	struct super_block *sb = th->t_super;
	struct reiserfs_journal *journal = SB_JOURNAL(sb);
	struct reiserfs_journal_cnode *cn = NULL;
	int count_already_incd = 0;
	int prepared = 0;
	BUG_ON(!th->t_trans_id);

	PROC_INFO_INC(sb, journal.mark_dirty);
	if (th->t_trans_id != journal->j_trans_id) {
		reiserfs_panic(th->t_super, "journal-1577",
			       "handle trans id %ld != current trans id %ld",
			       th->t_trans_id, journal->j_trans_id);
	}

	prepared = test_clear_buffer_journal_prepared(bh);
	clear_buffer_journal_restore_dirty(bh);
	/* already in this transaction, we are done */
	if (buffer_journaled(bh)) {
		PROC_INFO_INC(sb, journal.mark_dirty_already);
		return 0;
	}

	/*
	 * this must be turned into a panic instead of a warning.  We can't
	 * allow a dirty or journal_dirty or locked buffer to be logged, as
	 * some changes could get to disk too early.  NOT GOOD.
	 */
	if (!prepared || buffer_dirty(bh)) {
		reiserfs_warning(sb, "journal-1777",
				 "buffer %llu bad state "
				 "%cPREPARED %cLOCKED %cDIRTY %cJDIRTY_WAIT",
				 (unsigned long long)bh->b_blocknr,
				 prepared ? ' ' : '!',
				 buffer_locked(bh) ? ' ' : '!',
				 buffer_dirty(bh) ? ' ' : '!',
				 buffer_journal_dirty(bh) ? ' ' : '!');
	}

	if (atomic_read(&journal->j_wcount) <= 0) {
		reiserfs_warning(sb, "journal-1409",
				 "returning because j_wcount was %d",
				 atomic_read(&journal->j_wcount));
		return 1;
	}
	/*
	 * this error means I've screwed up, and we've overflowed
	 * the transaction.  Nothing can be done here, except make the
	 * FS readonly or panic.
	 */
	if (journal->j_len >= journal->j_trans_max) {
		reiserfs_panic(th->t_super, "journal-1413",
			       "j_len (%lu) is too big",
			       journal->j_len);
	}

	if (buffer_journal_dirty(bh)) {
		count_already_incd = 1;
		PROC_INFO_INC(sb, journal.mark_dirty_notjournal);
		clear_buffer_journal_dirty(bh);
	}

	if (journal->j_len > journal->j_len_alloc) {
		journal->j_len_alloc = journal->j_len + JOURNAL_PER_BALANCE_CNT;
	}

	set_buffer_journaled(bh);

	/* now put this guy on the end */
	if (!cn) {
		cn = get_cnode(sb);
		if (!cn) {
			reiserfs_panic(sb, "journal-4", "get_cnode failed!");
		}

		if (th->t_blocks_logged == th->t_blocks_allocated) {
			th->t_blocks_allocated += JOURNAL_PER_BALANCE_CNT;
			journal->j_len_alloc += JOURNAL_PER_BALANCE_CNT;
		}
		th->t_blocks_logged++;
		journal->j_len++;

		cn->bh = bh;
		cn->blocknr = bh->b_blocknr;
		cn->sb = sb;
		cn->jlist = NULL;
		insert_journal_hash(journal->j_hash_table, cn);
		if (!count_already_incd) {
			get_bh(bh);
		}
	}
	cn->next = NULL;
	cn->prev = journal->j_last;
	cn->bh = bh;
	if (journal->j_last) {
		journal->j_last->next = cn;
		journal->j_last = cn;
	} else {
		journal->j_first = cn;
		journal->j_last = cn;
	}
	reiserfs_schedule_old_flush(sb);
	return 0;
}

int journal_end(struct reiserfs_transaction_handle *th)
{
	struct super_block *sb = th->t_super;
	if (!current->journal_info && th->t_refcount > 1)
		reiserfs_warning(sb, "REISER-NESTING",
				 "th NULL, refcount %d", th->t_refcount);

	if (!th->t_trans_id) {
		WARN_ON(1);
		return -EIO;
	}

	th->t_refcount--;
	if (th->t_refcount > 0) {
		struct reiserfs_transaction_handle *cur_th =
		    current->journal_info;

		/*
		 * we aren't allowed to close a nested transaction on a
		 * different filesystem from the one in the task struct
		 */
		BUG_ON(cur_th->t_super != th->t_super);

		if (th != cur_th) {
			memcpy(current->journal_info, th, sizeof(*th));
			th->t_trans_id = 0;
		}
		return 0;
	} else {
		return do_journal_end(th, 0);
	}
}

/*
 * removes from the current transaction, relsing and descrementing any counters.
 * also files the removed buffer directly onto the clean list
 *
 * called by journal_mark_freed when a block has been deleted
 *
 * returns 1 if it cleaned and relsed the buffer. 0 otherwise
 */
static int remove_from_transaction(struct super_block *sb,
				   b_blocknr_t blocknr, int already_cleaned)
{
	struct buffer_head *bh;
	struct reiserfs_journal_cnode *cn;
	struct reiserfs_journal *journal = SB_JOURNAL(sb);
	int ret = 0;

	cn = get_journal_hash_dev(sb, journal->j_hash_table, blocknr);
	if (!cn || !cn->bh) {
		return ret;
	}
	bh = cn->bh;
	if (cn->prev) {
		cn->prev->next = cn->next;
	}
	if (cn->next) {
		cn->next->prev = cn->prev;
	}
	if (cn == journal->j_first) {
		journal->j_first = cn->next;
	}
	if (cn == journal->j_last) {
		journal->j_last = cn->prev;
	}
	if (bh)
		remove_journal_hash(sb, journal->j_hash_table, NULL,
				    bh->b_blocknr, 0);
	clear_buffer_journaled(bh);	/* don't log this one */

	if (!already_cleaned) {
		clear_buffer_journal_dirty(bh);
		clear_buffer_dirty(bh);
		clear_buffer_journal_test(bh);
		put_bh(bh);
		if (atomic_read(&bh->b_count) < 0) {
			reiserfs_warning(sb, "journal-1752",
					 "b_count < 0");
		}
		ret = 1;
	}
	journal->j_len--;
	journal->j_len_alloc--;
	free_cnode(sb, cn);
	return ret;
}

/*
 * for any cnode in a journal list, it can only be dirtied of all the
 * transactions that include it are committed to disk.
 * this checks through each transaction, and returns 1 if you are allowed
 * to dirty, and 0 if you aren't
 *
 * it is called by dirty_journal_list, which is called after
 * flush_commit_list has gotten all the log blocks for a given
 * transaction on disk
 *
 */
static int can_dirty(struct reiserfs_journal_cnode *cn)
{
	struct super_block *sb = cn->sb;
	b_blocknr_t blocknr = cn->blocknr;
	struct reiserfs_journal_cnode *cur = cn->hprev;
	int can_dirty = 1;

	/*
	 * first test hprev.  These are all newer than cn, so any node here
	 * with the same block number and dev means this node can't be sent
	 * to disk right now.
	 */
	while (cur && can_dirty) {
		if (cur->jlist && cur->bh && cur->blocknr && cur->sb == sb &&
		    cur->blocknr == blocknr) {
			can_dirty = 0;
		}
		cur = cur->hprev;
	}
	/*
	 * then test hnext.  These are all older than cn.  As long as they
	 * are committed to the log, it is safe to write cn to disk
	 */
	cur = cn->hnext;
	while (cur && can_dirty) {
		if (cur->jlist && cur->jlist->j_len > 0 &&
		    atomic_read(&cur->jlist->j_commit_left) > 0 && cur->bh &&
		    cur->blocknr && cur->sb == sb && cur->blocknr == blocknr) {
			can_dirty = 0;
		}
		cur = cur->hnext;
	}
	return can_dirty;
}

/*
 * syncs the commit blocks, but does not force the real buffers to disk
 * will wait until the current transaction is done/committed before returning
 */
int journal_end_sync(struct reiserfs_transaction_handle *th)
{
	struct super_block *sb = th->t_super;
	struct reiserfs_journal *journal = SB_JOURNAL(sb);

	BUG_ON(!th->t_trans_id);
	/* you can sync while nested, very, very bad */
	BUG_ON(th->t_refcount > 1);
	if (journal->j_len == 0) {
		reiserfs_prepare_for_journal(sb, SB_BUFFER_WITH_SB(sb),
					     1);
		journal_mark_dirty(th, SB_BUFFER_WITH_SB(sb));
	}
	return do_journal_end(th, COMMIT_NOW | WAIT);
}

/* writeback the pending async commits to disk */
static void flush_async_commits(struct work_struct *work)
{
	struct reiserfs_journal *journal =
		container_of(work, struct reiserfs_journal, j_work.work);
	struct super_block *sb = journal->j_work_sb;
	struct reiserfs_journal_list *jl;
	struct list_head *entry;

	reiserfs_write_lock(sb);
	if (!list_empty(&journal->j_journal_list)) {
		/* last entry is the youngest, commit it and you get everything */
		entry = journal->j_journal_list.prev;
		jl = JOURNAL_LIST_ENTRY(entry);
		flush_commit_list(sb, jl, 1);
	}
	reiserfs_write_unlock(sb);
}

/*
 * flushes any old transactions to disk
 * ends the current transaction if it is too old
 */
void reiserfs_flush_old_commits(struct super_block *sb)
{
	time_t now;
	struct reiserfs_transaction_handle th;
	struct reiserfs_journal *journal = SB_JOURNAL(sb);

	now = get_seconds();
	/*
	 * safety check so we don't flush while we are replaying the log during
	 * mount
	 */
	if (list_empty(&journal->j_journal_list))
		return;

	/*
	 * check the current transaction.  If there are no writers, and it is
	 * too old, finish it, and force the commit blocks to disk
	 */
	if (atomic_read(&journal->j_wcount) <= 0 &&
	    journal->j_trans_start_time > 0 &&
	    journal->j_len > 0 &&
	    (now - journal->j_trans_start_time) > journal->j_max_trans_age) {
		if (!journal_join(&th, sb)) {
			reiserfs_prepare_for_journal(sb,
						     SB_BUFFER_WITH_SB(sb),
						     1);
			journal_mark_dirty(&th, SB_BUFFER_WITH_SB(sb));

			/*
			 * we're only being called from kreiserfsd, it makes
			 * no sense to do an async commit so that kreiserfsd
			 * can do it later
			 */
			do_journal_end(&th, COMMIT_NOW | WAIT);
		}
	}
}

/*
 * returns 0 if do_journal_end should return right away, returns 1 if
 * do_journal_end should finish the commit
 *
 * if the current transaction is too old, but still has writers, this will
 * wait on j_join_wait until all the writers are done.  By the time it
 * wakes up, the transaction it was called has already ended, so it just
 * flushes the commit list and returns 0.
 *
 * Won't batch when flush or commit_now is set.  Also won't batch when
 * others are waiting on j_join_wait.
 *
 * Note, we can't allow the journal_end to proceed while there are still
 * writers in the log.
 */
static int check_journal_end(struct reiserfs_transaction_handle *th, int flags)
{

	time_t now;
	int flush = flags & FLUSH_ALL;
	int commit_now = flags & COMMIT_NOW;
	int wait_on_commit = flags & WAIT;
	struct reiserfs_journal_list *jl;
	struct super_block *sb = th->t_super;
	struct reiserfs_journal *journal = SB_JOURNAL(sb);

	BUG_ON(!th->t_trans_id);

	if (th->t_trans_id != journal->j_trans_id) {
		reiserfs_panic(th->t_super, "journal-1577",
			       "handle trans id %ld != current trans id %ld",
			       th->t_trans_id, journal->j_trans_id);
	}

	journal->j_len_alloc -= (th->t_blocks_allocated - th->t_blocks_logged);
	/* <= 0 is allowed.  unmounting might not call begin */
	if (atomic_read(&journal->j_wcount) > 0)
		atomic_dec(&journal->j_wcount);

	/*
	 * BUG, deal with case where j_len is 0, but people previously
	 * freed blocks need to be released will be dealt with by next
	 * transaction that actually writes something, but should be taken
	 * care of in this trans
	 */
	BUG_ON(journal->j_len == 0);

	/*
	 * if wcount > 0, and we are called to with flush or commit_now,
	 * we wait on j_join_wait.  We will wake up when the last writer has
	 * finished the transaction, and started it on its way to the disk.
	 * Then, we flush the commit or journal list, and just return 0
	 * because the rest of journal end was already done for this
	 * transaction.
	 */
	if (atomic_read(&journal->j_wcount) > 0) {
		if (flush || commit_now) {
			unsigned trans_id;

			jl = journal->j_current_jl;
			trans_id = jl->j_trans_id;
			if (wait_on_commit)
				jl->j_state |= LIST_COMMIT_PENDING;
			atomic_set(&journal->j_jlock, 1);
			if (flush) {
				journal->j_next_full_flush = 1;
			}
			unlock_journal(sb);

			/*
			 * sleep while the current transaction is
			 * still j_jlocked
			 */
			while (journal->j_trans_id == trans_id) {
				if (atomic_read(&journal->j_jlock)) {
					queue_log_writer(sb);
				} else {
					lock_journal(sb);
					if (journal->j_trans_id == trans_id) {
						atomic_set(&journal->j_jlock,
							   1);
					}
					unlock_journal(sb);
				}
			}
			BUG_ON(journal->j_trans_id == trans_id);

			if (commit_now
			    && journal_list_still_alive(sb, trans_id)
			    && wait_on_commit) {
				flush_commit_list(sb, jl, 1);
			}
			return 0;
		}
		unlock_journal(sb);
		return 0;
	}

	/* deal with old transactions where we are the last writers */
	now = get_seconds();
	if ((now - journal->j_trans_start_time) > journal->j_max_trans_age) {
		commit_now = 1;
		journal->j_next_async_flush = 1;
	}
	/* don't batch when someone is waiting on j_join_wait */
	/* don't batch when syncing the commit or flushing the whole trans */
	if (!(journal->j_must_wait > 0) && !(atomic_read(&journal->j_jlock))
	    && !flush && !commit_now && (journal->j_len < journal->j_max_batch)
	    && journal->j_len_alloc < journal->j_max_batch
	    && journal->j_cnode_free > (journal->j_trans_max * 3)) {
		journal->j_bcount++;
		unlock_journal(sb);
		return 0;
	}

	if (journal->j_start > SB_ONDISK_JOURNAL_SIZE(sb)) {
		reiserfs_panic(sb, "journal-003",
			       "j_start (%ld) is too high",
			       journal->j_start);
	}
	return 1;
}

/*
 * Does all the work that makes deleting blocks safe.
 * when deleting a block mark BH_JNew, just remove it from the current
 * transaction, clean it's buffer_head and move on.
 *
 * otherwise:
 * set a bit for the block in the journal bitmap.  That will prevent it from
 * being allocated for unformatted nodes before this transaction has finished.
 *
 * mark any cnodes for this block as BLOCK_FREED, and clear their bh pointers.
 * That will prevent any old transactions with this block from trying to flush
 * to the real location.  Since we aren't removing the cnode from the
 * journal_list_hash, *the block can't be reallocated yet.
 *
 * Then remove it from the current transaction, decrementing any counters and
 * filing it on the clean list.
 */
int journal_mark_freed(struct reiserfs_transaction_handle *th,
		       struct super_block *sb, b_blocknr_t blocknr)
{
	struct reiserfs_journal *journal = SB_JOURNAL(sb);
	struct reiserfs_journal_cnode *cn = NULL;
	struct buffer_head *bh = NULL;
	struct reiserfs_list_bitmap *jb = NULL;
	int cleaned = 0;
	BUG_ON(!th->t_trans_id);

	cn = get_journal_hash_dev(sb, journal->j_hash_table, blocknr);
	if (cn && cn->bh) {
		bh = cn->bh;
		get_bh(bh);
	}
	/* if it is journal new, we just remove it from this transaction */
	if (bh && buffer_journal_new(bh)) {
		clear_buffer_journal_new(bh);
		clear_prepared_bits(bh);
		reiserfs_clean_and_file_buffer(bh);
		cleaned = remove_from_transaction(sb, blocknr, cleaned);
	} else {
		/*
		 * set the bit for this block in the journal bitmap
		 * for this transaction
		 */
		jb = journal->j_current_jl->j_list_bitmap;
		if (!jb) {
			reiserfs_panic(sb, "journal-1702",
				       "journal_list_bitmap is NULL");
		}
		set_bit_in_list_bitmap(sb, blocknr, jb);

		/* Note, the entire while loop is not allowed to schedule.  */

		if (bh) {
			clear_prepared_bits(bh);
			reiserfs_clean_and_file_buffer(bh);
		}
		cleaned = remove_from_transaction(sb, blocknr, cleaned);

		/*
		 * find all older transactions with this block,
		 * make sure they don't try to write it out
		 */
		cn = get_journal_hash_dev(sb, journal->j_list_hash_table,
					  blocknr);
		while (cn) {
			if (sb == cn->sb && blocknr == cn->blocknr) {
				set_bit(BLOCK_FREED, &cn->state);
				if (cn->bh) {
					/*
					 * remove_from_transaction will brelse
					 * the buffer if it was in the current
					 * trans
					 */
					if (!cleaned) {
						clear_buffer_journal_dirty(cn->
									   bh);
						clear_buffer_dirty(cn->bh);
						clear_buffer_journal_test(cn->
									  bh);
						cleaned = 1;
						put_bh(cn->bh);
						if (atomic_read
						    (&cn->bh->b_count) < 0) {
							reiserfs_warning(sb,
								 "journal-2138",
								 "cn->bh->b_count < 0");
						}
					}
					/*
					 * since we are clearing the bh,
					 * we MUST dec nonzerolen
					 */
					if (cn->jlist) {
						atomic_dec(&cn->jlist->
							   j_nonzerolen);
					}
					cn->bh = NULL;
				}
			}
			cn = cn->hnext;
		}
	}

	if (bh)
		release_buffer_page(bh); /* get_hash grabs the buffer */
	return 0;
}

void reiserfs_update_inode_transaction(struct inode *inode)
{
	struct reiserfs_journal *journal = SB_JOURNAL(inode->i_sb);
	REISERFS_I(inode)->i_jl = journal->j_current_jl;
	REISERFS_I(inode)->i_trans_id = journal->j_trans_id;
}

/*
 * returns -1 on error, 0 if no commits/barriers were done and 1
 * if a transaction was actually committed and the barrier was done
 */
static int __commit_trans_jl(struct inode *inode, unsigned long id,
			     struct reiserfs_journal_list *jl)
{
	struct reiserfs_transaction_handle th;
	struct super_block *sb = inode->i_sb;
	struct reiserfs_journal *journal = SB_JOURNAL(sb);
	int ret = 0;

	/*
	 * is it from the current transaction,
	 * or from an unknown transaction?
	 */
	if (id == journal->j_trans_id) {
		jl = journal->j_current_jl;
		/*
		 * try to let other writers come in and
		 * grow this transaction
		 */
		let_transaction_grow(sb, id);
		if (journal->j_trans_id != id) {
			goto flush_commit_only;
		}

		ret = journal_begin(&th, sb, 1);
		if (ret)
			return ret;

		/* someone might have ended this transaction while we joined */
		if (journal->j_trans_id != id) {
			reiserfs_prepare_for_journal(sb, SB_BUFFER_WITH_SB(sb),
						     1);
			journal_mark_dirty(&th, SB_BUFFER_WITH_SB(sb));
			ret = journal_end(&th);
			goto flush_commit_only;
		}

		ret = journal_end_sync(&th);
		if (!ret)
			ret = 1;

	} else {
		/*
		 * this gets tricky, we have to make sure the journal list in
		 * the inode still exists.  We know the list is still around
		 * if we've got a larger transaction id than the oldest list
		 */
flush_commit_only:
		if (journal_list_still_alive(inode->i_sb, id)) {
			/*
			 * we only set ret to 1 when we know for sure
			 * the barrier hasn't been started yet on the commit
			 * block.
			 */
			if (atomic_read(&jl->j_commit_left) > 1)
				ret = 1;
			flush_commit_list(sb, jl, 1);
			if (journal->j_errno)
				ret = journal->j_errno;
		}
	}
	/* otherwise the list is gone, and long since committed */
	return ret;
}

int reiserfs_commit_for_inode(struct inode *inode)
{
	unsigned int id = REISERFS_I(inode)->i_trans_id;
	struct reiserfs_journal_list *jl = REISERFS_I(inode)->i_jl;

	/*
	 * for the whole inode, assume unset id means it was
	 * changed in the current transaction.  More conservative
	 */
	if (!id || !jl) {
		reiserfs_update_inode_transaction(inode);
		id = REISERFS_I(inode)->i_trans_id;
		/* jl will be updated in __commit_trans_jl */
	}

	return __commit_trans_jl(inode, id, jl);
}

void reiserfs_restore_prepared_buffer(struct super_block *sb,
				      struct buffer_head *bh)
{
	struct reiserfs_journal *journal = SB_JOURNAL(sb);
	PROC_INFO_INC(sb, journal.restore_prepared);
	if (!bh) {
		return;
	}
	if (test_clear_buffer_journal_restore_dirty(bh) &&
	    buffer_journal_dirty(bh)) {
		struct reiserfs_journal_cnode *cn;
		reiserfs_write_lock(sb);
		cn = get_journal_hash_dev(sb,
					  journal->j_list_hash_table,
					  bh->b_blocknr);
		if (cn && can_dirty(cn)) {
			set_buffer_journal_test(bh);
			mark_buffer_dirty(bh);
		}
		reiserfs_write_unlock(sb);
	}
	clear_buffer_journal_prepared(bh);
}

extern struct tree_balance *cur_tb;
/*
 * before we can change a metadata block, we have to make sure it won't
 * be written to disk while we are altering it.  So, we must:
 * clean it
 * wait on it.
 */
int reiserfs_prepare_for_journal(struct super_block *sb,
				 struct buffer_head *bh, int wait)
{
	PROC_INFO_INC(sb, journal.prepare);

	if (!trylock_buffer(bh)) {
		if (!wait)
			return 0;
		lock_buffer(bh);
	}
	set_buffer_journal_prepared(bh);
	if (test_clear_buffer_dirty(bh) && buffer_journal_dirty(bh)) {
		clear_buffer_journal_test(bh);
		set_buffer_journal_restore_dirty(bh);
	}
	unlock_buffer(bh);
	return 1;
}

/*
 * long and ugly.  If flush, will not return until all commit
 * blocks and all real buffers in the trans are on disk.
 * If no_async, won't return until all commit blocks are on disk.
 *
 * keep reading, there are comments as you go along
 *
 * If the journal is aborted, we just clean up. Things like flushing
 * journal lists, etc just won't happen.
 */
static int do_journal_end(struct reiserfs_transaction_handle *th, int flags)
{
	struct super_block *sb = th->t_super;
	struct reiserfs_journal *journal = SB_JOURNAL(sb);
	struct reiserfs_journal_cnode *cn, *next, *jl_cn;
	struct reiserfs_journal_cnode *last_cn = NULL;
	struct reiserfs_journal_desc *desc;
	struct reiserfs_journal_commit *commit;
	struct buffer_head *c_bh;	/* commit bh */
	struct buffer_head *d_bh;	/* desc bh */
	int cur_write_start = 0;	/* start index of current log write */
	int old_start;
	int i;
	int flush;
	int wait_on_commit;
	struct reiserfs_journal_list *jl, *temp_jl;
	struct list_head *entry, *safe;
	unsigned long jindex;
	unsigned int commit_trans_id;
	int trans_half;
	int depth;

	BUG_ON(th->t_refcount > 1);
	BUG_ON(!th->t_trans_id);
	BUG_ON(!th->t_super);

	/*
	 * protect flush_older_commits from doing mistakes if the
	 * transaction ID counter gets overflowed.
	 */
	if (th->t_trans_id == ~0U)
		flags |= FLUSH_ALL | COMMIT_NOW | WAIT;
	flush = flags & FLUSH_ALL;
	wait_on_commit = flags & WAIT;

	current->journal_info = th->t_handle_save;
	reiserfs_check_lock_depth(sb, "journal end");
	if (journal->j_len == 0) {
		reiserfs_prepare_for_journal(sb, SB_BUFFER_WITH_SB(sb),
					     1);
		journal_mark_dirty(th, SB_BUFFER_WITH_SB(sb));
	}

	lock_journal(sb);
	if (journal->j_next_full_flush) {
		flags |= FLUSH_ALL;
		flush = 1;
	}
	if (journal->j_next_async_flush) {
		flags |= COMMIT_NOW | WAIT;
		wait_on_commit = 1;
	}

	/*
	 * check_journal_end locks the journal, and unlocks if it does
	 * not return 1 it tells us if we should continue with the
	 * journal_end, or just return
	 */
	if (!check_journal_end(th, flags)) {
		reiserfs_schedule_old_flush(sb);
		wake_queued_writers(sb);
		reiserfs_async_progress_wait(sb);
		goto out;
	}

	/* check_journal_end might set these, check again */
	if (journal->j_next_full_flush) {
		flush = 1;
	}

	/*
	 * j must wait means we have to flush the log blocks, and the
	 * real blocks for this transaction
	 */
	if (journal->j_must_wait > 0) {
		flush = 1;
	}
#ifdef REISERFS_PREALLOCATE
	/*
	 * quota ops might need to nest, setup the journal_info pointer
	 * for them and raise the refcount so that it is > 0.
	 */
	current->journal_info = th;
	th->t_refcount++;

	/* it should not involve new blocks into the transaction */
	reiserfs_discard_all_prealloc(th);

	th->t_refcount--;
	current->journal_info = th->t_handle_save;
#endif

	/* setup description block */
	d_bh =
	    journal_getblk(sb,
			   SB_ONDISK_JOURNAL_1st_BLOCK(sb) +
			   journal->j_start);
	set_buffer_uptodate(d_bh);
	desc = (struct reiserfs_journal_desc *)(d_bh)->b_data;
	memset(d_bh->b_data, 0, d_bh->b_size);
	memcpy(get_journal_desc_magic(d_bh), JOURNAL_DESC_MAGIC, 8);
	set_desc_trans_id(desc, journal->j_trans_id);

	/*
	 * setup commit block.  Don't write (keep it clean too) this one
	 * until after everyone else is written
	 */
	c_bh = journal_getblk(sb, SB_ONDISK_JOURNAL_1st_BLOCK(sb) +
			      ((journal->j_start + journal->j_len +
				1) % SB_ONDISK_JOURNAL_SIZE(sb)));
	commit = (struct reiserfs_journal_commit *)c_bh->b_data;
	memset(c_bh->b_data, 0, c_bh->b_size);
	set_commit_trans_id(commit, journal->j_trans_id);
	set_buffer_uptodate(c_bh);

	/* init this journal list */
	jl = journal->j_current_jl;

	/*
	 * we lock the commit before doing anything because
	 * we want to make sure nobody tries to run flush_commit_list until
	 * the new transaction is fully setup, and we've already flushed the
	 * ordered bh list
	 */
	reiserfs_mutex_lock_safe(&jl->j_commit_mutex, sb);

	/* save the transaction id in case we need to commit it later */
	commit_trans_id = jl->j_trans_id;

	atomic_set(&jl->j_older_commits_done, 0);
	jl->j_trans_id = journal->j_trans_id;
	jl->j_timestamp = journal->j_trans_start_time;
	jl->j_commit_bh = c_bh;
	jl->j_start = journal->j_start;
	jl->j_len = journal->j_len;
	atomic_set(&jl->j_nonzerolen, journal->j_len);
	atomic_set(&jl->j_commit_left, journal->j_len + 2);
	jl->j_realblock = NULL;

	/*
	 * The ENTIRE FOR LOOP MUST not cause schedule to occur.
	 * for each real block, add it to the journal list hash,
	 * copy into real block index array in the commit or desc block
	 */
	trans_half = journal_trans_half(sb->s_blocksize);
	for (i = 0, cn = journal->j_first; cn; cn = cn->next, i++) {
		if (buffer_journaled(cn->bh)) {
			jl_cn = get_cnode(sb);
			if (!jl_cn) {
				reiserfs_panic(sb, "journal-1676",
					       "get_cnode returned NULL");
			}
			if (i == 0) {
				jl->j_realblock = jl_cn;
			}
			jl_cn->prev = last_cn;
			jl_cn->next = NULL;
			if (last_cn) {
				last_cn->next = jl_cn;
			}
			last_cn = jl_cn;
			/*
			 * make sure the block we are trying to log
			 * is not a block of journal or reserved area
			 */
			if (is_block_in_log_or_reserved_area
			    (sb, cn->bh->b_blocknr)) {
				reiserfs_panic(sb, "journal-2332",
					       "Trying to log block %lu, "
					       "which is a log block",
					       cn->bh->b_blocknr);
			}
			jl_cn->blocknr = cn->bh->b_blocknr;
			jl_cn->state = 0;
			jl_cn->sb = sb;
			jl_cn->bh = cn->bh;
			jl_cn->jlist = jl;
			insert_journal_hash(journal->j_list_hash_table, jl_cn);
			if (i < trans_half) {
				desc->j_realblock[i] =
				    cpu_to_le32(cn->bh->b_blocknr);
			} else {
				commit->j_realblock[i - trans_half] =
				    cpu_to_le32(cn->bh->b_blocknr);
			}
		} else {
			i--;
		}
	}
	set_desc_trans_len(desc, journal->j_len);
	set_desc_mount_id(desc, journal->j_mount_id);
	set_desc_trans_id(desc, journal->j_trans_id);
	set_commit_trans_len(commit, journal->j_len);

	/*
	 * special check in case all buffers in the journal
	 * were marked for not logging
	 */
	BUG_ON(journal->j_len == 0);

	/*
	 * we're about to dirty all the log blocks, mark the description block
	 * dirty now too.  Don't mark the commit block dirty until all the
	 * others are on disk
	 */
	mark_buffer_dirty(d_bh);

	/*
	 * first data block is j_start + 1, so add one to
	 * cur_write_start wherever you use it
	 */
	cur_write_start = journal->j_start;
	cn = journal->j_first;
	jindex = 1;	/* start at one so we don't get the desc again */
	while (cn) {
		clear_buffer_journal_new(cn->bh);
		/* copy all the real blocks into log area.  dirty log blocks */
		if (buffer_journaled(cn->bh)) {
			struct buffer_head *tmp_bh;
			char *addr;
			struct page *page;
			tmp_bh =
			    journal_getblk(sb,
					   SB_ONDISK_JOURNAL_1st_BLOCK(sb) +
					   ((cur_write_start +
					     jindex) %
					    SB_ONDISK_JOURNAL_SIZE(sb)));
			set_buffer_uptodate(tmp_bh);
			page = cn->bh->b_page;
			addr = kmap(page);
			memcpy(tmp_bh->b_data,
			       addr + offset_in_page(cn->bh->b_data),
			       cn->bh->b_size);
			kunmap(page);
			mark_buffer_dirty(tmp_bh);
			jindex++;
			set_buffer_journal_dirty(cn->bh);
			clear_buffer_journaled(cn->bh);
		} else {
			/*
			 * JDirty cleared sometime during transaction.
			 * don't log this one
			 */
			reiserfs_warning(sb, "journal-2048",
					 "BAD, buffer in journal hash, "
					 "but not JDirty!");
			brelse(cn->bh);
		}
		next = cn->next;
		free_cnode(sb, cn);
		cn = next;
		reiserfs_cond_resched(sb);
	}

	/*
	 * we are done with both the c_bh and d_bh, but
	 * c_bh must be written after all other commit blocks,
	 * so we dirty/relse c_bh in flush_commit_list, with commit_left <= 1.
	 */

	journal->j_current_jl = alloc_journal_list(sb);

	/* now it is safe to insert this transaction on the main list */
	list_add_tail(&jl->j_list, &journal->j_journal_list);
	list_add_tail(&jl->j_working_list, &journal->j_working_list);
	journal->j_num_work_lists++;

	/* reset journal values for the next transaction */
	old_start = journal->j_start;
	journal->j_start =
	    (journal->j_start + journal->j_len +
	     2) % SB_ONDISK_JOURNAL_SIZE(sb);
	atomic_set(&journal->j_wcount, 0);
	journal->j_bcount = 0;
	journal->j_last = NULL;
	journal->j_first = NULL;
	journal->j_len = 0;
	journal->j_trans_start_time = 0;
	/* check for trans_id overflow */
	if (++journal->j_trans_id == 0)
		journal->j_trans_id = 10;
	journal->j_current_jl->j_trans_id = journal->j_trans_id;
	journal->j_must_wait = 0;
	journal->j_len_alloc = 0;
	journal->j_next_full_flush = 0;
	journal->j_next_async_flush = 0;
	init_journal_hash(sb);

	/*
	 * make sure reiserfs_add_jh sees the new current_jl before we
	 * write out the tails
	 */
	smp_mb();

	/*
	 * tail conversion targets have to hit the disk before we end the
	 * transaction.  Otherwise a later transaction might repack the tail
	 * before this transaction commits, leaving the data block unflushed
	 * and clean, if we crash before the later transaction commits, the
	 * data block is lost.
	 */
	if (!list_empty(&jl->j_tail_bh_list)) {
		depth = reiserfs_write_unlock_nested(sb);
		write_ordered_buffers(&journal->j_dirty_buffers_lock,
				      journal, jl, &jl->j_tail_bh_list);
		reiserfs_write_lock_nested(sb, depth);
	}
	BUG_ON(!list_empty(&jl->j_tail_bh_list));
	mutex_unlock(&jl->j_commit_mutex);

	/*
	 * honor the flush wishes from the caller, simple commits can
	 * be done outside the journal lock, they are done below
	 *
	 * if we don't flush the commit list right now, we put it into
	 * the work queue so the people waiting on the async progress work
	 * queue don't wait for this proc to flush journal lists and such.
	 */
	if (flush) {
		flush_commit_list(sb, jl, 1);
		flush_journal_list(sb, jl, 1);
	} else if (!(jl->j_state & LIST_COMMIT_PENDING)) {
		/*
		 * Avoid queueing work when sb is being shut down. Transaction
		 * will be flushed on journal shutdown.
		 */
		if (sb->s_flags & MS_ACTIVE)
			queue_delayed_work(REISERFS_SB(sb)->commit_wq,
					   &journal->j_work, HZ / 10);
	}

	/*
	 * if the next transaction has any chance of wrapping, flush
	 * transactions that might get overwritten.  If any journal lists
	 * are very old flush them as well.
	 */
first_jl:
	list_for_each_safe(entry, safe, &journal->j_journal_list) {
		temp_jl = JOURNAL_LIST_ENTRY(entry);
		if (journal->j_start <= temp_jl->j_start) {
			if ((journal->j_start + journal->j_trans_max + 1) >=
			    temp_jl->j_start) {
				flush_used_journal_lists(sb, temp_jl);
				goto first_jl;
			} else if ((journal->j_start +
				    journal->j_trans_max + 1) <
				   SB_ONDISK_JOURNAL_SIZE(sb)) {
				/*
				 * if we don't cross into the next
				 * transaction and we don't wrap, there is
				 * no way we can overlap any later transactions
				 * break now
				 */
				break;
			}
		} else if ((journal->j_start +
			    journal->j_trans_max + 1) >
			   SB_ONDISK_JOURNAL_SIZE(sb)) {
			if (((journal->j_start + journal->j_trans_max + 1) %
			     SB_ONDISK_JOURNAL_SIZE(sb)) >=
			    temp_jl->j_start) {
				flush_used_journal_lists(sb, temp_jl);
				goto first_jl;
			} else {
				/*
				* we don't overlap anything from out start
				* to the end of the log, and our wrapped
				* portion doesn't overlap anything at
				* the start of the log.  We can break
				*/
				break;
			}
		}
	}

	journal->j_current_jl->j_list_bitmap =
	    get_list_bitmap(sb, journal->j_current_jl);

	if (!(journal->j_current_jl->j_list_bitmap)) {
		reiserfs_panic(sb, "journal-1996",
			       "could not get a list bitmap");
	}

	atomic_set(&journal->j_jlock, 0);
	unlock_journal(sb);
	/* wake up any body waiting to join. */
	clear_bit(J_WRITERS_QUEUED, &journal->j_state);
	wake_up(&journal->j_join_wait);

	if (!flush && wait_on_commit &&
	    journal_list_still_alive(sb, commit_trans_id)) {
		flush_commit_list(sb, jl, 1);
	}
out:
	reiserfs_check_lock_depth(sb, "journal end2");

	memset(th, 0, sizeof(*th));
	/*
	 * Re-set th->t_super, so we can properly keep track of how many
	 * persistent transactions there are. We need to do this so if this
	 * call is part of a failed restart_transaction, we can free it later
	 */
	th->t_super = sb;

	return journal->j_errno;
}

/* Send the file system read only and refuse new transactions */
void reiserfs_abort_journal(struct super_block *sb, int errno)
{
	struct reiserfs_journal *journal = SB_JOURNAL(sb);
	if (test_bit(J_ABORTED, &journal->j_state))
		return;

	if (!journal->j_errno)
		journal->j_errno = errno;

	sb->s_flags |= MS_RDONLY;
	set_bit(J_ABORTED, &journal->j_state);

#ifdef CONFIG_REISERFS_CHECK
	dump_stack();
#endif
}
