/* 
 * QNX4 file system, Linux implementation.
 * 
 * Version : 0.1
 * 
 * Using parts of the xiafs filesystem.
 * 
 * History :
 * 
 * 24-03-1998 by Richard Frowijn : first release.
 */

#include <linux/config.h>
#include <linux/errno.h>
#include <linux/time.h>
#include <linux/stat.h>
#include <linux/fcntl.h>
#include <linux/smp_lock.h>
#include <linux/buffer_head.h>

#include <linux/fs.h>
#include <linux/qnx4_fs.h>

#include <asm/system.h>

/*
 * The functions for qnx4 fs file synchronization.
 */

#ifdef CONFIG_QNX4FS_RW

static int sync_block(struct inode *inode, unsigned short *block, int wait)
{
	struct buffer_head *bh;
	unsigned short tmp;

	if (!*block)
		return 0;
	tmp = *block;
	bh = sb_find_get_block(inode->i_sb, *block);
	if (!bh)
		return 0;
	if (*block != tmp) {
		brelse(bh);
		return 1;
	}
	if (wait && buffer_req(bh) && !buffer_uptodate(bh)) {
		brelse(bh);
		return -1;
	}
	if (wait || !buffer_uptodate(bh) || !buffer_dirty(bh)) {
		brelse(bh);
		return 0;
	}
	ll_rw_block(WRITE, 1, &bh);
	atomic_dec(&bh->b_count);
	return 0;
}

#ifdef WTF
static int sync_iblock(struct inode *inode, unsigned short *iblock,
		       struct buffer_head **bh, int wait)
{
	int rc;
	unsigned short tmp;

	*bh = NULL;
	tmp = *iblock;
	if (!tmp)
		return 0;
	rc = sync_block(inode, iblock, wait);
	if (rc)
		return rc;
	*bh = sb_bread(inode->i_sb, tmp);
	if (tmp != *iblock) {
		brelse(*bh);
		*bh = NULL;
		return 1;
	}
	if (!*bh)
		return -1;
	return 0;
}
#endif

static int sync_direct(struct inode *inode, int wait)
{
	int i;
	int rc, err = 0;

	for (i = 0; i < 7; i++) {
		rc = sync_block(inode,
				(unsigned short *) qnx4_raw_inode(inode)->di_first_xtnt.xtnt_blk + i, wait);
		if (rc > 0)
			break;
		if (rc)
			err = rc;
	}
	return err;
}

#ifdef WTF
static int sync_indirect(struct inode *inode, unsigned short *iblock, int wait)
{
	int i;
	struct buffer_head *ind_bh;
	int rc, err = 0;

	rc = sync_iblock(inode, iblock, &ind_bh, wait);
	if (rc || !ind_bh)
		return rc;

	for (i = 0; i < 512; i++) {
		rc = sync_block(inode,
				((unsigned short *) ind_bh->b_data) + i,
				wait);
		if (rc > 0)
			break;
		if (rc)
			err = rc;
	}
	brelse(ind_bh);
	return err;
}

static int sync_dindirect(struct inode *inode, unsigned short *diblock,
			  int wait)
{
	int i;
	struct buffer_head *dind_bh;
	int rc, err = 0;

	rc = sync_iblock(inode, diblock, &dind_bh, wait);
	if (rc || !dind_bh)
		return rc;

	for (i = 0; i < 512; i++) {
		rc = sync_indirect(inode,
				((unsigned short *) dind_bh->b_data) + i,
				   wait);
		if (rc > 0)
			break;
		if (rc)
			err = rc;
	}
	brelse(dind_bh);
	return err;
}
#endif

int qnx4_sync_file(struct file *file, struct dentry *dentry, int unused)
{
        struct inode *inode = dentry->d_inode;
	int wait, err = 0;
        
        (void) file;
	if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
	      S_ISLNK(inode->i_mode)))
		return -EINVAL;

	lock_kernel();
	for (wait = 0; wait <= 1; wait++) {
		err |= sync_direct(inode, wait);
	}
	err |= qnx4_sync_inode(inode);
	unlock_kernel();
	return (err < 0) ? -EIO : 0;
}

#endif
